cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gkossakow...@apache.org
Subject svn commit: r564760 - in /cocoon/trunk: blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/ core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ core/cocoon-expres...
Date Fri, 10 Aug 2007 20:42:37 GMT
Author: gkossakowski
Date: Fri Aug 10 13:42:36 2007
New Revision: 564760

URL: http://svn.apache.org/viewvc?view=rev&rev=564760
Log:
COCOON-2086:
  * Added putAt() method to ObjectModel interface. Main purpose of this method is to add value
to ObjectModel so it is available at given path.
  * Implemented putAt() method in ObjectModelImpl class.
  * Added new tests for ObjectModelImpl's putAt() implementation.
  * switched to putAt() method in various places where hacks were used previously.

Modified:
    cocoon/trunk/blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/JXTemplateGenerator.java
    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/main/java/org/apache/cocoon/template/environment/FlowObjectModelHelper.java
    cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
    cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/FlowHelper.java

Modified: cocoon/trunk/blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/JXTemplateGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/JXTemplateGenerator.java?view=diff&rev=564760&r1=564759&r2=564760
==============================================================================
--- cocoon/trunk/blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/JXTemplateGenerator.java
(original)
+++ cocoon/trunk/blocks/cocoon-template/cocoon-template-impl/src/main/java/org/apache/cocoon/template/JXTemplateGenerator.java
Fri Aug 10 13:42:36 2007
@@ -145,7 +145,8 @@
         newObjectModel.markLocalContext();
         FlowObjectModelHelper.fillNewObjectModelWithFOM(newObjectModel, objectModel, parameters);
         XMLConsumer consumer = new AttributeAwareXMLConsumerImpl(new RedundantNamespacesFilter(this.xmlConsumer));
