Browse Source

unnecessary code

tags/pre268419
aclement 15 years ago
parent
commit
e41d199171
2 changed files with 338 additions and 225 deletions
  1. 225
    155
      util/src/org/aspectj/util/FileUtil.java
  2. 113
    70
      util/src/org/aspectj/util/LangUtil.java

+ 225
- 155
util/src/org/aspectj/util/FileUtil.java View File

import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.Reader; import java.io.Reader;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;


/** /**
* *
} }
}; };


public static final FileFilter SOURCE_FILTER = new FileFilter() {
public boolean accept(File file) {
return hasSourceSuffix(file);
}
public String toString() {
return "SOURCE_FILTER";
}
};
// public static final FileFilter SOURCE_FILTER = new FileFilter() {
// public boolean accept(File file) {
// return hasSourceSuffix(file);
// }
//
// public String toString() {
// return "SOURCE_FILTER";
// }
// };


final static int[] INT_RA = new int[0]; final static int[] INT_RA = new int[0];


return ((null != path) && (0 != sourceSuffixLength(path))); return ((null != path) && (0 != sourceSuffixLength(path)));
} }


/** @return 0 if file has no source suffix or the length of the suffix otherwise */
/**
* @return 0 if file has no source suffix or the length of the suffix
* otherwise
*/
public static int sourceSuffixLength(File file) { public static int sourceSuffixLength(File file) {
return (null == file ? 0 : sourceSuffixLength(file.getPath())); return (null == file ? 0 : sourceSuffixLength(file.getPath()));
} }
return ((null != file) && file.canWrite() && file.isFile()); return ((null != file) && file.canWrite() && file.isFile());
} }


/** @throws IllegalArgumentException unless file is readable and not a directory */
public static void throwIaxUnlessCanReadFile(File file, String label) {
if (!canReadFile(file)) {
throw new IllegalArgumentException(label + " not readable file: " + file);
}
}
// /**
// * @throws IllegalArgumentException unless file is readable and not a
// * directory
// */
// public static void throwIaxUnlessCanReadFile(File file, String label) {
// if (!canReadFile(file)) {
// throw new IllegalArgumentException(label + " not readable file: " +
// file);
// }
// }


/** @throws IllegalArgumentException unless dir is a readable directory */
/**
* @throws IllegalArgumentException unless dir is a readable directory
*/
public static void throwIaxUnlessCanReadDir(File dir, String label) { public static void throwIaxUnlessCanReadDir(File dir, String label) {
if (!canReadDir(dir)) { if (!canReadDir(dir)) {
throw new IllegalArgumentException(label + " not readable dir: " + dir); throw new IllegalArgumentException(label + " not readable dir: " + dir);
} }
} }


/** @throws IllegalArgumentException unless file is readable and not a directory */
/**
* @throws IllegalArgumentException unless file is readable and not a
* directory
*/
public static void throwIaxUnlessCanWriteFile(File file, String label) { public static void throwIaxUnlessCanWriteFile(File file, String label) {
if (!canWriteFile(file)) { if (!canWriteFile(file)) {
throw new IllegalArgumentException(label + " not writable file: " + file); throw new IllegalArgumentException(label + " not writable file: " + file);
} }


/** /**
* Extract the name of a class from the path to its file. If the basedir is null, then the class is assumed to be in the default
* package unless the classFile has one of the top-level suffixes { com, org, java, javax } as a parent directory.
* Extract the name of a class from the path to its file. If the basedir is
* null, then the class is assumed to be in the default package unless the
* classFile has one of the top-level suffixes { com, org, java, javax } as
* a parent directory.
* *
* @param basedir the File of the base directory (prefix of classFile) * @param basedir the File of the base directory (prefix of classFile)
* @param classFile the File of the class to extract the name for * @param classFile the File of the class to extract the name for
* @throws IllegalArgumentException if classFile is null or does not end with ".class" or a non-null basedir is not a prefix of
* classFile
* @throws IllegalArgumentException if classFile is null or does not end
* with ".class" or a non-null basedir is not a prefix of
* classFile
*/ */
public static String fileToClassName(File basedir, File classFile) { public static String fileToClassName(File basedir, File classFile) {
LangUtil.throwIaxIfNull(classFile, "classFile"); LangUtil.throwIaxIfNull(classFile, "classFile");
} }


/** /**
* Normalize path for comparisons by rendering absolute, clipping basedir prefix, trimming and changing '\\' to '/'
* Normalize path for comparisons by rendering absolute, clipping basedir
* prefix, trimming and changing '\\' to '/'
* *
* @param file the File with the path to normalize * @param file the File with the path to normalize
* @param basedir the File for the prefix of the file to normalize - ignored if null
* @param basedir the File for the prefix of the file to normalize - ignored
* if null
* @return "" if null or normalized path otherwise * @return "" if null or normalized path otherwise
* @throws IllegalArgumentException if basedir is not a prefix of file * @throws IllegalArgumentException if basedir is not a prefix of file
*/ */
} }


