diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/Location.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/Location.java
deleted file mode 100644
index 7015cdcc6..000000000
--- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/Location.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.owasp.dependencycheck.org.apache.tools.ant;
-
-import java.io.Serializable;
-import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
-import org.xml.sax.Locator;
-
-/**
- * Stores the location of a piece of text within a file (file name,
- * line number and column number). Note that the column number is
- * currently ignored.
- *
- */
-public class Location implements Serializable {
- private static final long serialVersionUID = 1L;
-
- /** Name of the file. */
- private final String fileName;
- /** Line number within the file. */
- private final int lineNumber;
- /** Column number within the file. */
- private final int columnNumber;
-
- /** Location to use when one is needed but no information is available */
- public static final Location UNKNOWN_LOCATION = new Location();
-
- private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
- /**
- * Creates an "unknown" location.
- */
- private Location() {
- this(null, 0, 0);
- }
-
- /**
- * Creates a location consisting of a file name but no line number or
- * column number.
- *
- * @param fileName The name of the file. May be null,
- * in which case the location is equivalent to
- * {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
- */
- public Location(String fileName) {
- this(fileName, 0, 0);
- }
-
- /**
- * Creates a location from the SAX locator using the system ID as
- * the filename.
- *
- * @param loc Must not be null.
- *
- * @since Ant 1.6
- */
- public Location(Locator loc) {
- this(loc.getSystemId(), loc.getLineNumber(), loc.getColumnNumber());
- }
-
- /**
- * Creates a location consisting of a file name, line number and
- * column number.
- *
- * @param fileName The name of the file. May be null,
- * in which case the location is equivalent to
- * {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
- *
- * @param lineNumber Line number within the file. Use 0 for unknown
- * positions within a file.
- * @param columnNumber Column number within the line.
- */
- public Location(String fileName, int lineNumber, int columnNumber) {
- if (fileName != null && fileName.startsWith("file:")) {
- this.fileName = FILE_UTILS.fromURI(fileName);
- } else {
- this.fileName = fileName;
- }
- this.lineNumber = lineNumber;
- this.columnNumber = columnNumber;
- }
-
- /**
- * @return the filename portion of the location
- * @since Ant 1.6
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * @return the line number
- * @since Ant 1.6
- */
- public int getLineNumber() {
- return lineNumber;
- }
-
- /**
- * @return the column number
- * @since Ant 1.7
- */
- public int getColumnNumber() {
- return columnNumber;
- }
-
- /**
- * Returns the file name, line number, a colon and a trailing space.
- * An error message can be appended easily. For unknown locations, an
- * empty string is returned.
- *
- * @return a String of the form "fileName:lineNumber: "
- * if both file name and line number are known,
- * "fileName: " if only the file name is known,
- * and the empty string for unknown locations.
- */
- public String toString() {
- final StringBuilder buf = new StringBuilder();
-
- if (fileName != null) {
- buf.append(fileName);
-
- if (lineNumber != 0) {
- buf.append(':').append(lineNumber);
- }
-
- buf.append(": ");
- }
-
- return buf.toString();
- }
-
- /**
- * Equality operation.
- * @param other the object to compare to.
- * @return true if the other object contains the same information
- * as this object.
- * @since Ant 1.6.3
- */
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
- if (other == null) {
- return false;
- }
- if (!(other.getClass() == getClass())) {
- return false;
- }
- return toString().equals(other.toString());
- }
-
- /**
- * Hash operation.
- * @return a hash code value for this location.
- * @since Ant 1.6.3
- */
- public int hashCode() {
- return toString().hashCode();
- }
-}
diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/launch/Locator.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/launch/Locator.java
deleted file mode 100644
index e4f91baea..000000000
--- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/launch/Locator.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * 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.owasp.dependencycheck.org.apache.tools.ant.launch;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.Locale;
-
-import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
-
-// CheckStyle:LineLengthCheck OFF - urls are long!
-/**
- * The Locator is a utility class which is used to find certain items
- * in the environment.
- *
- * It is used at boot time in the launcher, and cannot make use of any of Ant's other classes.
- *
- * This is a surprisingly brittle piece of code, and has had lots of bugs filed against it.
- * {@link running ant off a network share can cause Ant to fail}
- * {@link use File.toURI().toURL().toExternalForm()}
- * {@link Locator implementation not encoding URI strings properly: spaces in paths}
- * It also breaks Eclipse 3.3 Betas
- * {@link Exception if installation path has spaces}
- *
- * Be very careful when making changes to this class, as a break will upset a lot of people.
- * @since Ant 1.6
- */
-// CheckStyle:LineLengthCheck ON - urls are long!
-public final class Locator {
-
- private static final int NIBBLE = 4;
- private static final int NIBBLE_MASK = 0xF;
-
- private static final int ASCII_SIZE = 128;
-
- private static final int BYTE_SIZE = 256;
-
- private static final int WORD = 16;
-
- private static final int SPACE = 0x20;
- private static final int DEL = 0x7F;
-
- /**
- * encoding used to represent URIs
- */
- public static final String URI_ENCODING = "UTF-8";
- // stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir()
- // of the Xerces-J team
- // which ASCII characters need to be escaped
- private static boolean[] gNeedEscaping = new boolean[ASCII_SIZE];
- // the first hex character if a character needs to be escaped
- private static char[] gAfterEscaping1 = new char[ASCII_SIZE];
- // the second hex character if a character needs to be escaped
- private static char[] gAfterEscaping2 = new char[ASCII_SIZE];
- private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
- /** Error string used when an invalid uri is seen */
- public static final String ERROR_NOT_FILE_URI
- = "Can only handle valid file: URIs, not ";
-
- // initialize the above 3 arrays
- static {
- for (int i = 0; i < SPACE; i++) {
- gNeedEscaping[i] = true;
- gAfterEscaping1[i] = gHexChs[i >> NIBBLE];
- gAfterEscaping2[i] = gHexChs[i & NIBBLE_MASK];
- }
- gNeedEscaping[DEL] = true;
- gAfterEscaping1[DEL] = '7';
- gAfterEscaping2[DEL] = 'F';
- char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
- '|', '\\', '^', '~', '[', ']', '`'};
- int len = escChs.length;
- char ch;
- for (int i = 0; i < len; i++) {
- ch = escChs[i];
- gNeedEscaping[ch] = true;
- gAfterEscaping1[ch] = gHexChs[ch >> NIBBLE];
- gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK];
- }
- }
- /**
- * Not instantiable
- */
- private Locator() {
- }
-
- /**
- * Find the directory or jar file the class has been loaded from.
- *
- * @param c the class whose location is required.
- * @return the file or jar with the class or null if we cannot
- * determine the location.
- *
- * @since Ant 1.6
- */
- public static File getClassSource(Class> c) {
- String classResource = c.getName().replace('.', '/') + ".class";
- return getResourceSource(c.getClassLoader(), classResource);
- }
-
- /**
- * Find the directory or jar a given resource has been loaded from.
- *
- * @param c the classloader to be consulted for the source.
- * @param resource the resource whose location is required.
- *
- * @return the file with the resource source or null if
- * we cannot determine the location.
- *
- * @since Ant 1.6
- */
- public static File getResourceSource(ClassLoader c, String resource) {
- if (c == null) {
- c = Locator.class.getClassLoader();
- }
- URL url = null;
- if (c == null) {
- url = ClassLoader.getSystemResource(resource);
- } else {
- url = c.getResource(resource);
- }
- if (url != null) {
- String u = url.toString();
- try {
- if (u.startsWith("jar:file:")) {
- return new File(fromJarURI(u));
- } else if (u.startsWith("file:")) {
- int tail = u.indexOf(resource);
- String dirName = u.substring(0, tail);
- return new File(fromURI(dirName));
- }
- } catch (IllegalArgumentException e) {
- //unable to determine the URI for reasons unknown.
- return null;
- }
- }
- return null;
- }
-
-
-
- /**
- * Constructs a file path from a file: URI.
- *
- *
Will be an absolute path if the given URI is absolute.
- * - *Prior to Java 1.4, - * swallows '%' that are not followed by two characters.
- * - * See dt-sysid - * which makes some mention of how - * characters not supported by URI Reference syntax should be escaped. - * - * @param uri the URI designating a file in the local filesystem. - * @return the local file system path for the file. - * @throws IllegalArgumentException if the URI is malformed or not a legal file: URL - * @since Ant 1.6 - */ - public static String fromURI(String uri) { - return fromURIJava13(uri); - // #buzilla8031: first try Java 1.4. - // TODO should use java.net.URI now that we can rely on 1.4... - // but check for UNC-related regressions, e.g. #42275 - // (and remember that \\server\share\file -> file:////server/share/file - // rather than -> file://server/share/file as it should; - // fixed only in JDK 7's java.nio.file.Path.toUri) - // return fromUriJava14(uri); - } - - /** - * Java1.4+ code to extract the path from the URI. - * @param uri - * @return null if a conversion was not possible - */ - /* currently unused: - private static String fromUriJava14(String uri) { - // Also check for properly formed URIs. Ant formerly recommended using - // nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't - // do that (just "foo.xml" is correct) but for compatibility we special-case - // things when the path is not absolute, and fall back to the old parsing behavior. - if (uri.startsWith("file:/")) { - try { - File f = new File(URI.create(encodeURI(uri))); - //bug #42227 forgot to decode before returning - return decodeUri(f.getAbsolutePath()); - } catch (IllegalArgumentException e) { - // Bad URI, pass this on. - // no, this is downgraded to a warning after various - // JRE bugs surfaced. Hand off - // to our built in code on a failure - //throw new IllegalArgumentException( - // "Bad URI " + uri + ":" + e.getMessage(), e); - e.printStackTrace(); - } catch (Exception e) { - // Unexpected exception? Should not happen. - e.printStackTrace(); - } - } - return null; - } - */ - - /** - * @param uri uri to expand - * @return the decoded URI - * @since Ant1.7.1 - */ - private static String fromURIJava13(String uri) { - // Fallback method for Java 1.3 or earlier. - - URL url = null; - try { - url = new URL(uri); - } catch (MalformedURLException emYouEarlEx) { - // Ignore malformed exception - } - if (url == null || !("file".equals(url.getProtocol()))) { - throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri); - } - final StringBuilder buf = new StringBuilder(url.getHost()); - if (buf.length() > 0) { - buf.insert(0, File.separatorChar).insert(0, File.separatorChar); - } - String file = url.getFile(); - int queryPos = file.indexOf('?'); - buf.append((queryPos < 0) ? file : file.substring(0, queryPos)); - - uri = buf.toString().replace('/', File.separatorChar); - - if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2 - && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { - uri = uri.substring(1); - } - String path = null; - try { - path = decodeUri(uri); - //consider adding the current directory. This is not done when - //the path is a UNC name - String cwd = System.getProperty("user.dir"); - int posi = cwd.indexOf(':'); - boolean pathStartsWithFileSeparator = path.startsWith(File.separator); - boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator); - if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) { - path = cwd.substring(0, posi + 1) + path; - } - } catch (UnsupportedEncodingException exc) { - // not sure whether this is clean, but this method is - // declared not to throw exceptions. - throw new IllegalStateException( - "Could not convert URI " + uri + " to path: " - + exc.getMessage()); - } - return path; - } - - /** - * Crack a JAR URI. - * This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API. - * @param uri uri to expand; contains jar: somewhere in it - * @return the decoded URI - * @since Ant1.7.1 - */ - public static String fromJarURI(String uri) { - int pling = uri.indexOf("!/"); - String jarName = uri.substring("jar:".length(), pling); - return fromURI(jarName); - } - - /** - * Decodes an Uri with % characters. - * The URI is escaped - * @param uri String with the uri possibly containing % characters. - * @return The decoded Uri - * @throws UnsupportedEncodingException if UTF-8 is not available - * @since Ant 1.7 - */ - public static String decodeUri(String uri) throws UnsupportedEncodingException { - if (uri.indexOf('%') == -1) { - return uri; - } - ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length()); - CharacterIterator iter = new StringCharacterIterator(uri); - for (char c = iter.first(); c != CharacterIterator.DONE; - c = iter.next()) { - if (c == '%') { - char c1 = iter.next(); - if (c1 != CharacterIterator.DONE) { - int i1 = Character.digit(c1, WORD); - char c2 = iter.next(); - if (c2 != CharacterIterator.DONE) { - int i2 = Character.digit(c2, WORD); - sb.write((char) ((i1 << NIBBLE) + i2)); - } - } - } else if (c >= 0x0000 && c < 0x0080) { - sb.write(c); - } else { // #50543 - byte[] bytes = String.valueOf(c).getBytes(URI_ENCODING); - sb.write(bytes, 0, bytes.length); - } - } - return sb.toString(URI_ENCODING); - } - - /** - * Encodes an Uri with % characters. - * The URI is escaped - * @param path String to encode. - * @return The encoded string, according to URI norms - * @throws UnsupportedEncodingException if UTF-8 is not available - * @since Ant 1.7 - */ - public static String encodeURI(String path) throws UnsupportedEncodingException { - int i = 0; - int len = path.length(); - int ch = 0; - StringBuilder sb = null; - for (; i < len; i++) { - ch = path.charAt(i); - // if it's not an ASCII character, break here, and use UTF-8 encoding - if (ch >= ASCII_SIZE) { - break; - } - if (gNeedEscaping[ch]) { - if (sb == null) { - sb = new StringBuilder(path.substring(0, i)); - } - sb.append('%'); - sb.append(gAfterEscaping1[ch]); - sb.append(gAfterEscaping2[ch]); - // record the fact that it's escaped - } else if (sb != null) { - sb.append((char) ch); - } - } - - // we saw some non-ascii character - if (i < len) { - if (sb == null) { - sb = new StringBuilder(path.substring(0, i)); - } - // get UTF-8 bytes for the remaining sub-string - byte[] bytes = null; - byte b; - bytes = path.substring(i).getBytes(URI_ENCODING); - len = bytes.length; - - // for each byte - for (i = 0; i < len; i++) { - b = bytes[i]; - // for non-ascii character: make it positive, then escape - if (b < 0) { - ch = b + BYTE_SIZE; - sb.append('%'); - sb.append(gHexChs[ch >> NIBBLE]); - sb.append(gHexChs[ch & NIBBLE_MASK]); - } else if (gNeedEscaping[b]) { - sb.append('%'); - sb.append(gAfterEscaping1[b]); - sb.append(gAfterEscaping2[b]); - } else { - sb.append((char) b); - } - } - } - return sb == null ? path : sb.toString(); - } - - /** - * Convert a File to a URL. - * File.toURL() does not encode characters like #. - * File.toURI() has been introduced in java 1.4, so - * Ant cannot use it (except by reflection) - * FileUtils.toURI() cannot be used by Locator.java - * Implemented this way. - * File.toURL() adds file: and changes '\' to '/' for dos OSes - * encodeURI converts characters like ' ' and '#' to %DD - * @param file the file to convert - * @return URL the converted File - * @throws MalformedURLException on error - * @deprecated since 1.9, use {@link FileUtils#getFileURL(File)} - */ - @Deprecated - public static URL fileToURL(File file) - throws MalformedURLException { - return new URL(file.toURI().toASCIIString()); - } - - /** - * Get the File necessary to load the Sun compiler tools. If the classes - * are available to this class, then no additional URL is required and - * null is returned. This may be because the classes are explicitly in the - * class path or provided by the JVM directly. - * - * @return the tools jar as a File if required, null otherwise. - */ - public static File getToolsJar() { - // firstly check if the tools jar is already in the classpath - boolean toolsJarAvailable = false; - try { - // just check whether this throws an exception - Class.forName("com.sun.tools.javac.Main"); - toolsJarAvailable = true; - } catch (Exception e) { - try { - Class.forName("sun.tools.javac.Main"); - toolsJarAvailable = true; - } catch (Exception e2) { - // ignore - } - } - if (toolsJarAvailable) { - return null; - } - // couldn't find compiler - try to find tools.jar - // based on java.home setting - String libToolsJar - = File.separator + "lib" + File.separator + "tools.jar"; - String javaHome = System.getProperty("java.home"); - File toolsJar = new File(javaHome + libToolsJar); - if (toolsJar.exists()) { - // Found in java.home as given - return toolsJar; - } - if (javaHome.toLowerCase(Locale.ENGLISH).endsWith(File.separator + "jre")) { - javaHome = javaHome.substring( - 0, javaHome.length() - "/jre".length()); - toolsJar = new File(javaHome + libToolsJar); - } - if (!toolsJar.exists()) { - System.out.println("Unable to locate tools.jar. " - + "Expected to find it in " + toolsJar.getPath()); - return null; - } - return toolsJar; - } - - /** - * Get an array of URLs representing all of the jar files in the - * given location. If the location is a file, it is returned as the only - * element of the array. If the location is a directory, it is scanned for - * jar files. - * - * @param location the location to scan for Jars. - * - * @return an array of URLs for all jars in the given location. - * - * @exception MalformedURLException if the URLs for the jars cannot be - * formed. - */ - public static URL[] getLocationURLs(File location) - throws MalformedURLException { - return getLocationURLs(location, new String[]{".jar"}); - } - - /** - * Get an array of URLs representing all of the files of a given set of - * extensions in the given location. If the location is a file, it is - * returned as the only element of the array. If the location is a - * directory, it is scanned for matching files. - * - * @param location the location to scan for files. - * @param extensions an array of extension that are to match in the - * directory search. - * - * @return an array of URLs of matching files. - * @exception MalformedURLException if the URLs for the files cannot be - * formed. - */ - public static URL[] getLocationURLs(File location, - final String[] extensions) - throws MalformedURLException { - URL[] urls = new URL[0]; - - if (!location.exists()) { - return urls; - } - if (!location.isDirectory()) { - urls = new URL[1]; - String path = location.getPath(); - String littlePath = path.toLowerCase(Locale.ENGLISH); - for (int i = 0; i < extensions.length; ++i) { - if (littlePath.endsWith(extensions[i])) { - urls[0] = fileToURL(location); - break; - } - } - return urls; - } - File[] matches = location.listFiles( - new FilenameFilter() { - public boolean accept(File dir, String name) { - String littleName = name.toLowerCase(Locale.ENGLISH); - for (int i = 0; i < extensions.length; ++i) { - if (littleName.endsWith(extensions[i])) { - return true; - } - } - return false; - } - }); - urls = new URL[matches.length]; - for (int i = 0; i < matches.length; ++i) { - urls[i] = fileToURL(matches[i]); - } - return urls; - } -} diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/types/selectors/SelectorUtils.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/types/selectors/SelectorUtils.java deleted file mode 100644 index 7f37eda43..000000000 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/org/apache/tools/ant/types/selectors/SelectorUtils.java +++ /dev/null @@ -1,695 +0,0 @@ -/* - * 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.owasp.dependencycheck.org.apache.tools.ant.types.selectors; - -import java.io.File; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.owasp.dependencycheck.org.apache.tools.ant.types.Resource; -import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils; - -/** - *This is a utility class used by selectors and DirectoryScanner. The - * functionality more properly belongs just to selectors, but unfortunately - * DirectoryScanner exposed these as protected methods. Thus we have to - * support any subclasses of DirectoryScanner that may access these methods. - *
- *This is a Singleton.
- * - * @since 1.5 - */ -public final class SelectorUtils { - - /** - * The pattern that matches an arbitrary number of directories. - * @since Ant 1.8.0 - */ - public static final String DEEP_TREE_MATCH = "**"; - - private static final SelectorUtils instance = new SelectorUtils(); - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); - - /** - * Private Constructor - */ - private SelectorUtils() { - } - - /** - * Retrieves the instance of the Singleton. - * @return singleton instance - */ - public static SelectorUtils getInstance() { - return instance; - } - - /** - * Tests whether or not a given path matches the start of a given - * pattern up to the first "**". - *
- * This is not a general purpose test and should only be used if you
- * can live with false positives. For example, pattern=**\a
- * and str=b will yield true.
- *
- * @param pattern The pattern to match against. Must not be
- * null.
- * @param str The path to match, as a String. Must not be
- * null.
- *
- * @return whether or not a given path matches the start of a given
- * pattern up to the first "**".
- */
- public static boolean matchPatternStart(String pattern, String str) {
- return matchPatternStart(pattern, str, true);
- }
-
- /**
- * Tests whether or not a given path matches the start of a given
- * pattern up to the first "**".
- *
- * This is not a general purpose test and should only be used if you
- * can live with false positives. For example, pattern=**\a
- * and str=b will yield true.
- *
- * @param pattern The pattern to match against. Must not be
- * null.
- * @param str The path to match, as a String. Must not be
- * null.
- * @param isCaseSensitive Whether or not matching should be performed
- * case sensitively.
- *
- * @return whether or not a given path matches the start of a given
- * pattern up to the first "**".
- */
- public static boolean matchPatternStart(String pattern, String str,
- boolean isCaseSensitive) {
- // When str starts with a File.separator, pattern has to start with a
- // File.separator.
- // When pattern starts with a File.separator, str has to start with a
- // File.separator.
- if (str.startsWith(File.separator)
- != pattern.startsWith(File.separator)) {
- return false;
- }
-
- String[] patDirs = tokenizePathAsArray(pattern);
- String[] strDirs = tokenizePathAsArray(str);
- return matchPatternStart(patDirs, strDirs, isCaseSensitive);
- }
-
-
- /**
- * Tests whether or not a given path matches the start of a given
- * pattern up to the first "**".
- *
- * This is not a general purpose test and should only be used if you
- * can live with false positives. For example,
- * This method uses PathTokenizer to separate the input path into its components. This handles DOS style paths in a
- * relatively sensible way. The file separators are then converted to their platform specific versions.
- *
- * @param toProcess The path to be translated. May be
- * This includes:
- *
- * The file denoted by the returned abstract pathname did not exist before this method was invoked, any subsequent
- * invocation of this method will yield a different file name.
- *
- * The filename is prefixNNNNNsuffix where NNNN is a random number.
- *
- * The file denoted by the returned abstract pathname did not exist before this method was invoked, any subsequent
- * invocation of this method will yield a different file name.
- * The file denoted by the returned abstract pathname did not exist before this method was invoked, any subsequent
- * invocation of this method will yield a different file name.
- *
- * The filename is prefixNNNNNsuffix where NNNN is a random number.
- *
- * This method has historically not guaranteed that the operation was atomic. In its current
- * implementation it is.
- *
- * @param f the file to be created.
- * @return true if the file did not exist already.
- * @throws IOException on error.
- * @since Ant 1.5
- */
- public boolean createNewFile(File f) throws IOException {
- return f.createNewFile();
- }
-
- /**
- * Create a new file, optionally creating parent directories.
- *
- * @param f the file to be created.
- * @param mkdirs
- * It doesn't really test for symbolic links but whether the canonical and absolute paths of the file are
- * identical--this may lead to false positives on some platforms.
- * Will be an absolute URI if the given path is absolute.
- * This code encodes non ASCII characters too.
- * The coding of the output is the same as what File.toURI().toASCIIString() produces
- * Will be an absolute path if the given URI is absolute.
- * Swallows '%' that are not followed by two characters, doesn't deal with non-ASCII characters.
- * Unlike java.io.File#equals this method will try to compare the absolute paths and "normalize" the
- * filenames before comparing them.
-// * This will remove
- * Implementation note:pattern=**\a
- * and str=b will yield true.
- *
- * @param patDirs The tokenized pattern to match against. Must not be
- * null.
- * @param strDirs The tokenized path to match. Must not be
- * null.
- * @param isCaseSensitive Whether or not matching should be performed
- * case sensitively.
- *
- * @return whether or not a given path matches the start of a given
- * pattern up to the first "**".
- */
- static boolean matchPatternStart(String[] patDirs, String[] strDirs,
- boolean isCaseSensitive) {
- int patIdxStart = 0;
- int patIdxEnd = patDirs.length - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.length - 1;
-
- // up to first '**'
- while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
- String patDir = patDirs[patIdxStart];
- if (patDir.equals(DEEP_TREE_MATCH)) {
- break;
- }
- if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
-
- // CheckStyle:SimplifyBooleanReturnCheck OFF
- // Check turned off as the code needs the comments for the various
- // code paths.
- if (strIdxStart > strIdxEnd) {
- // String is exhausted
- return true;
- } else if (patIdxStart > patIdxEnd) {
- // String not exhausted, but pattern is. Failure.
- return false;
- } else {
- // pattern now holds ** while string is not exhausted
- // this will generate false positives but we can live with that.
- return true;
- }
- }
-
- /**
- * Tests whether or not a given path matches a given pattern.
- *
- * If you need to call this method multiple times with the same
- * pattern you should rather use TokenizedPath
- *
- * @see TokenizedPath
- *
- * @param pattern The pattern to match against. Must not be
- * null.
- * @param str The path to match, as a String. Must not be
- * null.
- *
- * @return true if the pattern matches against the string,
- * or false otherwise.
- */
- public static boolean matchPath(String pattern, String str) {
- String[] patDirs = tokenizePathAsArray(pattern);
- return matchPath(patDirs, tokenizePathAsArray(str), true);
- }
-
- /**
- * Tests whether or not a given path matches a given pattern.
- *
- * If you need to call this method multiple times with the same
- * pattern you should rather use TokenizedPattern
- *
- * @see TokenizedPattern
- *
- * @param pattern The pattern to match against. Must not be
- * null.
- * @param str The path to match, as a String. Must not be
- * null.
- * @param isCaseSensitive Whether or not matching should be performed
- * case sensitively.
- *
- * @return true if the pattern matches against the string,
- * or false otherwise.
- */
- public static boolean matchPath(String pattern, String str,
- boolean isCaseSensitive) {
- String[] patDirs = tokenizePathAsArray(pattern);
- return matchPath(patDirs, tokenizePathAsArray(str), isCaseSensitive);
- }
-
- /**
- * Core implementation of matchPath. It is isolated so that it
- * can be called from TokenizedPattern.
- */
- static boolean matchPath(String[] tokenizedPattern, String[] strDirs,
- boolean isCaseSensitive) {
- int patIdxStart = 0;
- int patIdxEnd = tokenizedPattern.length - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.length - 1;
-
- // up to first '**'
- while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
- String patDir = tokenizedPattern[patIdxStart];
- if (patDir.equals(DEEP_TREE_MATCH)) {
- break;
- }
- if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
- if (strIdxStart > strIdxEnd) {
- // String is exhausted
- for (int i = patIdxStart; i <= patIdxEnd; i++) {
- if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
- return false;
- }
- }
- return true;
- } else {
- if (patIdxStart > patIdxEnd) {
- // String not exhausted, but pattern is. Failure.
- return false;
- }
- }
-
- // up to last '**'
- while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
- String patDir = tokenizedPattern[patIdxEnd];
- if (patDir.equals(DEEP_TREE_MATCH)) {
- break;
- }
- if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
- return false;
- }
- patIdxEnd--;
- strIdxEnd--;
- }
- if (strIdxStart > strIdxEnd) {
- // String is exhausted
- for (int i = patIdxStart; i <= patIdxEnd; i++) {
- if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
- return false;
- }
- }
- return true;
- }
-
- while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
- int patIdxTmp = -1;
- for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
- if (tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
- patIdxTmp = i;
- break;
- }
- }
- if (patIdxTmp == patIdxStart + 1) {
- // '**/**' situation, so skip one
- patIdxStart++;
- continue;
- }
- // Find the pattern between padIdxStart & padIdxTmp in str between
- // strIdxStart & strIdxEnd
- int patLength = (patIdxTmp - patIdxStart - 1);
- int strLength = (strIdxEnd - strIdxStart + 1);
- int foundIdx = -1;
- strLoop:
- for (int i = 0; i <= strLength - patLength; i++) {
- for (int j = 0; j < patLength; j++) {
- String subPat = tokenizedPattern[patIdxStart + j + 1];
- String subStr = strDirs[strIdxStart + i + j];
- if (!match(subPat, subStr, isCaseSensitive)) {
- continue strLoop;
- }
- }
-
- foundIdx = strIdxStart + i;
- break;
- }
-
- if (foundIdx == -1) {
- return false;
- }
-
- patIdxStart = patIdxTmp;
- strIdxStart = foundIdx + patLength;
- }
-
- for (int i = patIdxStart; i <= patIdxEnd; i++) {
- if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Tests whether or not a string matches against a pattern.
- * The pattern may contain two special characters:
- * '*' means zero or more characters
- * '?' means one and only one character
- *
- * @param pattern The pattern to match against.
- * Must not be null.
- * @param str The string which must be matched against the pattern.
- * Must not be null.
- *
- * @return true if the string matches against the pattern,
- * or false otherwise.
- */
- public static boolean match(String pattern, String str) {
- return match(pattern, str, true);
- }
-
- /**
- * Tests whether or not a string matches against a pattern.
- * The pattern may contain two special characters:
- * '*' means zero or more characters
- * '?' means one and only one character
- *
- * @param pattern The pattern to match against.
- * Must not be null.
- * @param str The string which must be matched against the pattern.
- * Must not be null.
- * @param caseSensitive Whether or not matching should be performed
- * case sensitively.
- *
- *
- * @return true if the string matches against the pattern,
- * or false otherwise.
- */
- public static boolean match(String pattern, String str,
- boolean caseSensitive) {
- char[] patArr = pattern.toCharArray();
- char[] strArr = str.toCharArray();
- int patIdxStart = 0;
- int patIdxEnd = patArr.length - 1;
- int strIdxStart = 0;
- int strIdxEnd = strArr.length - 1;
- char ch;
-
- boolean containsStar = false;
- for (int i = 0; i < patArr.length; i++) {
- if (patArr[i] == '*') {
- containsStar = true;
- break;
- }
- }
-
- if (!containsStar) {
- // No '*'s, so we make a shortcut
- if (patIdxEnd != strIdxEnd) {
- return false; // Pattern and string do not have the same size
- }
- for (int i = 0; i <= patIdxEnd; i++) {
- ch = patArr[i];
- if (ch != '?') {
- if (different(caseSensitive, ch, strArr[i])) {
- return false; // Character mismatch
- }
- }
- }
- return true; // String matches against pattern
- }
-
- if (patIdxEnd == 0) {
- return true; // Pattern contains only '*', which matches anything
- }
-
- // Process characters before first star
- while (true) {
- ch = patArr[patIdxStart];
- if (ch == '*' || strIdxStart > strIdxEnd) {
- break;
- }
- if (ch != '?') {
- if (different(caseSensitive, ch, strArr[strIdxStart])) {
- return false; // Character mismatch
- }
- }
- patIdxStart++;
- strIdxStart++;
- }
- if (strIdxStart > strIdxEnd) {
- // All characters in the string are used. Check if only '*'s are
- // left in the pattern. If so, we succeeded. Otherwise failure.
- return allStars(patArr, patIdxStart, patIdxEnd);
- }
-
- // Process characters after last star
- while (true) {
- ch = patArr[patIdxEnd];
- if (ch == '*' || strIdxStart > strIdxEnd) {
- break;
- }
- if (ch != '?') {
- if (different(caseSensitive, ch, strArr[strIdxEnd])) {
- return false; // Character mismatch
- }
- }
- patIdxEnd--;
- strIdxEnd--;
- }
- if (strIdxStart > strIdxEnd) {
- // All characters in the string are used. Check if only '*'s are
- // left in the pattern. If so, we succeeded. Otherwise failure.
- return allStars(patArr, patIdxStart, patIdxEnd);
- }
-
- // process pattern between stars. padIdxStart and patIdxEnd point
- // always to a '*'.
- while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
- int patIdxTmp = -1;
- for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
- if (patArr[i] == '*') {
- patIdxTmp = i;
- break;
- }
- }
- if (patIdxTmp == patIdxStart + 1) {
- // Two stars next to each other, skip the first one.
- patIdxStart++;
- continue;
- }
- // Find the pattern between padIdxStart & padIdxTmp in str between
- // strIdxStart & strIdxEnd
- int patLength = (patIdxTmp - patIdxStart - 1);
- int strLength = (strIdxEnd - strIdxStart + 1);
- int foundIdx = -1;
- strLoop:
- for (int i = 0; i <= strLength - patLength; i++) {
- for (int j = 0; j < patLength; j++) {
- ch = patArr[patIdxStart + j + 1];
- if (ch != '?') {
- if (different(caseSensitive, ch,
- strArr[strIdxStart + i + j])) {
- continue strLoop;
- }
- }
- }
-
- foundIdx = strIdxStart + i;
- break;
- }
-
- if (foundIdx == -1) {
- return false;
- }
-
- patIdxStart = patIdxTmp;
- strIdxStart = foundIdx + patLength;
- }
-
- // All characters in the string are used. Check if only '*'s are left
- // in the pattern. If so, we succeeded. Otherwise failure.
- return allStars(patArr, patIdxStart, patIdxEnd);
- }
-
- private static boolean allStars(char[] chars, int start, int end) {
- for (int i = start; i <= end; ++i) {
- if (chars[i] != '*') {
- return false;
- }
- }
- return true;
- }
-
- private static boolean different(
- boolean caseSensitive, char ch, char other) {
- return caseSensitive
- ? ch != other
- : Character.toUpperCase(ch) != Character.toUpperCase(other);
- }
-
- /**
- * Breaks a path up into a Vector of path elements, tokenizing on
- * File.separator.
- *
- * @param path Path to tokenize. Must not be null.
- *
- * @return a Vector of path elements from the tokenized path
- */
- public static Vectornull.
- * @param separator the separator against which to tokenize.
- *
- * @return a Vector of path elements from the tokenized path
- * @since Ant 1.6
- */
- public static Vectornull.
-// * @param destFile Name of file to copy to.
-// * Must not be null.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(String sourceFile, String destFile) throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), null, false, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination
-// * specifying if token filtering must be used.
-// *
-// * @param sourceFile Name of file to copy from.
-// * Must not be null.
-// * @param destFile Name of file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(String sourceFile, String destFile, FilterSetCollection filters)
-// throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters, false, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination specifying if token
-// * filtering must be used and if source files may overwrite newer destination files.
-// *
-// * @param sourceFile Name of file to copy from. Must not be null.
-// * @param destFile Name of file to copy to. Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be overwritten if it already
-// * exists.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(String sourceFile, String destFile, FilterSetCollection filters,
-// boolean overwrite) throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters, overwrite, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination
-// * specifying if token
-// * filtering must be used, if source files may overwrite newer destination
-// * files and the last
-// * modified time of destFile file should be made equal to
-// * the last modified time
-// * of sourceFile.
-// *
-// * @param sourceFile Name of file to copy from. Must not be null.
-// * @param destFile Name of file to copy to. Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file
-// * should be set to that of the source file.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(String sourceFile, String destFile,
-// FilterSetCollection filters,
-// boolean overwrite, boolean preserveLastModified)
-// throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters, overwrite,
-// preserveLastModified);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination specifying if token
-// * filtering must be used, if source files may overwrite newer destination files and the last
-// * modified time of destFile file should be made equal to the last modified time
-// * of sourceFile.
-// *
-// * @param sourceFile Name of file to copy from. Must not be null.
-// * @param destFile Name of file to copy to. Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be overwritten if it already
-// * exists.
-// * @param preserveLastModified Whether or not the last modified time of the resulting file
-// * should be set to that of the source file.
-// * @param encoding the encoding used to read and write the files.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.5
-// */
-// public void copyFile(String sourceFile, String destFile,
-// FilterSetCollection filters, boolean overwrite,
-// boolean preserveLastModified, String encoding) throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters,
-// overwrite, preserveLastModified, encoding);
-// }
-// // CheckStyle:ParameterNumberCheck OFF - bc
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * filter chains must be used, if source files may overwrite
-// * newer destination files and the last modified time of
-// * destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile Name of file to copy from.
-// * Must not be null.
-// * @param destFile Name of file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// * @param encoding the encoding used to read and write the files.
-// * @param project the project instance.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.5
-// */
-// public void copyFile(String sourceFile, String destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// String encoding, Project project) throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters, filterChains, overwrite,
-// preserveLastModified, encoding, project);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination specifying if token
-// * filtering must be used, if filter chains must be used, if source files may overwrite newer
-// * destination files and the last modified time of destFile file should be made
-// * equal to the last modified time of sourceFile.
-// *
-// * @param sourceFile Name of file to copy from. Must not be null.
-// * @param destFile Name of file to copy to. Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be overwritten if it already
-// * exists.
-// * @param preserveLastModified Whether or not the last modified time of the resulting file
-// * should be set to that of the source file.
-// * @param inputEncoding the encoding used to read the files.
-// * @param outputEncoding the encoding used to write the files.
-// * @param project the project instance.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.6
-// */
-// public void copyFile(String sourceFile, String destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// String inputEncoding, String outputEncoding,
-// Project project) throws IOException {
-// copyFile(new File(sourceFile), new File(destFile), filters, filterChains, overwrite,
-// preserveLastModified, inputEncoding, outputEncoding, project);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination. No filtering is performed.
-// *
-// * @param sourceFile the file to copy from. Must not be null.
-// * @param destFile the file to copy to. Must not be null.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(File sourceFile, File destFile) throws IOException {
-// copyFile(sourceFile, destFile, null, false, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination
-// * specifying if token filtering must be used.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(File sourceFile, File destFile, FilterSetCollection filters)
-// throws IOException {
-// copyFile(sourceFile, destFile, filters, false, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used and if
-// * source files may overwrite newer destination files.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
-// boolean overwrite) throws IOException {
-// copyFile(sourceFile, destFile, filters, overwrite, false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * source files may overwrite newer destination files and the
-// * last modified time of destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// *
-// * @throws IOException if the copying fails.
-// */
-// public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
-// boolean overwrite, boolean preserveLastModified) throws IOException {
-// copyFile(sourceFile, destFile, filters, overwrite, preserveLastModified, null);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a destination specifying if token
-// * filtering must be used, if source files may overwrite newer destination files, the last
-// * modified time of destFile file should be made equal to the last modified time
-// * of sourceFile and which character encoding to assume.
-// *
-// * @param sourceFile the file to copy from. Must not be null.
-// * @param destFile the file to copy to. Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param overwrite Whether or not the destination file should be overwritten if it already
-// * exists.
-// * @param preserveLastModified Whether or not the last modified time of the resulting file
-// * should be set to that of the source file.
-// * @param encoding the encoding used to read and write the files.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.5
-// */
-// public void copyFile(File sourceFile, File destFile,
-// FilterSetCollection filters, boolean overwrite,
-// boolean preserveLastModified, String encoding) throws IOException {
-// copyFile(sourceFile, destFile, filters, null, overwrite,
-// preserveLastModified, encoding, null);
-// }
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * filter chains must be used, if source files may overwrite
-// * newer destination files and the last modified time of
-// * destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// * @param encoding the encoding used to read and write the files.
-// * @param project the project instance.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.5
-// */
-// public void copyFile(File sourceFile, File destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// String encoding, Project project) throws IOException {
-// copyFile(sourceFile, destFile, filters, filterChains,
-// overwrite, preserveLastModified, encoding, encoding, project);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * filter chains must be used, if source files may overwrite
-// * newer destination files and the last modified time of
-// * destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// * @param inputEncoding the encoding used to read the files.
-// * @param outputEncoding the encoding used to write the files.
-// * @param project the project instance.
-// *
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.6
-// */
-// public void copyFile(File sourceFile, File destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// String inputEncoding, String outputEncoding,
-// Project project) throws IOException {
-// copyFile(sourceFile, destFile, filters, filterChains, overwrite, preserveLastModified,
-// false, inputEncoding, outputEncoding, project);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * filter chains must be used, if source files may overwrite
-// * newer destination files and the last modified time of
-// * destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// * @param append whether to append to the destination file.
-// * @param inputEncoding the encoding used to read the files.
-// * @param outputEncoding the encoding used to write the files.
-// * @param project the project instance.
-// *
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.8
-// */
-// public void copyFile(File sourceFile, File destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// boolean append,
-// String inputEncoding, String outputEncoding,
-// Project project) throws IOException {
-// copyFile(sourceFile, destFile, filters, filterChains, overwrite,
-// preserveLastModified, append, inputEncoding, outputEncoding,
-// project, /* force: */ false);
-// }
-//
-// /**
-// * Convenience method to copy a file from a source to a
-// * destination specifying if token filtering must be used, if
-// * filter chains must be used, if source files may overwrite
-// * newer destination files and the last modified time of
-// * destFile file should be made equal
-// * to the last modified time of sourceFile.
-// *
-// * @param sourceFile the file to copy from.
-// * Must not be null.
-// * @param destFile the file to copy to.
-// * Must not be null.
-// * @param filters the collection of filters to apply to this copy.
-// * @param filterChains filterChains to apply during the copy.
-// * @param overwrite Whether or not the destination file should be
-// * overwritten if it already exists.
-// * @param preserveLastModified Whether or not the last modified time of
-// * the resulting file should be set to that
-// * of the source file.
-// * @param append whether to append to the destination file.
-// * @param inputEncoding the encoding used to read the files.
-// * @param outputEncoding the encoding used to write the files.
-// * @param project the project instance.
-// * @param force whether to overwrite read-only destination files.
-// *
-// * @throws IOException if the copying fails.
-// *
-// * @since Ant 1.8.2
-// */
-// public void copyFile(File sourceFile, File destFile,
-// FilterSetCollection filters, Vector filterChains,
-// boolean overwrite, boolean preserveLastModified,
-// boolean append,
-// String inputEncoding, String outputEncoding,
-// Project project, boolean force) throws IOException {
-// ResourceUtils.copyResource(new FileResource(sourceFile),
-// new FileResource(destFile),
-// filters, filterChains, overwrite,
-// preserveLastModified, append, inputEncoding,
-// outputEncoding, project, force);
-// }
-//
-// // CheckStyle:ParameterNumberCheck ON
-//
-// /**
-// * Calls File.setLastModified(long time). Originally written to
-// * to dynamically bind to that call on Java1.2+.
-// *
-// * @param file the file whose modified time is to be set
-// * @param time the time to which the last modified time is to be set.
-// * if this is -1, the current time is used.
-// */
-// public void setFileLastModified(File file, long time) {
-// ResourceUtils.setLastModified(new FileResource(file), time);
-// }
- /**
- * Interpret the filename as a file relative to the given file unless the filename already represents an absolute
- * filename. Differs from new File(file, filename) in that the resulting File's path will always be a
- * normalized, absolute pathname. Also, if it is determined that filename is context-relative,
- * file will be discarded and the reference will be resolved using available context/state information
- * about the filesystem.
- *
- * @param file the "reference" file for relative paths. This instance must be an absolute file and must not contain
- * "./" or "../" sequences (same for \ instead of /). If it is null, this call is equivalent to
- * new java.io.File(filename).getAbsoluteFile().
- *
- * @param filename a file name.
- *
- * @return an absolute file.
- * @throws java.lang.NullPointerException if filename is null.
- */
- public File resolveFile(File file, String filename) {
- if (!isAbsolutePath(filename)) {
- char sep = File.separatorChar;
- filename = filename.replace('/', sep).replace('\\', sep);
- if (isContextRelativePath(filename)) {
- file = null;
- // on cygwin, our current directory can be a UNC;
- // assume user.dir is absolute or all hell breaks loose...
- String udir = System.getProperty("user.dir");
- if (filename.charAt(0) == sep && udir.charAt(0) == sep) {
- filename = dissect(udir)[0] + filename.substring(1);
- }
- }
- filename = new File(file, filename).getAbsolutePath();
- }
- return normalize(filename);
- }
-
- /**
- * On DOS and NetWare, the evaluation of certain file specifications is context-dependent. These are filenames
- * beginning with a single separator (relative to current root directory) and filenames with a drive specification
- * and no intervening separator (relative to current directory of the specified root).
- *
- * @param filename the filename to evaluate.
- * @return true if the filename is relative to system context.
- * @throws java.lang.NullPointerException if filename is null.
- * @since Ant 1.7
- */
- public static boolean isContextRelativePath(String filename) {
- if (!(ON_DOS || ON_NETWARE) || filename.length() == 0) {
- return false;
- }
- char sep = File.separatorChar;
- filename = filename.replace('/', sep).replace('\\', sep);
- char c = filename.charAt(0);
- int len = filename.length();
- return (c == sep && (len == 1 || filename.charAt(1) != sep))
- || (Character.isLetter(c) && len > 1
- && filename.charAt(1) == ':'
- && (len == 2 || filename.charAt(2) != sep));
- }
-
- /**
- * Verifies that the specified filename represents an absolute path. Differs from new
- * java.io.File("filename").isAbsolute() in that a path beginning with a double file separator--signifying a Windows
- * UNC--must at minimum match "\\a\b" to be considered an absolute path.
- *
- * @param filename the filename to be checked.
- * @return true if the filename represents an absolute path.
- * @throws java.lang.NullPointerException if filename is null.
- * @since Ant 1.6.3
- */
- public static boolean isAbsolutePath(String filename) {
- int len = filename.length();
- if (len == 0) {
- return false;
- }
- char sep = File.separatorChar;
- filename = filename.replace('/', sep).replace('\\', sep);
- char c = filename.charAt(0);
- if (!(ON_DOS || ON_NETWARE)) {
- return (c == sep);
- }
- if (c == sep) {
- // CheckStyle:MagicNumber OFF
- if (!(ON_DOS && len > 4 && filename.charAt(1) == sep)) {
- return false;
- }
- // CheckStyle:MagicNumber ON
- int nextsep = filename.indexOf(sep, 2);
- return nextsep > 2 && nextsep + 1 < len;
- }
- int colon = filename.indexOf(':');
- return (Character.isLetter(c) && colon == 1
- && filename.length() > 2 && filename.charAt(2) == sep)
- || (ON_NETWARE && colon > 0);
- }
-
- /**
- * Translate a path into its native (platform specific) format.
- * null.
- *
- * @return the native version of the specified path or an empty string if the path is null or empty.
- *
- * @since ant 1.7
- * @see PathTokenizer
- */
- public static String translatePath(String toProcess) {
- if (toProcess == null || toProcess.length() == 0) {
- return "";
- }
- final StringBuilder path = new StringBuilder(toProcess.length() + EXPAND_SPACE);
- final PathTokenizer tokenizer = new PathTokenizer(toProcess);
- while (tokenizer.hasMoreTokens()) {
- String pathComponent = tokenizer.nextToken();
- pathComponent = pathComponent.replace('/', File.separatorChar);
- pathComponent = pathComponent.replace('\\', File.separatorChar);
- if (path.length() != 0) {
- path.append(File.pathSeparatorChar);
- }
- path.append(pathComponent);
- }
- return path.toString();
- }
-
- /**
- * "Normalize" the given absolute path.
- *
- *
- *
- * Unlike {@link File#getCanonicalPath()} this method specifically does not resolve symbolic links.
- *
- * @param path the path to be normalized.
- * @return the normalized version of the path.
- *
- * @throws java.lang.NullPointerException if path is null.
- */
- public File normalize(final String path) {
- Stack s = new Stack();
- String[] dissect = dissect(path);
- s.push(dissect[0]);
-
- StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
- while (tok.hasMoreTokens()) {
- String thisToken = tok.nextToken();
- if (".".equals(thisToken)) {
- continue;
- }
- if ("..".equals(thisToken)) {
- if (s.size() < 2) {
- // Cannot resolve it, so skip it.
- return new File(path);
- }
- s.pop();
- } else { // plain component
- s.push(thisToken);
- }
- }
- final StringBuilder sb = new StringBuilder();
- final int size = s.size();
- for (int i = 0; i < size; i++) {
- if (i > 1) {
- // not before the filesystem root and not after it, since root
- // already contains one
- sb.append(File.separatorChar);
- }
- sb.append(s.elementAt(i));
- }
- return new File(sb.toString());
- }
-
- /**
- * Dissect the specified absolute path.
- *
- * @param path the path to dissect.
- * @return String[] {root, remaining path}.
- * @throws java.lang.NullPointerException if path is null.
- * @since Ant 1.7
- */
- public String[] dissect(String path) {
- char sep = File.separatorChar;
- path = path.replace('/', sep).replace('\\', sep);
-
- // make sure we are dealing with an absolute path
- if (!isAbsolutePath(path)) {
- throw new BuildException(path + " is not an absolute path");
- }
- String root = null;
- int colon = path.indexOf(':');
- if (colon > 0 && (ON_DOS || ON_NETWARE)) {
-
- int next = colon + 1;
- root = path.substring(0, next);
- char[] ca = path.toCharArray();
- root += sep;
- //remove the initial separator; the root has it.
- next = (ca[next] == sep) ? next + 1 : next;
-
- final StringBuilder sbPath = new StringBuilder();
- // Eliminate consecutive slashes after the drive spec:
- for (int i = next; i < ca.length; i++) {
- if (ca[i] != sep || ca[i - 1] != sep) {
- sbPath.append(ca[i]);
- }
- }
- path = sbPath.toString();
- } else if (path.length() > 1 && path.charAt(1) == sep) {
- // UNC drive
- int nextsep = path.indexOf(sep, 2);
- nextsep = path.indexOf(sep, nextsep + 1);
- root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
- path = path.substring(root.length());
- } else {
- root = File.separator;
- path = path.substring(1);
- }
- return new String[]{root, path};
- }
-
- /**
- * Returns a VMS String representation of a File object. This is useful since the JVM by default
- * internally converts VMS paths to Unix style. The returned String is always an absolute path.
- *
- * @param f The File to get the VMS path for.
- * @return The absolute VMS path to f.
- */
- public String toVMSPath(File f) {
- // format: "DEVICE:[DIR.SUBDIR]FILE"
- String osPath;
- String path = normalize(f.getAbsolutePath()).getPath();
- String name = f.getName();
- boolean isAbsolute = path.charAt(0) == File.separatorChar;
- // treat directories specified using .DIR syntax as files
- // CheckStyle:MagicNumber OFF
- boolean isDirectory = f.isDirectory()
- && !name.regionMatches(true, name.length() - 4, ".DIR", 0, 4);
- // CheckStyle:MagicNumber ON
- String device = null;
- StringBuilder directory = null;
- String file = null;
-
- int index = 0;
-
- if (isAbsolute) {
- index = path.indexOf(File.separatorChar, 1);
- if (index == -1) {
- return path.substring(1) + ":[000000]";
- }
- device = path.substring(1, index++);
- }
- if (isDirectory) {
- directory = new StringBuilder(path.substring(index).replace(File.separatorChar, '.'));
- } else {
- int dirEnd = path.lastIndexOf(File.separatorChar, path.length());
- if (dirEnd == -1 || dirEnd < index) {
- file = path.substring(index);
- } else {
- directory = new StringBuilder(path.substring(index, dirEnd).
- replace(File.separatorChar, '.'));
- index = dirEnd + 1;
- if (path.length() > index) {
- file = path.substring(index);
- }
- }
- }
- if (!isAbsolute && directory != null) {
- directory.insert(0, '.');
- }
- osPath = ((device != null) ? device + ":" : "")
- + ((directory != null) ? "[" + directory + "]" : "")
- + ((file != null) ? file : "");
- return osPath;
- }
-
- /**
- * Create a File object for a temporary file in a given directory. Without actually creating the file.
- *
- * boolean whether to create parent directories.
- * @return true if the file did not exist already.
- * @throws IOException on error.
- * @since Ant 1.6.3
- */
- public boolean createNewFile(File f, boolean mkdirs) throws IOException {
- File parent = f.getParentFile();
- if (mkdirs && !(parent.exists())) {
- parent.mkdirs();
- }
- return f.createNewFile();
- }
-
- /**
- * Checks whether a given file is a symbolic link.
- *
- * file: URI that represents the external form of the given pathname.
- *
- * file: URI.
- *
- * to (if it exists), ensure that to's parent directory exists and move
-// * from, which involves deleting from as well.to may have been deleted
-// * already when this happens.
-// *
-// * @since Ant 1.6
-// */
-// public void rename(File from, File to) throws IOException {
-// // identical logic lives in Move.renameFile():
-// from = normalize(from.getAbsolutePath()).getCanonicalFile();
-// to = normalize(to.getAbsolutePath());
-// if (!from.exists()) {
-// System.err.println("Cannot rename nonexistent file " + from);
-// return;
-// }
-// if (from.getAbsolutePath().equals(to.getAbsolutePath())) {
-// System.err.println("Rename of " + from + " to " + to + " is a no-op.");
-// return;
-// }
-// if (to.exists() && !(areSame(from, to) || tryHardToDelete(to))) {
-// throw new IOException("Failed to delete " + to + " while trying to rename " + from);
-// }
-// File parent = to.getParentFile();
-// if (parent != null && !parent.isDirectory()
-// && !(parent.mkdirs() || parent.isDirectory())) {
-// throw new IOException("Failed to create directory " + parent
-// + " while trying to rename " + from);
-// }
-// if (!from.renameTo(to)) {
-// copyFile(from, to);
-// if (!tryHardToDelete(from)) {
-// throw new IOException("Failed to delete " + from + " while trying to rename it.");
-// }
-// }
-// }
-
- /**
- * Get the granularity of file timestamps. The choice is made based on OS, which is incorrect--it should really be
- * by filesystem. We do not have an easy way to probe for file systems, however, so this heuristic gives us a decent
- * default.
- *
- * @return the difference, in milliseconds, which two file timestamps must have in order for the two files to be
- * considered to have different timestamps.
- */
- public long getFileTimestampGranularity() {
- if (ON_WIN9X) {
- return FAT_FILE_TIMESTAMP_GRANULARITY;
- }
- if (ON_WINDOWS) {
- return NTFS_FILE_TIMESTAMP_GRANULARITY;
- }
- if (ON_DOS) {
- return FAT_FILE_TIMESTAMP_GRANULARITY;
- }
- return UNIX_FILE_TIMESTAMP_GRANULARITY;
- }
-
- /**
- * test whether a file or directory exists, with an error in the upper/lower case spelling of the name. Using this
- * method is only interesting on case insensitive file systems (Windows).
- * It will return true only if 3 conditions are met :
- *
- *
- *
- *
- * the purpose is to identify files or directories on case-insensitive filesystems whose case is not what is
- * expected.
- * Possibly to rename them afterwards to the desired upper/lowercase combination.
- *
- *
- * @param localFile file to test
- * @return true if the file exists and the case of the actual file is not the case of the parameter
- * @since Ant 1.7.1
- */
- public boolean hasErrorInCase(File localFile) {
- localFile = normalize(localFile.getAbsolutePath());
- if (!localFile.exists()) {
- return false;
- }
- final String localFileName = localFile.getName();
- FilenameFilter ff = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.equalsIgnoreCase(localFileName) && (!name.equals(localFileName));
- }
- };
- String[] names = localFile.getParentFile().list(ff);
- return names != null && names.length == 1;
- }
-
- /**
- * Returns true if the source is older than the dest. If the dest file does not exist, then the test returns false;
- * it is implicitly not up do date.
- *
- * @param source source file (should be the older).
- * @param dest dest file (should be the newer).
- * @param granularity an offset added to the source time.
- * @return true if the source is older than the dest after accounting for granularity.
- * @since Ant 1.6.3
- */
- public boolean isUpToDate(File source, File dest, long granularity) {
- //do a check for the destination file existing
- if (!dest.exists()) {
- //if it does not, then the file is not up to date.
- return false;
- }
- long sourceTime = source.lastModified();
- long destTime = dest.lastModified();
- return isUpToDate(sourceTime, destTime, granularity);
- }
-
- /**
- * Returns true if the source is older than the dest.
- *
- * @param source source file (should be the older).
- * @param dest dest file (should be the newer).
- * @return true if the source is older than the dest, taking the granularity into account.
- * @since Ant 1.6.3
- */
- public boolean isUpToDate(File source, File dest) {
- return isUpToDate(source, dest, getFileTimestampGranularity());
- }
-
- /**
- * Compare two timestamps for being up to date using the specified granularity.
- *
- * @param sourceTime timestamp of source file.
- * @param destTime timestamp of dest file.
- * @param granularity os/filesys granularity.
- * @return true if the dest file is considered up to date.
- */
- public boolean isUpToDate(long sourceTime, long destTime, long granularity) {
- return destTime != -1 && destTime >= sourceTime + granularity;
- }
-
- /**
- * Compare two timestamps for being up to date using the current granularity.
- *
- * @param sourceTime timestamp of source file.
- * @param destTime timestamp of dest file.
- * @return true if the dest file is considered up to date.
- */
- public boolean isUpToDate(long sourceTime, long destTime) {
- return isUpToDate(sourceTime, destTime, getFileTimestampGranularity());
- }
-
- /**
- * Close a Writer without throwing any exception if something went wrong. Do not attempt to close it if the argument
- * is null.
- *
- * @param device output writer, can be null.
- */
- public static void close(Writer device) {
- if (null != device) {
- try {
- device.close();
- } catch (IOException e) {
- //ignore
- }
- }
- }
-
- /**
- * Close a Reader without throwing any exception if something went wrong. Do not attempt to close it if the argument
- * is null.
- *
- * @param device Reader, can be null.
- */
- public static void close(Reader device) {
- if (null != device) {
- try {
- device.close();
- } catch (IOException e) {
- //ignore
- }
- }
- }
-
- /**
- * Close a stream without throwing any exception if something went wrong. Do not attempt to close it if the argument
- * is null.
- *
- * @param device stream, can be null.
- */
- public static void close(OutputStream device) {
- if (null != device) {
- try {
- device.close();
- } catch (IOException e) {
- //ignore
- }
- }
- }
-
- /**
- * Close a stream without throwing any exception if something went wrong. Do not attempt to close it if the argument
- * is null.
- *
- * @param device stream, can be null.
- */
- public static void close(InputStream device) {
- if (null != device) {
- try {
- device.close();
- } catch (IOException e) {
- //ignore
- }
- }
- }
-
- /**
- * Close a Channel without throwing any exception if something went wrong. Do not attempt to close it if the
- * argument is null.
- *
- * @param device channel, can be null.
- * @since Ant 1.8.0
- */
- public static void close(Channel device) {
- if (null != device) {
- try {
- device.close();
- } catch (IOException e) {
- //ignore
- }
- }
- }
-
- /**
- * Closes an URLConnection if its concrete implementation provides a way to close it that Ant knows of.
- *
- * @param conn connection, can be null
- * @since Ant 1.8.0
- */
- public static void close(URLConnection conn) {
- if (conn != null) {
- try {
- if (conn instanceof JarURLConnection) {
- JarURLConnection juc = (JarURLConnection) conn;
- JarFile jf = juc.getJarFile();
- jf.close();
- jf = null;
- } else if (conn instanceof HttpURLConnection) {
- ((HttpURLConnection) conn).disconnect();
- }
- } catch (IOException exc) {
- //ignore
- }
- }
- }
-
- /**
- * Delete the file with {@link File#delete()} if the argument is not null. Do nothing on a null argument.
- *
- * @param file file to delete.
- */
- public static void delete(File file) {
- if (file != null) {
- file.delete();
- }
- }
-
- /**
- * Accommodate Windows bug encountered in both Sun and IBM JDKs. Others possible. If the delete does not work, call
- * System.gc(), wait a little and try again.
- *
- * @return whether deletion was successful
- * @since Ant 1.8.0
- */
- public boolean tryHardToDelete(File f) {
- return tryHardToDelete(f, ON_WINDOWS);
- }
-
- /**
- * If delete does not work, call System.gc() if asked to, wait a little and try again.
- *
- * @return whether deletion was successful
- * @since Ant 1.8.3
- */
- public boolean tryHardToDelete(File f, boolean runGC) {
- if (!f.delete()) {
- if (runGC) {
- System.gc();
- }
- try {
- Thread.sleep(DELETE_RETRY_SLEEP_MILLIS);
- } catch (InterruptedException ex) {
- // Ignore Exception
- }
- return f.delete();
- }
- return true;
- }
-
- /**
- * Calculates the relative path between two files.
- *
This function may throw an IOException if an I/O error occurs because its use of the
- * canonical pathname may require filesystem queries.
- * File to calculate the path from
- * @param toFile the File to calculate the path to
- * @return the relative path between the files
- * @throws Exception for undocumented reasons
- * @see File#getCanonicalPath()
- *
- * @since Ant 1.7
- */
- public static String getRelativePath(File fromFile, File toFile) throws Exception {
- String fromPath = fromFile.getCanonicalPath();
- String toPath = toFile.getCanonicalPath();
-
- // build the path stack info to compare
- String[] fromPathStack = getPathStack(fromPath);
- String[] toPathStack = getPathStack(toPath);
-
- if (0 < toPathStack.length && 0 < fromPathStack.length) {
- if (!fromPathStack[0].equals(toPathStack[0])) {
- // not the same device (would be "" on Linux/Unix)
-
- return getPath(Arrays.asList(toPathStack));
- }
- } else {
- // no comparison possible
- return getPath(Arrays.asList(toPathStack));
- }
-
- int minLength = Math.min(fromPathStack.length, toPathStack.length);
- int same = 1; // Used outside the for loop
-
- // get index of parts which are equal
- for (;
- same < minLength && fromPathStack[same].equals(toPathStack[same]);
- same++) {
- // Do nothing
- }
-
- List relativePathStack = new ArrayList();
-
- // if "from" part is longer, fill it up with ".."
- // to reach path which is equal to both paths
- for (int i = same; i < fromPathStack.length; i++) {
- relativePathStack.add("..");
- }
-
- // fill it up path with parts which were not equal
- for (int i = same; i < toPathStack.length; i++) {
- relativePathStack.add(toPathStack[i]);
- }
-
- return getPath(relativePathStack);
- }
-
- /**
- * Gets all names of the path as an array of Strings.
- *
- * @param path to get names from
- * @return Strings, never null
- *
- * @since Ant 1.7
- */
- public static String[] getPathStack(String path) {
- String normalizedPath = path.replace(File.separatorChar, '/');
-
- return normalizedPath.split("/");
- }
-
- /**
- * Gets path from a List of Strings.
- *
- * @param pathStack List of Strings to be concatenated as a path.
- * @return String, never null
- *
- * @since Ant 1.7
- */
- public static String getPath(List pathStack) {
- // can safely use '/' because Windows understands '/' as separator
- return getPath(pathStack, '/');
- }
-
- /**
- * Gets path from a List of Strings.
- *
- * @param pathStack List of Strings to be concated as a path.
- * @param separatorChar char to be used as separator between names in path
- * @return String, never null
- *
- * @since Ant 1.7
- */
- public static String getPath(final List pathStack, final char separatorChar) {
- final StringBuilder buffer = new StringBuilder();
-
- final Iterator iter = pathStack.iterator();
- if (iter.hasNext()) {
- buffer.append(iter.next());
- }
- while (iter.hasNext()) {
- buffer.append(separatorChar);
- buffer.append(iter.next());
- }
- return buffer.toString();
- }
-
- /**
- * Get the default encoding. This is done by opening an InputStreamReader on a dummy InputStream and getting the
- * encoding. Could use System.getProperty("file.encoding"), but cannot see where this is documented.
- *
- * @return the default file encoding.
- */
- public String getDefaultEncoding() {
- InputStreamReader is = new InputStreamReader(
- new InputStream() {
- public int read() {
- return -1;
- }
- });
- try {
- return is.getEncoding();
- } finally {
- close(is);
- }
- }
-}