00001
import java.util.*;
00002
import java.io.*;
00003
import java.net.*;
00004
import java.lang.reflect.*;
00005
00006 public class PluginLoader {
00007 final static private Hashtable
classloaders =
new Hashtable();
00008 final static private ClassLoader
parentClassLoader =
00009
new PluginLoader().getClass().getClassLoader();
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 public static ClassLoader
getClassLoader(URL url) {
00025
00026 URLClassLoader loader =
00027 (URLClassLoader)
classloaders.get(url);
00028
if (loader==null) {
00029 loader = URLClassLoader.newInstance
00030 (
new URL[] {url},
parentClassLoader);
00031
classloaders.put(url,loader);
00032 }
00033
return loader;
00034 }
00035
00036 public static Object
load(Class classType, URL baseURL,
00037 BufferedReader input)
00038
throws IOException,
FileFormatException {
00039
00040
00041 String urlstring = input.readLine();
00042 String className = input.readLine();
00043
if (className==null)
00044
throw new FileFormatException
00045 (
"plugin specification is not at least two lines long");
00046
00047
00048 URL classurl;
00049
try {
00050 classurl =
new URL(baseURL,urlstring);
00051 }
catch (MalformedURLException e) {
00052
throw new FileFormatException
00053 (
"invalid URL "+urlstring+
": "+e.getMessage());
00054 }
00055
00056
00057 Class theClass;
00058
try {
00059
try {
00060 theClass = getClassLoader(classurl).loadClass(className);
00061 }
catch (ClassNotFoundException ex) {
00062
00063 URL proxy =
InputManager.makeProxyURL(baseURL,classurl);
00064 System.out.println(
"in plugin loader: possibly "+classurl+
00065
" is not accessible. Trying "+proxy+
00066
" instead.");
00067 theClass = getClassLoader(proxy).loadClass(className);
00068 }
00069 }
catch (ClassNotFoundException e) {
00070 e.printStackTrace();
00071
throw new FileFormatException
00072 (
"in plugin loader: "+baseURL+
00073
" does not contain class "+className+
00074
": "+e);
00075 }
catch (NoClassDefFoundError e) {
00076
throw new FileFormatException
00077 (
"in plugin loader: error loading class "+
00078 className+
": "+e);
00079 }
catch (UnsupportedClassVersionError e) {
00080
throw new FileFormatException
00081 (
"in plugin loader: error loading class "+
00082 className+
": "+e);
00083 }
00084
00085
00086
if (!classType.isAssignableFrom(theClass))
00087
throw new FileFormatException
00088 (
"in plugin loader: class "+className+
00089
" is not a subclass of "+classType);
00090
00091
00092 Constructor constructor;
00093
try {
00094 constructor = theClass.getConstructor
00095 (
new Class[] { input.getClass() });
00096 }
catch (NoSuchMethodException e) {
00097
throw new FileFormatException
00098 (
"in plugin loader: cannot create new "+className+
00099
"("+input.getClass().getName()+
"): "+e);
00100 }
00101
00102
00103 Object obj;
00104
try {
00105 obj = constructor.newInstance(
new Object[]{input});
00106 }
catch (InstantiationException e) {
00107
throw new FileFormatException
00108 (
"in plugin loader: cannot create new "+className+
00109
"("+input.getClass().getName()+
"): "+e);
00110 }
catch (IllegalAccessException e) {
00111
throw new FileFormatException
00112 (
"in plugin loader: cannot create new "+className+
00113
"("+input.getClass().getName()+
"): "+e);
00114 }
catch (IllegalArgumentException e) {
00115
throw new FileFormatException
00116 (
"in plugin loader: cannot create new "+className+
00117
"("+input.getClass().getName()+
"): "+e);
00118 }
catch (ExceptionInInitializerError e) {
00119
throw new FileFormatException
00120 (
"in plugin loader: cannot create new "+className+
00121
"("+input.getClass().getName()+
"): "+e);
00122 }
catch (InvocationTargetException e) {
00123 e.printStackTrace();
00124
throw new FileFormatException
00125 (
"in plugin loader: "+className+
00126
".createReplacement("+input.getClass().getName()+
00127
") failed: "+e.getTargetException());
00128 }
00129
00130
return obj;
00131 }
00132 }