Mega Code Archive

 
Categories / Java / File Input Output
 

Search class in class path and Jar files

/*  * $Id: ClassSearchUtils.java,v 1.1 2009/03/01 12:01:11 rah003 Exp $  *  * Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle,  * Santa Clara, California 95054, U.S.A. All rights reserved.  *  * This library is free software; you can redistribute it and/or  * modify it under the terms of the GNU Lesser General Public  * License as published by the Free Software Foundation; either  * version 2.1 of the License, or (at your option) any later version.  *   * This library is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  * Lesser General Public License for more details.  *   * You should have received a copy of the GNU Lesser General Public  * License along with this library; if not, write to the Free Software  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *  */ import java.awt.HeadlessException; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; public class ClassSearchUtils {     private static final Logger log = Logger.getAnonymousLogger();     /**      * Classloader to be used to obtain resources from file system.      */     private ClassLoader classloader;     /**      * List of the resource found in the classpath.      */     private ArrayList list;     /**      * Extension of the resource to be found in the classpath.      */     private String extension;     private String prefix;     /**      * Search for the resource with the extension in the classpath. Method      * self-instantiate factory for every call to ensure thread safety.      * @param extension Mandatory extension of the resource. If all resources      * are required extension should be empty string. Null extension is not      * allowed and will cause method to fail.      * @return List of all resources with specified extension.      */     public static List<Class<?>> searchClassPath(String prefix) {         return searchClassPath(prefix, ".class");     }     /**      * Search for the resource with the extension in the classpath. Method      * self-instantiate factory for every call to ensure thread safety.      * @param extension Mandatory extension of the resource. If all resources      * are required extension should be empty string. Null extension is not      * allowed and will cause method to fail.      * @return List of all resources with specified extension.      */     public static List searchClassPath(String prefix, String extension) {         ClassSearchUtils factory = new ClassSearchUtils();         factory.prefix = prefix;         return factory.find(extension);     }     /**      * Search for the resource with the extension in the classpath.      * @param extension Mandatory extension of the resource. If all resources      * are required extension should be empty string. Null extension is not      * allowed and will cause method to fail.      * @return List of all resources with specified extension.      */     private List<Class<?>> find(String extension) {         this.extension = extension;         this.list = new ArrayList();         this.classloader = this.getClass().getClassLoader();         String classpath = System.getProperty("java.class.path");         try {             Method method =                 this.classloader.getClass().getMethod("getClassPath", (Class<?>) null);             if (method != null) {                 classpath = (String) method.invoke(this.classloader, (Object) null);             }         } catch (Exception e) {             // ignore         }         if (classpath == null) {             classpath = System.getProperty("java.class.path");         }         StringTokenizer tokenizer =             new StringTokenizer(classpath, File.pathSeparator);         String token;         File dir;         String name;         while (tokenizer.hasMoreTokens()) {             token = tokenizer.nextToken();             dir = new File(token);             if (dir.isDirectory()) {                 lookInDirectory("", dir);             }             if (dir.isFile()) {                 name = dir.getName().toLowerCase();                 if (name.endsWith(".zip") || name.endsWith(".jar")) {                     this.lookInArchive(dir);                 }             }         }         return this.list;     }     /**      * @param name Name of to parent directories in java class notation (dot      * separator)      * @param dir Directory to be searched for classes.      */     private void lookInDirectory(String name, File dir) {         log.fine( "Looking in directory [" + dir.getName() + "].");         File[] files = dir.listFiles();         File file;         String fileName;         final int size = files.length;         for (int i = 0; i < size; i++) {             file = files[i];             fileName = file.getName();             if (file.isFile()                 && fileName.toLowerCase().endsWith(this.extension)) {                 try {                     if (this.extension.equalsIgnoreCase(".class")) {                         fileName = fileName.substring(0, fileName.length() - 6);                         // filter ignored resources                         if (!(name + fileName).startsWith(this.prefix)) {                             continue;                         }                         log.fine(                             "Found class: [" + name + fileName + "].");                         this.list.add(Class.forName(name + fileName));                     } else {                         this.list.add(                             this.classloader.getResource(                                 name.replace('.', File.separatorChar)                                     + fileName));                     }                 } catch (ClassNotFoundException e) {                     // ignore                 } catch (NoClassDefFoundError e) {                         //ignore too                 } catch (ExceptionInInitializerError e) {                     if (e.getCause() instanceof HeadlessException) {                         // running in headless env ... ignore                      } else {                         throw e;                     }                 }             }             // search recursively.             // I don't like that but we will see how it will work.             if (file.isDirectory()) {                 lookInDirectory(name + fileName + ".", file);             }         }     }     /**      * Search archive files for required resource.      * @param archive Jar or zip to be searched for classes or other resources.      */     private void lookInArchive(File archive) {         log.fine(             "Looking in archive ["                 + archive.getName()                 + "] for extension ["                 + this.extension                 + "].");         JarFile jarFile = null;         try {             jarFile = new JarFile(archive);         } catch (IOException e) {             log.warning(                 "Non fatal error. Unable to read jar item.");             return;         }         Enumeration entries = jarFile.entries();         JarEntry entry;         String entryName;         while (entries.hasMoreElements()) {             entry = (JarEntry) entries.nextElement();             entryName = entry.getName();             if (entryName.toLowerCase().endsWith(this.extension)) {                 try {                     if (this.extension.equalsIgnoreCase(".class")) {                         // convert name into java classloader notation                         entryName =                             entryName.substring(0, entryName.length() - 6);                         entryName = entryName.replace('/', '.');                         // filter ignored resources                         if (!entryName.startsWith(this.prefix)) {                             continue;                         }                         log.fine(                             "Found class: [" + entryName + "]. ");                         this.list.add(Class.forName(entryName));                     } else {                         this.list.add(this.classloader.getResource(entryName));                         log.fine(                             "Found appropriate resource with name ["                                 + entryName                                 + "]. Resource instance:"                                 + this.classloader.getResource(entryName));                     }                 } catch (Throwable e) {                     // ignore                     log.warning(                         "Unable to load resource ["                             + entryName                             + "] form file ["                             + archive.getAbsolutePath()                             + "].");                 }             }         }     } }