-        ((Map) newObjectModel.get("cocoon")).put("consumer", consumer);
+        //not sure why this is needed
+        newObjectModel.putAt("cocoon/consumer", consumer);
         Invoker.execute(consumer, this.newObjectModel, new ExecutionContext(this.definitions,
this.scriptManager,
                 this.manager), null, namespaces, startEvent, null);
         newObjectModel.cleanupLocalContext();

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=564760&r1=564759&r2=564760
==============================================================================
--- 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 Aug 10 13:42:36 2007
@@ -60,6 +60,17 @@
     public void cleanupLocalContext();
 
     /**
+     * Puts object at certain <code>path</code>. Each segment of path is separated
by "/" symbol. This method
+     * supports only traversing through objects implementing {@link Map} interface. If certain
segment does not exist it
+     * will be created automatically.
+     * 
+     * @param path
+     *            where the <code>value</code> should be put at
+     * @param value that is going to be put
+     */
+    public void putAt(String path, Object value);
+
+    /**
      * <p>
      * Copies properties (both static and dynamic) of current context bean to the Object
Model. The method is useful
      * when you want, for example, to access properties of context bean in JEXL expression
and omit

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=564760&r1=564759&r2=564760
==============================================================================
--- 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 Aug 10 13:42:36 2007
@@ -43,9 +43,12 @@
 public class ObjectModelImpl extends AbstractMapDecorator implements ObjectModel {
     //FIXME: It seems that there is no easy way to reuse MuliValueMap
     
+    private static final String SEGMENT_SEPARATOR = "/";
+    
     private ArrayStack localContexts;
     private Map singleValueMap;
     private MultiMap multiValueMap;
+    private MultiMap multiValueMapForLocated;
     private Map initialEntries = null;
     
     public ObjectModelImpl() {
@@ -53,6 +56,7 @@
         super.map = UnmodifiableMap.decorate(singleValueMap);
         localContexts = new ArrayStack();
         multiValueMap = MultiValueMap.decorate(new HashMap(), StackReversedIteration.class);
+        multiValueMapForLocated = MultiValueMap.decorate(new HashMap(), StackReversedIteration.class);
     }
 
     public static class StackReversedIteration extends ArrayStack {
@@ -99,21 +103,89 @@
         singleValueMap.putAll(mapToCopy);
         multiValueMap.putAll(mapToCopy);
     }
+    
+    /**
+     * Locates map at given path
+     * @param path where Map can be found
+     * @param createIfNeeded indicates if map(s) should be created if no corresponding found
+     * @return located Map or null if <code>createIfNeeded</code> is false and
Map cannot be found
+     */
+    private Map locateMapAt(String path, boolean createIfNeeded) {
+        if (path.lastIndexOf(SEGMENT_SEPARATOR) == -1)
+            return this;
+        
+        Map map = this;
+        int segmentBegin = 0;
+        int segmentEnd = path.indexOf(SEGMENT_SEPARATOR);
+        while (segmentEnd != -1) {
+            String key = path.substring(segmentBegin, segmentEnd);
+            if (map.containsKey(key)) {
+                Object obj = map.get(key);
+                if (!(obj instanceof Map))
+                    throw new ClassCastException("Object at path " + path.substring(0, segmentEnd)
+ "is not a Map");
+                map = (Map)obj;
+            } else {
+                if (!createIfNeeded)
+                    return null;
+                Map newMap = new HashMap();
+                map.put(key, newMap);
+                map = newMap;
+            }
+            segmentBegin = segmentEnd + 1;
+            segmentEnd = path.indexOf(SEGMENT_SEPARATOR, segmentBegin);
+        }
+        return map;
+    }
+    
+    public void putAt(String path, Object value) {
+        if (path == null)
+            throw new NullPointerException("Path cannot be null.");
+        if (path.length() == 0)
+            throw new IllegalArgumentException("Path cannot be empty");
+        
+        Map map = locateMapAt(path, true);
+        String key = path.substring(path.lastIndexOf(SEGMENT_SEPARATOR) + 1, path.length());
+        if (!localContexts.empty())
+            ((ArrayStack) localContexts.peek()).push(new PathValue(path, value));
+        map.put(key, value);
+    }
+    
+    private void removeAt(String path, Object value) {
+        if (path == null)
+            throw new NullPointerException("Path cannot be null.");
+        if (path.length() == 0)
+            throw new IllegalArgumentException("Path cannot be empty");
+        
+        Map map = locateMapAt(path, false);
+        String key = path.substring(path.lastIndexOf(SEGMENT_SEPARATOR) + 1, path.length());
+        if (map == null)
+            return;
+        multiValueMapForLocated.remove(key, value);
+        if (multiValueMap.containsKey(key))
+            map.put(key, ((StackReversedIteration)multiValueMap.get(key)).peek());
+        else
+            map.remove(key);
+    }
 
     public void cleanupLocalContext() {
         if (localContexts.empty())
             throw new IllegalStateException("Local contexts stack is empty");
         ArrayStack removeEntries = (ArrayStack)localContexts.pop();
         while (!removeEntries.isEmpty()) {
-            KeyValue entry = (KeyValue)removeEntries.pop();
-            Object key = entry.getKey();
-            Object value = entry.getValue();
+            if (removeEntries.peek() instanceof PathValue) {
+                PathValue entry = (PathValue)removeEntries.pop(); 
+                removeAt(entry.getPath(), entry.getValue());
+            } else {
+                KeyValue entry = (KeyValue)removeEntries.pop();
+                Object key = entry.getKey();
+                Object value = entry.getValue();
             
-            multiValueMap.remove(key, value);
-            if (multiValueMap.containsKey(key))
-                singleValueMap.put(key, ((StackReversedIteration)multiValueMap.get(key)).peek());
-            else
-                singleValueMap.remove(key);
+                multiValueMap.remove(key, value);
+                if (multiValueMap.containsKey(key))
+                    singleValueMap.put(key, ((StackReversedIteration)multiValueMap.get(key)).peek());
+                else
+                    singleValueMap.remove(key);
+            }
         }
     }
 
@@ -178,5 +250,24 @@
             }
         }
     }
