git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@894449 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,28 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| 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. | |||
| --> | |||
| <project> | |||
| <target name="tearDown"> | |||
| </target> | |||
| <target name="setUp"> | |||
| <typedef name="resourcelist" | |||
| classname="org.apache.tools.ant.types.resources.ResourceList"/> | |||
| </target> | |||
| </project> | |||
| @@ -22,6 +22,7 @@ import java.io.BufferedReader; | |||
| import java.io.IOException; | |||
| import java.io.InputStreamReader; | |||
| import java.io.Reader; | |||
| import java.util.ArrayList; | |||
| import java.util.Iterator; | |||
| import java.util.Stack; | |||
| import java.util.Vector; | |||
| @@ -32,6 +33,7 @@ import org.apache.tools.ant.PropertyHelper; | |||
| import org.apache.tools.ant.filters.util.ChainReaderHelper; | |||
| import org.apache.tools.ant.types.DataType; | |||
| import org.apache.tools.ant.types.FilterChain; | |||
| import org.apache.tools.ant.types.Reference; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.ResourceCollection; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| @@ -43,13 +45,12 @@ import org.apache.tools.ant.util.FileUtils; | |||
| */ | |||
| public class ResourceList extends DataType implements ResourceCollection { | |||
| private final Vector filterChains = new Vector(); | |||
| private final Union textDocuments = new Union(); | |||
| private final ArrayList textDocuments = new ArrayList(); | |||
| private final Union cachedResources = new Union(); | |||
| private volatile boolean cached = false; | |||
| private String encoding = null; | |||
| public ResourceList() { | |||
| textDocuments.setCache(true); | |||
| cachedResources.setCache(true); | |||
| } | |||
| @@ -61,6 +62,7 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| textDocuments.add(rc); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -71,6 +73,7 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| filterChains.add(filter); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -89,6 +92,20 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| this.encoding = encoding; | |||
| } | |||
| /** | |||
| * Makes this instance in effect a reference to another ResourceList | |||
| * instance. | |||
| */ | |||
| public void setRefid(Reference r) throws BuildException { | |||
| if (encoding != null) { | |||
| throw tooManyAttributes(); | |||
| } | |||
| if (filterChains.size() > 0 || textDocuments.size() > 0) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| super.setRefid(r); | |||
| } | |||
| /** | |||
| * Fulfill the ResourceCollection contract. The Iterator returned | |||
| * will throw ConcurrentModificationExceptions if ResourceCollections | |||
| @@ -99,7 +116,6 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| if (isReference()) { | |||
| return ((ResourceList) getCheckedRef()).iterator(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return cache().iterator(); | |||
| } | |||
| @@ -111,7 +127,6 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| if (isReference()) { | |||
| return ((ResourceList) getCheckedRef()).size(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return cache().size(); | |||
| } | |||
| @@ -123,7 +138,6 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| if (isReference()) { | |||
| return ((ResourceList) getCheckedRef()).isFilesystemOnly(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return cache().isFilesystemOnly(); | |||
| } | |||
| @@ -142,7 +156,12 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| pushAndInvokeCircularReferenceCheck(textDocuments, stk, p); | |||
| for (Iterator iter = textDocuments.iterator(); iter.hasNext(); ) { | |||
| Object o = (Object) iter.next(); | |||
| if (o instanceof DataType) { | |||
| pushAndInvokeCircularReferenceCheck((DataType) o, stk, p); | |||
| } | |||
| } | |||
| for (Iterator iter = filterChains.iterator(); iter.hasNext(); ) { | |||
| FilterChain fc = (FilterChain) iter.next(); | |||
| pushAndInvokeCircularReferenceCheck(fc, stk, p); | |||
| @@ -153,8 +172,12 @@ public class ResourceList extends DataType implements ResourceCollection { | |||
| private synchronized ResourceCollection cache() { | |||
| if (!cached) { | |||
| dieOnCircularReference(); | |||
| for (Iterator iter = textDocuments.iterator(); iter.hasNext(); ) { | |||
| cachedResources.add(read((Resource) iter.next())); | |||
| ResourceCollection rc = (ResourceCollection) iter.next(); | |||
| for (Iterator r = rc.iterator(); r.hasNext(); ) { | |||
| cachedResources.add(read((Resource) r.next())); | |||
| } | |||
| } | |||
| cached = true; | |||
| } | |||
| @@ -0,0 +1,120 @@ | |||
| /* | |||
| * 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 org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.BuildFileTest; | |||
| import org.apache.tools.ant.types.FilterChain; | |||
| import org.apache.tools.ant.types.Reference; | |||
| public class ResourceListTest extends BuildFileTest { | |||
| protected void setUp() throws Exception { | |||
| configureProject("src/etc/testcases/types/resources/resourcelist.xml"); | |||
| } | |||
| protected void tearDown() throws Exception { | |||
| executeTarget("tearDown"); | |||
| } | |||
| public void testEmptyElementWithReference() { | |||
| ResourceList rl = new ResourceList(); | |||
| rl.setEncoding("foo"); | |||
| try { | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| fail("Can add reference to ResourceList with encoding attribute set."); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify more than one attribute when using refid", | |||
| be.getMessage()); | |||
| } | |||
| rl = new ResourceList(); | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| try { | |||
| rl.setEncoding("foo"); | |||
| fail("Can set encoding in ResourceList that is a reference"); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify more than one attribute when using refid", | |||
| be.getMessage()); | |||
| } | |||
| rl = new ResourceList(); | |||
| rl.add(new FileResource(getProject(), ".")); | |||
| try { | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| fail("Can add reference to ResourceList with nested resource collection."); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify nested elements when using refid", | |||
| be.getMessage()); | |||
| } | |||
| rl = new ResourceList(); | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| try { | |||
| rl.add(new FileResource(getProject(), ".")); | |||
| fail("Can add reference to ResourceList with nested resource collection."); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify nested elements when using refid", | |||
| be.getMessage()); | |||
| } | |||
| rl = new ResourceList(); | |||
| rl.addFilterChain(new FilterChain()); | |||
| try { | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| fail("Can add reference to ResourceList with nested filter chain."); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify nested elements when using refid", | |||
| be.getMessage()); | |||
| } | |||
| rl = new ResourceList(); | |||
| rl.setRefid(new Reference(getProject(), "dummyref")); | |||
| try { | |||
| rl.addFilterChain(new FilterChain()); | |||
| fail("Can add reference to ResourceList with nested filter chain."); | |||
| } catch (BuildException be) { | |||
| assertEquals("You must not specify nested elements when using refid", | |||
| be.getMessage()); | |||
| } | |||
| } | |||
| public void testCircularReference() throws Exception { | |||
| ResourceList rl1 = new ResourceList(); | |||
| rl1.setProject(getProject()); | |||
| rl1.setRefid(new Reference(getProject(), "foo")); | |||
| ResourceList rl2 = new ResourceList(); | |||
| rl2.setProject(getProject()); | |||
| getProject().addReference("foo", rl2); | |||
| Union u = new Union(); | |||
| u.add(rl1); | |||
| u.setProject(getProject()); | |||
| rl2.add(u); | |||
| try { | |||
| rl2.size(); | |||
| fail("Can make ResourceList a Reference to itself."); | |||
| } catch (BuildException be) { | |||
| assertEquals("This data type contains a circular reference.", | |||
| be.getMessage()); | |||
| } | |||
| } | |||
| } | |||