diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
index 0f00b557e..c9f548e99 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
@@ -160,23 +160,6 @@ public class ExtensionAdapter extends DataType {
|| null != implementationURL) {
throw tooManyAttributes();
}
- // change this to get the objects from the other reference
- Object o = reference.getReferencedObject(getProject());
- if (o instanceof ExtensionAdapter) {
- final ExtensionAdapter other = (ExtensionAdapter) o;
- extensionName = other.extensionName;
- specificationVersion = other.specificationVersion;
- specificationVendor = other.specificationVendor;
- implementationVersion = other.implementationVersion;
- implementationVendorID = other.implementationVendorID;
- implementationVendor = other.implementationVendor;
- implementationURL = other.implementationURL;
- } else {
- final String message =
- reference.getRefId() + " doesn\'t refer to a Extension";
- throw new BuildException(message);
- }
-
super.setRefid(reference);
}
@@ -194,6 +177,10 @@ public class ExtensionAdapter extends DataType {
*/
Extension toExtension()
throws BuildException {
+ if (isReference()) {
+ return ((ExtensionAdapter) getCheckedRef()).toExtension();
+ }
+ dieOnCircularReference();
if (null == extensionName) {
final String message = "Extension is missing name.";
throw new BuildException(message);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
index 069f095fa..743edd95e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
@@ -19,6 +19,8 @@ package org.apache.tools.ant.taskdefs.optional.extension;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Stack;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.DataType;
@@ -49,6 +51,10 @@ public class ExtensionSet
* @param extensionAdapter an extension that this library requires.
*/
public void addExtension(final ExtensionAdapter extensionAdapter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
extensions.add(extensionAdapter);
}
@@ -58,6 +64,10 @@ public class ExtensionSet
* @param fileSet a set of files about which extensions data will be extracted.
*/
public void addLibfileset(final LibFileSet fileSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
extensionsFilesets.add(fileSet);
}
@@ -67,6 +77,10 @@ public class ExtensionSet
* @param fileSet a set of files about which extensions data will be extracted.
*/
public void addFileset(final FileSet fileSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
extensionsFilesets.add(fileSet);
}
@@ -79,6 +93,10 @@ public class ExtensionSet
*/
public Extension[] toExtensions(final Project proj)
throws BuildException {
+ if (isReference()) {
+ return ((ExtensionSet) getCheckedRef()).toExtensions(proj);
+ }
+ dieOnCircularReference();
final ArrayList extensionsList = ExtensionUtil.toExtensions(extensions);
ExtensionUtil.extractExtensions(proj, extensionsList, extensionsFilesets);
return (Extension[]) extensionsList.toArray(new Extension[extensionsList.size()]);
@@ -99,20 +117,26 @@ public class ExtensionSet
if (!extensions.isEmpty() || !extensionsFilesets.isEmpty()) {
throw tooManyAttributes();
}
- // change this to get the objects from the other reference
- final Object object =
- reference.getReferencedObject(getProject());
- if (object instanceof ExtensionSet) {
- final ExtensionSet other = (ExtensionSet) object;
- extensions.addAll(other.extensions);
- extensionsFilesets.addAll(other.extensionsFilesets);
+ super.setRefid(reference);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
} else {
- final String message =
- reference.getRefId() + " doesn\'t refer to a ExtensionSet";
- throw new BuildException(message);
+ for (Iterator i = extensions.iterator(); i.hasNext(); ) {
+ pushAndInvokeCircularReferenceCheck((ExtensionAdapter) i.next(),
+ stk, p);
+ }
+ for (Iterator i = extensionsFilesets.iterator(); i.hasNext(); ) {
+ pushAndInvokeCircularReferenceCheck((FileSet) i.next(), stk, p);
+ }
+ setChecked(true);
}
-
- super.setRefid(reference);
}
/**
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
index 0a131187c..cf40922de 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
@@ -36,7 +36,7 @@ import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.util.FileUtils;
/**
@@ -67,7 +67,7 @@ import org.apache.tools.ant.util.FileUtils;
*
* @since Ant 1.8.0
*/
-public class FailureRecorder extends DataType implements JUnitResultFormatter, BuildListener {
+public class FailureRecorder extends ProjectComponent implements JUnitResultFormatter, BuildListener {
/**
* This is the name of a magic System property ({@value}). The value of this
diff --git a/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
index c1d04c0d9..10e5816cc 100644
--- a/src/main/org/apache/tools/ant/types/AbstractFileSet.java
+++ b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -18,8 +18,10 @@
package org.apache.tools.ant.types;
import java.io.File;
-import java.util.Vector;
import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.FileScanner;
@@ -147,7 +149,11 @@ public abstract class AbstractFileSet extends DataType
* @return File
.
*/
public synchronized File getDir(Project p) {
- return (isReference()) ? getRef(p).getDir(p) : dir;
+ if (isReference()) {
+ return getRef(p).getDir(p);
+ }
+ dieOnCircularReference();
+ return dir;
}
/**
@@ -342,8 +348,11 @@ public abstract class AbstractFileSet extends DataType
* @since Ant 1.6.3
*/
public synchronized boolean getDefaultexcludes() {
- return (isReference())
- ? getRef(getProject()).getDefaultexcludes() : useDefaultExcludes;
+ if (isReference()) {
+ return getRef(getProject()).getDefaultexcludes();
+ }
+ dieOnCircularReference();
+ return useDefaultExcludes;
}
/**
@@ -368,8 +377,11 @@ public abstract class AbstractFileSet extends DataType
* @since Ant 1.7
*/
public synchronized boolean isCaseSensitive() {
- return (isReference())
- ? getRef(getProject()).isCaseSensitive() : caseSensitive;
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return caseSensitive;
}
/**
@@ -394,8 +406,11 @@ public abstract class AbstractFileSet extends DataType
* @since Ant 1.6
*/
public synchronized boolean isFollowSymlinks() {
- return (isReference())
- ? getRef(getProject()).isFollowSymlinks() : followSymlinks;
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return followSymlinks;
}
/**
@@ -435,6 +450,7 @@ public abstract class AbstractFileSet extends DataType
if (isReference()) {
return getRef(p).getDirectoryScanner(p);
}
+ dieOnCircularReference();
DirectoryScanner ds = null;
synchronized (this) {
if (directoryScanner != null && p == getProject()) {
@@ -484,6 +500,7 @@ public abstract class AbstractFileSet extends DataType
getRef(p).setupDirectoryScanner(ds, p);
return;
}
+ dieOnCircularReference(p);
if (ds == null) {
throw new IllegalArgumentException("ds cannot be null");
}
@@ -523,8 +540,11 @@ public abstract class AbstractFileSet extends DataType
* @return whether any selectors are in this container.
*/
public synchronized boolean hasSelectors() {
- return (isReference() && getProject() != null)
- ? getRef(getProject()).hasSelectors() : !(selectors.isEmpty());
+ if (isReference()) {
+ return getRef(getProject()).hasSelectors();
+ }
+ dieOnCircularReference();
+ return !(selectors.isEmpty());
}
/**
@@ -536,6 +556,7 @@ public abstract class AbstractFileSet extends DataType
if (isReference() && getProject() != null) {
return getRef(getProject()).hasPatterns();
}
+ dieOnCircularReference();
if (defaultPatterns.hasPatterns(getProject())) {
return true;
}
@@ -555,8 +576,11 @@ public abstract class AbstractFileSet extends DataType
* @return the number of selectors in this container as an int
.
*/
public synchronized int selectorCount() {
- return (isReference() && getProject() != null)
- ? getRef(getProject()).selectorCount() : selectors.size();
+ if (isReference()) {
+ return getRef(getProject()).selectorCount();
+ }
+ dieOnCircularReference();
+ return selectors.size();
}
/**
@@ -565,8 +589,11 @@ public abstract class AbstractFileSet extends DataType
* @return a FileSelector[]
of the selectors in this container.
*/
public synchronized FileSelector[] getSelectors(Project p) {
- return (isReference())
- ? getRef(p).getSelectors(p) : (FileSelector[]) (selectors.toArray(
+ if (isReference()) {
+ return getRef(getProject()).getSelectors(p);
+ }
+ dieOnCircularReference(p);
+ return (FileSelector[]) (selectors.toArray(
new FileSelector[selectors.size()]));
}
@@ -576,8 +603,11 @@ public abstract class AbstractFileSet extends DataType
* @return an Enumeration
of selectors.
*/
public synchronized Enumeration selectorElements() {
- return (isReference() && getProject() != null)
- ? getRef(getProject()).selectorElements() : selectors.elements();
+ if (isReference()) {
+ return getRef(getProject()).selectorElements();
+ }
+ dieOnCircularReference();
+ return selectors.elements();
}
/**
@@ -591,6 +621,7 @@ public abstract class AbstractFileSet extends DataType
}
selectors.addElement(selector);
directoryScanner = null;
+ setChecked(false);
}
/* Methods below all add specific selectors */
@@ -763,6 +794,10 @@ public abstract class AbstractFileSet extends DataType
* @return a String
of included filenames.
*/
public String toString() {
+ if (isReference()) {
+ return getRef(getProject()).toString();
+ }
+ dieOnCircularReference();
DirectoryScanner ds = getDirectoryScanner(getProject());
String[] files = ds.getIncludedFiles();
StringBuffer sb = new StringBuffer();
@@ -840,6 +875,7 @@ public abstract class AbstractFileSet extends DataType
if (isReference()) {
return getRef(p).mergePatterns(p);
}
+ dieOnCircularReference();
PatternSet ps = (PatternSet) defaultPatterns.clone();
final int count = additionalPatterns.size();
for (int i = 0; i < count; i++) {
@@ -849,4 +885,21 @@ public abstract class AbstractFileSet extends DataType
return ps;
}
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (Iterator i = selectors.iterator(); i.hasNext(); ) {
+ Object o = i.next();
+ if (o instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) o, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
}
diff --git a/src/main/org/apache/tools/ant/types/AntFilterReader.java b/src/main/org/apache/tools/ant/types/AntFilterReader.java
index 737bcec68..64f6f027e 100644
--- a/src/main/org/apache/tools/ant/types/AntFilterReader.java
+++ b/src/main/org/apache/tools/ant/types/AntFilterReader.java
@@ -17,8 +17,10 @@
*/
package org.apache.tools.ant.types;
+import java.util.Stack;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
/**
* An AntFilterReader is a wrapper class that encloses the classname
@@ -39,6 +41,9 @@ public final class AntFilterReader
* @param className a String
value
*/
public void setClassName(final String className) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
this.className = className;
}
@@ -48,6 +53,10 @@ public final class AntFilterReader
* @return a String
value
*/
public String getClassName() {
+ if (isReference()) {
+ return ((AntFilterReader) getCheckedRef()).getClassName();
+ }
+ dieOnCircularReference();
return className;
}
@@ -57,6 +66,9 @@ public final class AntFilterReader
* @param param a Parameter
value
*/
public void addParam(final Parameter param) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
parameters.addElement(param);
}
@@ -73,6 +85,7 @@ public final class AntFilterReader
} else {
this.classpath.append(classpath);
}
+ setChecked(false);
}
/**
@@ -86,6 +99,7 @@ public final class AntFilterReader
if (this.classpath == null) {
this.classpath = new Path(getProject());
}
+ setChecked(false);
return this.classpath.createPath();
}
@@ -94,6 +108,10 @@ public final class AntFilterReader
* @return the classpath
*/
public Path getClasspath() {
+ if (isReference()) {
+ ((AntFilterReader) getCheckedRef()).getClasspath();
+ }
+ dieOnCircularReference();
return classpath;
}
@@ -115,6 +133,10 @@ public final class AntFilterReader
* @return a Parameter[]
value
*/
public Parameter[] getParams() {
+ if (isReference()) {
+ ((AntFilterReader) getCheckedRef()).getParams();
+ }
+ dieOnCircularReference();
Parameter[] params = new Parameter[parameters.size()];
parameters.copyInto(params);
return params;
@@ -135,23 +157,21 @@ public final class AntFilterReader
|| classpath != null) {
throw tooManyAttributes();
}
- // change this to get the objects from the other reference
- Object o = r.getReferencedObject(getProject());
- if (o instanceof AntFilterReader) {
- AntFilterReader afr = (AntFilterReader) o;
- setClassName(afr.getClassName());
- setClasspath(afr.getClasspath());
- Parameter[] p = afr.getParams();
- if (p != null) {
- for (int i = 0; i < p.length; i++) {
- addParam(p[i]);
- }
- }
+ super.setRefid(r);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
} else {
- String msg = r.getRefId() + " doesn\'t refer to a FilterReader";
- throw new BuildException(msg);
+ if (classpath != null) {
+ pushAndInvokeCircularReferenceCheck(classpath, stk, p);
+ }
+ setChecked(true);
}
-
- super.setRefid(r);
}
}
diff --git a/src/main/org/apache/tools/ant/types/FilterChain.java b/src/main/org/apache/tools/ant/types/FilterChain.java
index 82999b605..ebfc1531a 100644
--- a/src/main/org/apache/tools/ant/types/FilterChain.java
+++ b/src/main/org/apache/tools/ant/types/FilterChain.java
@@ -17,9 +17,12 @@
*/
package org.apache.tools.ant.types;
+import java.util.Iterator;
+import java.util.Stack;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
import org.apache.tools.ant.filters.ChainableReader;
import org.apache.tools.ant.filters.ClassConstants;
import org.apache.tools.ant.filters.EscapeUnicode;
@@ -52,6 +55,10 @@ public class FilterChain extends DataType
* @param filterReader an AntFilterReader
value
*/
public void addFilterReader(final AntFilterReader filterReader) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filterReader);
}
@@ -61,6 +68,10 @@ public class FilterChain extends DataType
* @return a Vector
value containing the filters
*/
public Vector getFilterReaders() {
+ if (isReference()) {
+ return ((FilterChain) getCheckedRef()).getFilterReaders();
+ }
+ dieOnCircularReference();
return filterReaders;
}
@@ -70,6 +81,10 @@ public class FilterChain extends DataType
* @param classConstants a ClassConstants
value
*/
public void addClassConstants(final ClassConstants classConstants) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(classConstants);
}
@@ -79,6 +94,10 @@ public class FilterChain extends DataType
* @param expandProperties an ExpandProperties
value
*/
public void addExpandProperties(final ExpandProperties expandProperties) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(expandProperties);
}
@@ -88,6 +107,10 @@ public class FilterChain extends DataType
* @param headFilter a HeadFilter
value
*/
public void addHeadFilter(final HeadFilter headFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(headFilter);
}
@@ -97,6 +120,10 @@ public class FilterChain extends DataType
* @param lineContains a LineContains
value
*/
public void addLineContains(final LineContains lineContains) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(lineContains);
}
@@ -107,6 +134,10 @@ public class FilterChain extends DataType
*/
public void addLineContainsRegExp(final LineContainsRegExp
lineContainsRegExp) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(lineContainsRegExp);
}
@@ -116,6 +147,10 @@ public class FilterChain extends DataType
* @param prefixLines a PrefixLines
value
*/
public void addPrefixLines(final PrefixLines prefixLines) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(prefixLines);
}
@@ -125,6 +160,10 @@ public class FilterChain extends DataType
* @param replaceTokens a ReplaceTokens
value
*/
public void addReplaceTokens(final ReplaceTokens replaceTokens) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(replaceTokens);
}
@@ -135,6 +174,10 @@ public class FilterChain extends DataType
*/
public void addStripJavaComments(final StripJavaComments
stripJavaComments) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(stripJavaComments);
}
@@ -145,6 +188,10 @@ public class FilterChain extends DataType
*/
public void addStripLineBreaks(final StripLineBreaks
stripLineBreaks) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(stripLineBreaks);
}
@@ -155,6 +202,10 @@ public class FilterChain extends DataType
*/
public void addStripLineComments(final StripLineComments
stripLineComments) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(stripLineComments);
}
@@ -164,6 +215,10 @@ public class FilterChain extends DataType
* @param tabsToSpaces a TabsToSpaces
value
*/
public void addTabsToSpaces(final TabsToSpaces tabsToSpaces) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(tabsToSpaces);
}
@@ -173,6 +228,10 @@ public class FilterChain extends DataType
* @param tailFilter a TailFilter
value
*/
public void addTailFilter(final TailFilter tailFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(tailFilter);
}
@@ -183,6 +242,10 @@ public class FilterChain extends DataType
* @since Ant 1.6
*/
public void addEscapeUnicode(final EscapeUnicode escapeUnicode) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(escapeUnicode);
}
@@ -193,6 +256,10 @@ public class FilterChain extends DataType
* @since Ant 1.6
*/
public void addTokenFilter(final TokenFilter tokenFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(tokenFilter);
}
@@ -203,6 +270,10 @@ public class FilterChain extends DataType
* @since Ant 1.6
*/
public void addDeleteCharacters(TokenFilter.DeleteCharacters filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -213,6 +284,10 @@ public class FilterChain extends DataType
* @since Ant 1.6
*/
public void addContainsRegex(TokenFilter.ContainsRegex filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -222,6 +297,10 @@ public class FilterChain extends DataType
* @param filter a TokenFilter.ReplaceRegex
value
*/
public void addReplaceRegex(TokenFilter.ReplaceRegex filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -232,6 +311,10 @@ public class FilterChain extends DataType
* @since Ant 1.6
*/
public void addTrim(TokenFilter.Trim filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -243,6 +326,10 @@ public class FilterChain extends DataType
*/
public void addReplaceString(
TokenFilter.ReplaceString filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -254,6 +341,10 @@ public class FilterChain extends DataType
*/
public void addIgnoreBlank(
TokenFilter.IgnoreBlank filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
@@ -272,16 +363,6 @@ public class FilterChain extends DataType
if (!filterReaders.isEmpty()) {
throw tooManyAttributes();
}
- // change this to get the objects from the other reference
- Object o = r.getReferencedObject(getProject());
- if (o instanceof FilterChain) {
- FilterChain fc = (FilterChain) o;
- filterReaders = fc.getFilterReaders();
- } else {
- String msg = r.getRefId() + " doesn\'t refer to a FilterChain";
- throw new BuildException(msg);
- }
-
super.setRefid(r);
}
@@ -293,7 +374,28 @@ public class FilterChain extends DataType
*/
public void add(ChainableReader filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
filterReaders.addElement(filter);
}
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (Iterator i = filterReaders.iterator(); i.hasNext(); ) {
+ Object o = i.next();
+ if (o instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) o, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
}
diff --git a/src/main/org/apache/tools/ant/types/FilterSet.java b/src/main/org/apache/tools/ant/types/FilterSet.java
index ee322d974..55cd6191f 100644
--- a/src/main/org/apache/tools/ant/types/FilterSet.java
+++ b/src/main/org/apache/tools/ant/types/FilterSet.java
@@ -218,6 +218,7 @@ public class FilterSet extends DataType implements Cloneable {
if (isReference()) {
return getRef().getFilters();
}
+ dieOnCircularReference();
//silly hack to avoid stack overflow...
if (!readingFiles) {
readingFiles = true;
@@ -245,6 +246,10 @@ public class FilterSet extends DataType implements Cloneable {
* @return The hash of the tokens and values for quick lookup.
*/
public synchronized Hashtable getFilterHash() {
+ if (isReference()) {
+ return getRef().getFilterHash();
+ }
+ dieOnCircularReference();
if (filterHash == null) {
filterHash = new Hashtable(getFilters().size());
for (Enumeration e = getFilters().elements(); e.hasMoreElements();) {
diff --git a/src/main/org/apache/tools/ant/types/PropertySet.java b/src/main/org/apache/tools/ant/types/PropertySet.java
index c39776001..2ac084398 100644
--- a/src/main/org/apache/tools/ant/types/PropertySet.java
+++ b/src/main/org/apache/tools/ant/types/PropertySet.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
+import java.util.Stack;
import java.util.TreeMap;
import java.util.Hashtable;
import java.util.Properties;
@@ -181,6 +182,7 @@ public class PropertySet extends DataType implements ResourceCollection {
*/
public void addPropertyref(PropertyRef ref) {
assertNotReference();
+ setChecked(false);
ptyRefs.addElement(ref);
}
@@ -190,6 +192,7 @@ public class PropertySet extends DataType implements ResourceCollection {
*/
public void addPropertyset(PropertySet ref) {
assertNotReference();
+ setChecked(false);
setRefs.addElement(ref);
}
@@ -203,6 +206,7 @@ public class PropertySet extends DataType implements ResourceCollection {
throw new BuildException("Too many s!");
}
mapper = new Mapper(getProject());
+ setChecked(false);
return mapper;
}
@@ -245,7 +249,11 @@ public class PropertySet extends DataType implements ResourceCollection {
* @return true if the property set is to be evalulated each time it is used.
*/
public boolean getDynamic() {
- return isReference() ? getRef().dynamic : dynamic;
+ if (isReference()) {
+ return getRef().dynamic;
+ }
+ dieOnCircularReference();
+ return dynamic;
}
/**
@@ -253,7 +261,11 @@ public class PropertySet extends DataType implements ResourceCollection {
* @return the mapper attribute.
*/
public Mapper getMapper() {
- return isReference() ? getRef().mapper : mapper;
+ if (isReference()) {
+ return getRef().mapper;
+ }
+ dieOnCircularReference();
+ return mapper;
}
/**
@@ -279,6 +291,7 @@ public class PropertySet extends DataType implements ResourceCollection {
if (isReference()) {
return getRef().getProperties();
}
+ dieOnCircularReference();
Set names = null;
Project prj = getProject();
Hashtable props =
@@ -343,6 +356,10 @@ public class PropertySet extends DataType implements ResourceCollection {
* avoid needless duplication of the Hashtable during recursion.
*/
private void addPropertyNames(Set names, Hashtable properties) {
+ if (isReference()) {
+ getRef().addPropertyNames(names, properties);
+ }
+ dieOnCircularReference();
// Add this PropertySet's property names.
for (Enumeration e = ptyRefs.elements(); e.hasMoreElements();) {
PropertyRef r = (PropertyRef) e.nextElement();
@@ -453,6 +470,10 @@ public class PropertySet extends DataType implements ResourceCollection {
* @return a string rep of this object.
*/
public String toString() {
+ if (isReference()) {
+ return getRef().toString();
+ }
+ dieOnCircularReference();
StringBuffer b = new StringBuffer();
TreeMap sorted = new TreeMap(getProperties());
for (Iterator i = sorted.entrySet().iterator(); i.hasNext();) {
@@ -473,6 +494,10 @@ public class PropertySet extends DataType implements ResourceCollection {
* @since Ant 1.7
*/
public Iterator iterator() {
+ if (isReference()) {
+ return getRef().iterator();
+ }
+ dieOnCircularReference();
final Enumeration e = getProperties().propertyNames();
return new Iterator() {
public boolean hasNext() {
@@ -500,7 +525,30 @@ public class PropertySet extends DataType implements ResourceCollection {
* @return whether this is a filesystem-only resource collection.
*/
public boolean isFilesystemOnly() {
- return isReference() && getRef().isFilesystemOnly();
+ if (isReference()) {
+ return getRef().isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return false;
+ }
+
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (mapper != null) {
+ pushAndInvokeCircularReferenceCheck(mapper, stk, p);
+ }
+ for (Iterator i = setRefs.iterator(); i.hasNext(); ) {
+ pushAndInvokeCircularReferenceCheck((PropertySet) i.next(), stk,
+ p);
+ }
+ setChecked(true);
+ }
}
}
diff --git a/src/main/org/apache/tools/ant/types/RedirectorElement.java b/src/main/org/apache/tools/ant/types/RedirectorElement.java
index 507fbe2f1..479ff2a70 100755
--- a/src/main/org/apache/tools/ant/types/RedirectorElement.java
+++ b/src/main/org/apache/tools/ant/types/RedirectorElement.java
@@ -592,9 +592,7 @@ public class RedirectorElement extends DataType {
if (v[i] != null) {
for (Iterator fci = v[i].iterator(); fci.hasNext();) {
FilterChain fc = (FilterChain) fci.next();
- stk.push(fc);
- fc.dieOnCircularReference(stk, p);
- stk.pop();
+ pushAndInvokeCircularReferenceCheck(fc, stk, p);
}
}
}