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