aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java775
1 files changed, 775 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java
new file mode 100644
index 00000000..db6f5e9f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java
@@ -0,0 +1,775 @@
+/*
+ * 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.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.PathTokenizer;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * This object represents a path as used by CLASSPATH or PATH
+ * environment variable. A path might also be described as a collection
+ * of unique filesystem resources.
+ * <p>
+ * <code>
+ * &lt;sometask&gt;<br>
+ * &nbsp;&nbsp;&lt;somepath&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file.jar" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement
+ * path="/path/to/file2.jar:/path/to/class2;/path/to/class3" /&gt;
+ * <br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file3.jar" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file4.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/somepath&gt;<br>
+ * &lt;/sometask&gt;<br>
+ * </code>
+ * <p>
+ * The object implementation <code>sometask</code> must provide a method called
+ * <code>createSomepath</code> which returns an instance of <code>Path</code>.
+ * Nested path definitions are handled by the Path object and must be labeled
+ * <code>pathelement</code>.<p>
+ *
+ * The path element takes a parameter <code>path</code> which will be parsed
+ * and split into single elements. It will usually be used
+ * to define a path from an environment variable.
+ */
+
+public class Path extends DataType implements Cloneable, ResourceCollection {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The system classpath as a Path object */
+ public static Path systemClasspath =
+ new Path(null, System.getProperty("java.class.path"));
+
+
+ /**
+ * The system bootclasspath as a Path object.
+ *
+ * @since Ant 1.6.2
+ */
+ public static Path systemBootClasspath =
+ new Path(null, System.getProperty("sun.boot.class.path"));
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * Helper class, holds the nested <code>&lt;pathelement&gt;</code> values.
+ */
+ public class PathElement implements ResourceCollection {
+ private String[] parts;
+
+ /**
+ * Set the location.
+ *
+ * @param loc a <code>File</code> value
+ */
+ public void setLocation(File loc) {
+ parts = new String[] {translateFile(loc.getAbsolutePath())};
+ }
+
+ /**
+ * Set the path.
+ *
+ * @param path a <code>String</code> value
+ */
+ public void setPath(String path) {
+ parts = Path.translatePath(getProject(), path);
+ }
+
+ /**
+ * Return the converted pathelements.
+ *
+ * @return a <code>String[]</code> value
+ */
+ public String[] getParts() {
+ return parts;
+ }
+
+ /**
+ * Create an iterator.
+ * @return an iterator.
+ */
+ public Iterator<Resource> iterator() {
+ return new FileResourceIterator(getProject(), null, parts);
+ }
+
+ /**
+ * Check if this resource is only for filesystems.
+ * @return true.
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ /**
+ * Get the number of resources.
+ * @return the number of parts.
+ */
+ public int size() {
+ return parts == null ? 0 : parts.length;
+ }
+
+ }
+
+ private Boolean preserveBC;
+
+ private Union union = null;
+ private boolean cache = false;
+
+ /**
+ * Invoked by IntrospectionHelper for <code>setXXX(Path p)</code>
+ * attribute setters.
+ * @param p the <code>Project</code> for this path.
+ * @param path the <code>String</code> path definition.
+ */
+ public Path(Project p, String path) {
+ this(p);
+ createPathElement().setPath(path);
+ }
+
+ /**
+ * Construct an empty <code>Path</code>.
+ * @param project the <code>Project</code> for this path.
+ */
+ public Path(Project project) {
+ setProject(project);
+ }
+
+ /**
+ * Adds a element definition to the path.
+ * @param location the location of the element to add (must not be
+ * <code>null</code> nor empty.
+ * @throws BuildException on error
+ */
+ public void setLocation(File location) throws BuildException {
+ checkAttributesAllowed();
+ createPathElement().setLocation(location);
+ }
+
+ /**
+ * Parses a path definition and creates single PathElements.
+ * @param path the <code>String</code> path definition.
+ * @throws BuildException on error
+ */
+ public void setPath(String path) throws BuildException {
+ checkAttributesAllowed();
+ createPathElement().setPath(path);
+ }
+
+ /**
+ * Makes this instance in effect a reference to another Path instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the reference to another Path
+ * @throws BuildException on error
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (union != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Creates the nested <code>&lt;pathelement&gt;</code> element.
+ * @return the <code>PathElement</code> to be configured
+ * @throws BuildException on error
+ */
+ public PathElement createPathElement() throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PathElement pe = new PathElement();
+ add(pe);
+ return pe;
+ }
+
+ /**
+ * Adds a nested <code>&lt;fileset&gt;</code> element.
+ * @param fs a <code>FileSet</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addFileset(FileSet fs) throws BuildException {
+ if (fs.getProject() == null) {
+ fs.setProject(getProject());
+ }
+ add(fs);
+ }
+
+ /**
+ * Adds a nested <code>&lt;filelist&gt;</code> element.
+ * @param fl a <code>FileList</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addFilelist(FileList fl) throws BuildException {
+ if (fl.getProject() == null) {
+ fl.setProject(getProject());
+ }
+ add(fl);
+ }
+
+ /**
+ * Adds a nested <code>&lt;dirset&gt;</code> element.
+ * @param dset a <code>DirSet</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addDirset(DirSet dset) throws BuildException {
+ if (dset.getProject() == null) {
+ dset.setProject(getProject());
+ }
+ add(dset);
+ }
+
+ /**
+ * Adds a nested path
+ * @param path a <code>Path</code> to be added to the path
+ * @throws BuildException on error
+ * @since Ant 1.6
+ */
+ public void add(Path path) throws BuildException {
+ if (path == this) {
+ throw circularReference();
+ }
+ if (path.getProject() == null) {
+ path.setProject(getProject());
+ }
+ add((ResourceCollection) path);
+ }
+
+ /**
+ * Add a nested <code>ResourceCollection</code>.
+ * @param c the ResourceCollection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection c) {
+ checkChildrenAllowed();
+ if (c == null) {
+ return;
+ }
+ if (union == null) {
+ union = new Union();
+ union.setProject(getProject());
+ union.setCache(cache);
+ }
+ union.add(c);
+ setChecked(false);
+ }
+
+ /**
+ * Creates a nested <code>&lt;path&gt;</code> element.
+ * @return a <code>Path</code> to be configured
+ * @throws BuildException on error
+ */
+ public Path createPath() throws BuildException {
+ Path p = new Path(getProject());
+ add(p);
+ return p;
+ }
+
+ /**
+ * Append the contents of the other Path instance to this.
+ * @param other a <code>Path</code> to be added to the path
+ */
+ public void append(Path other) {
+ if (other == null) {
+ return;
+ }
+ add(other);
+ }
+
+ /**
+ * Adds the components on the given path which exist to this
+ * Path. Components that don't exist aren't added.
+ *
+ * @param source - source path whose components are examined for existence
+ */
+ public void addExisting(Path source) {
+ addExisting(source, false);
+ }
+
+ /**
+ * Same as addExisting, but support classpath behavior if tryUserDir
+ * is true. Classpaths are relative to user dir, not the project base.
+ * That used to break jspc test
+ *
+ * @param source the source path
+ * @param tryUserDir if true try the user directory if the file is not present
+ */
+ public void addExisting(Path source, boolean tryUserDir) {
+ String[] list = source.list();
+ File userDir = (tryUserDir) ? new File(System.getProperty("user.dir"))
+ : null;
+
+ for (int i = 0; i < list.length; i++) {
+ File f = resolveFile(getProject(), list[i]);
+
+ // probably not the best choice, but it solves the problem of
+ // relative paths in CLASSPATH
+ if (tryUserDir && !f.exists()) {
+ f = new File(userDir, list[i]);
+ }
+ if (f.exists()) {
+ setLocation(f);
+ } else if (f.getParentFile() != null && f.getParentFile().exists()
+ && containsWildcards(f.getName())) {
+ setLocation(f);
+ log("adding " + f + " which contains wildcards and may not"
+ + " do what you intend it to do depending on your OS or"
+ + " version of Java", Project.MSG_VERBOSE);
+ } else {
+ log("dropping " + f + " from path as it doesn't exist",
+ Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Whether to cache the current path.
+ * @since Ant 1.8.0
+ */
+ public void setCache(boolean b) {
+ checkAttributesAllowed();
+ cache = b;
+ if (union != null) {
+ union.setCache(b);
+ }
+ }
+
+ /**
+ * Returns all path elements defined by this and nested path objects.
+ * @return list of path elements.
+ */
+ public String[] list() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).list();
+ }
+ return assertFilesystemOnly(union) == null
+ ? new String[0] : union.list();
+ }
+
+ /**
+ * Returns a textual representation of the path, which can be used as
+ * CLASSPATH or PATH environment variable definition.
+ * @return a textual representation of the path.
+ */
+ public String toString() {
+ return isReference() ? getCheckedRef().toString()
+ : union == null ? "" : union.toString();
+ }
+
+ /**
+ * Splits a PATH (with : or ; as separators) into its parts.
+ * @param project the project to use
+ * @param source a <code>String</code> value
+ * @return an array of strings, one for each path element
+ */
+ public static String[] translatePath(Project project, String source) {
+ final Vector<String> result = new Vector<String>();
+ if (source == null) {
+ return new String[0];
+ }
+ PathTokenizer tok = new PathTokenizer(source);
+ StringBuffer element = new StringBuffer();
+ while (tok.hasMoreTokens()) {
+ String pathElement = tok.nextToken();
+ try {
+ element.append(resolveFile(project, pathElement).getPath());
+ } catch (BuildException e) {
+ project.log("Dropping path element " + pathElement
+ + " as it is not valid relative to the project",
+ Project.MSG_VERBOSE);
+ }
+ for (int i = 0; i < element.length(); i++) {
+ translateFileSep(element, i);
+ }
+ result.addElement(element.toString());
+ element = new StringBuffer();
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Returns its argument with all file separator characters
+ * replaced so that they match the local OS conventions.
+ * @param source the path to convert
+ * @return the converted path
+ */
+ public static String translateFile(String source) {
+ if (source == null) {
+ return "";
+ }
+ final StringBuffer result = new StringBuffer(source);
+ for (int i = 0; i < result.length(); i++) {
+ translateFileSep(result, i);
+ }
+ return result.toString();
+ }
+
+ /**
+ * Translates occurrences at a position of / or \ to correct separator of the
+ * current platform and returns whether it had to do a
+ * replacement.
+ * @param buffer a buffer containing a string
+ * @param pos the position in the string buffer to convert
+ * @return true if the character was a / or \
+ */
+ protected static boolean translateFileSep(StringBuffer buffer, int pos) {
+ if (buffer.charAt(pos) == '/' || buffer.charAt(pos) == '\\') {
+ buffer.setCharAt(pos, File.separatorChar);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).size();
+ }
+ dieOnCircularReference();
+ return union == null ? 0 : assertFilesystemOnly(union).size();
+ }
+
+ /**
+ * Clone this Path.
+ * @return Path with shallowly cloned Resource children.
+ */
+ public Object clone() {
+ try {
+ Path result = (Path) super.clone();
+ result.union = union == null ? union : (Union) union.clone();
+ return result;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (union != null) {
+ pushAndInvokeCircularReferenceCheck(union, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Resolve a filename with Project's help - if we know one that is.
+ */
+ private static File resolveFile(Project project, String relativeName) {
+ return FileUtils.getFileUtils().resolveFile(
+ (project == null) ? null : project.getBaseDir(), relativeName);
+ }
+
+ /**
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using &quot;last&quot; as
+ * default value.
+ * @return the concatenated path
+ */
+ public Path concatSystemClasspath() {
+ return concatSystemClasspath("last");
+ }
+
+ /**
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using the supplied value
+ * if ${build.sysclasspath} has not been set.
+ * @param defValue the order ("first", "last", "only")
+ * @return the concatenated path
+ */
+ public Path concatSystemClasspath(String defValue) {
+ return concatSpecialPath(defValue, Path.systemClasspath);
+ }
+
+ /**
+ * Concatenates the system boot class path in the order specified
+ * by the ${build.sysclasspath} property - using the supplied
+ * value if ${build.sysclasspath} has not been set.
+ * @param defValue the order ("first", "last", "only")
+ * @return the concatenated path
+ */
+ public Path concatSystemBootClasspath(String defValue) {
+ return concatSpecialPath(defValue, Path.systemBootClasspath);
+ }
+
+ /**
+ * Concatenates a class path in the order specified by the
+ * ${build.sysclasspath} property - using the supplied value if
+ * ${build.sysclasspath} has not been set.
+ */
+ private Path concatSpecialPath(String defValue, Path p) {
+ Path result = new Path(getProject());
+
+ String order = defValue;
+ String o = getProject() != null
+ ? getProject().getProperty(MagicNames.BUILD_SYSCLASSPATH)
+ : System.getProperty(MagicNames.BUILD_SYSCLASSPATH);
+ if (o != null) {
+ order = o;
+ }
+ if (order.equals("only")) {
+ // only: the developer knows what (s)he is doing
+ result.addExisting(p, true);
+
+ } else if (order.equals("first")) {
+ // first: developer could use a little help
+ result.addExisting(p, true);
+ result.addExisting(this);
+
+ } else if (order.equals("ignore")) {
+ // ignore: don't trust anyone
+ result.addExisting(this);
+
+ } else {
+ // last: don't trust the developer
+ if (!order.equals("last")) {
+ log("invalid value for " + MagicNames.BUILD_SYSCLASSPATH
+ + ": " + order,
+ Project.MSG_WARN);
+ }
+ result.addExisting(this);
+ result.addExisting(p, true);
+ }
+ return result;
+ }
+
+ /**
+ * Add the Java Runtime classes to this Path instance.
+ */
+ public void addJavaRuntime() {
+ if (JavaEnvUtils.isKaffe()) {
+ // newer versions of Kaffe (1.1.1+) won't have this,
+ // but this will be sorted by FileSet anyway.
+ File kaffeShare = new File(System.getProperty("java.home")
+ + File.separator + "share"
+ + File.separator + "kaffe");
+ if (kaffeShare.isDirectory()) {
+ FileSet kaffeJarFiles = new FileSet();
+ kaffeJarFiles.setDir(kaffeShare);
+ kaffeJarFiles.setIncludes("*.jar");
+ addFileset(kaffeJarFiles);
+ }
+ } else if ("GNU libgcj".equals(System.getProperty("java.vm.name"))) {
+ addExisting(systemBootClasspath);
+ }
+
+ if (System.getProperty("java.vendor").toLowerCase(Locale.ENGLISH).indexOf("microsoft") >= 0) {
+ // TODO is this code still necessary? is there any 1.2+ port?
+ // Pull in *.zip from packages directory
+ FileSet msZipFiles = new FileSet();
+ msZipFiles.setDir(new File(System.getProperty("java.home")
+ + File.separator + "Packages"));
+ msZipFiles.setIncludes("*.ZIP");
+ addFileset(msZipFiles);
+ } else {
+ // JDK 1.2+ seems to set java.home to the JRE directory.
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + "rt.jar"));
+ // Just keep the old version as well and let addExisting
+ // sort it out.
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "jre"
+ + File.separator + "lib"
+ + File.separator + "rt.jar"));
+
+ // Sun's and Apple's 1.4 have JCE and JSSE in separate jars.
+ String[] secJars = {"jce", "jsse"};
+ for (int i = 0; i < secJars.length; i++) {
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + secJars[i] + ".jar"));
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + secJars[i] + ".jar"));
+ }
+
+ // IBM's 1.4 has rt.jar split into 4 smaller jars and a combined
+ // JCE/JSSE in security.jar.
+ String[] ibmJars
+ = {"core", "graphics", "security", "server", "xml"};
+ for (int i = 0; i < ibmJars.length; i++) {
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + ibmJars[i] + ".jar"));
+ }
+
+ // Added for MacOS X
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + "classes.jar"));
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + "ui.jar"));
+ }
+ }
+
+ /**
+ * Emulation of extdirs feature in java >= 1.2.
+ * This method adds all files in the given
+ * directories (but not in sub-directories!) to the classpath,
+ * so that you don't have to specify them all one by one.
+ * @param extdirs - Path to append files to
+ */
+ public void addExtdirs(Path extdirs) {
+ if (extdirs == null) {
+ String extProp = System.getProperty("java.ext.dirs");
+ if (extProp != null) {
+ extdirs = new Path(getProject(), extProp);
+ } else {
+ return;
+ }
+ }
+
+ String[] dirs = extdirs.list();
+ for (int i = 0; i < dirs.length; i++) {
+ File dir = resolveFile(getProject(), dirs[i]);
+ if (dir.exists() && dir.isDirectory()) {
+ FileSet fs = new FileSet();
+ fs.setDir(dir);
+ fs.setIncludes("*");
+ addFileset(fs);
+ }
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract. The Iterator returned
+ * will throw ConcurrentModificationExceptions if ResourceCollections
+ * are added to this container while the Iterator is in use.
+ * @return a "fail-fast" Iterator.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ if (getPreserveBC()) {
+ return new FileResourceIterator(getProject(), null, list());
+ }
+ return union == null ? Collections.<Resource> emptySet().iterator()
+ : assertFilesystemOnly(union).iterator();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ assertFilesystemOnly(union);
+ return true;
+ }
+
+ /**
+ * Verify the specified ResourceCollection is filesystem-only.
+ * @param rc the ResourceCollection to check.
+ * @throws BuildException if <code>rc</code> is not filesystem-only.
+ * @return the passed in ResourceCollection.
+ */
+ protected ResourceCollection assertFilesystemOnly(ResourceCollection rc) {
+ if (rc != null && !(rc.isFilesystemOnly())) {
+ throw new BuildException(getDataTypeName()
+ + " allows only filesystem resources.");
+ }
+ return rc;
+ }
+
+ /**
+ * Helps determine whether to preserve BC by calling <code>list()</code> on subclasses.
+ * The default behavior of this method is to return <code>true</code> for any subclass
+ * that implements <code>list()</code>; this can, of course, be avoided by overriding
+ * this method to return <code>false</code>. It is not expected that the result of this
+ * method should change over time, thus it is called only once.
+ * @return <code>true</code> if <code>iterator()</code> should delegate to <code>list()</code>.
+ */
+ protected boolean delegateIteratorToList() {
+ if (getClass().equals(Path.class)) {
+ return false;
+ }
+ try {
+ Method listMethod = getClass().getMethod("list", (Class[]) null);
+ return !listMethod.getDeclaringClass().equals(Path.class);
+ } catch (Exception e) {
+ //shouldn't happen, but
+ return false;
+ }
+ }
+
+ private synchronized boolean getPreserveBC() {
+ if (preserveBC == null) {
+ preserveBC = delegateIteratorToList() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ return preserveBC.booleanValue();
+ }
+
+ /**
+ * Does the given file name contain wildcards?
+ * @since Ant 1.8.2
+ */
+ private static boolean containsWildcards(String path) {
+ return path != null
+ && (path.indexOf("*") > -1 || path.indexOf("?") > -1);
+ }
+
+}