All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.darwinsys.io.ClassSourceUtils Maven / Gradle / Ivy

There is a newer version: 1.8.0
Show newest version
package com.darwinsys.io;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Logger;

/**
 * A set of utility methods for Class files.
 */
public class ClassSourceUtils extends SourceUtils {
	
	private final static Logger logger = 
		Logger.getLogger(ClassSourceUtils.class.getName());
		
	private static List> result;
	
	/**
	 * Create a list of the Classes in a Source;
	 * each class that is successfully loaded as though
	 * by Class.forName() will be included in the list.
	 * 
* N.B.: This method is not thread-safe! * @param name - the name of something that can be used * as a Source, e.g., a Jar file, a class file or a directory. * @param classpath List of classpath entries * @return List<Class<?>> List of classes found in the source * which were able to be loaded. */ public static List> classListFromSource(String name, List classpath) { switch(classify(name)) { case CLASS: result = new ArrayList>(); try { result.add(Class.forName(name)); } catch (Exception e) { // Caught here so we go on to next one. logger.warning( String.format("Class %s failed to load: %s", name, e)); } return result; case JAR: return classListFromJar(name, classpath); case DIRECTORY: return classListFromDirectory(name, classpath); default: throw new IllegalStateException( String.format("Could not classify %s: Unhandled type", name)); } } /** * Make a list of Class descripters from a source * @param classesToTest The names of the classes * @return The list of Class descriptors. */ public static List> classListFromSource(String classesToTest) { return classListFromSource(classesToTest, null); } /** * Make a list of Class descripters from a Jar file * @param name The name of the jar file * @param classpath The members of the classpath. * @return The list of Class descriptors. */ private static List> classListFromJar(final String name, List classpath) { final List> results = new ArrayList>(); final File jFile = new File(name); ClassLoader cl = null; try (final JarFile jf = new JarFile(name)) { cl = new URLClassLoader(new URL[]{makeFileURL(jFile.getAbsolutePath())}); final Enumeration entries = jf.entries(); while (entries.hasMoreElements()) { final JarEntry jarEntry = entries.nextElement(); String entName = jarEntry.getName(); if (entName.endsWith(".class")) { int n = entName.length(); try { results.add( cl.loadClass( entName.substring(0, n - 6).replace('/','.'))); } catch (Exception e) { logger.warning( String.format("Class %s failed to load: %s", entName, e)); // Caught here so we go on to next one. } } } } catch (Exception e) { logger.warning("Caught unknown exception: " + e); } return results; } /** * Tries to find all the classes in the given directory and set of classpath elements * @param dirName Starting directory * @param classpath List of classpath elements * @return List of classes */ private static List> classListFromDirectory(final String dirName, List classpath) { result = new ArrayList>(); ClassLoader cl = null; try { final File fileDir = new File(dirName); final URL fileDirURL = makeFileURL(fileDir.getCanonicalPath()); List urls = new ArrayList(); urls.add(fileDirURL); if (classpath != null) { for (String s : classpath) { final URL anotherURL = makeFileURL(s); urls.add(anotherURL); logger.fine("added " + anotherURL); } } final int extraElements = urls.size(); logger.fine("Creating URLClassLoader for " + fileDirURL + " with " + extraElements + " extra elements."); cl = new URLClassLoader(urls.toArray(new URL[extraElements])); } catch (Exception e) { logger.warning("Failed to list directory " + dirName); } startDir(dirName, cl); return result; } /** Whip up a URL for a filename * @param filename The file name * @return The URL * @throws IOException Something wrong in IO land. */ public static URL makeFileURL(String filename) throws IOException { File f = new File(filename); return new URL("file://" + f.getCanonicalPath() + (f.isDirectory() ? "/" : "")); } private static String startPath; /** startDir - do one directory recursively * @param name The input * @param cl The classloader */ private static void startDir(String name, ClassLoader cl) { final File file = new File(name); startPath = name; doDir(file, cl); } /** doDir - do one directory recursively * @param f The input file * @param cl The ClassLoader */ private static void doDir(File f, ClassLoader cl) { final String name = f.getPath(); System.out.println("SourceUtils.doDir(): " + name); if (!f.exists()) { logger.warning(name + " does not exist"); return; } if (f.isFile()) { final String className = f.getPath().substring(1+startPath.length()); try { final Class clazz = doFile(f, cl, className); if (clazz != null) result.add(clazz); } catch (Exception e) { logger.warning("Warning: non-classifiable: " + f); return; } } else if (f.isDirectory()) { File objects[] = f.listFiles(); for (int i=0; i doFile(File f, ClassLoader cl) { return doFile(f, cl, f.getName()); } /** * Process one file. * @param f The File to process. * @param cl The ClassLoader to use. * @param name A classfile name. * @return The Class descriptor */ private static Class doFile(File f, ClassLoader cl, String name) { if (name.endsWith(".class")) { String className = name.substring(0, name.length() - 6).replace("/", "."); logger.fine("SourceUtils.doFile(): '" + className + '\''); try { Class c = cl.loadClass(className); logger.fine("Loaded OK"); return c; } catch (Exception e) { logger.warning( String.format("Class %s failed to load: %s", name, e)); return null; } } throw new IllegalStateException("Not a class! " + f.getAbsolutePath()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy