ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hi...@apache.org
Subject svn commit: r958669 - in /ant/core/trunk: ./ src/main/org/apache/tools/ant/types/resources/ src/tests/junit/org/apache/tools/ant/types/resources/
Date Mon, 28 Jun 2010 18:23:32 GMT
Author: hibou
Date: Mon Jun 28 18:23:31 2010
New Revision: 958669

URL: http://svn.apache.org/viewvc?rev=958669&view=rev
Log:
Fix a perf issue with <restrict>: it now loads only necessary resources

Added:
    ant/core/trunk/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
      - copied, changed from r958244, ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
    ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
  (with props)
    ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
  (with props)
Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
    ant/core/trunk/src/main/org/apache/tools/ant/types/resources/Restrict.java

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=958669&r1=958668&r2=958669&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Mon Jun 28 18:23:31 2010
@@ -81,6 +81,11 @@ Fixed bugs:
    case-insensitive file system.
    Bugzilla Report 49041.
 
+ * The <restrict> resource collection was checking every resource even if
+   we actually just want the first one, like in the exemple of use of
+   resourcelist in the documentation (getting the first available resource
+   from a mirror list).
+
 Other changes:
 --------------
 

Copied: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
(from r958244, ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java)
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java?p2=ant/core/trunk/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java&p1=ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java&r1=958244&r2=958669&rev=958669&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
Mon Jun 28 18:23:31 2010
@@ -18,12 +18,11 @@
 package org.apache.tools.ant.types.resources;
 
 import java.io.File;
-import java.util.Stack;
 import java.util.Iterator;
-import java.util.Collection;
+import java.util.Stack;
 
-import org.apache.tools.ant.Project;
 import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.DataType;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
@@ -31,15 +30,14 @@ import org.apache.tools.ant.types.Resour
 /**
  * Base class for a ResourceCollection that wraps a single nested
  * ResourceCollection.
- * @since Ant 1.7
+ * @since Ant 1.8.2
  */
-public abstract class BaseResourceCollectionWrapper
+public abstract class AbstractResourceCollectionWrapper
     extends DataType implements ResourceCollection, Cloneable {
     private static final String ONE_NESTED_MESSAGE
         = " expects exactly one nested resource collection.";
 
     private ResourceCollection rc;
-    private Collection coll = null;
     private boolean cache = true;
 
     /**
@@ -89,25 +87,43 @@ public abstract class BaseResourceCollec
      */
     public final synchronized Iterator iterator() {
         if (isReference()) {
-            return ((BaseResourceCollectionWrapper) getCheckedRef()).iterator();
+            return ((AbstractResourceCollectionWrapper) getCheckedRef()).iterator();
         }
         dieOnCircularReference();
-        return new FailFast(this, cacheCollection().iterator());
+        return new FailFast(this, createIterator());
     }
 
     /**
+     * Do create an iterator on the resource collection. The creation
+     * of the iterator is allowed to not be thread safe whereas the iterator
+     * itself should. The returned iterator will be wrapped into the FailFast
+     * one.
+     * 
+     * @return the iterator on the resource collection
+     */
+    protected abstract Iterator createIterator();
+
+    /**
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
     public synchronized int size() {
         if (isReference()) {
-            return ((BaseResourceCollectionWrapper) getCheckedRef()).size();
+            return ((AbstractResourceCollectionWrapper) getCheckedRef()).size();
         }
         dieOnCircularReference();
-        return cacheCollection().size();
+        return getSize();
     }
 
     /**
+     * Do compute the size of the resource collection. The implementation of
+     * this function is allowed to be not thread safe.
+     * 
+     * @return
+     */
+    protected abstract int getSize();
+
+    /**
      * Fulfill the ResourceCollection contract.
      * @return whether this is a filesystem-only resource collection.
      */
@@ -122,7 +138,7 @@ public abstract class BaseResourceCollec
         }
         /* now check each Resource in case the child only
            lets through files from any children IT may have: */
