package abbot.util;
import java.io.File;
import java.net.*;
import java.util.StringTokenizer;
import java.util.ArrayList;
import abbot.Platform;
/** Provide a class loader that loads from a custom path. Similar to
* sun.misc.Launcher$AppClassLoader (the usual application class loader),
* except that it doesn't do the security checks that AppClassLoader does.
* If path given is null, uses java.class.path.
*/
public class PathClassLoader extends java.net.URLClassLoader {
private String classPath;
private static final Factory factory = new Factory();
/** Create a class loader that loads classes from the given path. */
public PathClassLoader(String path) {
this(path, null);
}
/** Create a class loader that loads classes from the given path. */
public PathClassLoader(String path, ClassLoader parent){
super(getURLs(path != null ? path
: System.getProperty("java.class.path"), ":;"),
parent, factory);
this.classPath = path != null
? path : System.getProperty("java.class.path");
}
public String getClassPath() { return classPath; }
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
int i = name.lastIndexOf('.');
if(i != -1) {
SecurityManager sm = System.getSecurityManager();
if(sm != null)
sm.checkPackageAccess(name.substring(0, i));
}
return super.loadClass(name, resolve);
}
/** Returns an array of URLs based on the given classpath string. */
static URL[] getURLs(String p, String separators) {
String s = p != null
? p : System.getProperty("java.class.path");
File files[] = s != null ? convertPathToFiles(s, separators) : new File[0];
URL[] urls = new URL[files.length];
for (int i=0;i < urls.length;i++) {
try {
urls[i] = files[i].toURL();
}
catch(MalformedURLException e) {
throw new RuntimeException(e.getMessage());
}
}
return urls;
}
/** Returns an array of filenames (including path). */
public static String[] convertPathToFilenames(String path) {
return convertPathToFilenames(path, ":;");
}
/** Convert the given path string into an array of File. */
public static File[] convertPathToFiles(String path, String seps) {
String[] names = convertPathToFilenames(path, ":;");
ArrayList files = new ArrayList();
for (int i=0;i < names.length;i++) {
files.add(new File(names[i]));
}
return (File[])files.toArray(new File[files.size()]);
}
static String[] convertPathToFilenames(String path, String seps) {
if (path == null)
path = "";
boolean fixDrives = Platform.isWindows() && seps.indexOf(":") != -1;
StringTokenizer st = new StringTokenizer(path, seps);
ArrayList names = new ArrayList();
while (st.hasMoreTokens()) {
String fp = st.nextToken();
// Fix up w32 absolute pathnames
if (fixDrives && fp.length() == 1 && st.hasMoreTokens()) {
char ch = fp.charAt(0);
if ((ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')) {
fp += ":" + st.nextToken();
}
}
names.add(fp);
}
return (String[])names.toArray(new String[names.size()]);
}
/** Taken from sun.misc.Launcher. */
private static class Factory implements URLStreamHandlerFactory {
private static final String PREFIX = "sun.net.www.protocol";
private Factory() { }
public URLStreamHandler createURLStreamHandler(String protocol) {
String name = PREFIX + "." + protocol + ".Handler";
try {
Class c = Class.forName(name);
return (URLStreamHandler)c.newInstance();
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
catch(InstantiationException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
throw new Error("could not load "
+ protocol + "system protocol handler");
}
}
public String toString() {
return super.toString() + " (classpath=" + classPath + ")";
}
}