cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gkossakow...@apache.org
Subject svn commit: r558020 - in /cocoon/trunk/core/cocoon-expression-language: cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ cocoon-expression-language-...
Date Fri, 20 Jul 2007 15:29:49 GMT
Author: gkossakowski
Date: Fri Jul 20 08:29:48 2007
New Revision: 558020

URL: http://svn.apache.org/viewvc?view=rev&rev=558020
Log:
COCOON-2086:
  * redesigned (again) ObjectModel interface, it is now plain Map with two additional methods
  * adapted ObjectModelImpl and test case to new interface

Modified:
    cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
    cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
    cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java

Modified: cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java?view=diff&rev=558020&r1=558019&r2=558020
==============================================================================
--- cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
(original)
+++ cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
Fri Jul 20 08:29:48 2007
@@ -18,26 +18,31 @@
 
 import java.util.Map;
 
-import org.apache.commons.collections.MultiMap;
-
 /**
- * ObjectModel is a special {@link Map} that can have multiple values associated to the same
key. If there is only one
- * value associated with key then ObjectModel will behave exactly as {@link Map}. If there
is more than one value associated with
- * key then ObjectModel's methods will operate on {@link java.util.Collection Collections}
associated with key. 
- * 
- * Another constrain is that {@link java.util.Collection} for each key is compliant with
LIFO list constracts. 
+ * ObjectModel is a special {@link Map} that cannot be modified using standard {@link Map}
methods, except {@link #put(Object, Object)} method.   
  */
