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()); | |||
} | |||
} | |||
} |