diff --git a/src/java/org/apache/commons/collections/IteratorUtils.java b/src/java/org/apache/commons/collections/IteratorUtils.java index 35253d213..2600e088e 100644 --- a/src/java/org/apache/commons/collections/IteratorUtils.java +++ b/src/java/org/apache/commons/collections/IteratorUtils.java @@ -40,6 +40,7 @@ import org.apache.commons.collections.iterators.ListIteratorWrapper; import org.apache.commons.collections.iterators.LoopingIterator; import org.apache.commons.collections.iterators.ObjectArrayIterator; import org.apache.commons.collections.iterators.ObjectArrayListIterator; +import org.apache.commons.collections.iterators.ObjectGraphIterator; import org.apache.commons.collections.iterators.SingletonIterator; import org.apache.commons.collections.iterators.SingletonListIterator; import org.apache.commons.collections.iterators.TransformIterator; @@ -52,7 +53,7 @@ import org.apache.commons.collections.iterators.UnmodifiableMapIterator; * instances. The implementations are provided in the iterators subpackage. * * @since Commons Collections 2.1 - * @version $Revision: 1.22 $ $Date: 2004/02/18 01:15:42 $ + * @version $Revision: 1.23 $ $Date: 2004/03/20 00:21:08 $ * * @author Stephen Colebourne * @author Phil Steitz @@ -502,7 +503,65 @@ public class IteratorUtils { public static Iterator collatedIterator(Comparator comparator, Collection iterators) { return new CollatingIterator(comparator, iterators); } - + + // Object Graph + //----------------------------------------------------------------------- + /** + * Gets an iterator that operates over an object graph. + *

+ * This iterator can extract multiple objects from a complex tree-like object graph. + * The iteration starts from a single root object. + * It uses a Transformer to extract the iterators and elements. + * Its main benefit is that no intermediate List is created. + *

+ * For example, consider an object graph: + *

+     *                 |- Branch -- Leaf
+     *                 |         \- Leaf
+     *         |- Tree |         /- Leaf
+     *         |       |- Branch -- Leaf
+     *  Forest |                 \- Leaf
+     *         |       |- Branch -- Leaf
+     *         |       |         \- Leaf
+     *         |- Tree |         /- Leaf
+     *                 |- Branch -- Leaf
+     *                 |- Branch -- Leaf
+ * The following Transformer, used in this class, will extract all + * the Leaf objects without creating a combined intermediate list: + *
+     * public Object transform(Object input) {
+     *   if (input instanceof Forest) {
+     *     return ((Forest) input).treeIterator();
+     *   }
+     *   if (input instanceof Tree) {
+     *     return ((Tree) input).branchIterator();
+     *   }
+     *   if (input instanceof Branch) {
+     *     return ((Branch) input).leafIterator();
+     *   }
+     *   if (input instanceof Leaf) {
+     *     return input;
+     *   }
+     *   throw new ClassCastException();
+     * }
+ *

+ * Internally, iteration starts from the root object. When next is called, + * the transformer is called to examine the object. The transformer will return + * either an iterator or an object. If the object is an Iterator, the next element + * from that iterator is obtained and the process repeats. If the element is an object + * it is returned. + *

+ * Under many circumstances, linking Iterators together in this manner is + * more efficient (and convenient) than using nested for loops to extract a list. + * + * @param root the root object to start iterating from, null results in an empty iterator + * @param transformer the transformer to use, see above, null uses no effect transformer + * @return + */ + public static Iterator objectGraphIterator(Object root, Transformer transformer) { + return new ObjectGraphIterator(root, transformer); + } + // Transformed //----------------------------------------------------------------------- /** diff --git a/src/java/org/apache/commons/collections/iterators/TreeIterator.java b/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java similarity index 94% rename from src/java/org/apache/commons/collections/iterators/TreeIterator.java rename to src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java index 67cca9fed..7cb83e9b0 100644 --- a/src/java/org/apache/commons/collections/iterators/TreeIterator.java +++ b/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java @@ -71,11 +71,11 @@ import org.apache.commons.collections.TransformerUtils; * more efficient (and convenient) than using nested for loops to extract a list. * * @since Commons Collections 3.1 - * @version $Revision: 1.1 $ $Date: 2004/03/14 23:27:22 $ + * @version $Revision: 1.1 $ $Date: 2004/03/20 00:21:08 $ * * @author Stephen Colebourne */ -public class TreeIterator implements Iterator { +public class ObjectGraphIterator implements Iterator { /** The stack of iterators */ protected final ArrayStack stack = new ArrayStack(8); @@ -95,7 +95,7 @@ public class TreeIterator implements Iterator { //----------------------------------------------------------------------- /** - * Constructs a TreeIterator using a root object and transformer. + * Constructs an ObjectGraphIterator using a root object and transformer. *

* The root object can be an iterator, in which case it will be immediately * looped around. @@ -103,7 +103,7 @@ public class TreeIterator implements Iterator { * @param root the root object, null will result in an empty iterator * @param transformer the transformer to use, null will use a no effect transformer */ - public TreeIterator(Object root, Transformer transformer) { + public ObjectGraphIterator(Object root, Transformer transformer) { super(); if (root instanceof Iterator) { this.currentIterator = (Iterator) root; @@ -114,7 +114,7 @@ public class TreeIterator implements Iterator { } /** - * Constructs a TreeIterator that will handle an iterator of iterators. + * Constructs a ObjectGraphIterator that will handle an iterator of iterators. *

* This constructor exists for convenience to emphasise that this class can * be used to iterate over nested iterators. That is to say that the iterator @@ -123,7 +123,7 @@ public class TreeIterator implements Iterator { * * @param rootIterator the root iterator, null will result in an empty iterator */ - public TreeIterator(Iterator rootIterator) { + public ObjectGraphIterator(Iterator rootIterator) { super(); this.currentIterator = rootIterator; this.transformer = TransformerUtils.nopTransformer(); @@ -189,7 +189,7 @@ public class TreeIterator implements Iterator { //----------------------------------------------------------------------- /** - * Checks whether there are any more elements in the tree to obtain. + * Checks whether there are any more elements in the iteration to obtain. * * @return true if elements remain in the iteration */ diff --git a/src/test/org/apache/commons/collections/iterators/TestAll.java b/src/test/org/apache/commons/collections/iterators/TestAll.java index 43951480c..8c6151d52 100644 --- a/src/test/org/apache/commons/collections/iterators/TestAll.java +++ b/src/test/org/apache/commons/collections/iterators/TestAll.java @@ -22,7 +22,7 @@ import junit.framework.TestSuite; /** * Entry point for all iterator tests. * - * @version $Revision: 1.13 $ $Date: 2004/03/14 23:27:22 $ + * @version $Revision: 1.14 $ $Date: 2004/03/20 00:21:08 $ * * @author Rodney Waldhoff */ @@ -49,7 +49,7 @@ public class TestAll extends TestCase { suite.addTest(TestLoopingIterator.suite()); suite.addTest(TestSingletonIterator.suite()); suite.addTest(TestSingletonListIterator.suite()); - suite.addTest(TestTreeIterator.suite()); + suite.addTest(TestObjectGraphIterator.suite()); suite.addTest(TestUniqueFilterIterator.suite()); suite.addTest(TestUnmodifiableIterator.suite()); suite.addTest(TestUnmodifiableListIterator.suite()); diff --git a/src/test/org/apache/commons/collections/iterators/TestTreeIterator.java b/src/test/org/apache/commons/collections/iterators/TestObjectGraphIterator.java similarity index 89% rename from src/test/org/apache/commons/collections/iterators/TestTreeIterator.java rename to src/test/org/apache/commons/collections/iterators/TestObjectGraphIterator.java index 7332c5565..5d235b2d3 100644 --- a/src/test/org/apache/commons/collections/iterators/TestTreeIterator.java +++ b/src/test/org/apache/commons/collections/iterators/TestObjectGraphIterator.java @@ -30,11 +30,11 @@ import org.apache.commons.collections.Transformer; /** * Testcase. * - * @version $Revision: 1.1 $ $Date: 2004/03/14 23:27:22 $ + * @version $Revision: 1.1 $ $Date: 2004/03/20 00:21:08 $ * * @author Stephen Colebourne */ -public class TestTreeIterator extends AbstractTestIterator { +public class TestObjectGraphIterator extends AbstractTestIterator { protected String[] testArray = { "One", "Two", "Three", "Four", "Five", "Six" }; @@ -43,7 +43,7 @@ public class TestTreeIterator extends AbstractTestIterator { protected List list3 = null; protected List iteratorList = null; - public TestTreeIterator(String testName) { + public TestObjectGraphIterator(String testName) { super(testName); } @@ -52,7 +52,7 @@ public class TestTreeIterator extends AbstractTestIterator { } public static Test suite() { - return new TestSuite(TestTreeIterator.class); + return new TestSuite(TestObjectGraphIterator.class); } public void setUp() { @@ -74,16 +74,16 @@ public class TestTreeIterator extends AbstractTestIterator { //----------------------------------------------------------------------- public Iterator makeEmptyIterator() { ArrayList list = new ArrayList(); - return new TreeIterator(list.iterator(), null); + return new ObjectGraphIterator(list.iterator(), null); } public Iterator makeFullIterator() { - return new TreeIterator(iteratorList.iterator(), null); + return new ObjectGraphIterator(iteratorList.iterator(), null); } //----------------------------------------------------------------------- public void testIteratorConstructor_null1() { - Iterator it = new TreeIterator(null); + Iterator it = new ObjectGraphIterator(null); assertEquals(false, it.hasNext()); try { @@ -99,7 +99,7 @@ public class TestTreeIterator extends AbstractTestIterator { } public void testIteratorConstructor_null_next() { - Iterator it = new TreeIterator(null); + Iterator it = new ObjectGraphIterator(null); try { it.next(); fail(); @@ -108,7 +108,7 @@ public class TestTreeIterator extends AbstractTestIterator { } public void testIteratorConstructor_null_remove() { - Iterator it = new TreeIterator(null); + Iterator it = new ObjectGraphIterator(null); try { it.remove(); fail(); @@ -119,7 +119,7 @@ public class TestTreeIterator extends AbstractTestIterator { //----------------------------------------------------------------------- public void testIteratorConstructorIteration_Empty() { List iteratorList = new ArrayList(); - Iterator it = new TreeIterator(iteratorList.iterator()); + Iterator it = new ObjectGraphIterator(iteratorList.iterator()); assertEquals(false, it.hasNext()); try { @@ -139,7 +139,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(list1.iterator()); iteratorList.add(list2.iterator()); iteratorList.add(list3.iterator()); - Iterator it = new TreeIterator(iteratorList.iterator()); + Iterator it = new ObjectGraphIterator(iteratorList.iterator()); for (int i = 0; i < 6; i++) { assertEquals(true, it.hasNext()); @@ -158,7 +158,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(list1.iterator()); iteratorList.add(list2.iterator()); iteratorList.add(list3.iterator()); - Iterator it = new TreeIterator(iteratorList.iterator()); + Iterator it = new ObjectGraphIterator(iteratorList.iterator()); for (int i = 0; i < 6; i++) { assertEquals(testArray[i], it.next()); @@ -179,7 +179,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(IteratorUtils.EMPTY_ITERATOR); iteratorList.add(list3.iterator()); iteratorList.add(IteratorUtils.EMPTY_ITERATOR); - Iterator it = new TreeIterator(iteratorList.iterator()); + Iterator it = new ObjectGraphIterator(iteratorList.iterator()); for (int i = 0; i < 6; i++) { assertEquals(true, it.hasNext()); @@ -198,7 +198,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(list1.iterator()); iteratorList.add(list2.iterator()); iteratorList.add(list3.iterator()); - Iterator it = new TreeIterator(iteratorList.iterator()); + Iterator it = new ObjectGraphIterator(iteratorList.iterator()); for (int i = 0; i < 6; i++) { assertEquals(testArray[i], it.next()); @@ -216,7 +216,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(list1.iterator()); iteratorList.add(list2.iterator()); iteratorList.add(list3.iterator()); - Iterator it = new TreeIterator(iteratorList.iterator(), null); + Iterator it = new ObjectGraphIterator(iteratorList.iterator(), null); for (int i = 0; i < 6; i++) { assertEquals(true, it.hasNext()); @@ -234,7 +234,7 @@ public class TestTreeIterator extends AbstractTestIterator { iteratorList.add(IteratorUtils.EMPTY_ITERATOR); iteratorList.add(list3.iterator()); iteratorList.add(IteratorUtils.EMPTY_ITERATOR); - Iterator it = new TreeIterator(iteratorList.iterator(), null); + Iterator it = new ObjectGraphIterator(iteratorList.iterator(), null); for (int i = 0; i < 6; i++) { assertEquals(true, it.hasNext()); @@ -245,7 +245,7 @@ public class TestTreeIterator extends AbstractTestIterator { //----------------------------------------------------------------------- public void testIteration_RootNull() { - Iterator it = new TreeIterator(null, null); + Iterator it = new ObjectGraphIterator(null, null); assertEquals(false, it.hasNext()); try { @@ -262,7 +262,7 @@ public class TestTreeIterator extends AbstractTestIterator { public void testIteration_RootNoTransformer() { Forest forest = new Forest(); - Iterator it = new TreeIterator(forest, null); + Iterator it = new ObjectGraphIterator(forest, null); assertEquals(true, it.hasNext()); assertSame(forest, it.next()); @@ -277,7 +277,7 @@ public class TestTreeIterator extends AbstractTestIterator { public void testIteration_Transformed1() { Forest forest = new Forest(); Leaf l1 = forest.addTree().addBranch().addLeaf(); - Iterator it = new TreeIterator(forest, new LeafFinder()); + Iterator it = new ObjectGraphIterator(forest, new LeafFinder()); assertEquals(true, it.hasNext()); assertSame(l1, it.next()); @@ -305,7 +305,7 @@ public class TestTreeIterator extends AbstractTestIterator { Leaf l4 = b3.addLeaf(); Leaf l5 = b5.addLeaf(); - Iterator it = new TreeIterator(forest, new LeafFinder()); + Iterator it = new ObjectGraphIterator(forest, new LeafFinder()); assertEquals(true, it.hasNext()); assertSame(l1, it.next()); @@ -341,7 +341,7 @@ public class TestTreeIterator extends AbstractTestIterator { Leaf l4 = b3.addLeaf(); Leaf l5 = b4.addLeaf(); - Iterator it = new TreeIterator(forest, new LeafFinder()); + Iterator it = new ObjectGraphIterator(forest, new LeafFinder()); assertEquals(true, it.hasNext()); assertSame(l1, it.next());