-public interface ObjectModel extends MultiMap {
+public interface ObjectModel extends Map {
     
     public static final String CONTEXTBEAN = "contextBean";
     public static final String NAMESPACE = "namespace";
-
+    
+    /**
+     * @return a {@link org.apache.commons.collections.MultiMap} that contains all stored
values in all context in LIFO-compliant order.
+     * Returned {@link org.apache.commons.collections.MultiMap} is {@link org.apache.commons.collections.Unmodifiable}.
+     */
+    public Map getAll();
+    
+    /**
+     * Works exactly the same way as {@link Map#put(Object, Object)} but previous value associated
to <code>key</code> is not lost in
+     * a case {@link #markLocalContext()} was called before. The previous value is stored
and can be recovered by calling 
+     * {@link #markLocalContext()}.
+     */
+    public Object put(Object key, Object value);
     
     /** 
-     * This method behaves almost exactly as {@link MultiMap#get(Object)} method. The only
difference is that value itself is returned
-     * instead of {@link java.util.Collection} containing that value.
+     * @see #put(Object, Object)
      */
-    public Object get(Object key);
+    public void putAll(Map mapToCopy);
     
     /**
      * Marks new local context. Such mark is useful to do a clean up of entries. 

Modified: cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java?view=diff&rev=558020&r1=558019&r2=558020
==============================================================================
--- cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
(original)
+++ cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
Fri Jul 20 08:29:48 2007
@@ -16,7 +16,6 @@
  */
 package org.apache.cocoon.objectmodel;
 
-import java.util.AbstractCollection;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -26,11 +25,12 @@
 
 import org.apache.commons.collections.ArrayStack;
 import org.apache.commons.collections.KeyValue;
-import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.collections.MultiMap;
 import org.apache.commons.collections.iterators.ReverseListIterator;
-import org.apache.commons.collections.iterators.SingletonIterator;
 import org.apache.commons.collections.keyvalue.DefaultKeyValue;
 import org.apache.commons.collections.map.AbstractMapDecorator;
+import org.apache.commons.collections.map.MultiValueMap;
+import org.apache.commons.collections.map.UnmodifiableMap;
 
 /**
  * Prototype implementation of {@link ObjectModel} interface. It <b>must</b>
be initialized manually for now.
@@ -40,13 +40,17 @@
     //FIXME: It seems that there is no easy way to reuse MuliValueMap
     
     private ArrayStack localContexts;
+    private Map singleValueMap;
+    private MultiMap multiValueMap;
     
     public ObjectModelImpl() {
-        super(new HashMap());
+        singleValueMap = new HashMap();
+        super.map = UnmodifiableMap.decorate(singleValueMap);
         localContexts = new ArrayStack();
+        multiValueMap = MultiValueMap.decorate(new HashMap(), StackReversedIteration.class);
     }
 
-    private static class StackReversedIteration extends ArrayStack {
+    public static class StackReversedIteration extends ArrayStack {
         
         public Iterator iterator() {
             return new ReverseListIterator(this);
@@ -57,24 +61,18 @@
         }
     }
     
+    public Map getAll() {
+        return UnmodifiableMap.decorate(multiValueMap);
+    }
+    
     public Object put(Object key, Object value) {
         if (!localContexts.empty())
             ((Collection) localContexts.peek()).add(new DefaultKeyValue(key, value));
         
-        Object valuesForKey = getMap().get(key);
-        if (valuesForKey == null) {
-            super.put(key, value);
-            return value;
-        }
-        else if (valuesForKey instanceof StackReversedIteration)
-            return ((StackReversedIteration) valuesForKey).add(value) ? value : null;
-        else {
-            StackReversedIteration stack = new StackReversedIteration();
-            stack.add(valuesForKey);
-            stack.add(value);
-            super.put(key, stack);
-            return value;
-        }
+        singleValueMap.put(key, value);
+        multiValueMap.put(key, value);
+        
+        return value;
     }
     
     public void putAll(Map mapToCopy) {
@@ -86,100 +84,8 @@
             }
         }
         
-        super.putAll(mapToCopy);
-    }
-
-    public Object remove(Object key, Object item) {
-        Object valuesForKey = getMap().get(key);
-        if (valuesForKey == null)
-            return null;
-        else if (valuesForKey instanceof StackReversedIteration) {
-            StackReversedIteration stack = (StackReversedIteration)valuesForKey;
-            boolean changed = stack.remove(item);
-            if (stack.size() == 1) {
-                super.put(key, stack.pop());
-                changed = true;
-            }
-            return changed ? item : null;
-        } 
-        else
-            return super.remove(key);
-    }
-    
-    /**
-     * Gets the total size of the map by counting all the values.
-     *
-     * @return the total size of the map counting all values
-     */
-    public int totalSize() {
-        int total = 0;
-        Collection values = getMap().values();
-        for (Iterator it = values.iterator(); it.hasNext();) {
-            Object object = it.next();
-            if (object instanceof StackReversedIteration)
-                total += ((Collection) object).size();
-            else
-                total++;
-        }
-        return total;
-    }
-    
-    public Collection values() {
-        return new Values();
-    }
-    
-    private class Values extends AbstractCollection {
-        public Iterator iterator() {
-            final IteratorChain chain = new IteratorChain();
-            for (Iterator it = keySet().iterator(); it.hasNext();) {
-                Object key = it.next();
-                Object object = get(key);
-                if (object instanceof StackReversedIteration)
-                    chain.addIterator(new ValuesIterator(key));
-                else
-                    //TODO: Implement removing
-                    chain.addIterator(new SingletonIterator(object, false));
-            }
-            return chain;
-        }
-
-        public int size() {
-            return totalSize();
-        }
-
-        public void clear() {
-            ObjectModelImpl.this.clear();
-        }
-    }
-
-    /**
-     * Inner class that provides the values iterator.
-     */
-    private class ValuesIterator implements Iterator {
-        private final Object key;
-        private final Collection values;
-        private final Iterator iterator;
-
-        public ValuesIterator(Object key) {
-            this.key = key;
-            this.values = (Collection)getMap().get(key);
-            this.iterator = values.iterator();
-        }
-
-        public void remove() {
-            iterator.remove();
-            if (values.isEmpty()) {
-                ObjectModelImpl.this.remove(key);
-            }
-        }
-
-        public boolean hasNext() {
-            return iterator.hasNext();
-        }
-
-        public Object next() {
-            return iterator.next();
-        }
+        singleValueMap.putAll(mapToCopy);
+        multiValueMap.putAll(mapToCopy);
     }
 
     public void cleanupLocalContext() {
@@ -187,8 +93,18 @@
             throw new IllegalStateException("Local contexts stack is empty");
         Collection removeEntries = (Collection)localContexts.pop();
         for (Iterator entriesIterator = removeEntries.iterator(); entriesIterator.hasNext();)
{
-            KeyValue entry = (KeyValue) entriesIterator.next();
-            remove(entry.getKey(), entry.getValue());
+            KeyValue entry = (KeyValue)entriesIterator.next();
+            Object key = entry.getKey();
+            Object value = entry.getValue();
+            if (!singleValueMap.containsKey(key))
+                continue;
+            
+            multiValueMap.remove(key, value);
+            if (!multiValueMap.containsKey(key)) {
+                singleValueMap.remove(key);
+            }
+            else if (singleValueMap.get(key).equals(value))
+                singleValueMap.put(key, ((StackReversedIteration)multiValueMap.get(key)).peek());
         }
     }
 

Modified: cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java?view=diff&rev=558020&r1=558019&r2=558020
==============================================================================
--- cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
(original)
+++ cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
Fri Jul 20 08:29:48 2007
@@ -28,24 +28,25 @@
         objectModel.put("foo1", "bar1");
         assertEquals("bar2", objectModel.put("foo2", "bar2")); 
         assertEquals(true, objectModel.containsKey("foo1"));
-        assertEquals("bar2", objectModel.get("foo2"));
-        
-        objectModel.remove("foo1");
-        assertEquals(null, objectModel.get("foo1"));
     }
     
     public void testMultiValue() {
         ObjectModel objectModel = new ObjectModelImpl();
         
+        objectModel.markLocalContext();
         objectModel.put("foo", "bar1");
+        
+        objectModel.markLocalContext();
         objectModel.put("foo", "bar2");
-        assertEquals(2, ((Collection)objectModel.get("foo")).size());
+        assertEquals(2, ((Collection)objectModel.getAll().get("foo")).size());
         
-        objectModel.remove("foo", "bar2");
+        objectModel.cleanupLocalContext();
+        assertEquals(1, ((Collection)objectModel.getAll().get("foo")).size());
         assertEquals("bar1", objectModel.get("foo"));
         
-        objectModel.remove("foo", "bar1");
+        objectModel.cleanupLocalContext();
         assertEquals(null, objectModel.get("foo"));
+        assertEquals(null, objectModel.getAll().get("foo"));
     }
     
     public void testValues() {
@@ -55,14 +56,15 @@
         Collection values = objectModel.values();
         assertEquals(true, values.contains("bar1"));
         
+        objectModel.markLocalContext();
         objectModel.put("foo", "bar2");
         values = objectModel.values();
-        assertEquals(true, values.contains("bar1"));
+        assertEquals(false, values.contains("bar1"));
         assertEquals(true, values.contains("bar2"));
         
-        objectModel.remove("foo", "bar1");
+        objectModel.cleanupLocalContext();
         values = objectModel.values();
-        assertEquals(false, values.contains("bar1"));
+        assertEquals(false, values.contains("bar2"));
     }
     
     public void testLocalContext() {
@@ -73,14 +75,14 @@
         objectModel.put("foo", "bar2");
         objectModel.put("abc", "xyz");
         
-        assertEquals(true, objectModel.values().contains("bar2"));
-        assertEquals(true, objectModel.values().contains("bar1"));
+        assertEquals(true, objectModel.getAll().values().contains("bar2"));
+        assertEquals(true, objectModel.getAll().values().contains("bar1"));
         assertEquals(true, objectModel.containsKey("abc"));
         
         objectModel.cleanupLocalContext();
         
-        assertEquals(false, objectModel.values().contains("bar2"));
-        assertEquals(true, objectModel.values().contains("bar1"));
+        assertEquals(false, objectModel.getAll().values().contains("bar2"));
+        assertEquals(true, objectModel.getAll().values().contains("bar1"));
         assertEquals(false, objectModel.containsKey("abc"));
     }
     



Mime
View raw message