tbennett 2004/04/19 11:12:12
Added: composition/impl/src/java/org/apache/avalon/composition/util
FileUtils.java Resource.java ScannerUtils.java
Log:
Support/helpers for the FilesetModel/DirectoryScanner
Revision Changes Path
1.1
avalon/composition/impl/src/java/org/apache/avalon/composition/util/FileUtils.java
Index: FileUtils.java
===================================================================
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.avalon.composition.util;
import java.io.File;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;
import org.apache.avalon.util.env.Env;
/**
* This class provides some common file utilities used by the
* composition implementation, and is borrowed from the Apache
* Ant development team.
*
* @author Apache Ant Development Team (MacNeill, Umasankar, and Bodewig)
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2004/04/19 18:12:12 $
*/
public class FileUtils {
private boolean onNetWare = Env.isNetWare();
/**
* Factory method.
*
* @return a new instance of FileUtils.
*/
public static FileUtils newFileUtils() {
return new FileUtils();
}
/**
* Empty constructor.
*/
protected FileUtils() {
}
/**
* Checks whether a given file is a symbolic link.
*
* <p>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.</p>
*
* @param parent the parent directory of the file to test
* @param name the name of the file to test.
* @return true if the file is a symbolic link.
*/
public boolean isSymbolicLink(File parent, String name)
throws IOException
{
File resolvedParent = new File( parent.getCanonicalPath() );
File toTest = new File( resolvedParent, name );
return !toTest.getAbsolutePath().equals( toTest.getCanonicalPath() );
}
/**
* Removes a leading path from a second path.
*
* @param leading The leading path, must not be null, must be absolute.
* @param path The path to remove from, must not be null, must be absolute.
*
* @return path's normalized absolute if it doesn't start with
* leading, path's path with leading's path removed otherwise.
*/
public String removeLeadingPath(File leading, File path) throws IOException {
String l = normalize(leading.getAbsolutePath()).getAbsolutePath();
String p = normalize(path.getAbsolutePath()).getAbsolutePath();
if (l.equals(p)) {
return "";
}
// ensure that l ends with a /
// so we never think /foo was a parent directory of /foobar
if (!l.endsWith(File.separator)) {
l += File.separator;
}
if (p.startsWith(l)) {
return p.substring(l.length());
} else {
return p;
}
}
/**
* "normalize" the given absolute path.
*
* <p>This includes:
* <ul>
* <li>Uppercase the drive letter if there is one.</li>
* <li>Remove redundant slashes after the drive spec.</li>
* <li>resolve all ./, .\, ../ and ..\ sequences.</li>
* <li>DOS style paths that start with a drive letter will have
* \ as the separator.</li>
* </ul>
* Unlike <code>File#getCanonicalPath()</code> it specifically doesn't
* resolve symbolic links.
*
* @param path the path to be normalized
* @return the normalized version of the path.
*
* @throws java.lang.NullPointerException if the file path is
* equal to null.
*/
public File normalize(String path) throws IOException {
String orig = path;
path = path.replace('/', File.separatorChar)
.replace('\\', File.separatorChar);
// make sure we are dealing with an absolute path
int colon = path.indexOf(":");
if (!onNetWare) {
if (!path.startsWith(File.separator)
&& !(path.length() >= 2
&& Character.isLetter(path.charAt(0))
&& colon == 1)) {
String msg = path + " is not an absolute path";
throw new IOException(msg);
}
} else {
if (!path.startsWith(File.separator)
&& (colon == -1)) {
String msg = path + " is not an absolute path";
throw new IOException(msg);
}
}
boolean dosWithDrive = false;
String root = null;
// Eliminate consecutive slashes after the drive spec
if ((!onNetWare && path.length() >= 2
&& Character.isLetter(path.charAt(0))
&& path.charAt(1) == ':')
|| (onNetWare && colon > -1)) {
dosWithDrive = true;
char[] ca = path.replace('/', '\\').toCharArray();
StringBuffer sbRoot = new StringBuffer();
for (int i = 0; i < colon; i++) {
sbRoot.append(Character.toUpperCase(ca[i]));
}
sbRoot.append(':');
if (colon + 1 < path.length()) {
sbRoot.append(File.separatorChar);
}
root = sbRoot.toString();
// Eliminate consecutive slashes after the drive spec
StringBuffer sbPath = new StringBuffer();
for (int i = colon + 1; i < ca.length; i++) {
if ((ca[i] != '\\')
|| (ca[i] == '\\' && ca[i - 1] != '\\')) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString().replace('\\', File.separatorChar);
} else {
if (path.length() == 1) {
root = File.separator;
path = "";
} else if (path.charAt(1) == File.separatorChar) {
// UNC drive
root = File.separator + File.separator;
path = path.substring(2);
} else {
root = File.separator;
path = path.substring(1);
}
}
Stack s = new Stack();
s.push(root);
StringTokenizer tok = new StringTokenizer(path, File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (".".equals(thisToken)) {
continue;
} else if ("..".equals(thisToken)) {
if (s.size() < 2) {
throw new IOException("Cannot resolve path " + orig);
} else {
s.pop();
}
} else { // plain component
s.push(thisToken);
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.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));
}
path = sb.toString();
if (dosWithDrive) {
path = path.replace('/', '\\');
}
return new File(path);
}
}
1.1
avalon/composition/impl/src/java/org/apache/avalon/composition/util/Resource.java
Index: Resource.java
===================================================================
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.avalon.composition.util;
/**
* describes a File or a ZipEntry
*
* this class is meant to be used by classes needing to record path
* and date/time information about a file, a zip entry or some similar
* resource (URL, archive in a version control repository, ...)
*
* @author Apache Ant Development Team (Levy-Lamber)
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2004/04/19 18:12:12 $
*/
public class Resource {
private String name = null;
private boolean exists = true;
private long lastmodified = 0;
private boolean directory = false;
/**
* default constructor
*/
public Resource() {
}
/**
* only sets the name.
*
* <p>This is a dummy, used for not existing resources.</p>
*
* @param name relative path of the resource. Expects
* "/" to be used as the directory separator.
*/
public Resource(String name) {
this(name, false, 0, false);
}
/**
* sets the name, lastmodified flag, and exists flag
*
* @param name relative path of the resource. Expects
* "/" to be used as the directory separator.
*/
public Resource(String name, boolean exists, long lastmodified) {
this(name, exists, lastmodified, false);
}
/**
* @param name relative path of the resource. Expects
* "/" to be used as the directory separator.
*/
public Resource(String name, boolean exists, long lastmodified,
boolean directory) {
this.name = name;
this.exists = exists;
this.lastmodified = lastmodified;
this.directory = directory;
}
/**
* name attribute will contain the path of a file relative to the
* root directory of its fileset or the recorded path of a zip
* entry.
*
* <p>example for a file with fullpath /var/opt/adm/resource.txt
* in a file set with root dir /var/opt it will be
* adm/resource.txt.</p>
*
* <p>"/" will be used as the directory separator.</p>
*/
public String getName() {
return name;
}
/**
* @param name relative path of the resource. Expects
* "/" to be used as the directory separator.
*/
public void setName(String name) {
this.name = name;
}
/**
* the exists attribute tells whether a file exists
*/
public boolean isExists() {
return exists;
}
public void setExists(boolean exists) {
this.exists = exists;
}
/**
* tells the modification time in milliseconds since 01.01.1970 of
*
* @return 0 if the resource does not exist to mirror the behavior
* of [EMAIL PROTECTED] java.io.File File}.
*/
public long getLastModified() {
return !exists || lastmodified < 0 ? 0 : lastmodified;
}
public void setLastModified(long lastmodified) {
this.lastmodified = lastmodified;
}
/**
* tells if the resource is a directory
* @return boolean flag indicating if the resource is a directory
*/
public boolean isDirectory() {
return directory;
}
public void setDirectory(boolean directory) {
this.directory = directory;
}
/**
* @return copy of this
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new Error("CloneNotSupportedException for a "
+ "Clonable Resource caught?");
}
}
/**
* delegates to a comparison of names.
*/
public int compareTo(Object other) {
if (!(other instanceof Resource)) {
throw new IllegalArgumentException("Can only be compared with "
+ "Resources");
}
Resource r = (Resource) other;
return getName().compareTo(r.getName());
}
}
1.1
avalon/composition/impl/src/java/org/apache/avalon/composition/util/ScannerUtils.java
Index: ScannerUtils.java
===================================================================
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.avalon.composition.util;
import java.io.File;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* <p>This is a utility class used by DirectoryScanner.</p>
* <p>This is a Singleton.</p>
*
* @author Apache Ant Development Team (Kuiper, Umasankar, Atherton)
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2004/04/19 18:12:12 $
*/
public class ScannerUtils {
private static ScannerUtils instance = new ScannerUtils();
/**
* Private Constructor
*/
private ScannerUtils() {
}
/**
* Retrieves the instance of the Singleton.
* @return singleton instance
*/
public static ScannerUtils getInstance() {
return instance;
}
/**
* Tests whether or not a given path matches the start of a given
* pattern up to the first "**".
* <p>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
*
* @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 "**".
* <p>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @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);
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("**")) {
break;
}
if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
return false;
}
patIdxStart++;
strIdxStart++;
}
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.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
*
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
public static boolean matchPath(String pattern, String str) {
return matchPath(pattern, str, true);
}
/**
* Tests whether or not a given path matches a given pattern.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
public static boolean matchPath(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);
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("**")) {
break;
}
if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
patDirs = null;
strDirs = null;
return false;
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {
// String is exhausted
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (!patDirs[i].equals("**")) {
patDirs = null;
strDirs = null;
return false;
}
}
return true;
} else {
if (patIdxStart > patIdxEnd) {
// String not exhausted, but pattern is. Failure.
patDirs = null;
strDirs = null;
return false;
}
}
// up to last '**'
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
String patDir = patDirs[patIdxEnd];
if (patDir.equals("**")) {
break;
}
if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
patDirs = null;
strDirs = null;
return false;
}
patIdxEnd--;
strIdxEnd--;
}
if (strIdxStart > strIdxEnd) {
// String is exhausted
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (!patDirs[i].equals("**")) {
patDirs = null;
strDirs = null;
return false;
}
}
return true;
}
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
int patIdxTmp = -1;
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
if (patDirs[i].equals("**")) {
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 = patDirs[patIdxStart + j + 1];
String subStr = strDirs[strIdxStart + i + j];
if (!match(subPat, subStr, isCaseSensitive)) {
continue strLoop;
}
}
foundIdx = strIdxStart + i;
break;
}
if (foundIdx == -1) {
patDirs = null;
strDirs = null;
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx + patLength;
}
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (!patDirs[i].equals("**")) {
patDirs = null;
strDirs = null;
return false;
}
}
return true;
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
*
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> 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:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
*
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> otherwise.
*/
public static boolean match(String pattern, String str,
boolean isCaseSensitive) {
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 (isCaseSensitive && ch != strArr[i]) {
return false; // Character mismatch
}
if (!isCaseSensitive && Character.toUpperCase(ch)
!= Character.toUpperCase(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 ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
if (ch != '?') {
if (isCaseSensitive && ch != strArr[strIdxStart]) {
return false; // Character mismatch
}
if (!isCaseSensitive && Character.toUpperCase(ch)
!= Character.toUpperCase(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.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// Process characters after last star
while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
if (ch != '?') {
if (isCaseSensitive && ch != strArr[strIdxEnd]) {
return false; // Character mismatch
}
if (!isCaseSensitive && Character.toUpperCase(ch)
!= Character.toUpperCase(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.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// 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 (isCaseSensitive && ch != strArr[strIdxStart + i
+ j]) {
continue strLoop;
}
if (!isCaseSensitive
&& Character.toUpperCase(ch)
!= Character.toUpperCase(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.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
/**
* Breaks a path up into a Vector of path elements, tokenizing on
* <code>File.separator</code>.
*
* @param path Path to tokenize. Must not be <code>null</code>.
*
* @return a Vector of path elements from the tokenized path
*/
public static Vector tokenizePath (String path) {
return tokenizePath(path, File.separator);
}
/**
* Breaks a path up into a Vector of path elements, tokenizing on
*
* @param path Path to tokenize. Must not be <code>null</code>.
* @param separator the separator against which to tokenize.
*
* @return a Vector of path elements from the tokenized path
* @since Ant 1.6
*/
public static Vector tokenizePath (String path, String separator) {
Vector ret = new Vector();
StringTokenizer st = new StringTokenizer(path, separator);
while (st.hasMoreTokens()) {
ret.addElement(st.nextToken());
}
return ret;
}
/**
* Same as [EMAIL PROTECTED] #tokenizePath tokenizePath} but hopefully faster.
*/
private static String[] tokenizePathAsArray(String path) {
char sep = File.separatorChar;
int start = 0;
int len = path.length();
int count = 0;
for (int pos = 0; pos < len; pos++) {
if (path.charAt(pos) == sep) {
if (pos != start) {
count++;
}
start = pos + 1;
}
}
if (len != start) {
count++;
}
String[] l = new String[count];
count = 0;
start = 0;
for (int pos = 0; pos < len; pos++) {
if (path.charAt(pos) == sep) {
if (pos != start) {
String tok = path.substring(start, pos);
l[count++] = tok;
}
start = pos + 1;
}
}
if (len != start) {
String tok = path.substring(start);
l[count/*++*/] = tok;
}
return l;
}
/**
* Returns dependency information on these two files. If src has been
* modified later than target, it returns true. If target doesn't exist,
* it likewise returns true. Otherwise, target is newer than src and
* is not out of date, thus the method returns false. It also returns
* false if the src file doesn't even exist, since how could the
* target then be out of date.
*
* @param src the original file
* @param target the file being compared against
* @param granularity the amount in seconds of slack we will give in
* determining out of dateness
* @return whether the target is out of date
*/
public static boolean isOutOfDate(File src, File target, int granularity) {
if (!src.exists()) {
return false;
}
if (!target.exists()) {
return true;
}
if ((src.lastModified() - granularity) > target.lastModified()) {
return true;
}
return false;
}
/**
* Returns dependency information on these two resources. If src has been
* modified later than target, it returns true. If target doesn't exist,
* it likewise returns true. Otherwise, target is newer than src and
* is not out of date, thus the method returns false. It also returns
* false if the src file doesn't even exist, since how could the
* target then be out of date.
*
* @param src the original resource
* @param target the resource being compared against
* @param granularity the amount in seconds of slack we will give in
* determining out of dateness
* @return whether the target is out of date
*/
public static boolean isOutOfDate(Resource src, Resource target,
int granularity) {
if (!src.isExists()) {
return false;
}
if (!target.isExists()) {
return true;
}
if ((src.getLastModified() - granularity) > target.getLastModified()) {
return true;
}
return false;
}
/**
* "Flattens" a string by removing all whitespace (space, tab, linefeed,
* carriage return, and formfeed). This uses StringTokenizer and the
* default set of tokens as documented in the single arguement constructor.
*
* @param input a String to remove all whitespace.
* @return a String that has had all whitespace removed.
*/
public static String removeWhitespace(String input) {
StringBuffer result = new StringBuffer();
if (input != null) {
StringTokenizer st = new StringTokenizer(input);
while (st.hasMoreTokens()) {
result.append(st.nextToken());
}
}
return result.toString();
}
/**
* Tests if a string contains stars or question marks
* @param input a String which one wants to test for containing wildcard
* @return true if the string contains at least a star or a question mark
*/
public static boolean hasWildcards(String input) {
return (input.indexOf('*') != -1 || input.indexOf('?') != -1);
}
/**
* removes from a pattern all tokens to the right containing wildcards
* @param input the input string
* @return the leftmost part of the pattern without wildcards
*/
public static String rtrimWildcardTokens(String input) {
Vector v = tokenizePath(input, File.separator);
StringBuffer sb = new StringBuffer();
for (int counter = 0; counter < v.size(); counter++) {
if (hasWildcards((String) v.elementAt(counter))) {
break;
}
if (counter > 0) {
sb.append(File.separator);
}
sb.append((String) v.elementAt(counter));
}
return sb.toString();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]