You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by gk...@apache.org on 2007/07/17 21:06:15 UTC
svn commit: r557030 - in
/cocoon/whiteboard/objectmodel/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-expressi...
Author: gkossakowski
Date: Tue Jul 17 12:06:12 2007
New Revision: 557030
URL: http://svn.apache.org/viewvc?view=rev&rev=557030
Log:
COCOON-2086:
* changed constracts for ObjectModel interface, more in javadoc comments
* dropped use of MultiValueMap because it did not conform to new ObjectModel interface
* added test case testing new implementation of ObjectModelImpl
Added:
cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/
cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java (with props)
Modified:
cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
Modified: cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java?view=diff&rev=557030&r1=557029&r2=557030
==============================================================================
--- cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java (original)
+++ cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/objectmodel/ObjectModel.java Tue Jul 17 12:06:12 2007
@@ -16,12 +16,16 @@
*/
package org.apache.cocoon.objectmodel;
+import java.util.Map;
+
import org.apache.commons.collections.MultiMap;
/**
- * ObjectModel is just a {@link MultiMap} with little more constrained and changed contracts.
+ * 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.
*
- * One difference is that Collection for each key is compliant with LIFO list constracts. Another is about {@link #get(Object)} method.
+ * Another constrain is that {@link java.util.Collection} for each key is compliant with LIFO list constracts.
*/
public interface ObjectModel extends MultiMap {
Modified: cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java?view=diff&rev=557030&r1=557029&r2=557030
==============================================================================
--- cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java (original)
+++ cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/main/java/org/apache/cocoon/objectmodel/ObjectModelImpl.java Tue Jul 17 12:06:12 2007
@@ -16,39 +16,29 @@
*/
package org.apache.cocoon.objectmodel;
+import java.util.AbstractCollection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import org.apache.commons.collections.ArrayStack;
-import org.apache.commons.collections.Factory;
+import org.apache.commons.collections.iterators.IteratorChain;
import org.apache.commons.collections.iterators.ReverseListIterator;
-import org.apache.commons.collections.map.MultiValueMap;
+import org.apache.commons.collections.iterators.SingletonIterator;
+import org.apache.commons.collections.map.AbstractMapDecorator;
/**
* Prototype implementation of {@link ObjectModel} interface. It <b>must</b> be initialized manually for now.
*
*/
-public class ObjectModelImpl extends MultiValueMap implements ObjectModel {
+public class ObjectModelImpl extends AbstractMapDecorator implements ObjectModel {
//FIXME: It seems that there is no easy way to reuse MuliValueMap
-
- public ObjectModelImpl() {
- super(new HashMap(), new Factory() {
-
- public Object create() {
- return new StackReversedIteration();
- }
-
- });
- }
- public Object get(Object key) {
- Collection collection = (Collection)super.get(key);
- //if there is exactly one element in collection, return it instead of collection
- return collection != null && (collection.size() == 1) ? collection.iterator().next() : collection;
+ public ObjectModelImpl() {
+ super(new HashMap());
}
-
+
private static class StackReversedIteration extends ArrayStack {
public Iterator iterator() {
@@ -59,4 +49,115 @@
throw new UnsupportedOperationException();
}
}
+
+ public Object put(Object key, Object 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;
+ }
+ }
+
+ 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();
+ }
+ }
+
}
Added: cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java?view=auto&rev=557030
==============================================================================
--- cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java (added)
+++ cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java Tue Jul 17 12:06:12 2007
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.objectmodel;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class ObjectModelImplTestCase extends TestCase {
+
+ public void testMap() {
+ ObjectModel objectModel = new ObjectModelImpl();
+
+ 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.put("foo", "bar1");
+ objectModel.put("foo", "bar2");
+ assertEquals(2, ((Collection)objectModel.get("foo")).size());
+
+ objectModel.remove("foo", "bar2");
+ assertEquals("bar1", objectModel.get("foo"));
+
+ objectModel.remove("foo", "bar1");
+ assertEquals(null, objectModel.get("foo"));
+ }
+
+ public void testValues() {
+ ObjectModel objectModel = new ObjectModelImpl();
+
+ objectModel.put("foo", "bar1");
+ Collection values = objectModel.values();
+ assertEquals(true, values.contains("bar1"));
+
+ objectModel.put("foo", "bar2");
+ values = objectModel.values();
+ assertEquals(true, values.contains("bar1"));
+ assertEquals(true, values.contains("bar2"));
+
+ objectModel.remove("foo", "bar1");
+ values = objectModel.values();
+ assertEquals(false, values.contains("bar1"));
+ }
+
+}
Propchange: cocoon/whiteboard/objectmodel/cocoon-expression-language/cocoon-expression-language-impl/src/test/java/org/apache/cocoon/objectmodel/ObjectModelImplTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native