/** /**
* Render a set of files to String as a path by getting absolute paths of each and delimiting with infix.
* Render a set of files to String as a path by getting absolute paths of
* each and delimiting with infix.
* *
* @param files the File[] to flatten - may be null or empty * @param files the File[] to flatten - may be null or empty
* @param infix the String delimiter internally between entries (if null, then use File.pathSeparator). (alias to
* <code>flatten(getAbsolutePaths(files), infix)</code>
* @return String with absolute paths to entries in order, delimited with infix
* @param infix the String delimiter internally between entries (if null,
* then use File.pathSeparator). (alias to
* <code>flatten(getAbsolutePaths(files), infix)</code>
* @return String with absolute paths to entries in order, delimited with
* infix
*/ */
public static String flatten(File[] files, String infix) { public static String flatten(File[] files, String infix) {
if (LangUtil.isEmpty(files)) { if (LangUtil.isEmpty(files)) {
} }


/** /**
* Normalize path for comparisons by rendering absolute trimming and changing '\\' to '/'
* Normalize path for comparisons by rendering absolute trimming and
* changing '\\' to '/'
* *
* @return "" if null or normalized path otherwise * @return "" if null or normalized path otherwise
*/ */
} }


/** /**
* Weakly normalize path for comparisons by trimming and changing '\\' to '/'
* Weakly normalize path for comparisons by trimming and changing '\\' to
* '/'
*/ */
public static String weakNormalize(String path) { public static String weakNormalize(String path) {
if (null != path) { if (null != path) {
} }


/** /**
* Get best File for the first-readable path in input paths, treating entries prefixed "sp:" as system property keys. Safe to
* call in static initializers.
* Get best File for the first-readable path in input paths, treating
* entries prefixed "sp:" as system property keys. Safe to call in static
* initializers.
* *
* @param paths the String[] of paths to check. * @param paths the String[] of paths to check.
* @return null if not found, or valid File otherwise * @return null if not found, or valid File otherwise
} }


/** /**
* Recursively delete some contents of dir, but not the dir itself. This deletes any subdirectory which is empty after its files
* are deleted.
* Recursively delete some contents of dir, but not the dir itself. This
* deletes any subdirectory which is empty after its files are deleted.
* *
* @return the total number of files deleted * @return the total number of files deleted
*/ */
} }


/** /**
* Recursively delete some contents of dir, but not the dir itself. If deleteEmptyDirs is true, this deletes any subdirectory
* which is empty after its files are deleted.
* Recursively delete some contents of dir, but not the dir itself. If
* deleteEmptyDirs is true, this deletes any subdirectory which is empty
* after its files are deleted.
* *
* @param dir the File directory (if a file, the the file is deleted) * @param dir the File directory (if a file, the the file is deleted)
* @return the total number of files deleted * @return the total number of files deleted
} }


/** /**
* Recursively copy files in fromDir (with any fromSuffix) to toDir, replacing fromSuffix with toSuffix if any. This silently
* ignores dirs and files that are not readable but throw IOException for directories that are not writable. This does not clean
* out the original contents of toDir. (subdirectories are not renamed per directory rules)
* Recursively copy files in fromDir (with any fromSuffix) to toDir,
* replacing fromSuffix with toSuffix if any. This silently ignores dirs and
* files that are not readable but throw IOException for directories that
* are not writable. This does not clean out the original contents of toDir.
* (subdirectories are not renamed per directory rules)
* *
* @param fromSuffix select files with this suffix - select all if null or empty
* @param toSuffix replace fromSuffix with toSuffix in the destination file name - ignored if null or empty, appended to name if
* fromSuffix is null or empty
* @param fromSuffix select files with this suffix - select all if null or
* empty
* @param toSuffix replace fromSuffix with toSuffix in the destination file
* name - ignored if null or empty, appended to name if
* fromSuffix is null or empty
* @return the total number of files copied * @return the total number of files copied
*/ */
public static int copyDir(File fromDir, File toDir, final String fromSuffix, String toSuffix) throws IOException { public static int copyDir(File fromDir, File toDir, final String fromSuffix, String toSuffix) throws IOException {
return copyDir(fromDir, toDir, fromSuffix, toSuffix, (FileFilter) null); return copyDir(fromDir, toDir, fromSuffix, toSuffix, (FileFilter) null);
} }


/**
* Recursively copy files in fromDir (with any fromSuffix) to toDir, replacing fromSuffix with toSuffix if any, and adding the
* destination file to any collector. This silently ignores dirs and files that are not readable but throw IOException for
* directories that are not writable. This does not clean out the original contents of toDir. (subdirectories are not renamed
* per directory rules) This calls any delegate FilenameFilter to collect any selected file.
*
* @param fromSuffix select files with this suffix - select all if null or empty
* @param toSuffix replace fromSuffix with toSuffix in the destination file name - ignored if null or empty, appended to name if
* fromSuffix is null or empty
* @param collector the List sink for destination files - ignored if null
* @return the total number of files copied
*/
public static int copyDir(File fromDir, File toDir, final String fromSuffix, final String toSuffix, final List collector)
throws IOException {
// int before = collector.size();
if (null == collector) {
return copyDir(fromDir, toDir, fromSuffix, toSuffix);
} else {
FileFilter collect = new FileFilter() {
public boolean accept(File pathname) {
return collector.add(pathname);
}
};
return copyDir(fromDir, toDir, fromSuffix, toSuffix, collect);
}
}
// /**
// * Recursively copy files in fromDir (with any fromSuffix) to toDir,
// * replacing fromSuffix with toSuffix if any, and adding the destination
// * file to any collector. This silently ignores dirs and files that are
// not
// * readable but throw IOException for directories that are not writable.
// * This does not clean out the original contents of toDir. (subdirectories
// * are not renamed per directory rules) This calls any delegate
// * FilenameFilter to collect any selected file.
// *
// * @param fromSuffix select files with this suffix - select all if null or
// * empty
// * @param toSuffix replace fromSuffix with toSuffix in the destination
// file
// * name - ignored if null or empty, appended to name if
// * fromSuffix is null or empty
// * @param collector the List sink for destination files - ignored if null
// * @return the total number of files copied
// */
// public static int copyDir(File fromDir, File toDir, final String
// fromSuffix, final String toSuffix, final List collector)
// throws IOException {
// // int before = collector.size();
// if (null == collector) {
// return copyDir(fromDir, toDir, fromSuffix, toSuffix);
// } else {
// FileFilter collect = new FileFilter() {
// public boolean accept(File pathname) {
// return collector.add(pathname);
// }
// };
// return copyDir(fromDir, toDir, fromSuffix, toSuffix, collect);
// }
// }


/** /**
* Recursively copy files in fromDir (with any fromSuffix) to toDir, replacing fromSuffix with toSuffix if any. This silently
* ignores dirs and files that are not readable but throw IOException for directories that are not writable. This does not clean
* out the original contents of toDir. (subdirectories are not renamed per directory rules) This calls any delegate
* FilenameFilter to collect any selected file.
* Recursively copy files in fromDir (with any fromSuffix) to toDir,
* replacing fromSuffix with toSuffix if any. This silently ignores dirs and
* files that are not readable but throw IOException for directories that
* are not writable. This does not clean out the original contents of toDir.
* (subdirectories are not renamed per directory rules) This calls any
* delegate FilenameFilter to collect any selected file.
* *
* @param fromSuffix select files with this suffix - select all if null or empty
* @param toSuffix replace fromSuffix with toSuffix in the destination file name - ignored if null or empty, appended to name if
* fromSuffix is null or empty
* @param fromSuffix select files with this suffix - select all if null or
* empty
* @param toSuffix replace fromSuffix with toSuffix in the destination file
* name - ignored if null or empty, appended to name if
* fromSuffix is null or empty
* @return the total number of files copied * @return the total number of files copied
*/ */
public static int copyDir(File fromDir, File toDir, final String fromSuffix, final String toSuffix, final FileFilter delegate) public static int copyDir(File fromDir, File toDir, final String fromSuffix, final String toSuffix, final FileFilter delegate)
/** /**
* Recursively list files in srcDir. * Recursively list files in srcDir.
* *
* @return ArrayList with String paths of File under srcDir (relative to srcDir)
* @return ArrayList with String paths of File under srcDir (relative to
* srcDir)
*/ */
public static String[] listFiles(File srcDir) { public static String[] listFiles(File srcDir) {
ArrayList result = new ArrayList(); ArrayList result = new ArrayList();
/** /**
* Recursively list files in srcDir. * Recursively list files in srcDir.
* *
* @return ArrayList with String paths of File under srcDir (relative to srcDir)
* @return ArrayList with String paths of File under srcDir (relative to
* srcDir)
*/ */
public static File[] listFiles(File srcDir, FileFilter fileFilter) { public static File[] listFiles(File srcDir, FileFilter fileFilter) {
ArrayList result = new ArrayList(); ArrayList result = new ArrayList();
/** /**
* Convert String[] paths to File[] as offset of base directory * Convert String[] paths to File[] as offset of base directory
* *
* @param basedir the non-null File base directory for File to create with paths
* @param basedir the non-null File base directory for File to create with
* paths
* @param paths the String[] of paths to create * @param paths the String[] of paths to create
* @return File[] with same length as paths * @return File[] with same length as paths
*/ */
/** /**
* Convert String[] paths to File[] as offset of base directory * Convert String[] paths to File[] as offset of base directory
* *
* @param basedir the non-null File base directory for File to create with paths
* @param basedir the non-null File base directory for File to create with
* paths
* @param paths the String[] of paths to create * @param paths the String[] of paths to create
* @param suffixes the String[] of suffixes to limit sources to - ignored if null
* @param suffixes the String[] of suffixes to limit sources to - ignored if
* null
* @return File[] with same length as paths * @return File[] with same length as paths
*/ */
public static File[] getBaseDirFiles(File basedir, String[] paths, String[] suffixes) { public static File[] getBaseDirFiles(File basedir, String[] paths, String[] suffixes) {
} }


/** /**
* Copy files from source dir into destination directory, creating any needed directories. This differs from copyDir in not
* being recursive; each input with the source dir creates a full path. However, if the source is a directory, it is copied as
* such.
* Copy files from source dir into destination directory, creating any
* needed directories. This differs from copyDir in not being recursive;
* each input with the source dir creates a full path. However, if the
* source is a directory, it is copied as such.
* *
* @param srcDir an existing, readable directory containing relativePaths files
* @param relativePaths a set of paths relative to srcDir to readable File to copy
* @param srcDir an existing, readable directory containing relativePaths
* files
* @param relativePaths a set of paths relative to srcDir to readable File
* to copy
* @param destDir an existing, writable directory to copy files to * @param destDir an existing, writable directory to copy files to
* @throws IllegalArgumentException if input invalid, IOException if operations fail
* @throws IllegalArgumentException if input invalid, IOException if
* operations fail
*/ */
public static File[] copyFiles(File srcDir, String[] relativePaths, File destDir) throws IllegalArgumentException, IOException { public static File[] copyFiles(File srcDir, String[] relativePaths, File destDir) throws IllegalArgumentException, IOException {
final String[] paths = relativePaths; final String[] paths = relativePaths;
} }


/** /**
* Copy fromFile to toFile, handling file-file, dir-dir, and file-dir copies.
* Copy fromFile to toFile, handling file-file, dir-dir, and file-dir
* copies.
* *
* @param fromFile the File path of the file or directory to copy - must be readable
* @param toFile the File path of the target file or directory - must be writable (will be created if it does not exist)
* @param fromFile the File path of the file or directory to copy - must be
* readable
* @param toFile the File path of the target file or directory - must be
* writable (will be created if it does not exist)
*/ */
public static void copyFile(File fromFile, File toFile) throws IOException { public static void copyFile(File fromFile, File toFile) throws IOException {
LangUtil.throwIaxIfNull(fromFile, "fromFile"); LangUtil.throwIaxIfNull(fromFile, "fromFile");
} }


/** /**
* Ensure that the parent directory to path can be written. If the path has a null parent, DEFAULT_PARENT is tested. If the path
* parent does not exist, this tries to create it.
* Ensure that the parent directory to path can be written. If the path has
* a null parent, DEFAULT_PARENT is tested. If the path parent does not
* exist, this tries to create it.
* *
* @param path the File path whose parent should be writable * @param path the File path whose parent should be writable
* @return the File path of the writable parent directory * @return the File path of the writable parent directory
* @throws IllegalArgumentException if parent cannot be written or path is null.
* @throws IllegalArgumentException if parent cannot be written or path is
* null.
*/ */
public static File ensureParentWritable(File path) { public static File ensureParentWritable(File path) {
LangUtil.throwIaxIfNull(path, "path"); LangUtil.throwIaxIfNull(path, "path");
} }


/** /**
* Make a new temporary directory in the same directory that the system uses for temporary files, or if that files, in the
* current directory.
* Make a new temporary directory in the same directory that the system uses
* for temporary files, or if that files, in the current directory.
* *
* @param name the preferred (simple) name of the directory - may be null. * @param name the preferred (simple) name of the directory - may be null.
* @return File of an existing new temp dir, or null if unable to create * @return File of an existing new temp dir, or null if unable to create
} }


/** /**
* Get URL for a File. This appends "/" for directories. prints errors to System.err
* Get URL for a File. This appends "/" for directories. prints errors to
* System.err
* *
* @param file the File to convert to URL (not null) * @param file the File to convert to URL (not null)
*/ */
LangUtil.throwIaxIfNull(file, "file"); LangUtil.throwIaxIfNull(file, "file");
URL result = null; URL result = null;
try { try {
result = file.toURL();// TODO AV - was toURI.toURL that does not works on Java 1.3
result = file.toURL();// TODO AV - was toURI.toURL that does not
// works on Java 1.3
if (null != result) { if (null != result) {
return result; return result;
} }
} }


/** /**
* Write contents to file, returning null on success or error message otherwise. This tries to make any necessary parent
* directories first.
* Write contents to file, returning null on success or error message
* otherwise. This tries to make any necessary parent directories first.
* *
* @param file the File to write (not null) * @param file the File to write (not null)
* @param contents the String to write (use "" if null) * @param contents the String to write (use "" if null)
return b.toString(); return b.toString();
} }


/**
* Returns the contents of this stream as a String
*/
public static String readAsString(InputStream in) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuffer b = new StringBuffer();
while (true) {
int ch = r.read();
if (ch == -1)
break;
b.append((char) ch);
}
in.close();
r.close();
return b.toString();
}
// /**
// * Returns the contents of this stream as a String
// */
// public static String readAsString(InputStream in) throws IOException {
// BufferedReader r = new BufferedReader(new InputStreamReader(in));
// StringBuffer b = new StringBuffer();
// while (true) {
// int ch = r.read();
// if (ch == -1)
// break;
// b.append((char) ch);
// }
// in.close();
// r.close();
// return b.toString();
// }


/** /**
* Returns the contents of this file as a byte[] * Returns the contents of this file as a byte[]
} }
} }


public static void extractJar(String zipFile, String outDir) throws IOException {
ZipInputStream zs = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry entry;
while ((entry = zs.getNextEntry()) != null) {
if (entry.isDirectory())
continue;
byte[] in = readAsByteArray(zs);

File outFile = new File(outDir + "/" + entry.getName());
// if (!outFile.getParentFile().exists())
// System.err.println("parent: " + outFile.getParentFile());
// System.err.println("parent: " + outFile.getParentFile());
outFile.getParentFile().mkdirs();
FileOutputStream os = new FileOutputStream(outFile);
os.write(in);
os.close();
zs.closeEntry();
}
zs.close();
}
//
// public static void extractJar(String zipFile, String outDir) throws
// IOException {
// ZipInputStream zs = new ZipInputStream(new FileInputStream(zipFile));
// ZipEntry entry;
// while ((entry = zs.getNextEntry()) != null) {
// if (entry.isDirectory())
// continue;
// byte[] in = readAsByteArray(zs);
//
// File outFile = new File(outDir + "/" + entry.getName());
// // if (!outFile.getParentFile().exists())
// // System.err.println("parent: " + outFile.getParentFile());
// // System.err.println("parent: " + outFile.getParentFile());
// outFile.getParentFile().mkdirs();
// FileOutputStream os = new FileOutputStream(outFile);
// os.write(in);
// os.close();
// zs.closeEntry();
// }
// zs.close();
// }


/** /**
* Do line-based search for literal text in source files, returning file:line where found.
* Do line-based search for literal text in source files, returning
* file:line where found.
* *
* @param sought the String text to seek in the file * @param sought the String text to seek in the file
* @param sources the List of String paths to the source files * @param sources the List of String paths to the source files
* @param listAll if false, only list first match in file * @param listAll if false, only list first match in file
* @param errorSink the PrintStream to print any errors to (one per line) (use null to silently ignore errors)
* @return List of String of the form file:line for each found entry (never null, might be empty)
* @param errorSink the PrintStream to print any errors to (one per line)
* (use null to silently ignore errors)
* @return List of String of the form file:line for each found entry (never
* null, might be empty)
*/ */
// OPTIMIZE only used by tests? move it out // OPTIMIZE only used by tests? move it out
public static List lineSeek(String sought, List sources, boolean listAll, PrintStream errorSink) { public static List lineSeek(String sought, List sources, boolean listAll, PrintStream errorSink) {
} }


/** /**
* Do line-based search for literal text in source file, returning line where found as a String in the form
* {sourcePath}:line:column submitted to the collecting parameter sink. Any error is rendered to String and returned as the
* result.
* Do line-based search for literal text in source file, returning line
* where found as a String in the form {sourcePath}:line:column submitted to
* the collecting parameter sink. Any error is rendered to String and
* returned as the result.
* *
* @param sought the String text to seek in the file * @param sought the String text to seek in the file
* @param sources the List of String paths to the source files * @param sources the List of String paths to the source files
* @param listAll if false, only list first match in file * @param listAll if false, only list first match in file
* @param List sink the List for String entries of the form {sourcePath}:line:column
* @param List sink the List for String entries of the form
* {sourcePath}:line:column
* @return String error if any, or add String entries to sink * @return String error if any, or add String entries to sink
*/ */
public static String lineSeek(String sought, String sourcePath, boolean listAll, ArrayList sink) { public static String lineSeek(String sought, String sourcePath, boolean listAll, ArrayList sink) {
/** /**
* Sleep until after the last last-modified stamp from the files. * Sleep until after the last last-modified stamp from the files.
* *
* @param files the File[] of files to inspect for last modified times (this ignores null or empty files array and null or
* non-existing components of files array)
* @param files the File[] of files to inspect for last modified times (this
* ignores null or empty files array and null or non-existing
* components of files array)
* @return true if succeeded without 100 interrupts * @return true if succeeded without 100 interrupts
*/ */
public static boolean sleepPastFinalModifiedTime(File[] files) { public static boolean sleepPastFinalModifiedTime(File[] files) {
} }


private FileUtil() { private FileUtil() {
throw new Error("utility class");
} }


public static List makeClasspath(URL[] urls) { public static List makeClasspath(URL[] urls) {
} }


/** /**
* A pipe when run reads from an input stream to an output stream, optionally sleeping between reads.
* A pipe when run reads from an input stream to an output stream,
* optionally sleeping between reads.
* *
* @see #copyStream(InputStream, OutputStream) * @see #copyStream(InputStream, OutputStream)
*/ */
private final boolean closeOutput; private final boolean closeOutput;


/** /**
* If true, then continue processing stream until no characters are returned when halting.
* If true, then continue processing stream until no characters are
* returned when halting.
*/ */
private boolean finishStream; private boolean finishStream;


/** /**
* @param in the InputStream source to read * @param in the InputStream source to read
* @param out the OutputStream sink to write * @param out the OutputStream sink to write
* @param tryClosingStreams if true, then try closing both streams when done
* @param sleep milliseconds to delay between reads (pinned to 0..1 minute)
* @param tryClosingStreams if true, then try closing both streams when
* done
* @param sleep milliseconds to delay between reads (pinned to 0..1
* minute)
*/ */
Pipe(InputStream in, OutputStream out, long sleep, boolean closeInput, boolean closeOutput) { Pipe(InputStream in, OutputStream out, long sleep, boolean closeInput, boolean closeOutput) {
LangUtil.throwIaxIfNull(in, "in"); LangUtil.throwIaxIfNull(in, "in");
} }


/** /**
* Run the pipe. This halts on the first Throwable thrown or when a read returns -1 (for end-of-file) or on demand.
* Run the pipe. This halts on the first Throwable thrown or when a read
* returns -1 (for end-of-file) or on demand.
*/ */
public void run() { public void run() {
totalWritten = 0; totalWritten = 0;
* Tell the pipe to halt the next time it gains control. * Tell the pipe to halt the next time it gains control.
* *
* @param wait if true, this waits synchronously until pipe is done * @param wait if true, this waits synchronously until pipe is done
* @param finishStream if true, then continue until a read from the input stream returns no bytes, then halt.
* @return true if <code>run()</code> will return the next time it gains control
* @param finishStream if true, then continue until a read from the
* input stream returns no bytes, then halt.
* @return true if <code>run()</code> will return the next time it gains
* control
*/ */
public boolean halt(boolean wait, boolean finishStream) { public boolean halt(boolean wait, boolean finishStream) {
if (!halt) { if (!halt) {
} }


/** /**
* This is called when the pipe is completing. This implementation does nothing. Subclasses implement this to get notice.
* Note that halt(true, true) might or might not have completed before this method is called.
* This is called when the pipe is completing. This implementation does
* nothing. Subclasses implement this to get notice. Note that
* halt(true, true) might or might not have completed before this method
* is called.
*/ */
protected void completing(long totalWritten, Throwable thrown) { protected void completing(long totalWritten, Throwable thrown) {
} }

+ 113
- 70
util/src/org/aspectj/util/LangUtil.java View File

*/ */
public class LangUtil { public class LangUtil {


// /** map from String version to String class implemented in that version or later */
// /** map from String version to String class implemented in that version
// or later */
// private static final Map VM_CLASSES; // private static final Map VM_CLASSES;


public static final String EOL; public static final String EOL;
} }


/** /**
* Shorthand for "if not null or not assignable, throw IllegalArgumentException"
* Shorthand for
* "if not null or not assignable, throw IllegalArgumentException"
* *
* @param c the Class to check - use null to ignore type check * @param c the Class to check - use null to ignore type check
* @throws IllegalArgumentException "null {name}" if o is null * @throws IllegalArgumentException "null {name}" if o is null
} }


/** /**
* Shorthand for "if not null or not assignable, throw IllegalArgumentException"
* Shorthand for
* "if not null or not assignable, throw IllegalArgumentException"
* *
* @throws IllegalArgumentException "null {name}" if o is null * @throws IllegalArgumentException "null {name}" if o is null
*/ */
} }


// /** // /**
// * Shorthand for "if any not null or not assignable, throw IllegalArgumentException"
// * Shorthand for
// "if any not null or not assignable, throw IllegalArgumentException"
// * @throws IllegalArgumentException "{name} is not assignable to {c}" // * @throws IllegalArgumentException "{name} is not assignable to {c}"
// */ // */
// public static final void throwIaxIfNotAllAssignable(final Collection collection,
// public static final void throwIaxIfNotAllAssignable(final Collection
// collection,
// final Class c, final String name) { // final Class c, final String name) {
// throwIaxIfNull(collection, name); // throwIaxIfNull(collection, name);
// if (null != c) { // if (null != c) {
} }


/** /**
* Split string as classpath, delimited at File.pathSeparator. Entries are not trimmed, but empty entries are ignored.
* Split string as classpath, delimited at File.pathSeparator. Entries are
* not trimmed, but empty entries are ignored.
* *
* @param classpath the String to split - may be null or empty * @param classpath the String to split - may be null or empty
* @return String[] of classpath entries * @return String[] of classpath entries
} }


/** /**
* Get System property as boolean, but use default value where the system property is not set.
* Get System property as boolean, but use default value where the system
* property is not set.
* *
* @return true if value is set to true, false otherwise * @return true if value is set to true, false otherwise
*/ */
} }


/** /**
* Splits <code>input</code>, removing delimiter and trimming any white space. Returns an empty collection if the input is null.
* If delimiter is null or empty or if the input contains no delimiters, the input itself is returned after trimming white
* space.
* Splits <code>input</code>, removing delimiter and trimming any white
* space. Returns an empty collection if the input is null. If delimiter is
* null or empty or if the input contains no delimiters, the input itself is
* returned after trimming white space.
* *
* @param input <code>String</code> to split. * @param input <code>String</code> to split.
* @param delim <code>String</code> separators for input. * @param delim <code>String</code> separators for input.
} }


/** /**
* Splits strings into a <code>List</code> using a <code>StringTokenizer</code>.
* Splits strings into a <code>List</code> using a
* <code>StringTokenizer</code>.
* *
* @param text <code>String</code> to split. * @param text <code>String</code> to split.
*/ */
// * @param ignoreCase if true, ignore case // * @param ignoreCase if true, ignore case
// * @return String[] of input that end with any input // * @return String[] of input that end with any input
// */ // */
// public static String[] endsWith(String[] inputs, String[] suffixes, boolean ignoreCase) {
// public static String[] endsWith(String[] inputs, String[] suffixes,
// boolean ignoreCase) {
// if (LangUtil.isEmpty(inputs) || LangUtil.isEmpty(suffixes)) { // if (LangUtil.isEmpty(inputs) || LangUtil.isEmpty(suffixes)) {
// return new String[0]; // return new String[0];
// } // }
} }


/** /**
* Extract options and arguments to input option list, returning remainder. The input options will be nullified if not found.
* e.g.,
* Extract options and arguments to input option list, returning remainder.
* The input options will be nullified if not found. e.g.,
* *
* <pre> * <pre>
* String[] options = new String[][] { new String[] { &quot;-verbose&quot; }, new String[] { &quot;-classpath&quot;, null } }; * String[] options = new String[][] { new String[] { &quot;-verbose&quot; }, new String[] { &quot;-classpath&quot;, null } };
* </pre> * </pre>
* *
* @param args the String[] input options * @param args the String[] input options
* @param options the String[][]options to find in the input args - not null for each String[] component the first subcomponent
* is the option itself, and there is one String subcomponent for each additional argument.
* @param options the String[][]options to find in the input args - not null
* for each String[] component the first subcomponent is the
* option itself, and there is one String subcomponent for each
* additional argument.
* @return String[] of args remaining after extracting options to extracted * @return String[] of args remaining after extracting options to extracted
*/ */
public static String[] extractOptions(String[] args, String[][] options) { public static String[] extractOptions(String[] args, String[][] options) {


// //
// /** // /**
// * Extract options and arguments to input parameter list, returning remainder.
// * Extract options and arguments to input parameter list, returning
// remainder.
// * @param args the String[] input options // * @param args the String[] input options
// * @param validOptions the String[] options to find in the input args - not null
// * @param optionArgs the int[] number of arguments for each option in validOptions
// * @param validOptions the String[] options to find in the input args -
// not null
// * @param optionArgs the int[] number of arguments for each option in
// validOptions
// * (if null, then no arguments for any option) // * (if null, then no arguments for any option)
// * @param extracted the List for the matched options // * @param extracted the List for the matched options
// * @return String[] of args remaining after extracting options to extracted
// * @return String[] of args remaining after extracting options to
// extracted
// */ // */
// public static String[] extractOptions(String[] args, String[] validOptions,
// public static String[] extractOptions(String[] args, String[]
// validOptions,
// int[] optionArgs, List extracted) { // int[] optionArgs, List extracted) {
// if (LangUtil.isEmpty(args) // if (LangUtil.isEmpty(args)
// || LangUtil.isEmpty(validOptions) ) { // || LangUtil.isEmpty(validOptions) ) {
// } // }


// /** @return String[] of entries in validOptions found in args */ // /** @return String[] of entries in validOptions found in args */
// public static String[] selectOptions(String[] args, String[] validOptions) {
// public static String[] selectOptions(String[] args, String[]
// validOptions) {
// if (LangUtil.isEmpty(args) || LangUtil.isEmpty(validOptions)) { // if (LangUtil.isEmpty(args) || LangUtil.isEmpty(validOptions)) {
// return new String[0]; // return new String[0];
// } // }
// } // }


/** /**
* Convert arrays safely. The number of elements in the result will be 1 smaller for each element that is null or not
* assignable. This will use sink if it has exactly the right size. The result will always have the same component type as sink.
* Convert arrays safely. The number of elements in the result will be 1
* smaller for each element that is null or not assignable. This will use
* sink if it has exactly the right size. The result will always have the
* same component type as sink.
* *
* @return an array with the same component type as sink containing any assignable elements in source (in the same order).
* @return an array with the same component type as sink containing any
* assignable elements in source (in the same order).
* @throws IllegalArgumentException if either is null * @throws IllegalArgumentException if either is null
*/ */
public static Object[] safeCopy(Object[] source, Object[] sink) { public static Object[] safeCopy(Object[] source, Object[] sink) {
} }


/** /**
* @return a String with the unqualified class name of the object (or "null")
* @return a String with the unqualified class name of the object (or
* "null")
*/ */
public static String unqualifiedClassName(Object o) { public static String unqualifiedClassName(Object o) {
return LangUtil.unqualifiedClassName(null == o ? null : o.getClass()); return LangUtil.unqualifiedClassName(null == o ? null : o.getClass());
} }


/** /**
* Renders exception <code>t</code> after unwrapping and eliding any test packages.
* Renders exception <code>t</code> after unwrapping and eliding any test
* packages.
* *
* @param t <code>Throwable</code> to print. * @param t <code>Throwable</code> to print.
* @see #maxStackTrace * @see #maxStackTrace
} }


/** /**
* Renders exception <code>t</code>, unwrapping, optionally eliding and limiting total number of lines.
* Renders exception <code>t</code>, unwrapping, optionally eliding and
* limiting total number of lines.
* *
* @param t <code>Throwable</code> to print. * @param t <code>Throwable</code> to print.
* @param elide true to limit to 100 lines and elide test packages * @param elide true to limit to 100 lines and elide test packages
} }


/** /**
* Trim ending lines from a StringBuffer, clipping to maxLines and further removing any number of trailing lines accepted by
* checker.
* Trim ending lines from a StringBuffer, clipping to maxLines and further
* removing any number of trailing lines accepted by checker.
* *
* @param checker returns true if trailing line should be elided. * @param checker returns true if trailing line should be elided.
* @param stack StringBuffer with lines to elide * @param stack StringBuffer with lines to elide
} }


/** /**
* Replacement for Arrays.asList(..) which gacks on null and returns a List in which remove is an unsupported operation.
* Replacement for Arrays.asList(..) which gacks on null and returns a List
* in which remove is an unsupported operation.
* *
* @param array the Object[] to convert (may be null) * @param array the Object[] to convert (may be null)
* @return the List corresponding to array (never null) * @return the List corresponding to array (never null)
/** /**
* @param input ignored if null * @param input ignored if null
* @param sink the StringBuffer to add input to - return false if null * @param sink the StringBuffer to add input to - return false if null
* @param delimiter the String to append to input when added - ignored if empty
* @param delimiter the String to append to input when added - ignored if
* empty
* @return true if input + delimiter added to sink * @return true if input + delimiter added to sink
*/ */
private static boolean addIfNotEmpty(String input, StringBuffer sink, String delimiter) { private static boolean addIfNotEmpty(String input, StringBuffer sink, String delimiter) {
} }


/** /**
* Create or initialize a process controller to run a process in another VM asynchronously.
* Create or initialize a process controller to run a process in another VM
* asynchronously.
* *
* @param controller the ProcessController to initialize, if not null * @param controller the ProcessController to initialize, if not null
* @param classpath * @param classpath
return result; return result;
} }


/**
* Sleep for a particular period (in milliseconds).
*
* @param time the long time in milliseconds to sleep
* @return true if delay succeeded, false if interrupted 100 times
*/
public static boolean sleep(long milliseconds) {
if (milliseconds == 0) {
return true;
} else if (milliseconds < 0) {
throw new IllegalArgumentException("negative: " + milliseconds);
}
return sleepUntil(milliseconds + System.currentTimeMillis());
}
// /**
// * Sleep for a particular period (in milliseconds).
// *
// * @param time the long time in milliseconds to sleep
// * @return true if delay succeeded, false if interrupted 100 times
// */
// public static boolean sleep(long milliseconds) {
// if (milliseconds == 0) {
// return true;
// } else if (milliseconds < 0) {
// throw new IllegalArgumentException("negative: " + milliseconds);
// }
// return sleepUntil(milliseconds + System.currentTimeMillis());
// }


/** /**
* Sleep until a particular time. * Sleep until a particular time.
} }


/** /**
* Handle an external process asynchrously. <code>start()</code> launches a main thread to wait for the process and pipes
* streams (in child threads) through to the corresponding streams (e.g., the process System.err to this System.err). This can
* complete normally, by exception, or on demand by a client. Clients can implement <code>doCompleting(..)</code> to get notice
* when the process completes.
* Handle an external process asynchrously. <code>start()</code> launches a
* main thread to wait for the process and pipes streams (in child threads)
* through to the corresponding streams (e.g., the process System.err to
* this System.err). This can complete normally, by exception, or on demand
* by a client. Clients can implement <code>doCompleting(..)</code> to get
* notice when the process completes.
* <p> * <p>
* The following sample code creates a process with a completion callback starts it, and some time later retries the process.
* The following sample code creates a process with a completion callback
* starts it, and some time later retries the process.
* *
* <pre> * <pre>
* LangUtil.ProcessController controller = new LangUtil.ProcessController() { * LangUtil.ProcessController controller = new LangUtil.ProcessController() {
* } * }
* </pre> * </pre>
* *
* <u>warning</u>: Currently this does not close the input or output streams, since doing so prevents their use later.
* <u>warning</u>: Currently this does not close the input or output
* streams, since doing so prevents their use later.
*/ */
public static class ProcessController { public static class ProcessController {
/* /*
* XXX not verified thread-safe, but should be. Known problems: - user stops (completed = true) then exception thrown from
* destroying process (stop() expects !completed) ...
* XXX not verified thread-safe, but should be. Known problems: - user
* stops (completed = true) then exception thrown from destroying
* process (stop() expects !completed) ...
*/ */
private String[] command; private String[] command;
private String[] envp; private String[] envp;
} }


/** /**
* Permit re-running using the same command if this is not started or if completed. Can also call this when done with
* results to release references associated with results (e.g., stack traces).
* Permit re-running using the same command if this is not started or if
* completed. Can also call this when done with results to release
* references associated with results (e.g., stack traces).
*/ */
public final void reinit() { public final void reinit() {
if (!init) { if (!init) {
throw new IllegalArgumentException("empty command"); throw new IllegalArgumentException("empty command");
} }
this.label = LangUtil.isEmpty(label) ? command[0] : label; this.label = LangUtil.isEmpty(label) ? command[0] : label;
this.init = true;
init = true;
reinit(); reinit();
} }


/** /**
* Start running the process and pipes asynchronously. * Start running the process and pipes asynchronously.
* *
* @return Thread started or null if unable to start thread (results available via <code>getThrown()</code>, etc.)
* @return Thread started or null if unable to start thread (results
* available via <code>getThrown()</code>, etc.)
*/ */
public final Thread start() { public final Thread start() {
if (!init) { if (!init) {
} }


/** /**
* Destroy any process, stop any pipes. This waits for the pipes to clear (reading until no more input is available), but
* does not wait for the input stream for the pipe to close (i.e., not waiting for end-of-file on input stream).
* Destroy any process, stop any pipes. This waits for the pipes to
* clear (reading until no more input is available), but does not wait
* for the input stream for the pipe to close (i.e., not waiting for
* end-of-file on input stream).
*/ */
public final synchronized void stop() { public final synchronized void stop() {
if (completed) { if (completed) {
} }


/** /**
* Get any Throwable thrown. Note that the process can complete normally (with a valid return value), at the same time the
* pipes throw exceptions, and that this may return some exceptions even if the process is not complete.
* Get any Throwable thrown. Note that the process can complete normally
* (with a valid return value), at the same time the pipes throw
* exceptions, and that this may return some exceptions even if the
* process is not complete.
* *
* @return null if not complete or Thrown containing exceptions thrown by the process and streams.
* @return null if not complete or Thrown containing exceptions thrown
* by the process and streams.
*/ */
public final Thrown getThrown() { // cache this public final Thrown getThrown() { // cache this
return makeThrown(null); return makeThrown(null);
} }


/** /**
* Subclasses implement this to get synchronous notice of completion. All pipes and processes should be complete at this
* time. To get the exceptions thrown for the pipes, use <code>getThrown()</code>. If there is an exception, the process
* completed abruptly (including side-effects of the user halting the process). If <code>userStopped()</code> is true, then
* some client asked that the process be destroyed using <code>stop()</code>. Otherwise, the result code should be the
* result value returned by the process.
* Subclasses implement this to get synchronous notice of completion.
* All pipes and processes should be complete at this time. To get the
* exceptions thrown for the pipes, use <code>getThrown()</code>. If
* there is an exception, the process completed abruptly (including
* side-effects of the user halting the process). If
* <code>userStopped()</code> is true, then some client asked that the
* process be destroyed using <code>stop()</code>. Otherwise, the result
* code should be the result value returned by the process.
* *
* @param thrown same as <code>getThrown().fromProcess</code>. * @param thrown same as <code>getThrown().fromProcess</code>.
* @param result same as <code>getResult()</code> * @param result same as <code>getResult()</code>
} }


/** /**
* Handle termination (on-demand, abrupt, or normal) by destroying and/or halting process and pipes.
* Handle termination (on-demand, abrupt, or normal) by destroying
* and/or halting process and pipes.
* *
* @param thrown ignored if null * @param thrown ignored if null
* @param result ignored if Integer.MIN_VALUE * @param result ignored if Integer.MIN_VALUE

Loading…
Cancel
Save