git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@722437 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -899,6 +899,10 @@ public abstract class AbstractFileSet extends DataType | |||
| pushAndInvokeCircularReferenceCheck((DataType) o, stk, p); | |||
| } | |||
| } | |||
| for (Iterator i = additionalPatterns.iterator(); i.hasNext(); ) { | |||
| PatternSet ps = (PatternSet) i.next(); | |||
| pushAndInvokeCircularReferenceCheck(ps, stk, p); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| @@ -183,6 +183,10 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| * @return the archive in case the archive is a file, null otherwise. | |||
| */ | |||
| public File getSrc() { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getCheckedRef()).getSrc(); | |||
| } | |||
| dieOnCircularReference(); | |||
| if (src != null) { | |||
| FileProvider fp = (FileProvider) src.as(FileProvider.class); | |||
| if (fp != null) { | |||
| @@ -215,6 +219,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(p)).getPrefix(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| return prefix; | |||
| } | |||
| @@ -241,6 +246,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(p)).getFullpath(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| return fullpath; | |||
| } | |||
| @@ -258,10 +264,10 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| * @return a directory scanner | |||
| */ | |||
| public DirectoryScanner getDirectoryScanner(Project p) { | |||
| dieOnCircularReference(); | |||
| if (isReference()) { | |||
| return getRef(p).getDirectoryScanner(p); | |||
| } | |||
| dieOnCircularReference(); | |||
| if (src == null) { | |||
| return super.getDirectoryScanner(p); | |||
| } | |||
| @@ -323,6 +329,10 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| * @since Ant 1.7 | |||
| */ | |||
| public boolean isFilesystemOnly() { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getCheckedRef()).isFilesystemOnly(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return src == null; | |||
| } | |||
| @@ -361,6 +371,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(p)).getFileMode(p); | |||
| } | |||
| dieOnCircularReference(); | |||
| return fileMode; | |||
| } | |||
| @@ -372,6 +383,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(getProject())).hasFileModeBeenSet(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return fileModeHasBeenSet; | |||
| } | |||
| @@ -409,6 +421,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(p)).getDirMode(p); | |||
| } | |||
| dieOnCircularReference(); | |||
| return dirMode; | |||
| } | |||
| @@ -421,6 +434,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isReference()) { | |||
| return ((ArchiveFileSet) getRef(getProject())).hasDirModeBeenSet(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return dirModeHasBeenSet; | |||
| } | |||
| @@ -521,9 +535,11 @@ public abstract class ArchiveFileSet extends FileSet { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| // takes care of nested selectors | |||
| super.dieOnCircularReference(stk, p); | |||
| if (!isReference()) { | |||
| if (src != null) { | |||
| pushAndInvokeCircularReferenceCheck(src, stk, p); | |||
| } | |||
| @@ -357,6 +357,7 @@ public class PatternSet extends DataType implements Cloneable { | |||
| if (isReference()) { | |||
| throw new BuildException("Cannot append to a reference"); | |||
| } | |||
| dieOnCircularReference(p); | |||
| String[] incl = other.getIncludePatterns(p); | |||
| if (incl != null) { | |||
| for (int i = 0; i < incl.length; i++) { | |||
| @@ -380,6 +381,7 @@ public class PatternSet extends DataType implements Cloneable { | |||
| if (isReference()) { | |||
| return getRef(p).getIncludePatterns(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| readFiles(p); | |||
| return makeArray(includeList, p); | |||
| } | |||
| @@ -393,6 +395,7 @@ public class PatternSet extends DataType implements Cloneable { | |||
| if (isReference()) { | |||
| return getRef(p).getExcludePatterns(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| readFiles(p); | |||
| return makeArray(excludeList, p); | |||
| } | |||
| @@ -407,6 +410,7 @@ public class PatternSet extends DataType implements Cloneable { | |||
| if (isReference()) { | |||
| return getRef(p).hasPatterns(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| return includesFileList.size() > 0 || excludesFileList.size() > 0 | |||
| || includeList.size() > 0 || excludeList.size() > 0; | |||
| } | |||
| @@ -17,8 +17,9 @@ | |||
| */ | |||
| package org.apache.tools.ant.types.optional.depend; | |||
| import java.util.Vector; | |||
| import java.util.Enumeration; | |||
| import java.util.Stack; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.DirectoryScanner; | |||
| import org.apache.tools.ant.types.FileSet; | |||
| @@ -86,6 +87,7 @@ public class ClassfileSet extends FileSet { | |||
| */ | |||
| public void addRootFileset(FileSet rootFileSet) { | |||
| rootFileSets.addElement(rootFileSet); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -118,6 +120,7 @@ public class ClassfileSet extends FileSet { | |||
| if (isReference()) { | |||
| return getRef(p).getDirectoryScanner(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| Vector allRootClasses = (Vector) rootClasses.clone(); | |||
| for (Enumeration e = rootFileSets.elements(); e.hasMoreElements();) { | |||
| FileSet additionalRootSet = (FileSet) e.nextElement(); | |||
| @@ -160,4 +163,21 @@ public class ClassfileSet extends FileSet { | |||
| ? (ClassfileSet) (getRef(getProject())) : this); | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| // takes care of nested selectors | |||
| super.dieOnCircularReference(stk, p); | |||
| if (!isReference()) { | |||
| for (Enumeration e = rootFileSets.elements(); | |||
| e.hasMoreElements();) { | |||
| FileSet additionalRootSet = (FileSet) e.nextElement(); | |||
| pushAndInvokeCircularReferenceCheck(additionalRootSet, stk, p); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,7 @@ | |||
| */ | |||
| package org.apache.tools.ant.types.resources; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Reference; | |||
| @@ -24,6 +25,7 @@ import org.apache.tools.ant.util.FileUtils; | |||
| import java.io.InputStream; | |||
| import java.io.IOException; | |||
| import java.util.Stack; | |||
| /** | |||
| * | |||
| @@ -48,6 +50,7 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| } else { | |||
| this.classpath.append(classpath); | |||
| } | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -59,6 +62,7 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| if (classpath == null) { | |||
| classpath = new Path(getProject()); | |||
| } | |||
| setChecked(false); | |||
| return classpath.createPath(); | |||
| } | |||
| @@ -77,8 +81,11 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| * @return The classpath | |||
| */ | |||
| public Path getClasspath() { | |||
| return isReference() | |||
| ? ((JavaResource) getCheckedRef()).getClasspath() : classpath; | |||
| if (isReference()) { | |||
| return ((AbstractClasspathResource) getCheckedRef()).getClasspath(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return classpath; | |||
| } | |||
| /** | |||
| @@ -86,6 +93,10 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| * @return the loader. | |||
| */ | |||
| public Reference getLoader() { | |||
| if (isReference()) { | |||
| return ((AbstractClasspathResource) getCheckedRef()).getLoader(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return loader; | |||
| } | |||
| @@ -125,6 +136,7 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| if (isReference()) { | |||
| return ((Resource) getCheckedRef()).isExists(); | |||
| } | |||
| dieOnCircularReference(); | |||
| InputStream is = null; | |||
| try { | |||
| is = getInputStream(); | |||
| @@ -145,6 +157,7 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| if (isReference()) { | |||
| return ((Resource) getCheckedRef()).getInputStream(); | |||
| } | |||
| dieOnCircularReference(); | |||
| ClassLoader cl = null; | |||
| if (loader != null) { | |||
| cl = (ClassLoader) loader.getReferencedObject(); | |||
| @@ -170,4 +183,19 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| * @throws IOException if an error occurs. | |||
| */ | |||
| protected abstract InputStream openInputStream(ClassLoader cl) throws IOException; | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (classpath != null) { | |||
| pushAndInvokeCircularReferenceCheck(classpath, stk, p); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -18,8 +18,10 @@ | |||
| package org.apache.tools.ant.types.resources; | |||
| import java.io.File; | |||
| import java.util.Stack; | |||
| import org.apache.tools.ant.BuildException; | |||
| 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.Reference; | |||
| @@ -241,6 +243,7 @@ public abstract class ArchiveResource extends Resource { | |||
| } | |||
| private synchronized void checkEntry() throws BuildException { | |||
| dieOnCircularReference(); | |||
| if (haveEntry) { | |||
| return; | |||
| } | |||
| @@ -266,4 +269,18 @@ public abstract class ArchiveResource extends Resource { | |||
| * fetches information from the named entry inside the archive. | |||
| */ | |||
| protected abstract void fetchEntry(); | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (archive != null) { | |||
| pushAndInvokeCircularReferenceCheck(archive, stk, p); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -104,7 +104,11 @@ public class FileResource extends Resource implements Touchable, FileProvider, | |||
| * @return the File. | |||
| */ | |||
| public File getFile() { | |||
| return isReference() ? ((FileResource) getCheckedRef()).getFile() : file; | |||
| if (isReference()) { | |||
| return ((FileResource) getCheckedRef()).getFile(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return file; | |||
| } | |||
| /** | |||
| @@ -121,8 +125,11 @@ public class FileResource extends Resource implements Touchable, FileProvider, | |||
| * @return the basedir as File. | |||
| */ | |||
| public File getBaseDir() { | |||
| return isReference() | |||
| ? ((FileResource) getCheckedRef()).getBaseDir() : baseDir; | |||
| if (isReference()) { | |||
| return ((FileResource) getCheckedRef()).getBaseDir(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return baseDir; | |||
| } | |||
| /** | |||
| @@ -322,8 +329,11 @@ public class FileResource extends Resource implements Touchable, FileProvider, | |||
| * @return whether this Resource is a FileResource. | |||
| */ | |||
| public boolean isFilesystemOnly() { | |||
| return !isReference() | |||
| || ((FileResource) getCheckedRef()).isFilesystemOnly(); | |||
| if (isReference()) { | |||
| return ((FileResource) getCheckedRef()).isFilesystemOnly(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return true; | |||
| } | |||
| /** | |||
| @@ -347,6 +357,7 @@ public class FileResource extends Resource implements Touchable, FileProvider, | |||
| if (getFile() == null) { | |||
| throw new BuildException("file attribute is null!"); | |||
| } | |||
| dieOnCircularReference(); | |||
| return getFile(); | |||
| } | |||
| @@ -36,14 +36,13 @@ import org.apache.tools.ant.types.selectors.AbstractSelectorContainer; | |||
| * @since Ant 1.7 | |||
| */ | |||
| public class Files extends AbstractSelectorContainer | |||
| implements Cloneable, ResourceCollection { | |||
| implements ResourceCollection { | |||
| private static final Iterator EMPTY_ITERATOR | |||
| = Collections.EMPTY_SET.iterator(); | |||
| private PatternSet defaultPatterns = new PatternSet(); | |||
| private Vector additionalPatterns = new Vector(); | |||
| private Vector selectors = new Vector(); | |||
| private boolean useDefaultExcludes = true; | |||
| private boolean caseSensitive = true; | |||
| @@ -67,7 +66,6 @@ public class Files extends AbstractSelectorContainer | |||
| protected Files(Files f) { | |||
| this.defaultPatterns = f.defaultPatterns; | |||
| this.additionalPatterns = f.additionalPatterns; | |||
| this.selectors = f.selectors; | |||
| this.useDefaultExcludes = f.useDefaultExcludes; | |||
| this.caseSensitive = f.caseSensitive; | |||
| this.followSymlinks = f.followSymlinks; | |||
| @@ -90,7 +88,7 @@ public class Files extends AbstractSelectorContainer | |||
| if (!additionalPatterns.isEmpty()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| if (!selectors.isEmpty()) { | |||
| if (hasSelectors()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| super.setRefid(r); | |||
| @@ -107,6 +105,7 @@ public class Files extends AbstractSelectorContainer | |||
| PatternSet patterns = new PatternSet(); | |||
| additionalPatterns.addElement(patterns); | |||
| ds = null; | |||
| setChecked(false); | |||
| return patterns; | |||
| } | |||
| @@ -353,6 +352,7 @@ public class Files extends AbstractSelectorContainer | |||
| if (isReference()) { | |||
| return getRef().hasPatterns(); | |||
| } | |||
| dieOnCircularReference(); | |||
| if (hasPatterns(defaultPatterns)) { | |||
| return true; | |||
| } | |||
| @@ -408,19 +408,14 @@ public class Files extends AbstractSelectorContainer | |||
| if (isReference()) { | |||
| return getRef().clone(); | |||
| } | |||
| try { | |||
| Files f = (Files) super.clone(); | |||
| f.defaultPatterns = (PatternSet) defaultPatterns.clone(); | |||
| f.additionalPatterns = new Vector(additionalPatterns.size()); | |||
| for (Iterator iter = additionalPatterns.iterator(); iter.hasNext();) { | |||
| PatternSet ps = (PatternSet) iter.next(); | |||
| f.additionalPatterns.add(ps.clone()); | |||
| } | |||
| f.selectors = new Vector(selectors); | |||
| return f; | |||
| } catch (CloneNotSupportedException e) { | |||
| throw new BuildException(e); | |||
| Files f = (Files) super.clone(); | |||
| f.defaultPatterns = (PatternSet) defaultPatterns.clone(); | |||
| f.additionalPatterns = new Vector(additionalPatterns.size()); | |||
| for (Iterator iter = additionalPatterns.iterator(); iter.hasNext();) { | |||
| PatternSet ps = (PatternSet) iter.next(); | |||
| f.additionalPatterns.add(ps.clone()); | |||
| } | |||
| return f; | |||
| } | |||
| /** | |||
| @@ -453,6 +448,7 @@ public class Files extends AbstractSelectorContainer | |||
| if (isReference()) { | |||
| return getRef().mergePatterns(p); | |||
| } | |||
| dieOnCircularReference(); | |||
| PatternSet ps = new PatternSet(); | |||
| ps.append(defaultPatterns, p); | |||
| final int count = additionalPatterns.size(); | |||
| @@ -482,6 +478,7 @@ public class Files extends AbstractSelectorContainer | |||
| } | |||
| private synchronized void ensureDirectoryScannerSetup() { | |||
| dieOnCircularReference(); | |||
| if (ds == null) { | |||
| ds = new DirectoryScanner(); | |||
| PatternSet ps = mergePatterns(getProject()); | |||
| @@ -31,7 +31,7 @@ import java.lang.reflect.Field; | |||
| public class JavaConstantResource extends AbstractClasspathResource { | |||
| /** | |||
| * open the inpout stream from a specific classloader | |||
| * open the input stream from a specific classloader | |||
| * | |||
| * @param cl the classloader to use. Will be null if the system classloader is used | |||
| * @return an open input stream for the resource | |||
| @@ -34,6 +34,7 @@ public abstract class SizeLimitCollection extends BaseResourceCollectionWrapper | |||
| * @param i the count as <code>int</count>. | |||
| */ | |||
| public synchronized void setCount(int i) { | |||
| checkAttributesAllowed(); | |||
| count = i; | |||
| } | |||
| @@ -141,9 +141,11 @@ public class Sort extends BaseResourceCollectionWrapper { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| // check nested collection | |||
| super.dieOnCircularReference(stk, p); | |||
| if (!isReference()) { | |||
| DataType.pushAndInvokeCircularReferenceCheck(comp, stk, p); | |||
| setChecked(true); | |||
| } | |||
| @@ -117,9 +117,11 @@ public class Tokens extends BaseResourceCollectionWrapper { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| // check nested collection | |||
| super.dieOnCircularReference(stk, p); | |||
| if (!isReference()) { | |||
| if (tokenizer instanceof DataType) { | |||
| pushAndInvokeCircularReferenceCheck((DataType) tokenizer, stk, | |||
| p); | |||
| @@ -17,7 +17,10 @@ | |||
| */ | |||
| package org.apache.tools.ant.types.resources.comparators; | |||
| import java.util.Stack; | |||
| 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.Resource; | |||
| /** | |||
| @@ -54,6 +57,7 @@ public class Reverse extends ResourceComparator { | |||
| throw new BuildException(ONE_NESTED); | |||
| } | |||
| nested = c; | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -68,4 +72,19 @@ public class Reverse extends ResourceComparator { | |||
| ? foo.compareTo(bar) : nested.compare(foo, bar)); | |||
| } | |||
| protected void dieOnCircularReference(Stack stk, Project p) | |||
| throws BuildException { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| if (nested instanceof DataType) { | |||
| pushAndInvokeCircularReferenceCheck((DataType) nested, stk, | |||
| p); | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -19,8 +19,11 @@ | |||
| package org.apache.tools.ant.types.selectors; | |||
| import java.util.Enumeration; | |||
| 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.types.DataType; | |||
| import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | |||
| @@ -32,7 +35,7 @@ import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | |||
| * @since 1.7 | |||
| */ | |||
| public abstract class AbstractSelectorContainer extends DataType | |||
| implements SelectorContainer { | |||
| implements Cloneable, SelectorContainer { | |||
| private Vector selectorsList = new Vector(); | |||
| @@ -41,6 +44,10 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * @return true if there are selectors | |||
| */ | |||
| public boolean hasSelectors() { | |||
| if (isReference()) { | |||
| return ((AbstractSelectorContainer) getCheckedRef()).hasSelectors(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return !(selectorsList.isEmpty()); | |||
| } | |||
| @@ -49,6 +56,10 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * @return the number of selectors | |||
| */ | |||
| public int selectorCount() { | |||
| if (isReference()) { | |||
| return ((AbstractSelectorContainer) getCheckedRef()).selectorCount(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return selectorsList.size(); | |||
| } | |||
| @@ -58,6 +69,11 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * @return an array of selectors | |||
| */ | |||
| public FileSelector[] getSelectors(Project p) { | |||
| if (isReference()) { | |||
| return ((AbstractSelectorContainer) getCheckedRef(p)) | |||
| .getSelectors(p); | |||
| } | |||
| dieOnCircularReference(p); | |||
| FileSelector[] result = new FileSelector[selectorsList.size()]; | |||
| selectorsList.copyInto(result); | |||
| return result; | |||
| @@ -68,6 +84,11 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * @return an enumerator for the selectors | |||
| */ | |||
| public Enumeration selectorElements() { | |||
| if (isReference()) { | |||
| return ((AbstractSelectorContainer) getCheckedRef()) | |||
| .selectorElements(); | |||
| } | |||
| dieOnCircularReference(); | |||
| return selectorsList.elements(); | |||
| } | |||
| @@ -99,7 +120,11 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * @param selector the new selector to add | |||
| */ | |||
| public void appendSelector(FileSelector selector) { | |||
| if (isReference()) { | |||
| throw noChildrenAllowed(); | |||
| } | |||
| selectorsList.addElement(selector); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -119,6 +144,10 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| * </ul> | |||
| */ | |||
| public void validate() { | |||
| if (isReference()) { | |||
| ((AbstractSelectorContainer) getCheckedRef()).validate(); | |||
| } | |||
| dieOnCircularReference(); | |||
| Enumeration e = selectorElements(); | |||
| while (e.hasMoreElements()) { | |||
| Object o = e.nextElement(); | |||
| @@ -293,4 +322,34 @@ public abstract class AbstractSelectorContainer extends DataType | |||
| appendSelector(selector); | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| for (Iterator i = selectorsList.iterator(); i.hasNext(); ) { | |||
| Object o = i.next(); | |||
| if (o instanceof DataType) { | |||
| pushAndInvokeCircularReferenceCheck((DataType) o, stk, p); | |||
| } | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| public synchronized Object clone() { | |||
| if (isReference()) { | |||
| return ((AbstractSelectorContainer) getCheckedRef()).clone(); | |||
| } | |||
| try { | |||
| AbstractSelectorContainer sc = | |||
| (AbstractSelectorContainer) super.clone(); | |||
| sc.selectorsList = new Vector(selectorsList); | |||
| return sc; | |||
| } catch (CloneNotSupportedException e) { | |||
| throw new BuildException(e); | |||
| } | |||
| } | |||
| } | |||
| @@ -89,6 +89,9 @@ public abstract class BaseSelector extends DataType implements FileSelector { | |||
| if (getError() != null) { | |||
| throw new BuildException(errmsg); | |||
| } | |||
| if (!isReference()) { | |||
| dieOnCircularReference(); | |||
| } | |||
| } | |||
| /** | |||
| @@ -20,10 +20,13 @@ package org.apache.tools.ant.types.selectors; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| 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.types.DataType; | |||
| import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | |||
| /** | |||
| @@ -47,6 +50,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| * @return true if there are selectors | |||
| */ | |||
| public boolean hasSelectors() { | |||
| dieOnCircularReference(); | |||
| return !(selectorsList.isEmpty()); | |||
| } | |||
| @@ -55,6 +59,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| * @return the number of selectors | |||
| */ | |||
| public int selectorCount() { | |||
| dieOnCircularReference(); | |||
| return selectorsList.size(); | |||
| } | |||
| @@ -64,6 +69,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| * @return an array of selectors | |||
| */ | |||
| public FileSelector[] getSelectors(Project p) { | |||
| dieOnCircularReference(); | |||
| FileSelector[] result = new FileSelector[selectorsList.size()]; | |||
| selectorsList.copyInto(result); | |||
| return result; | |||
| @@ -74,6 +80,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| * @return an enumerator for the selectors | |||
| */ | |||
| public Enumeration selectorElements() { | |||
| dieOnCircularReference(); | |||
| return selectorsList.elements(); | |||
| } | |||
| @@ -85,6 +92,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| * @return comma separated list of Selectors contained in this one | |||
| */ | |||
| public String toString() { | |||
| dieOnCircularReference(); | |||
| StringBuffer buf = new StringBuffer(); | |||
| Enumeration e = selectorElements(); | |||
| if (e.hasMoreElements()) { | |||
| @@ -106,6 +114,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| */ | |||
| public void appendSelector(FileSelector selector) { | |||
| selectorsList.addElement(selector); | |||
| setChecked(false); | |||
| } | |||
| /** | |||
| @@ -126,6 +135,7 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| */ | |||
| public void validate() { | |||
| verifySettings(); | |||
| dieOnCircularReference(); | |||
| String errmsg = getError(); | |||
| if (errmsg != null) { | |||
| throw new BuildException(errmsg); | |||
| @@ -318,4 +328,21 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
| appendSelector(selector); | |||
| } | |||
| protected synchronized void dieOnCircularReference(Stack stk, Project p) | |||
| throws BuildException { | |||
| if (isChecked()) { | |||
| return; | |||
| } | |||
| if (isReference()) { | |||
| super.dieOnCircularReference(stk, p); | |||
| } else { | |||
| for (Iterator i = selectorsList.iterator(); i.hasNext();) { | |||
| Object o = i.next(); | |||
| if (o instanceof DataType) { | |||
| pushAndInvokeCircularReferenceCheck((DataType) o, stk, p); | |||
| } | |||
| } | |||
| setChecked(true); | |||
| } | |||
| } | |||
| } | |||