1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
package org.mule.registry; |
12 | |
|
13 | |
import org.mule.util.FileUtils; |
14 | |
|
15 | |
import java.net.MalformedURLException; |
16 | |
import java.net.URL; |
17 | |
import java.net.URLClassLoader; |
18 | |
import java.security.SecureClassLoader; |
19 | |
import java.util.ArrayList; |
20 | |
import java.util.HashMap; |
21 | |
import java.util.Iterator; |
22 | |
import java.util.List; |
23 | |
import java.util.Map; |
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
public class ClassLoaderFactory |
29 | |
{ |
30 | |
|
31 | |
private static ClassLoaderFactory factory; |
32 | |
private Map sharedClassLoaders; |
33 | |
|
34 | |
public static ClassLoaderFactory getInstance() |
35 | |
{ |
36 | 0 | if (factory == null) |
37 | |
{ |
38 | 0 | factory = new ClassLoaderFactory(); |
39 | |
} |
40 | 0 | return factory; |
41 | |
} |
42 | |
|
43 | |
private ClassLoaderFactory() |
44 | 0 | { |
45 | 0 | this.sharedClassLoaders = new HashMap(); |
46 | 0 | } |
47 | |
|
48 | |
public ClassLoader createComponentClassLoader(RegistryComponent component) throws MalformedURLException |
49 | |
{ |
50 | 0 | DelegatingClassLoader dcl = new DelegatingClassLoader(); |
51 | 0 | Library[] libraries = component.getLibraries(); |
52 | 0 | for (int i = 0; i < libraries.length; i++) |
53 | |
{ |
54 | 0 | dcl.addClassLoader(getSharedClassLoader(libraries[i])); |
55 | |
} |
56 | 0 | URL[] urls = getUrlsFrom(component.getInstallRoot(), component.getClassPathElements()); |
57 | 0 | boolean isParentFirst = component.isClassLoaderParentFirst(); |
58 | 0 | JbiClassLoader ccl = new JbiClassLoader(urls, dcl, isParentFirst); |
59 | 0 | return ccl; |
60 | |
} |
61 | |
|
62 | |
private ClassLoader getSharedClassLoader(Library library) throws MalformedURLException |
63 | |
{ |
64 | 0 | ClassLoader cl = (ClassLoader)this.sharedClassLoaders.get(library.getName()); |
65 | 0 | if (cl == null) |
66 | |
{ |
67 | 0 | URL[] urls = getUrlsFrom(library.getInstallRoot(), library.getClassPathElements()); |
68 | 0 | boolean isParentFirst = library.isClassLoaderParentFirst(); |
69 | 0 | cl = new JbiClassLoader(urls, null, isParentFirst); |
70 | 0 | this.sharedClassLoaders.put(library.getName(), cl); |
71 | |
} |
72 | 0 | return cl; |
73 | |
} |
74 | |
|
75 | |
private URL[] getUrlsFrom(String root, List paths) throws MalformedURLException |
76 | |
{ |
77 | 0 | URL[] urls = new URL[paths.size()]; |
78 | 0 | for (int i = 0; i < urls.length; i++) |
79 | |
{ |
80 | 0 | String cpElement = (String)paths.get(i); |
81 | 0 | urls[i] = FileUtils.newFile(root, cpElement).toURL(); |
82 | |
} |
83 | 0 | return urls; |
84 | |
} |
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
public static class JbiClassLoader extends URLClassLoader |
93 | |
{ |
94 | |
|
95 | |
private boolean parentFirst; |
96 | |
|
97 | |
public JbiClassLoader(URL[] urls, ClassLoader parent, boolean parentFirst) |
98 | |
{ |
99 | 0 | super(urls, parent); |
100 | 0 | this.parentFirst = parentFirst; |
101 | 0 | } |
102 | |
|
103 | |
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException |
104 | |
{ |
105 | |
|
106 | 0 | Class clazz = findLoadedClass(name); |
107 | 0 | if (clazz == null) |
108 | |
{ |
109 | 0 | if (this.parentFirst) |
110 | |
{ |
111 | |
try |
112 | |
{ |
113 | 0 | clazz = getParent().loadClass(name); |
114 | |
} |
115 | 0 | catch (ClassNotFoundException cnfe) |
116 | |
{ |
117 | 0 | clazz = findClass(name); |
118 | 0 | } |
119 | |
} |
120 | |
else |
121 | |
{ |
122 | |
try |
123 | |
{ |
124 | 0 | clazz = findClass(name); |
125 | |
} |
126 | 0 | catch (ClassNotFoundException e) |
127 | |
{ |
128 | 0 | clazz = getParent().loadClass(name); |
129 | 0 | } |
130 | |
} |
131 | |
} |
132 | 0 | if (resolve) |
133 | |
{ |
134 | 0 | resolveClass(clazz); |
135 | |
} |
136 | 0 | return clazz; |
137 | |
} |
138 | |
} |
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
public static class DelegatingClassLoader extends SecureClassLoader |
146 | |
{ |
147 | |
private List loaders; |
148 | |
|
149 | |
public DelegatingClassLoader() |
150 | 0 | { |
151 | 0 | this.loaders = new ArrayList(); |
152 | 0 | } |
153 | |
|
154 | |
public void addClassLoader(ClassLoader loader) |
155 | |
{ |
156 | 0 | if (loader == null) |
157 | |
{ |
158 | 0 | throw new IllegalArgumentException("loader can not be null"); |
159 | |
} |
160 | 0 | loaders.add(loader); |
161 | 0 | } |
162 | |
|
163 | |
protected Class findClass(String name) throws ClassNotFoundException |
164 | |
{ |
165 | 0 | for (Iterator iter = this.loaders.iterator(); iter.hasNext();) |
166 | |
{ |
167 | 0 | ClassLoader loader = (ClassLoader)iter.next(); |
168 | |
try |
169 | |
{ |
170 | 0 | return loader.loadClass(name); |
171 | |
} |
172 | 0 | catch (ClassNotFoundException e) |
173 | |
{ |
174 | |
|
175 | 0 | } |
176 | |
} |
177 | 0 | throw new ClassNotFoundException(name); |
178 | |
} |
179 | |
} |
180 | |
|
181 | |
} |