1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.plugin;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.net.URLClassLoader;
24 import java.util.Enumeration;
25
26 import org.kuali.rice.core.lifecycle.Lifecycle;
27 import org.kuali.rice.kew.util.SimpleEnumeration;
28
29
30
31
32
33
34
35 public class PluginClassLoader extends URLClassLoader implements Lifecycle {
36 static final String CLASSES_DIR = "classes";
37 static final String LIB_DIR = "lib";
38 private static final String[] SYSTEM_CLASSES = new String[] { "java.", "javax.servlet.", "javax.xml.", "javax.management.", "org.xml.", "org.w3c." };
39
40
41
42 private PluginConfig config;
43 private boolean started = false;
44
45 public PluginClassLoader() {
46 super(new URL[0]);
47 }
48
49 public PluginClassLoader(ClassLoader parent) {
50 super(new URL[0], parent);
51 }
52
53 public PluginClassLoader(ClassLoader parent, File sharedDirectory, File pluginDirectory) throws MalformedURLException {
54 super(new URL[0], parent);
55 if (sharedDirectory != null) {
56 addClassesDirectory(new File(sharedDirectory, CLASSES_DIR));
57 addLibDirectory(new File(sharedDirectory, LIB_DIR));
58 }
59 addClassesDirectory(new File(pluginDirectory, CLASSES_DIR));
60 addLibDirectory(new File(pluginDirectory, LIB_DIR));
61 }
62
63 public void addClassesDirectory(File classesDir) throws MalformedURLException {
64 if (classesDir != null && classesDir.isDirectory()) {
65 addURL(classesDir.toURL());
66 }
67 }
68
69 public void addLibDirectory(File libDir) throws MalformedURLException {
70 File[] jars = PluginUtils.findJars(libDir);
71 for (int index = 0; index < jars.length; index++) {
72 addURL(jars[index].toURL());
73 }
74 }
75
76 public Class loadClass(String className) throws ClassNotFoundException {
77 return loadClass(className, false);
78 }
79
80 public void addURL(URL url) {
81 super.addURL(url);
82
83 }
84
85
86
87
88
89 public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
90 Class loadedClass = loadExistingClass(name, resolve);
91 if (loadedClass != null) {
92 return loadedClass;
93 }
94 loadedClass = loadSystemClass(name, resolve);
95 if (loadedClass != null) {
96 return loadedClass;
97 }
98 loadedClass = loadLocalClass(name, resolve);
99 if (loadedClass != null) {
100 return loadedClass;
101 }
102 loadedClass = loadParentClass(name, resolve);
103 if (loadedClass != null) {
104 return loadedClass;
105 }
106 throw new ClassNotFoundException(name);
107 }
108
109 public URL getResource(String name) {
110 URL resource = findResource(name);
111 if (resource == null) {
112 resource = getParent().getResource(name);
113 }
114 return resource;
115 }
116
117 public Enumeration<URL> getResources(String name) throws IOException {
118 Enumeration<URL> localResources = findResources(name);
119 Enumeration<URL> parentResources = getParent().getResources(name);
120 return new SimpleEnumeration<URL>(localResources, parentResources);
121 }
122
123
124
125 private Class loadExistingClass(String name, boolean resolve) {
126 Class loadedClass = findLoadedClass(name);
127 if (loadedClass != null && resolve) {
128 resolveClass(loadedClass);
129 }
130 return loadedClass;
131 }
132
133 private Class loadSystemClass(String name, boolean resolve) {
134 Class loadedClass = null;
135 if (isSystemClass(name)) {
136 try {
137 loadedClass = getSystemClassLoader().loadClass(name);
138 if (loadedClass != null && resolve) {
139 resolveClass(loadedClass);
140 }
141 } catch (ClassNotFoundException e) {
142
143 }
144 }
145 return loadedClass;
146 }
147
148 private Class loadLocalClass(String name, boolean resolve) {
149 Class loadedClass = null;
150 try {
151 loadedClass = findClass(name);
152 if (loadedClass != null && resolve) {
153 resolveClass(loadedClass);
154 }
155 } catch (ClassNotFoundException e) {
156
157 }
158 return loadedClass;
159 }
160
161 private Class loadParentClass(String name, boolean resolve) {
162 Class loadedClass = null;
163 try {
164 loadedClass = getParent().loadClass(name);
165 if (loadedClass != null && resolve) {
166 resolveClass(loadedClass);
167 }
168 } catch (ClassNotFoundException e) {
169
170 }
171 return loadedClass;
172 }
173
174
175
176
177
178
179
180
181 private boolean isSystemClass(String name) {
182 name = name.replace('/','.');
183 while(name.startsWith(".")) {
184 name=name.substring(1);
185 }
186 for (int index = 0; index < SYSTEM_CLASSES.length; index++) {
187 String systemClass = SYSTEM_CLASSES[index];
188 if (systemClass.endsWith(".")) {
189 if (name.startsWith(systemClass)) {
190 return true;
191 }
192 }
193 else if (name.equals(systemClass)) {
194 return true;
195 }
196 }
197 return false;
198 }
199
200 public String toString() {
201 StringBuffer sb = new StringBuffer("[PluginClassLoader: urls=");
202 URL[] urls = getURLs();
203 if (urls == null) {
204 sb.append("null");
205 } else {
206 for (int i = 0; i < urls.length; i++) {
207 sb.append(urls[i]);
208 sb.append(",");
209 }
210
211 if (urls.length > 1) {
212 sb.setLength(sb.length() - 1);
213 }
214 }
215 sb.append("]");
216 return sb.toString();
217 }
218
219 public PluginConfig getConfig() {
220 return config;
221 }
222
223 public void setConfig(PluginConfig config) {
224 this.config = config;
225 }
226
227 public void start() {
228 started = true;
229 }
230
231 public void stop() {
232 config = null;
233 started = false;
234 }
235
236 public boolean isStarted() {
237 return started;
238 }
239 }