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 if (factory == null)
37 {
38 factory = new ClassLoaderFactory();
39 }
40 return factory;
41 }
42
43 private ClassLoaderFactory()
44 {
45 this.sharedClassLoaders = new HashMap();
46 }
47
48 public ClassLoader createComponentClassLoader(RegistryComponent component) throws MalformedURLException
49 {
50 DelegatingClassLoader dcl = new DelegatingClassLoader();
51 Library[] libraries = component.getLibraries();
52 for (int i = 0; i < libraries.length; i++)
53 {
54 dcl.addClassLoader(getSharedClassLoader(libraries[i]));
55 }
56 URL[] urls = getUrlsFrom(component.getInstallRoot(), component.getClassPathElements());
57 boolean isParentFirst = component.isClassLoaderParentFirst();
58 JbiClassLoader ccl = new JbiClassLoader(urls, dcl, isParentFirst);
59 return ccl;
60 }
61
62 private ClassLoader getSharedClassLoader(Library library) throws MalformedURLException
63 {
64 ClassLoader cl = (ClassLoader)this.sharedClassLoaders.get(library.getName());
65 if (cl == null)
66 {
67 URL[] urls = getUrlsFrom(library.getInstallRoot(), library.getClassPathElements());
68 boolean isParentFirst = library.isClassLoaderParentFirst();
69 cl = new JbiClassLoader(urls, null, isParentFirst);
70 this.sharedClassLoaders.put(library.getName(), cl);
71 }
72 return cl;
73 }
74
75 private URL[] getUrlsFrom(String root, List paths) throws MalformedURLException
76 {
77 URL[] urls = new URL[paths.size()];
78 for (int i = 0; i < urls.length; i++)
79 {
80 String cpElement = (String)paths.get(i);
81 urls[i] = FileUtils.newFile(root, cpElement).toURL();
82 }
83 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 super(urls, parent);
100 this.parentFirst = parentFirst;
101 }
102
103 protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException
104 {
105
106 Class clazz = findLoadedClass(name);
107 if (clazz == null)
108 {
109 if (this.parentFirst)
110 {
111 try
112 {
113 clazz = getParent().loadClass(name);
114 }
115 catch (ClassNotFoundException cnfe)
116 {
117 clazz = findClass(name);
118 }
119 }
120 else
121 {
122 try
123 {
124 clazz = findClass(name);
125 }
126 catch (ClassNotFoundException e)
127 {
128 clazz = getParent().loadClass(name);
129 }
130 }
131 }
132 if (resolve)
133 {
134 resolveClass(clazz);
135 }
136 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 {
151 this.loaders = new ArrayList();
152 }
153
154 public void addClassLoader(ClassLoader loader)
155 {
156 if (loader == null)
157 {
158 throw new IllegalArgumentException("loader can not be null");
159 }
160 loaders.add(loader);
161 }
162
163 protected Class findClass(String name) throws ClassNotFoundException
164 {
165 for (Iterator iter = this.loaders.iterator(); iter.hasNext();)
166 {
167 ClassLoader loader = (ClassLoader)iter.next();
168 try
169 {
170 return loader.loadClass(name);
171 }
172 catch (ClassNotFoundException e)
173 {
174
175 }
176 }
177 throw new ClassNotFoundException(name);
178 }
179 }
180
181 }