aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java922
1 files changed, 922 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java
new file mode 100644
index 00000000..8f274a09
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -0,0 +1,922 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.FileScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.selectors.AndSelector;
+import org.apache.tools.ant.types.selectors.ContainsRegexpSelector;
+import org.apache.tools.ant.types.selectors.ContainsSelector;
+import org.apache.tools.ant.types.selectors.DateSelector;
+import org.apache.tools.ant.types.selectors.DependSelector;
+import org.apache.tools.ant.types.selectors.DepthSelector;
+import org.apache.tools.ant.types.selectors.DifferentSelector;
+import org.apache.tools.ant.types.selectors.ExtendSelector;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.types.selectors.MajoritySelector;
+import org.apache.tools.ant.types.selectors.NoneSelector;
+import org.apache.tools.ant.types.selectors.NotSelector;
+import org.apache.tools.ant.types.selectors.OrSelector;
+import org.apache.tools.ant.types.selectors.PresentSelector;
+import org.apache.tools.ant.types.selectors.ReadableSelector;
+import org.apache.tools.ant.types.selectors.SelectSelector;
+import org.apache.tools.ant.types.selectors.SelectorContainer;
+import org.apache.tools.ant.types.selectors.SelectorScanner;
+import org.apache.tools.ant.types.selectors.SizeSelector;
+import org.apache.tools.ant.types.selectors.TypeSelector;
+import org.apache.tools.ant.types.selectors.WritableSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * Class that holds an implicit patternset and supports nested
+ * patternsets and creates a DirectoryScanner using these patterns.
+ *
+ * <p>Common base class for DirSet and FileSet.</p>
+ *
+ */
+public abstract class AbstractFileSet extends DataType
+ implements Cloneable, SelectorContainer {
+
+ private PatternSet defaultPatterns = new PatternSet();
+ private List<PatternSet> additionalPatterns = new ArrayList<PatternSet>();
+ private List<FileSelector> selectors = new ArrayList<FileSelector>();
+
+ private File dir;
+ private boolean useDefaultExcludes = true;
+ private boolean caseSensitive = true;
+ private boolean followSymlinks = true;
+ private boolean errorOnMissingDir = true;
+ private int maxLevelsOfSymlinks = DirectoryScanner.MAX_LEVELS_OF_SYMLINKS;
+
+ /* cached DirectoryScanner instance for our own Project only */
+ private DirectoryScanner directoryScanner = null;
+
+ /**
+ * Construct a new <code>AbstractFileSet</code>.
+ */
+ public AbstractFileSet() {
+ super();
+ }
+
+ /**
+ * Construct a new <code>AbstractFileSet</code>, shallowly cloned
+ * from the specified <code>AbstractFileSet</code>.
+ * @param fileset the <code>AbstractFileSet</code> to use as a template.
+ */
+ protected AbstractFileSet(AbstractFileSet fileset) {
+ this.dir = fileset.dir;
+ this.defaultPatterns = fileset.defaultPatterns;
+ this.additionalPatterns = fileset.additionalPatterns;
+ this.selectors = fileset.selectors;
+ this.useDefaultExcludes = fileset.useDefaultExcludes;
+ this.caseSensitive = fileset.caseSensitive;
+ this.followSymlinks = fileset.followSymlinks;
+ this.errorOnMissingDir = fileset.errorOnMissingDir;
+ this.maxLevelsOfSymlinks = fileset.maxLevelsOfSymlinks;
+ setProject(fileset.getProject());
+ }
+
+ /**
+ * Makes this instance in effect a reference to another instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the <code>Reference</code> to use.
+ * @throws BuildException on error
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (dir != null || defaultPatterns.hasPatterns(getProject())) {
+ throw tooManyAttributes();
+ }
+ if (!additionalPatterns.isEmpty()) {
+ throw noChildrenAllowed();
+ }
+ if (!selectors.isEmpty()) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Sets the base-directory for this instance.
+ * @param dir the directory's <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setDir(File dir) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.dir = dir;
+ directoryScanner = null;
+ }
+
+ /**
+ * Retrieves the base-directory for this instance.
+ * @return <code>File</code>.
+ */
+ public File getDir() {
+ return getDir(getProject());
+ }
+
+ /**
+ * Retrieves the base-directory for this instance.
+ * @param p the <code>Project</code> against which the
+ * reference is resolved, if set.
+ * @return <code>File</code>.
+ */
+ public synchronized File getDir(Project p) {
+ if (isReference()) {
+ return getRef(p).getDir(p);
+ }
+ dieOnCircularReference();
+ return dir;
+ }
+
+ /**
+ * Creates a nested patternset.
+ * @return <code>PatternSet</code>.
+ */
+ public synchronized PatternSet createPatternSet() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PatternSet patterns = new PatternSet();
+ additionalPatterns.add(patterns);
+ directoryScanner = null;
+ return patterns;
+ }
+
+ /**
+ * Add a name entry to the include list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createInclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createInclude();
+ }
+
+ /**
+ * Add a name entry to the include files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createIncludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createIncludesFile();
+ }
+
+ /**
+ * Add a name entry to the exclude list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createExclude();
+ }
+
+ /**
+ * Add a name entry to the excludes files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExcludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createExcludesFile();
+ }
+
+ /**
+ * Creates a single file fileset.
+ * @param file the single <code>File</code> included in this
+ * <code>AbstractFileSet</code>.
+ */
+ public synchronized void setFile(File file) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ setDir(file.getParentFile());
+ createInclude().setName(file.getName());
+ }
+
+ /**
+ * Appends <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param includes the <code>String</code> containing the include patterns.
+ */
+ public synchronized void setIncludes(String includes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setIncludes(includes);
+ directoryScanner = null;
+ }
+
+ /**
+ * Appends <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * @param includes array containing the include patterns.
+ * @since Ant 1.7
+ */
+ public synchronized void appendIncludes(String[] includes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (includes != null) {
+ for (int i = 0; i < includes.length; i++) {
+ defaultPatterns.createInclude().setName(includes[i]);
+ }
+ directoryScanner = null;
+ }
+ }
+
+ /**
+ * Appends <code>excludes</code> to the current list of exclude
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param excludes the <code>String</code> containing the exclude patterns.
+ */
+ public synchronized void setExcludes(String excludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setExcludes(excludes);
+ directoryScanner = null;
+ }
+
+ /**
+ * Appends <code>excludes</code> to the current list of include
+ * patterns.
+ *
+ * @param excludes array containing the exclude patterns.
+ * @since Ant 1.7
+ */
+ public synchronized void appendExcludes(String[] excludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (excludes != null) {
+ for (int i = 0; i < excludes.length; i++) {
+ defaultPatterns.createExclude().setName(excludes[i]);
+ }
+ directoryScanner = null;
+ }
+ }
+
+ /**
+ * Sets the <code>File</code> containing the includes patterns.
+ *
+ * @param incl <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setIncludesfile(File incl) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setIncludesfile(incl);
+ directoryScanner = null;
+ }
+
+ /**
+ * Sets the <code>File</code> containing the excludes patterns.
+ *
+ * @param excl <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setExcludesfile(File excl) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setExcludesfile(excl);
+ directoryScanner = null;
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes <code>boolean</code>.
+ */
+ public synchronized void setDefaultexcludes(boolean useDefaultExcludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.useDefaultExcludes = useDefaultExcludes;
+ directoryScanner = null;
+ }
+
+ /**
+ * Whether default exclusions should be used or not.
+ * @return the default exclusions value.
+ * @since Ant 1.6.3
+ */
+ public synchronized boolean getDefaultexcludes() {
+ if (isReference()) {
+ return getRef(getProject()).getDefaultexcludes();
+ }
+ dieOnCircularReference();
+ return useDefaultExcludes;
+ }
+
+ /**
+ * Sets case sensitivity of the file system.
+ *
+ * @param caseSensitive <code>boolean</code>.
+ */
+ public synchronized void setCaseSensitive(boolean caseSensitive) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.caseSensitive = caseSensitive;
+ directoryScanner = null;
+ }
+
+ /**
+ * Find out if the fileset is case sensitive.
+ *
+ * @return <code>boolean</code> indicating whether the fileset is
+ * case sensitive.
+ *
+ * @since Ant 1.7
+ */
+ public synchronized boolean isCaseSensitive() {
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return caseSensitive;
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed.
+ */
+ public synchronized void setFollowSymlinks(boolean followSymlinks) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.followSymlinks = followSymlinks;
+ directoryScanner = null;
+ }
+
+ /**
+ * Find out if the fileset wants to follow symbolic links.
+ *
+ * @return <code>boolean</code> indicating whether symbolic links
+ * should be followed.
+ *
+ * @since Ant 1.6
+ */
+ public synchronized boolean isFollowSymlinks() {
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return followSymlinks;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMaxLevelsOfSymlinks(int max) {
+ maxLevelsOfSymlinks = max;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public int getMaxLevelsOfSymlinks() {
+ return maxLevelsOfSymlinks;
+ }
+
+ /**
+ * Sets whether an error is thrown if a directory does not exist.
+ *
+ * @param errorOnMissingDir true if missing directories cause errors,
+ * false if not.
+ */
+ public void setErrorOnMissingDir(boolean errorOnMissingDir) {
+ this.errorOnMissingDir = errorOnMissingDir;
+ }
+
+ /**
+ * Gets whether an error is/should be thrown if the base directory
+ * does not exist.
+ * @since Ant 1.8.2
+ */
+ public boolean getErrorOnMissingDir() {
+ return errorOnMissingDir;
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @return a <code>DirectoryScanner</code> instance.
+ */
+ public DirectoryScanner getDirectoryScanner() {
+ return getDirectoryScanner(getProject());
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @param p the Project against which the DirectoryScanner should be configured.
+ * @return a <code>DirectoryScanner</code> instance.
+ */
+ public DirectoryScanner getDirectoryScanner(Project p) {
+ if (isReference()) {
+ return getRef(p).getDirectoryScanner(p);
+ }
+ dieOnCircularReference();
+ DirectoryScanner ds = null;
+ synchronized (this) {
+ if (directoryScanner != null && p == getProject()) {
+ ds = directoryScanner;
+ } else {
+ if (dir == null) {
+ throw new BuildException("No directory specified for "
+ + getDataTypeName() + ".");
+ }
+ if (!dir.exists() && errorOnMissingDir) {
+ throw new BuildException(dir.getAbsolutePath()
+ + DirectoryScanner
+ .DOES_NOT_EXIST_POSTFIX);
+ }
+ if (!dir.isDirectory() && dir.exists()) {
+ throw new BuildException(dir.getAbsolutePath()
+ + " is not a directory.");
+ }
+ ds = new DirectoryScanner();
+ setupDirectoryScanner(ds, p);
+ ds.setFollowSymlinks(followSymlinks);
+ ds.setErrorOnMissingDir(errorOnMissingDir);
+ ds.setMaxLevelsOfSymlinks(maxLevelsOfSymlinks);
+ directoryScanner = (p == getProject()) ? ds : directoryScanner;
+ }
+ }
+ ds.scan();
+ return ds;
+ }
+
+ /**
+ * Set up the specified directory scanner against this
+ * AbstractFileSet's Project.
+ * @param ds a <code>FileScanner</code> instance.
+ */
+ public void setupDirectoryScanner(FileScanner ds) {
+ setupDirectoryScanner(ds, getProject());
+ }
+
+ /**
+ * Set up the specified directory scanner against the specified project.
+ * @param ds a <code>FileScanner</code> instance.
+ * @param p an Ant <code>Project</code> instance.
+ */
+ public synchronized void setupDirectoryScanner(FileScanner ds, Project p) {
+ if (isReference()) {
+ getRef(p).setupDirectoryScanner(ds, p);
+ return;
+ }
+ dieOnCircularReference(p);
+ if (ds == null) {
+ throw new IllegalArgumentException("ds cannot be null");
+ }
+ ds.setBasedir(dir);
+
+ PatternSet ps = mergePatterns(p);
+ p.log(getDataTypeName() + ": Setup scanner in dir " + dir
+ + " with " + ps, Project.MSG_DEBUG);
+
+ ds.setIncludes(ps.getIncludePatterns(p));
+ ds.setExcludes(ps.getExcludePatterns(p));
+ if (ds instanceof SelectorScanner) {
+ SelectorScanner ss = (SelectorScanner) ds;
+ ss.setSelectors(getSelectors(p));
+ }
+ if (useDefaultExcludes) {
+ ds.addDefaultExcludes();
+ }
+ ds.setCaseSensitive(caseSensitive);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced FileSet.
+ * @param p the current project
+ * @return the referenced FileSet
+ */
+ protected AbstractFileSet getRef(Project p) {
+ return (AbstractFileSet) getCheckedRef(p);
+ }
+
+ // SelectorContainer methods
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return whether any selectors are in this container.
+ */
+ public synchronized boolean hasSelectors() {
+ if (isReference()) {
+ return getRef(getProject()).hasSelectors();
+ }
+ dieOnCircularReference();
+ return !(selectors.isEmpty());
+ }
+
+ /**
+ * Indicates whether there are any patterns here.
+ *
+ * @return whether any patterns are in this container.
+ */
+ public synchronized boolean hasPatterns() {
+ if (isReference() && getProject() != null) {
+ return getRef(getProject()).hasPatterns();
+ }
+ dieOnCircularReference();
+ if (defaultPatterns.hasPatterns(getProject())) {
+ return true;
+ }
+ for (PatternSet ps : additionalPatterns) {
+ if (ps.hasPatterns(getProject())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container.
+ *
+ * @return the number of selectors in this container as an <code>int</code>.
+ */
+ public synchronized int selectorCount() {
+ if (isReference()) {
+ return getRef(getProject()).selectorCount();
+ }
+ dieOnCircularReference();
+ return selectors.size();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return a <code>FileSelector[]</code> of the selectors in this container.
+ */
+ public synchronized FileSelector[] getSelectors(Project p) {
+ if (isReference()) {
+ return getRef(getProject()).getSelectors(p);
+ }
+ dieOnCircularReference(p);
+ return (FileSelector[]) (selectors.toArray(
+ new FileSelector[selectors.size()]));
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ *
+ * @return an <code>Enumeration</code> of selectors.
+ */
+ public synchronized Enumeration<FileSelector> selectorElements() {
+ if (isReference()) {
+ return getRef(getProject()).selectorElements();
+ }
+ dieOnCircularReference();
+ return Collections.enumeration(selectors);
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new <code>FileSelector</code> to add.
+ */
+ public synchronized void appendSelector(FileSelector selector) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ selectors.add(selector);
+ directoryScanner = null;
+ setChecked(false);
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * Add a "Select" selector entry on the selector list.
+ * @param selector the <code>SelectSelector</code> to add.
+ */
+ public void addSelector(SelectSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an "And" selector entry on the selector list.
+ * @param selector the <code>AndSelector</code> to add.
+ */
+ public void addAnd(AndSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an "Or" selector entry on the selector list.
+ * @param selector the <code>OrSelector</code> to add.
+ */
+ public void addOr(OrSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a "Not" selector entry on the selector list.
+ * @param selector the <code>NotSelector</code> to add.
+ */
+ public void addNot(NotSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a "None" selector entry on the selector list.
+ * @param selector the <code>NoneSelector</code> to add.
+ */
+ public void addNone(NoneSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a majority selector entry on the selector list.
+ * @param selector the <code>MajoritySelector</code> to add.
+ */
+ public void addMajority(MajoritySelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector date entry on the selector list.
+ * @param selector the <code>DateSelector</code> to add.
+ */
+ public void addDate(DateSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector size entry on the selector list.
+ * @param selector the <code>SizeSelector</code> to add.
+ */
+ public void addSize(SizeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a DifferentSelector entry on the selector list.
+ * @param selector the <code>DifferentSelector</code> to add.
+ */
+ public void addDifferent(DifferentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector filename entry on the selector list.
+ * @param selector the <code>FilenameSelector</code> to add.
+ */
+ public void addFilename(FilenameSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector type entry on the selector list.
+ * @param selector the <code>TypeSelector</code> to add.
+ */
+ public void addType(TypeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an extended selector entry on the selector list.
+ * @param selector the <code>ExtendSelector</code> to add.
+ */
+ public void addCustom(ExtendSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a contains selector entry on the selector list.
+ * @param selector the <code>ContainsSelector</code> to add.
+ */
+ public void addContains(ContainsSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a present selector entry on the selector list.
+ * @param selector the <code>PresentSelector</code> to add.
+ */
+ public void addPresent(PresentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a depth selector entry on the selector list.
+ * @param selector the <code>DepthSelector</code> to add.
+ */
+ public void addDepth(DepthSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a depends selector entry on the selector list.
+ * @param selector the <code>DependSelector</code> to add.
+ */
+ public void addDepend(DependSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a regular expression selector entry on the selector list.
+ * @param selector the <code>ContainsRegexpSelector</code> to add.
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add the modified selector.
+ * @param selector the <code>ModifiedSelector</code> to add.
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ appendSelector(selector);
+ }
+
+ public void addReadable(ReadableSelector r) {
+ appendSelector(r);
+ }
+
+ public void addWritable(WritableSelector w) {
+ appendSelector(w);
+ }
+
+ /**
+ * Add an arbitrary selector.
+ * @param selector the <code>FileSelector</code> to add.
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Returns included files as a list of semicolon-separated filenames.
+ *
+ * @return a <code>String</code> 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();
+
+ for (int i = 0; i < files.length; i++) {
+ if (i > 0) {
+ sb.append(';');
+ }
+ sb.append(files[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Creates a deep clone of this instance, except for the nested
+ * selectors (the list of selectors is a shallow clone of this
+ * instance's list).
+ * @return the cloned object
+ * @since Ant 1.6
+ */
+ public synchronized Object clone() {
+ if (isReference()) {
+ return (getRef(getProject())).clone();
+ } else {
+ try {
+ AbstractFileSet fs = (AbstractFileSet) super.clone();
+ fs.defaultPatterns = (PatternSet) defaultPatterns.clone();
+ fs.additionalPatterns = new ArrayList<PatternSet>(additionalPatterns.size());
+ for (PatternSet ps : additionalPatterns) {
+ fs.additionalPatterns.add((PatternSet) ps.clone());
+ }
+ fs.selectors = new ArrayList<FileSelector>(selectors);
+ return fs;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+
+ /**
+ * Get the merged include patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the include patterns of the default pattern set and all
+ * nested patternsets.
+ *
+ * @since Ant 1.7
+ */
+ public String[] mergeIncludes(Project p) {
+ return mergePatterns(p).getIncludePatterns(p);
+ }
+
+ /**
+ * Get the merged exclude patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the exclude patterns of the default pattern set and all
+ * nested patternsets.
+ *
+ * @since Ant 1.7
+ */
+ public String[] mergeExcludes(Project p) {
+ return mergePatterns(p).getExcludePatterns(p);
+ }
+
+ /**
+ * Get the merged patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the default patternset merged with the additional sets
+ * in a new PatternSet instance.
+ *
+ * @since Ant 1.7
+ */
+ public synchronized PatternSet mergePatterns(Project p) {
+ 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++) {
+ ps.append(additionalPatterns.get(i), p);
+ }
+ return ps;
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (FileSelector fileSelector : selectors) {
+ if (fileSelector instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p);
+ }
+ }
+ for (PatternSet ps : additionalPatterns) {
+ pushAndInvokeCircularReferenceCheck(ps, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}