git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@721523 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -19,6 +19,7 @@ package org.apache.tools.ant.types; | |||
| import java.io.File; | |||
| import java.util.Iterator; | |||
| import java.util.Stack; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.DirectoryScanner; | |||
| import org.apache.tools.ant.Project; | |||
| @@ -150,6 +151,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| throw new BuildException(ERROR_DIR_AND_SRC_ATTRIBUTES); | |||
| } | |||
| this.src = src; | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -256,6 +258,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| * @return a directory scanner | |||
| */ | |||
| public DirectoryScanner getDirectoryScanner(Project p) { | |||
| dieOnCircularReference(); | |||
| if (isReference()) { | |||
| return getRef(p).getDirectoryScanner(p); | |||
| } | |||
| @@ -512,4 +515,21 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| checkAttributesAllowed(); | |||
| } | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) | |||
| throws BuildException { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (src != null) { | |||
| stk.push(src); | |||
| invokeCircularReferenceCheck(src, stk, p); | |||
| stk.pop(); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -92,6 +92,7 @@ public class Mapper extends DataType implements Cloneable { | |||
| } | |||
| } | |||
| container.add(fileNameMapper); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -139,6 +140,7 @@ public class Mapper extends DataType implements Cloneable { | |||
| if (this.classpath == null) { | |||
| this.classpath = new Path(getProject()); | |||
| } | |||
| setChecked(false); | |||
| return this.classpath.createPath(); | |||
| } | |||
| @@ -119,6 +119,7 @@ public class RedirectorElement extends DataType { | |||
| throw new BuildException("Cannot have > 1 <inputmapper>"); | |||
| } | |||
| } | |||
| setChecked(false); | |||
| this.inputMapper = inputMapper; | |||
| } | |||
| @@ -138,6 +139,7 @@ public class RedirectorElement extends DataType { | |||
| throw new BuildException("Cannot have > 1 <outputmapper>"); | |||
| } | |||
| } | |||
| setChecked(false); | |||
| this.outputMapper = outputMapper; | |||
| } | |||
| @@ -157,6 +159,7 @@ public class RedirectorElement extends DataType { | |||
| throw new BuildException("Cannot have > 1 <errormapper>"); | |||
| } | |||
| } | |||
| setChecked(false); | |||
| this.errorMapper = errorMapper; | |||
| } | |||
| @@ -388,6 +391,7 @@ public class RedirectorElement extends DataType { | |||
| FilterChain result = new FilterChain(); | |||
| result.setProject(getProject()); | |||
| inputFilterChains.add(result); | |||
| setChecked(false); | |||
| return result; | |||
| } | |||
| @@ -402,6 +406,7 @@ public class RedirectorElement extends DataType { | |||
| FilterChain result = new FilterChain(); | |||
| result.setProject(getProject()); | |||
| outputFilterChains.add(result); | |||
| setChecked(false); | |||
| return result; | |||
| } | |||
| @@ -416,6 +421,7 @@ public class RedirectorElement extends DataType { | |||
| FilterChain result = new FilterChain(); | |||
| result.setProject(getProject()); | |||
| errorFilterChains.add(result); | |||
| setChecked(false); | |||
| return result; | |||
| } | |||
| @@ -438,6 +444,7 @@ public class RedirectorElement extends DataType { | |||
| getRef().configure(redirector, sourcefile); | |||
| return; | |||
| } | |||
| dieOnCircularReference(); | |||
| if (alwaysLog != null) { | |||
| redirector.setAlwaysLog(alwaysLog.booleanValue()); | |||
| } | |||
| @@ -434,7 +434,7 @@ public class Resource extends DataType implements Cloneable, Comparable, Resourc | |||
| * <p>This implementation of the method will return the current | |||
| * instance itself if it can be assigned to the given class.</p> | |||
| * | |||
| * @since ant 1.8.0 | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public Object as(Class clazz) { | |||
| return clazz.isAssignableFrom(getClass()) ? this : null; | |||
| @@ -27,6 +27,7 @@ import java.io.InputStream; | |||
| import java.net.MalformedURLException; | |||
| import java.net.URL; | |||
| import java.util.Enumeration; | |||
| import java.util.Stack; | |||
| import java.util.Vector; | |||
| import javax.xml.parsers.ParserConfigurationException; | |||
| import javax.xml.parsers.SAXParserFactory; | |||
| @@ -451,6 +452,28 @@ public class XMLCatalog extends DataType | |||
| return source; | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) | |||
| throws BuildException { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (classpath != null) { | |||
| stk.push(classpath); | |||
| invokeCircularReferenceCheck(classpath, stk, p); | |||
| stk.pop(); | |||
| } | |||
| if (catalogPath != null) { | |||
| stk.push(catalogPath); | |||
| invokeCircularReferenceCheck(catalogPath, stk, p); | |||
| stk.pop(); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| /** | |||
| * @since Ant 1.6 | |||
| */ | |||
| @@ -23,6 +23,7 @@ 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.Mapper; | |||
| 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.FileNameMapper; | |||
| @@ -53,6 +54,7 @@ public class MappedResourceCollection | |||
| + " nested into mappedresources", | |||
| getLocation()); | |||
| } | |||
| setChecked(false); | |||
| nested = c; | |||
| } | |||
| @@ -69,6 +71,7 @@ public class MappedResourceCollection | |||
| throw new BuildException("Cannot define more than one mapper", | |||
| getLocation()); | |||
| } | |||
| setChecked(false); | |||
| mapper = new Mapper(getProject()); | |||
| return mapper; | |||
| } | |||
| @@ -113,6 +116,17 @@ public class MappedResourceCollection | |||
| return new MappedIterator(nested.iterator(), mapper); | |||
| } | |||
| /** | |||
| * Overrides the base version. | |||
| * @param r the Reference to set. | |||
| */ | |||
| public void setRefid(Reference r) { | |||
| if (nested != null || mapper != null) { | |||
| throw tooManyAttributes(); | |||
| } | |||
| super.setRefid(r); | |||
| } | |||
| /** | |||
| * Implement clone. The nested resource collection and mapper are | |||
| * copied. | |||
| @@ -165,6 +179,7 @@ public class MappedResourceCollection | |||
| throw new BuildException("A nested resource collection element is" | |||
| + " required", getLocation()); | |||
| } | |||
| dieOnCircularReference(); | |||
| } | |||
| private static class MappedIterator implements Iterator { | |||
| @@ -66,6 +66,7 @@ public abstract class ResourceDecorator extends Resource { | |||
| throw new BuildException("only single argument resource collections" | |||
| + " are supported"); | |||
| } | |||
| setChecked(false); | |||
| resource = (Resource) a.iterator().next(); | |||
| } | |||
| @@ -195,6 +196,7 @@ public abstract class ResourceDecorator extends Resource { | |||
| if (resource == null) { | |||
| throw new BuildException("no resource specified"); | |||
| } | |||
| dieOnCircularReference(); | |||
| return resource; | |||
| } | |||
| @@ -17,10 +17,12 @@ | |||
| */ | |||
| package org.apache.tools.ant.types.resources; | |||
| import java.util.Iterator; | |||
| import java.util.ArrayList; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.Stack; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.ResourceCollection; | |||
| import org.apache.tools.ant.types.resources.selectors.ResourceSelector; | |||
| @@ -67,6 +69,7 @@ outer: for (Iterator ri = w.getResourceCollection().iterator(); ri.hasNext( | |||
| return; | |||
| } | |||
| w.add(c); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -145,4 +148,19 @@ outer: for (Iterator ri = w.getResourceCollection().iterator(); ri.hasNext( | |||
| return w.toString(); | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| // takes care of Selectors | |||
| super.dieOnCircularReference(stk, p); | |||
| if (!isReference()) { | |||
| stk.push(w); | |||
| invokeCircularReferenceCheck(w, stk, p); | |||
| stk.pop(); | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -126,6 +126,7 @@ public class Sort extends BaseResourceCollectionWrapper { | |||
| } | |||
| comp.add(c); | |||
| FailFast.invalidate(this); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -143,7 +144,9 @@ public class Sort extends BaseResourceCollectionWrapper { | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| stk.push(comp); | |||
| DataType.invokeCircularReferenceCheck(comp, stk, p); | |||
| stk.pop(); | |||
| setChecked(true); | |||
| } | |||
| } | |||
| @@ -102,6 +102,7 @@ public class Tokens extends BaseResourceCollectionWrapper { | |||
| throw new BuildException("Only one nested tokenizer allowed."); | |||
| } | |||
| this.tokenizer = tokenizer; | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -122,6 +123,7 @@ public class Tokens extends BaseResourceCollectionWrapper { | |||
| if (tokenizer instanceof DataType) { | |||
| stk.push(tokenizer); | |||
| invokeCircularReferenceCheck((DataType) tokenizer, stk, p); | |||
| stk.pop(); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| @@ -48,6 +48,7 @@ public class DelegatedResourceComparator extends ResourceComparator { | |||
| } | |||
| v = (v == null) ? new Vector() : v; | |||
| v.add(c); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -115,6 +116,7 @@ s. | |||
| if (o instanceof DataType) { | |||
| stk.push(o); | |||
| invokeCircularReferenceCheck((DataType) o, stk, p); | |||
| stk.pop(); | |||
| } | |||
| } | |||
| } | |||
| @@ -58,6 +58,7 @@ public class Compare extends DataType implements ResourceSelector { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| comp.add(c); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -95,6 +96,7 @@ public class Compare extends DataType implements ResourceSelector { | |||
| throw oneControl(); | |||
| } | |||
| control = new Union(); | |||
| setChecked(false); | |||
| return control; | |||
| } | |||
| @@ -107,6 +109,7 @@ public class Compare extends DataType implements ResourceSelector { | |||
| if (control == null) { | |||
| throw oneControl(); | |||
| } | |||
| dieOnCircularReference(); | |||
| int t = 0, f = 0; | |||
| for (Iterator it = control.iterator(); it.hasNext();) { | |||
| if (when.evaluate(comp.compare(r, (Resource) it.next()))) { | |||
| @@ -134,9 +137,13 @@ public class Compare extends DataType implements ResourceSelector { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (control != null) { | |||
| stk.push(control); | |||
| DataType.invokeCircularReferenceCheck(control, stk, p); | |||
| stk.pop(); | |||
| } | |||
| stk.push(comp); | |||
| DataType.invokeCircularReferenceCheck(comp, stk, p); | |||
| stk.pop(); | |||
| setChecked(true); | |||
| } | |||
| } | |||
| @@ -120,6 +120,7 @@ public class ResourceSelectorContainer extends DataType { | |||
| if (o instanceof DataType) { | |||
| stk.push(o); | |||
| invokeCircularReferenceCheck((DataType) o, stk, p); | |||
| stk.pop(); | |||
| } | |||
| } | |||
| setChecked(true); | |||