piyclassloader.java
字号:
package piy;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Vector;
/**
* A utility class that provides simple class loading for classes of a particular type
* in a particular directory.
* @author David Vivash
* @version 1.0, 20/11/00
*/
public class PIYClassLoader
{
/**
* Retrieves all of the classes from the supplied directory that can be cast
* to baseClass. If baseClass is Object, all of the classes in the directory
* will be returned. The classes should be accessible as "directoryName.className"
* or "directoryName.subDirectoryName.className" etc. That is, the classes in the
* directory specified must belong to a package with the directoryName being the
* root package name.
* @param directory the (absolute) path to the directory containing the classes
* @param prefix the (classname) prefix representing the full package name up to the
* final directory which equals the specified directory
* @param baseClass the top level class from which all the returned classes can
* be cast to
* @param secondBaseClass another top level class to which the returned classes can be cast. Set to Object
* if only one class cast is needed and is represented in baseClass
* @param recurse set to true if the classloader should load from subdirectories as well
* @return an array containing all of the valid classes found
* @throws FileNotFoundException if directory is not found or does not represent a directory
*/
public static Class[] getClasses(File directory, String prefix, Class baseClass, Class secondBaseClass, boolean recurse) throws FileNotFoundException {
//check that the file exists and is a directory
if (!directory.isDirectory()) {
throw new FileNotFoundException("Directory argument to getClasses method not a directory: " + directory);
}
if (secondBaseClass == null) secondBaseClass = Object.class;
//get all files in the directory - in the form directory/file.ext or directory1/directory2/file.ext etc.
Vector listing = getFiles(directory, directory.getPath(), recurse); //a vector of strings representing file names
//we now have a complete list of file names
listing = filterNames(listing, ".class"); //filter out all files which are not class files
Vector acceptedClasses = new Vector(listing.size());
//we now have a complete list of class file names
for (int i=0; i<listing.size(); i++) {
//convert directoryName/subDirectoryName/file.class to directoryName.subDirectoryName.file.class
String className = ((String)listing.elementAt(i)).replace(File.separatorChar, '.');
//get rid of the ".class" bit
className = className.substring(0, className.length() - 6);
Class test = null;
try{
test = Class.forName(className);
} catch (ClassNotFoundException e) {
//The class couldn't be loaded - many possible reasons
} catch (Error e) {
//Errors are possible here - for example, if the class has the wrong package parameters
//ie. it shouldn't be in the directory it is.
}
//See if the base class is a superclass of the one we've just loaded
if (test != null) {
if (baseClass.isAssignableFrom(test) && secondBaseClass.isAssignableFrom(test)) {
acceptedClasses.add(test);
}
}
}
Class[] toReturn = new Class[acceptedClasses.size()];
for (int i=0; i<acceptedClasses.size(); i++)
toReturn[i] = (Class)acceptedClasses.elementAt(i);
return toReturn;
}
/**
* Gets all of the files and files in subdirectories of the given directory name.
* Filenames returned are of the form directory/file.ext or directory1/directory2/file.ext etc.
* where the '/' is platform dependent.
* @param directory the directory to retrieve files from
* @param prefix current file directory prefix, should start at "directoryName"
* @param recurse set to true if files should be returned from lower directories
* @return an array containing all filenames from the specified directory level and below
*/
private static Vector getFiles(File directory, String prefix, boolean recurse)
{
if (prefix == null) prefix = ""; //don't allow null prefix
String[] listing = directory.list();
Vector names = new Vector(listing.length);
for (int i=0; i<listing.length; i++)
names.add(i, prefix + File.separator + listing[i]); //.../directory/file.ext
Vector toReturn = new Vector(2*names.size());
for (int i=0; i<names.size(); i++)
{
if (new File((String)names.get(i)).isDirectory())
{
//only include files in the lower directory if the recurse flag is set
if (recurse) {
toReturn.addAll(getFiles(new File((String)names.get(i)), (String)names.get(i), recurse));
}
}
else
toReturn.add(names.get(i));
}
return toReturn;
}
/**
* Assumes the given Vector contains Strings. Returns all the strings in the vector
* that end in the given suffix.
* @param strings the list of strings to seive
* @param suffix the required suffix for all of the returned strings to have
* @return a Vector no larger than the one supplied which contains all strings in the original
* vector which have the specified suffix
*/
private static Vector filterNames(Vector strings, String suffix)
{
Vector toReturn = new Vector(strings.size());
for (int i=0; i<strings.size(); i++)
if ( ((String)strings.elementAt(i)).endsWith(suffix) )
toReturn.add(strings.elementAt(i));
return toReturn;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -