diff options
Diffstat (limited to 'common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/Classpath.java')
-rw-r--r-- | common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/Classpath.java | 939 |
1 files changed, 0 insertions, 939 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/Classpath.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/Classpath.java deleted file mode 100644 index dcf03bd2cf..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/Classpath.java +++ /dev/null @@ -1,939 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.utility.internal; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.io.Serializable; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.eclipse.jpt.common.utility.Filter; -import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable; -import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator; -import org.eclipse.jpt.common.utility.internal.iterators.CompositeIterator; -import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; -import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator; -import org.eclipse.jpt.common.utility.internal.iterators.TransformationIterator; - -/** - * <code>Classpath</code> models a Java classpath, which consists of a list of - * {@link Entry}s, each of which contain Java classes. The classpath can return - * the names of classes found in it etc. There are a number of static - * convenience methods that can be use to construct <code>Classpath</code>s - * corresponding to the Java classpath etc. - */ -public class Classpath - implements Serializable -{ - /** The entries in the classpath */ - private final Entry[] entries; - - private static final long serialVersionUID = 1L; - - - // ********** static methods ********** - - // ***** factory methods for "standard" classpaths ***** - - /** - * Return the Java "boot" classpath. This includes <code>rt.jar</code>. - */ - public static Classpath bootClasspath() { - return new Classpath(System.getProperty("sun.boot.class.path")); //$NON-NLS-1$ - } - - /** - * Return a "virtual classpath" that contains all the jars - * that would be used by the Java Extension Mechanism. - */ - public static Classpath javaExtensionClasspath() { - File[] dirs = javaExtensionDirectories(); - List<String> jarFileNames = new ArrayList<String>(); - for (File dir : dirs) { - if (dir.isDirectory()) { - addJarFileNamesTo(dir, jarFileNames); - } - } - return new Classpath(jarFileNames); - } - - /** - * Return the Java "system" classpath. - */ - public static Classpath javaClasspath() { - return new Classpath(System.getProperty("java.class.path")); //$NON-NLS-1$ - } - - /** - * Return the unretouched "complete" classpath. - * This includes the boot classpath, the Java Extension - * Mechanism classpath, and the normal "system" classpath. - */ - public static Classpath completeClasspath() { - return new Classpath(new Classpath[] { - bootClasspath(), - javaExtensionClasspath(), - javaClasspath() - }); - } - - /** - * Return a classpath that contains the location of the specified class. - */ - public static Classpath classpathFor(Class<?> javaClass) { - return new Classpath(locationFor(javaClass)); - } - - - // ***** file => class ***** - - /** - * Convert a relative file name to a class name; this will work for - * any file that has a single extension beyond the base - * class name:<ul> - * <li><code>"java/lang/String.class"</code> is converted to <code>"java.lang.String"</code> - * <li><code>"java/lang/String.java"</code> is converted to <code>"java.lang.String"</code> - * </ul> - */ - public static String convertToClassName(String classFileName) { - String className = FileTools.stripExtension(classFileName); - // do this for archive entry names - className = className.replace('/', '.'); - // do this for O/S-specific file names - if (File.separatorChar != '/') { - className = className.replace(File.separatorChar, '.'); - } - return className; - } - - /** - * Convert a file to a class name; - * e.g. <code>File(java/lang/String.class)</code> is converted to - * <code>"java.lang.String"</code>. - */ - public static String convertToClassName(File classFile) { - return convertToClassName(classFile.getPath()); - } - - /** - * Convert a relative file name to a class; - * e.g. <code>"java/lang/String.class"</code> is converted to - * <code>java.lang.String.class</code>. - */ - public static Class<?> convertToClass(String classFileName) throws ClassNotFoundException { - return Class.forName(convertToClassName(classFileName)); - } - - /** - * Convert a relative file to a class; - * e.g. <code>File(java/lang/String.class)</code> is converted to - * <code>java.lang.String.class</code>. - */ - public static Class<?> convertToClass(File classFile) throws ClassNotFoundException { - return convertToClass(classFile.getPath()); - } - - - // ***** class => JAR entry ***** - - /** - * Convert a class name to an archive entry name base; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>"java/lang/String"</code>. - */ - public static String convertToArchiveEntryNameBase(String className) { - return className.replace('.', '/'); - } - - /** - * Convert a class to an archive entry name base; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"java/lang/String"</code>. - */ - public static String convertToArchiveEntryNameBase(Class<?> javaClass) { - return convertToArchiveEntryNameBase(javaClass.getName()); - } - - /** - * Convert a class name to an archive class file entry name; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>"java/lang/String.class"</code>. - */ - public static String convertToArchiveClassFileEntryName(String className) { - return convertToArchiveEntryNameBase(className) + ".class"; //$NON-NLS-1$ - } - - /** - * Convert a class to an archive class file entry name; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"java/lang/String.class"</code>. - */ - public static String convertToArchiveClassFileEntryName(Class<?> javaClass) { - return convertToArchiveClassFileEntryName(javaClass.getName()); - } - - - // ***** class => file (.class or .java) ***** - - /** - * Convert a class name to a file name base for the current O/S; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>"java/lang/String"</code> on Unix and - * <code>"java\\lang\\String"</code> on Windows. - */ - public static String convertToFileNameBase(String className) { - return className.replace('.', File.separatorChar); - } - - /** - * Convert a class to a file name base for the current O/S; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"java/lang/String"</code> on Unix and - * <code>"java\\lang\\String"</code> on Windows. - */ - public static String convertToFileNameBase(Class<?> javaClass) { - return convertToFileNameBase(javaClass.getName()); - } - - /** - * Convert a class name to a class file name for the current O/S; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>"java/lang/String.class"</code> on Unix and - * <code>"java\\lang\\String.class"</code> on Windows. - */ - public static String convertToClassFileName(String className) { - return convertToFileNameBase(className) + ".class"; //$NON-NLS-1$ - } - - /** - * Convert a class to a class file name for the current O/S; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"java/lang/String.class"</code> on Unix and - * <code>"java\\lang\\String.class"</code> on Windows. - */ - public static String convertToClassFileName(Class<?> javaClass) { - return convertToClassFileName(javaClass.getName()); - } - - /** - * Convert a class name to a class file for the current O/S; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>File(java/lang/String.class)</code>. - */ - public static File convertToClassFile(String className) { - return new File(convertToClassFileName(className)); - } - - /** - * Convert a class to a class file for the current O/S; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>File(java/lang/String.class)</code>. - */ - public static File convertToClassFile(Class<?> javaClass) { - return convertToClassFile(javaClass.getName()); - } - - /** - * Convert a class name to a java file name for the current O/S; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>"java/lang/String.java"</code> on Unixl and - * <code>"java\\lang\\String.java"</code> on Windows. - */ - public static String convertToJavaFileName(String className) { - return convertToFileNameBase(className) + ".java"; //$NON-NLS-1$ - } - - /** - * Convert a class to a java file name for the current O/S; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"java/lang/String.java"</code> on Unix and - * <code>"java\\lang\\String.java"</code> on Windows. - */ - public static String convertToJavaFileName(Class<?> javaClass) { - return convertToJavaFileName(javaClass.getName()); - } - - /** - * Convert a class name to a java file for the current O/S; - * e.g. <code>"java.lang.String"</code> is converted to - * <code>File(java/lang/String.java)</code>. - */ - public static File convertToJavaFile(String className) { - return new File(convertToJavaFileName(className)); - } - - /** - * Convert a class to a java file for the current O/S; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>File(java/lang/String.java)</code>. - */ - public static File convertToJavaFile(Class<?> javaClass) { - return convertToJavaFile(javaClass.getName()); - } - - - // ***** class => resource ***** - - /** - * Convert a class to a resource name; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>"/java/lang/String.class"</code>. - */ - public static String convertToResourceName(Class<?> javaClass) { - return '/' + convertToArchiveClassFileEntryName(javaClass); - } - - /** - * Convert a class to a resource; - * e.g. <code>java.lang.String.class</code> is converted to - * <code>URL(jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class)</code>. - */ - public static URL convertToResource(Class<?> javaClass) { - return javaClass.getResource(convertToResourceName(javaClass)); - } - - - // ***** utilities ***** - - /** - * Return whether the specified file is an archive file; - * i.e. its name ends with <code>".zip"</code> or <code>".jar"</code>. - */ - public static boolean fileNameIsArchive(String fileName) { - String ext = FileTools.extension(fileName).toLowerCase(); - return ext.equals(".jar") || ext.equals(".zip"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Return whether the specified file is an archive file; - * i.e. its name ends with <code>".zip"</code> or <code>".jar"</code>. - */ - public static boolean fileIsArchive(File file) { - return fileNameIsArchive(file.getName()); - } - - /** - * Return what should be the fully-qualified file name - * for the JRE runtime JAR; - * e.g. <code>"C:\jdk1.4.2_04\jre\lib\rt.jar"</code>. - */ - public static String rtJarName() { - return locationFor(java.lang.Object.class); - } - - /** - * Return the location from where the specified class was loaded. - */ - public static String locationFor(Class<?> javaClass) { - URL url = convertToResource(javaClass); - String path; - try { - path = FileTools.buildFile(url).getPath(); - } catch (URISyntaxException ex) { - throw new RuntimeException(ex); - } - String protocol = url.getProtocol().toLowerCase(); - if (protocol.equals("jar")) { //$NON-NLS-1$ - // if the class is in a JAR, the URL will look something like this: - // jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class - return path.substring(0, path.indexOf('!')); - } else if (protocol.equals("file")) { //$NON-NLS-1$ - // if the class is in a directory, the URL will look something like this: - // file:/C:/dev/main/mwdev/class/org/eclipse/dali/utility/Classpath.class - return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1); - } else if (protocol.equals("bundleresource")) { //$NON-NLS-1$ - // if the class is in a bundle resource (Eclipse?), the URL will look something like this: - // bundleresource://43/org/eclipse/dali/utility/Classpath.class - return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1); - } - - throw new IllegalStateException(url.toString()); - } - - /** - * Return the directories used by the Java Extension Mechanism. - */ - public static File[] javaExtensionDirectories() { - return convertToFiles(javaExtensionDirectoryNames()); - } - - /** - * Return the directory names used by the Java Extension Mechanism. - */ - public static String[] javaExtensionDirectoryNames() { - return System.getProperty("java.ext.dirs").split(File.pathSeparator); //$NON-NLS-1$ - } - - - // ***** internal ***** - - private static File[] convertToFiles(String[] fileNames) { - File[] files = new File[fileNames.length]; - for (int i = fileNames.length; i-- > 0; ) { - files[i] = new File(fileNames[i]); - } - return files; - } - - private static void addJarFileNamesTo(File dir, List<String> jarFileNames) { - File[] jarFiles = jarFilesIn(dir); - for (File jarFile : jarFiles) { - jarFileNames.add(FileTools.canonicalFile(jarFile).getPath()); - } - } - - private static File[] jarFilesIn(File directory) { - return directory.listFiles(jarFileFilter()); - } - - private static FileFilter jarFileFilter() { - return new FileFilter() { - public boolean accept(File file) { - return FileTools.extension(file.getName()).toLowerCase().equals(".jar"); //$NON-NLS-1$ - } - }; - } - - - // ********** constructors ********** - - /** - * Construct a classpath with the specified entries. - */ - private Classpath(Entry[] entries) { - super(); - this.entries = entries; - } - - /** - * Construct a classpath with the specified entries. - */ - public Classpath(String... fileNames) { - this(buildEntries(fileNames)); - } - - /** - * Skip empty file names because they will end up expanding to the current - * working directory, which is not what we want. Empty file names actually - * occur with some frequency; such as when the classpath has been built up - * dynamically with too many separators. For example:<pre> - * "C:\dev\foo.jar;;C:\dev\bar.jar" - * </pre>will be parsed into three file names:<pre> - * { "C:\dev\foo.jar", "", "C:\dev\bar.jar" } - * </pre> - */ - private static Entry[] buildEntries(String[] fileNames) { - List<Entry> entries = new ArrayList<Entry>(); - for (String fileName : fileNames) { - if ((fileName != null) && (fileName.length() != 0)) { - entries.add(new Entry(fileName)); - } - } - return entries.toArray(new Entry[entries.size()]); - } - - /** - * Construct a classpath with the specified path. - */ - public Classpath(String path) { - this(path.split(File.pathSeparator)); - } - - /** - * Construct a classpath with the specified entries. - */ - public Classpath(Iterable<String> fileNames) { - this(ArrayTools.array(fileNames, StringTools.EMPTY_STRING_ARRAY)); - } - - /** - * Consolidate the specified classpaths into a single classpath. - */ - public Classpath(Classpath... classpaths) { - this(consolidateEntries(classpaths)); - } - - private static Entry[] consolidateEntries(Classpath[] classpaths) { - List<Entry> entries = new ArrayList<Entry>(); - for (Classpath classpath : classpaths) { - CollectionTools.addAll(entries, classpath.getEntries()); - } - return entries.toArray(new Entry[entries.size()]); - } - - - // ********** public API ********** - - /** - * Return the classpath's entries. - */ - public Iterable<Entry> getEntries() { - return new ArrayIterable<Entry>(this.entries); - } - - /** - * Return the classpath's path. - */ - public String getPath() { - int max = this.entries.length - 1; - if (max == -1) { - return ""; //$NON-NLS-1$ - } - StringBuilder sb = new StringBuilder(2000); - // stop one short of the end of the array - for (int i = 0; i < max; i++) { - sb.append(this.entries[i].getFileName()); - sb.append(File.pathSeparatorChar); - } - sb.append(this.entries[max].getFileName()); - return sb.toString(); - } - - /** - * Search the classpath for the specified (unqualified) file - * and return its entry. Return null if an entry is not found. - * For example, you could use this method to find the entry - * for <code>"rt.jar"</code> or <code>"toplink.jar"</code>. - */ - public Entry getEntryForFileNamed(String shortFileName) { - for (Entry entry : this.entries) { - if (entry.getFile().getName().equals(shortFileName)) { - return entry; - } - } - return null; - } - - /** - * Return the first entry file in the classpath - * that contains the specified class. - * Return null if an entry is not found. - */ - public Entry getEntryForClassNamed(String className) { - String relativeClassFileName = convertToClassFileName(className); - String archiveEntryName = convertToArchiveClassFileEntryName(className); - for (Entry entry : this.entries) { - if (entry.contains(relativeClassFileName, archiveEntryName)) { - return entry; - } - } - return null; - } - - /** - * Return the names of all the classes discovered on the classpath, - * with duplicates removed. - * @see #classNames() - */ - public Iterable<String> getClassNames() { - return this.getClassNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * and accepted by the specified filter, with duplicates removed. - * @see #classNames(Filter) - */ - public Iterable<String> getClassNames(Filter<String> filter) { - Collection<String> classNames = new HashSet<String>(10000); - this.addClassNamesTo(classNames, filter); - return classNames; - } - - /** - * Add the names of all the classes discovered on the classpath - * to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames) { - this.addClassNamesTo(classNames, Filter.Null.<String>instance()); - } - - /** - * Add the names of all the classes discovered on the classpath - * and accepted by the specified filter to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) { - for (Entry entry : this.entries) { - entry.addClassNamesTo(classNames, filter); - } - } - - /** - * Return the names of all the classes discovered on the classpath. - * Just a bit more performant than {@link #getClassNames()}. - */ - public Iterator<String> classNames() { - return this.classNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * that are accepted by the specified filter. - * Just a bit more performant than {@link #getClassNames(Filter)}. - */ - public Iterator<String> classNames(Filter<String> filter) { - return new CompositeIterator<String>(this.entryClassNamesIterators(filter)); - } - - private Iterator<Iterator<String>> entryClassNamesIterators(final Filter<String> filter) { - return new TransformationIterator<Entry, Iterator<String>>(new ArrayIterator<Entry>(this.entries)) { - @Override - protected Iterator<String> transform(Entry entry) { - return entry.classNames(filter); - } - }; - } - - /** - * Return a "compressed" version of the classpath with its - * duplicate entries eliminated. - */ - public Classpath compressed() { - return new Classpath(ArrayTools.removeDuplicateElements(this.entries)); - } - - /** - * Convert the classpath to an array of URLs - * (that can be used to instantiate a {@link java.net.URLClassLoader}). - */ - public Iterable<URL> getURLs() { - int len = this.entries.length; - URL[] urls = new URL[len]; - for (int i = 0; i < len; i++) { - urls[i] = this.entries[i].getURL(); - } - return new ArrayIterable<URL>(urls); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.getPath()); - } - - - // ********** inner class ********** - - /** - * <code>Entry</code> models a Java classpath entry, which can be either a - * directory containing <code>.class</code> files or a JAR file (or, - * similarly, a <code>.zip</code> file). The entry can return the names of - * classes found in it etc. - */ - public static class Entry implements Serializable { - private final String fileName; - private final File file; - private final File canonicalFile; - - private static final long serialVersionUID = 1L; - - Entry(String fileName) { - super(); - if ((fileName == null) || (fileName.length() == 0)) { - throw new IllegalArgumentException("'fileName' must be non-empty"); //$NON-NLS-1$ - } - this.fileName = fileName; - this.file = new File(fileName); - this.canonicalFile = FileTools.canonicalFile(this.file); - } - - public String getFileName() { - return this.fileName; - } - - public File getFile() { - return this.file; - } - - public File getCanonicalFile() { - return this.canonicalFile; - } - - public String getCanonicalFileName() { - return this.canonicalFile.getAbsolutePath(); - } - - @Override - public boolean equals(Object o) { - if ( ! (o instanceof Entry)) { - return false; - } - return ((Entry) o).canonicalFile.equals(this.canonicalFile); - } - - @Override - public int hashCode() { - return this.canonicalFile.hashCode(); - } - - /** - * Return the entry's "canonical" URL. - */ - public URL getURL() { - try { - return this.canonicalFile.toURI().toURL(); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Return whether the entry contains the specified class. - */ - public boolean contains(Class<?> javaClass) { - return this.contains(javaClass.getName()); - } - - /** - * Return whether the entry contains the specified class. - */ - public boolean contains(String className) { - return this.contains(convertToClassFileName(className), convertToArchiveClassFileEntryName(className)); - } - - /** - * Return whether the entry contains either the specified relative - * class file or the specified archive entry. - * Not the prettiest signature, but it's internal.... - */ - boolean contains(String relativeClassFileName, String archiveEntryName) { - if ( ! this.canonicalFile.exists()) { - return false; - } - if (this.canonicalFile.isDirectory() && (new File(this.canonicalFile, relativeClassFileName)).exists()) { - return true; - } - return (fileIsArchive(this.canonicalFile) && this.archiveContainsEntry(archiveEntryName)); - } - - /** - * Return whether the entry's archive contains the specified entry. - */ - private boolean archiveContainsEntry(String zipEntryName) { - ZipFile zipFile = null; - ZipEntry zipEntry = null; - try { - zipFile = new ZipFile(this.canonicalFile); - zipEntry = zipFile.getEntry(zipEntryName); - } catch (IOException ex) { - // something is wrong, leave the entry null - } finally { - try { - if (zipFile != null) { - zipFile.close(); - } - } catch (IOException ex) { - zipEntry = null; // something is wrong, clear out the entry - } - } - return zipEntry != null; - } - - /** - * Return the names of all the classes discovered in the entry. - * @see #classNames() - */ - public Iterable<String> getClassNames() { - return this.getClassNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered in the entry - * and accepted by the specified filter. - * @see #classNames(Filter) - */ - public Iterable<String> getClassNames(Filter<String> filter) { - Collection<String> classNames = new ArrayList<String>(2000); - this.addClassNamesTo(classNames, filter); - return classNames; - } - - /** - * Add the names of all the classes discovered in the entry - * to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames) { - this.addClassNamesTo(classNames, Filter.Null.<String>instance()); - } - - /** - * Add the names of all the classes discovered in the entry - * and accepted by the specified filter to the specified collection. - */ - public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) { - if (this.canonicalFile.exists()) { - if (this.canonicalFile.isDirectory()) { - this.addClassNamesForDirectoryTo(classNames, filter); - } else if (fileIsArchive(this.canonicalFile)) { - this.addClassNamesForArchiveTo(classNames, filter); - } - } - } - - /** - * Add the names of all the classes discovered - * under the entry's directory and accepted by - * the specified filter to the specified collection. - */ - private void addClassNamesForDirectoryTo(Collection<String> classNames, Filter<String> filter) { - int start = this.canonicalFile.getAbsolutePath().length() + 1; - for (Iterator<File> stream = this.classFilesForDirectory(); stream.hasNext(); ) { - String className = convertToClassName(stream.next().getAbsolutePath().substring(start)); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - - /** - * Return an iterator on all the class files discovered - * under the entry's directory. - */ - private Iterator<File> classFilesForDirectory() { - return new FilteringIterator<File>(FileTools.filesInTree(this.canonicalFile)) { - @Override - protected boolean accept(File next) { - return Entry.this.fileNameMightBeForClassFile(next.getName()); - } - }; - } - - /** - * Add the names of all the classes discovered - * in the entry's archive file and accepted by the - * specified filter to the specified collection. - */ - private void addClassNamesForArchiveTo(Collection<String> classNames, Filter<String> filter) { - ZipFile zipFile = null; - try { - zipFile = new ZipFile(this.canonicalFile); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) { - ZipEntry zipEntry = stream.nextElement(); - String zipEntryName = zipEntry.getName(); - if (this.fileNameMightBeForClassFile(zipEntryName)) { - String className = convertToClassName(zipEntryName); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - try { - zipFile.close(); - } catch (IOException ex) { - return; - } - } - - /** - * Return whether the specified file might be a Java class file. - * The file name must at least end with <code>".class"</code> and contain no spaces. - * (Neither class names nor package names may contain spaces.) - * Whether it actually is a class file will need to be determined by - * a class loader. - */ - boolean fileNameMightBeForClassFile(String name) { - return FileTools.extension(name).toLowerCase().equals(".class") //$NON-NLS-1$ - && (name.indexOf(' ') == -1); - } - - /** - * Return the names of all the classes discovered on the classpath. - * Just a bit more performant than {@link #getClassNames()}. - */ - public Iterator<String> classNames() { - return this.classNames(Filter.Null.<String>instance()); - } - - /** - * Return the names of all the classes discovered on the classpath - * that are accepted by the specified filter. - * Just a bit more performant than {@link #getClassNames(Filter)}. - */ - public Iterator<String> classNames(Filter<String> filter) { - if (this.canonicalFile.exists()) { - if (this.canonicalFile.isDirectory()) { - return this.classNamesForDirectory(filter); - } - if (fileIsArchive(this.canonicalFile)) { - return this.classNamesForArchive(filter); - } - } - return EmptyIterator.instance(); - } - - /** - * Return the names of all the classes discovered - * under the entry's directory and accepted by - * the specified filter. - */ - private Iterator<String> classNamesForDirectory(Filter<String> filter) { - return new FilteringIterator<String>(this.classNamesForDirectory(), filter); - } - - /** - * Transform the class files to class names. - */ - private Iterator<String> classNamesForDirectory() { - final int start = this.canonicalFile.getAbsolutePath().length() + 1; - return new TransformationIterator<File, String>(this.classFilesForDirectory()) { - @Override - protected String transform(File f) { - return convertToClassName(f.getAbsolutePath().substring(start)); - } - }; - } - - /** - * Return the names of all the classes discovered - * in the entry's archive file and accepted by the - * specified filter. - */ - private Iterator<String> classNamesForArchive(Filter<String> filter) { - // we can't simply wrap iterators here because we need to close the archive file... - ZipFile zipFile = null; - try { - zipFile = new ZipFile(this.canonicalFile); - } catch (IOException ex) { - return EmptyIterator.instance(); - } - Collection<String> classNames = new HashSet<String>(zipFile.size()); - for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) { - ZipEntry zipEntry = stream.nextElement(); - String zipEntryName = zipEntry.getName(); - if (this.fileNameMightBeForClassFile(zipEntryName)) { - String className = convertToClassName(zipEntryName); - if (filter.accept(className)) { - classNames.add(className); - } - } - } - try { - zipFile.close(); - } catch (IOException ex) { - return EmptyIterator.instance(); - } - return classNames.iterator(); - } - - } - -} |