-        for (Iterator i = cacheCollection().iterator(); i.hasNext();) {
+        for (Iterator i = createIterator(); i.hasNext();) {
             Resource r = (Resource) i.next();
             if (r.as(FileProvider.class) == null) {
                 return false;
@@ -167,12 +183,6 @@ public abstract class BaseResourceCollec
     }
 
     /**
-     * Template method for subclasses to return a Collection of Resources.
-     * @return Collection.
-     */
-    protected abstract Collection getCollection();
-
-    /**
      * Format this BaseResourceCollectionWrapper as a String.
      * @return a descriptive <code>String</code>.
      */
@@ -180,11 +190,11 @@ public abstract class BaseResourceCollec
         if (isReference()) {
             return getCheckedRef().toString();
         }
-        if (cacheCollection().size() == 0) {
+        if (getSize() == 0) {
             return "";
         }
         StringBuffer sb = new StringBuffer();
-        for (Iterator i = coll.iterator(); i.hasNext();) {
+        for (Iterator i = createIterator(); i.hasNext();) {
             if (sb.length() > 0) {
                 sb.append(File.pathSeparatorChar);
             }
@@ -193,13 +203,6 @@ public abstract class BaseResourceCollec
         return sb.toString();
     }
 
-    private synchronized Collection cacheCollection() {
-        if (coll == null || !isCache()) {
-            coll = getCollection();
-        }
-        return coll;
-    }
-
     private BuildException oneNested() {
         return new BuildException(super.toString() + ONE_NESTED_MESSAGE);
     }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java?rev=958669&r1=958668&r2=958669&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
Mon Jun 28 18:23:31 2010
@@ -17,16 +17,8 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.io.File;
-import java.util.Stack;
-import java.util.Iterator;
 import java.util.Collection;
-
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.types.DataType;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
+import java.util.Iterator;
 
 /**
  * Base class for a ResourceCollection that wraps a single nested
@@ -34,165 +26,24 @@ import org.apache.tools.ant.types.Resour
  * @since Ant 1.7
  */
 public abstract class BaseResourceCollectionWrapper
-    extends DataType implements ResourceCollection, Cloneable {
-    private static final String ONE_NESTED_MESSAGE
-        = " expects exactly one nested resource collection.";
+    extends AbstractResourceCollectionWrapper {
 
-    private ResourceCollection rc;
     private Collection coll = null;
-    private boolean cache = true;
-
-    /**
-     * Set whether to cache collections.
-     * @param b boolean cache flag.
-     */
-    public synchronized void setCache(boolean b) {
-        cache = b;
-    }
 
-    /**
-     * Learn whether to cache collections. Default is <code>true</code>.
-     * @return boolean cache flag.
-     */
-    public synchronized boolean isCache() {
-        return cache;
+    protected Iterator createIterator() {
+        return cacheCollection().iterator();
     }
 
-    /**
-     * Add a ResourceCollection to the container.
-     * @param c the ResourceCollection to add.
-     * @throws BuildException on error.
-     */
-    public synchronized void add(ResourceCollection c) throws BuildException {
-        if (isReference()) {
-            throw noChildrenAllowed();
-        }
-        if (c == null) {
-            return;
-        }
-        if (rc != null) {
-            throw oneNested();
-        }
-        rc = c;
-        if (Project.getProject(rc) == null) {
-            Project p = getProject();
-            if (p != null) {
-                p.setProjectReference(rc);
-            }
-        }
-        setChecked(false);
-    }
-
-    /**
-     * Fulfill the ResourceCollection contract.
-     * @return an Iterator of Resources.
-     */
-    public final synchronized Iterator iterator() {
-        if (isReference()) {
-            return ((BaseResourceCollectionWrapper) getCheckedRef()).iterator();
-        }
-        dieOnCircularReference();
-        return new FailFast(this, cacheCollection().iterator());
-    }
-
-    /**
-     * Fulfill the ResourceCollection contract.
-     * @return number of elements as int.
-     */
-    public synchronized int size() {
-        if (isReference()) {
-            return ((BaseResourceCollectionWrapper) getCheckedRef()).size();
-        }
-        dieOnCircularReference();
+	protected int getSize() {
         return cacheCollection().size();
     }
 
     /**
-     * Fulfill the ResourceCollection contract.
-     * @return whether this is a filesystem-only resource collection.
-     */
-    public synchronized boolean isFilesystemOnly() {
-        if (isReference()) {
-            return ((BaseResourceCollectionContainer) getCheckedRef()).isFilesystemOnly();
-        }
-        dieOnCircularReference();
-
-        if (rc == null || rc.isFilesystemOnly()) {
-            return true;
-        }
-        /* now check each Resource in case the child only
-           lets through files from any children IT may have: */
-        for (Iterator i = cacheCollection().iterator(); i.hasNext();) {
-            Resource r = (Resource) i.next();
-            if (r.as(FileProvider.class) == null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Overrides the version of DataType to recurse on all DataType
-     * child elements that may have been added.
-     * @param stk the stack of data types to use (recursively).
-     * @param p   the project to use to dereference the references.
-     * @throws BuildException on error.
-     */
-    protected synchronized void dieOnCircularReference(Stack stk, Project p)
-        throws BuildException {
-        if (isChecked()) {
-            return;
-        }
-        if (isReference()) {
-            super.dieOnCircularReference(stk, p);
-        } else {
-            if (rc instanceof DataType) {
-                pushAndInvokeCircularReferenceCheck((DataType) rc, stk, p);
-            }
-            setChecked(true);
-        }
-    }
-
-    /**
-     * Get the nested ResourceCollection.
-     * @return a ResourceCollection.
-     * @throws BuildException if no nested ResourceCollection has been provided.
-     */
-    protected final synchronized ResourceCollection getResourceCollection() {
-        dieOnCircularReference();
-        if (rc == null) {
-            throw oneNested();
-        }
-        return rc;
-    }
-
-    /**
      * Template method for subclasses to return a Collection of Resources.
      * @return Collection.
      */
     protected abstract Collection getCollection();
 
-    /**
-     * Format this BaseResourceCollectionWrapper as a String.
-     * @return a descriptive <code>String</code>.
-     */
-    public synchronized String toString() {
-        if (isReference()) {
-            return getCheckedRef().toString();
-        }
-        if (cacheCollection().size() == 0) {
-            return "";
-        }
-        StringBuffer sb = new StringBuffer();
-        for (Iterator i = coll.iterator(); i.hasNext();) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(i.next());
-        }
-        return sb.toString();
-    }
-
     private synchronized Collection cacheCollection() {
         if (coll == null || !isCache()) {
             coll = getCollection();
@@ -200,8 +51,4 @@ public abstract class BaseResourceCollec
         return coll;
     }
 
-    private BuildException oneNested() {
-        return new BuildException(super.toString() + ONE_NESTED_MESSAGE);
-    }
-
 }

Added: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java?rev=958669&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
(added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
Mon Jun 28 18:23:31 2010
@@ -0,0 +1,157 @@
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Resource collection which load underlying resource collection only on demand
+ * with support for caching
+ */
+public class LazyResourceCollectionWrapper extends
+        AbstractResourceCollectionWrapper {
+
+    /** List of cached resources */
+    private List cachedResources = new ArrayList();
+
+    private FilteringIterator filteringIterator;
+
+    protected Iterator createIterator() {
+        Iterator iterator;
+        if (isCache()) {
+            if (filteringIterator == null) {
+                // no worry of thread safety here, see function's contract
+                filteringIterator = new FilteringIterator(
+                        getResourceCollection().iterator());
+            }
+            iterator = new CachedIterator(filteringIterator);
+        } else {
+            iterator = new FilteringIterator(getResourceCollection().iterator());
+        }
+        return iterator;
+    }
+
+    protected int getSize() {
+        // to compute the size, just iterate: the iterator will take care of
+        // caching
+        Iterator it = createIterator();
+        int size = 0;
+        while (it.hasNext()) {
+            it.next();
+            size++;
+        }
+        return size;
+    }
+
+    /**
+     * Specify if the resource should be filtered or not. This function should
+     * be overrided in order to define the filtering algorithm
+     * 
+     * @param r
+     * @return
+     */
+    protected boolean filterResource(Resource r) {
+        return false;
+    }
+
+    private class FilteringIterator implements Iterator {
+
+        Resource next = null;
+
+        boolean ended = false;
+
+        protected final Iterator it;
+
+        public FilteringIterator(Iterator it) {
+            this.it = it;
+        }
+
+        public boolean hasNext() {
+            if (ended) {
+                return false;
+            }
+            while (next == null) {
+                if (!it.hasNext()) {
+                    ended = true;
+                    return false;
+                }
+                next = (Resource) it.next();
+                if (filterResource(next)) {
+                    next = null;
+                }
+            }
+            return true;
+        }
+
+        public Object next() {
+            if (!hasNext()) {
+                throw new UnsupportedOperationException();
+            }
+            Resource r = next;
+            next = null;
+            return r;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Iterator that will put in the shared cache array list the selected
+     * resources
+     */
+    private class CachedIterator implements Iterator {
+
+        int cusrsor = 0;
+
+        private final Iterator it;
+
+        /**
+         * Default constructor
+         * 
+         * @param it
+         *            the iterator which will provide the resources to put in
+         *            cache
+         */
+        public CachedIterator(Iterator it) {
+            this.it = it;
+        }
+
+        public boolean hasNext() {
+            synchronized (cachedResources) {
+                // have we already cached the next entry ?
+                if (cachedResources.size() > cusrsor) {
+                    return true;
+                }
+                // does the wrapped iterator any more resource ?
+                if (!it.hasNext()) {
+                    return false;
+                }
+                // put in cache the next resource
+                Resource r = (Resource) it.next();
+                cachedResources.add(r);
+            }
+            return true;
+        }
+
+        public Object next() {
+            // first check that we have some to deliver
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            synchronized (cachedResources) {
+                // return the cached entry as hasNext should have put one for
+                // this iterator
+                return cachedResources.get(cusrsor++);
+            }
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ant/core/trunk/src/main/org/apache/tools/ant/types/resources/Restrict.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/resources/Restrict.java?rev=958669&r1=958668&r2=958669&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/resources/Restrict.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/resources/Restrict.java Mon Jun 28
18:23:31 2010
@@ -17,8 +17,6 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.Stack;
 
@@ -37,23 +35,17 @@ import org.apache.tools.ant.types.resour
 public class Restrict
     extends ResourceSelectorContainer implements ResourceCollection {
 
-    private BaseResourceCollectionWrapper w = new BaseResourceCollectionWrapper() {
+    private LazyResourceCollectionWrapper w = new  LazyResourceCollectionWrapper() {
         /**
          * Restrict the nested ResourceCollection based on the nested selectors.
-         * @return a Collection of Resources.
          */
-        protected Collection getCollection() {
-            ArrayList result = new ArrayList();
-outer:      for (Iterator ri = w.getResourceCollection().iterator(); ri.hasNext();) {
-                Resource r = (Resource) ri.next();
-                for (Iterator i = getSelectors(); i.hasNext();) {
-                    if (!((ResourceSelector) (i.next())).isSelected(r)) {
-                        continue outer;
-                    }
+        protected boolean filterResource(Resource r) {
+            for (Iterator i = getSelectors(); i.hasNext();) {
+                if (!((ResourceSelector) (i.next())).isSelected(r)) {
+                    return true;
                 }
-                result.add(r);
             }
-            return result;
+            return false;
         }
     };
 

Added: ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java?rev=958669&view=auto
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
(added)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
Mon Jun 28 18:23:31 2010
@@ -0,0 +1,180 @@
+/*
+ *  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.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+public class LazyResourceCollectionTest extends TestCase {
+
+    private class StringResourceCollection implements ResourceCollection {
+        List resources = Arrays.asList(new Resource[] {});
+
+        List createdIterators = new ArrayList();
+
+        public int size() {
+            return resources.size();
+        }
+
+        public Iterator iterator() {
+            StringResourceIterator it = new StringResourceIterator();
+            createdIterators.add(it);
+            return it;
+        }
+
+        public boolean isFilesystemOnly() {
+            return false;
+        }
+    }
+
+    private class StringResourceIterator implements Iterator {
+        int cursor = 0;
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object next() {
+            if (cursor < 3) {
+                cursor++;
+                return new StringResource("r" + cursor);
+            }
+            return null;
+        }
+
+        public boolean hasNext() {
+            return cursor < 3;
+        }
+    }
+
+    public void testLazyLoading() throws Exception {
+        StringResourceCollection collectionTest = new StringResourceCollection();
+        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+        lazyCollection.add(collectionTest);
+
+        Iterator it = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators
+                .get(0);
+        assertEquals("A resource was loaded without iterating", 1,
+                stringResourceIterator.cursor);
+
+        StringResource r = (StringResource) it.next();
+        assertOneCreatedIterator(collectionTest);
+        assertEquals("r1", r.getValue());
+        assertEquals("Iterating once load more than 1 resource", 2,
+                stringResourceIterator.cursor);
+
+        r = (StringResource) it.next();
+        assertOneCreatedIterator(collectionTest);
+        assertEquals("r2", r.getValue());
+        assertEquals("Iterating twice load more than 2 resources", 3,
+                stringResourceIterator.cursor);
+
+        r = (StringResource) it.next();
+        assertOneCreatedIterator(collectionTest);
+        assertEquals("r3", r.getValue());
+        assertEquals("Iterating 3 times load more than 3 resources", 3,
+                stringResourceIterator.cursor);
+
+        try {
+            it.next();
+            fail("NoSuchElementException shoudl have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
+
+    private void assertOneCreatedIterator(
+            StringResourceCollection testCollection) {
+        assertEquals("More than one iterator has been created", 1,
+                testCollection.createdIterators.size());
+    }
+
+    public void testCaching() throws Exception {
+        StringResourceCollection collectionTest = new StringResourceCollection();
+        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+        lazyCollection.add(collectionTest);
+
+        assertTrue(lazyCollection.isCache());
+        Iterator it1 = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+        Iterator it2 = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+
+        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators
+                .get(0);
+        assertEquals("A resource was loaded without iterating", 1,
+                stringResourceIterator.cursor);
+
+        StringResource r = (StringResource) it1.next();
+        assertEquals("r1", r.getValue());
+        assertEquals("Iterating once load more than 1 resource", 2,
+                stringResourceIterator.cursor);
+
+        r = (StringResource) it2.next();
+        assertEquals("r1", r.getValue());
+        assertEquals(
+                "The second iterator did not lookup in the cache for a resource",
+                2, stringResourceIterator.cursor);
+
+        r = (StringResource) it2.next();
+        assertEquals("r2", r.getValue());
+        assertEquals("Iterating twice load more than 2 resources", 3,
+                stringResourceIterator.cursor);
+
+        r = (StringResource) it1.next();
+        assertEquals("r2", r.getValue());
+        assertEquals(
+                "The first iterator did not lookup in the cache for a resource",
+                3, stringResourceIterator.cursor);
+
+        r = (StringResource) it2.next();
+        assertEquals("r3", r.getValue());
+        assertEquals("Iterating 3 times load more than 3 resources", 3,
+                stringResourceIterator.cursor);
+
+        r = (StringResource) it1.next();
+        assertEquals("r3", r.getValue());
+        assertEquals(
+                "The first iterator did not lookup in the cache for a resource",
+                3, stringResourceIterator.cursor);
+
+        try {
+            it1.next();
+            fail("NoSuchElementException should have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+
+        try {
+            it2.next();
+            fail("NoSuchElementException should have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
+}

Propchange: ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: ant/core/trunk/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message