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