+    
+    private final class PathValue {
+        private String path;
+        private Object value;
+        
+        public PathValue(String path, Object value) {
+            this.path = path;
+            this.value = value;
+        }
+        
+        public String getPath() { 
+            return this.path; 
+        };
+        
+        public Object getValue() {
+            return this.value;
+        }
+        
+    };
     
 }

Modified: cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/template/environment/FlowObjectModelHelper.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/template/environment/FlowObjectModelHelper.java?view=diff&rev=564760&r1=564759&r2=564760
==============================================================================
--- cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/template/environment/FlowObjectModelHelper.java
(original)
+++ cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/template/environment/FlowObjectModelHelper.java
Fri Aug 10 13:42:36 2007
@@ -40,7 +40,7 @@
     public static void fillNewObjectModelWithFOM(ObjectModel newObjectModel, 
                                                             final Map objectModel, final
Parameters parameters) {
         
-        ((Map)newObjectModel.get("cocoon")).put("parameters", new ParametersMap(parameters));
+        newObjectModel.putAt("cocoon/parameters", new ParametersMap(parameters));
     }
 
 }

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=564760&r1=564759&r2=564760
==============================================================================
--- 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 Aug 10 13:42:36 2007
@@ -17,6 +17,7 @@
 package org.apache.cocoon.objectmodel;
 
 import java.util.Collection;
+import java.util.Map;
 
 import junit.framework.TestCase;
 
@@ -109,5 +110,46 @@
         ObjectModel objectModel = new ObjectModelImpl();
         assertEquals(objectModel, objectModel.get("this"));
     }
-    
+
+    public void testKeyAsPath() {
+        ObjectModel objectModel = new ObjectModelImpl();
+        
+        objectModel.putAt("foo", "bar");
+        assertEquals("bar", objectModel.get("foo"));
+    }
+
+    public void testPutAt() {
+        ObjectModel objectModel = new ObjectModelImpl();
+        
+        objectModel.putAt("foo/bar", "xyz");
+        assertTrue(objectModel.containsKey("foo"));
+        assertTrue(objectModel.get("foo") instanceof Map);
+        assertEquals(((Map)objectModel.get("foo")).get("bar"), "xyz");
+    }
+
+    public void testPathInLocalContext() {
+        ObjectModel objectModel = new ObjectModelImpl();
+        
+        objectModel.markLocalContext();
+        objectModel.putAt("foo/bar", "xyz");
+        
+        objectModel.markLocalContext();
+        objectModel.putAt("foo2/bar", "abc");
+        assertEquals(((Map)objectModel.get("foo")).get("bar"), "xyz");
+        assertEquals(((Map)objectModel.get("foo2")).get("bar"), "abc");
+        objectModel.cleanupLocalContext();
+        
+        assertEquals(((Map)objectModel.get("foo")).get("bar"), "xyz");
+        assertTrue(!objectModel.containsKey("foo2"));
+        objectModel.cleanupLocalContext();
+        
+        assertTrue(objectModel.isEmpty());
+    }
+
+    public void testIfMapIsCreated() {
+        ObjectModel objectModel = new ObjectModelImpl();
+        
+        objectModel.putAt("foo/bar/xyz", "abc");
+        assertTrue(((Map)objectModel.get("foo")).get("bar") instanceof Map);
+    }
 }

Modified: cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/FlowHelper.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/FlowHelper.java?view=diff&rev=564760&r1=564759&r2=564760
==============================================================================
--- cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/FlowHelper.java
(original)
+++ cocoon/trunk/core/cocoon-sitemap/cocoon-sitemap-impl/src/main/java/org/apache/cocoon/components/flow/FlowHelper.java
Fri Aug 10 13:42:36 2007
@@ -76,8 +76,7 @@
     public final static void setWebContinuation(Map objectModel,
                                           ObjectModel newObjectModel, WebContinuation kont)
{
         objectModel.put(CONTINUATION_OBJECT, kont);
-        //FIXME: I think there should be a better way to do this (GK)
-        ((Map)newObjectModel.get("cocoon")).put("continuation", kont);
+        newObjectModel.putAt("cocoon/continuation", kont);
     }
 
     /**



Mime
View raw message