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