1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.util;
20
21 import java.io.BufferedReader;
22 import java.io.InputStream;
23 import java.io.IOException;
24
25 import java.io.InputStreamReader;
26
27 import java.net.URL;
28
29 import java.security.AccessController;
30 import java.security.PrivilegedActionException;
31 import java.security.PrivilegedExceptionAction;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Enumeration;
35 import java.util.HashSet;
36 import java.util.List;
37
38 import java.util.Set;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41
42 import javax.faces.FacesException;
43
44
45
46
47
48
49
50 public final class ClassLoaderUtils
51 {
52
53 private ClassLoaderUtils()
54 {
55 }
56
57
58
59
60
61
62
63
64
65
66
67 public static Class<?> loadClass(
68 String name) throws ClassNotFoundException
69 {
70 return loadClass(name, null);
71 }
72
73
74
75
76
77
78
79
80
81
82 public static URL getResource(
83 String name)
84 {
85 return getResource(name, null);
86 }
87
88
89
90
91
92
93
94
95
96
97 public static InputStream getResourceAsStream(
98 String name)
99 {
100 return getResourceAsStream(name, null);
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public static Class<?> loadClass(
116 String name,
117 ClassLoader callerClassLoader) throws ClassNotFoundException
118 {
119 Class<?> clazz = null;
120
121 try
122 {
123 ClassLoader loader = getContextClassLoader();
124
125 if (loader != null)
126 {
127 clazz = loader.loadClass(name);
128 }
129 }
130 catch (ClassNotFoundException e)
131 {
132
133 }
134
135 if (clazz == null)
136 {
137 if (callerClassLoader != null)
138 {
139 clazz = callerClassLoader.loadClass(name);
140 }
141 else
142 {
143 clazz = Class.forName(name);
144 }
145 }
146
147 return clazz;
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161 public static URL getResource(
162 String name,
163 ClassLoader callerClassLoader)
164 {
165 _checkResourceName(name);
166
167 URL url = null;
168
169 ClassLoader loader = getContextClassLoader();
170
171 if (loader != null)
172 {
173 url = loader.getResource(name);
174 }
175
176 if (url == null)
177 {
178 if (callerClassLoader != null)
179 {
180 url = callerClassLoader.getResource(name);
181 }
182 else
183 {
184 url = ClassLoader.getSystemResource(name);
185 }
186 }
187
188 return url;
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202 public static InputStream getResourceAsStream(
203 String name,
204 ClassLoader callerClassLoader)
205 {
206 _checkResourceName(name);
207
208 InputStream stream = null;
209
210 ClassLoader loader = getContextClassLoader();
211
212 if (loader != null)
213 {
214 stream = loader.getResourceAsStream(name);
215 }
216
217 if (stream == null)
218 {
219 if (callerClassLoader != null)
220 {
221 stream = callerClassLoader.getResourceAsStream(name);
222 }
223 else
224 {
225 stream = ClassLoader.getSystemResourceAsStream(name);
226 }
227 }
228
229 return stream;
230 }
231
232
233
234
235
236
237
238 public static ClassLoader getContextClassLoader()
239 {
240 if (System.getSecurityManager() != null)
241 {
242 try
243 {
244 ClassLoader cl = AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
245 {
246 public ClassLoader run() throws PrivilegedActionException
247 {
248 return Thread.currentThread().getContextClassLoader();
249 }
250 });
251 return cl;
252 }
253 catch (PrivilegedActionException pae)
254 {
255 throw new FacesException(pae);
256 }
257 }
258 else
259 {
260 return Thread.currentThread().getContextClassLoader();
261 }
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 @SuppressWarnings("unchecked")
280 public static <T> List<T> getServices(String service)
281 {
282 String serviceUri ="META-INF/services/" + service;
283 ClassLoader loader = Thread.currentThread().getContextClassLoader();
284 try
285 {
286 Enumeration<URL> urls = loader.getResources(serviceUri);
287 if (urls.hasMoreElements())
288 {
289 List<T> services = new ArrayList<T>(1);
290 Set<String> keys = new HashSet<String>(20);
291 do
292 {
293 URL url = urls.nextElement();
294
295 if (_LOG.isLoggable(Level.FINEST))
296 {
297 _LOG.finest("Processing: " + url);
298 }
299 try
300 {
301 BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
302 try
303 {
304 while(true)
305 {
306 String line = in.readLine();
307 if (line == null)
308 {
309 break;
310 }
311
312 String className = _parseLine(line);
313
314 if(className!=null && keys.add(className))
315 {
316 T instance = (T) _getClass(loader, className);
317 services.add(instance);
318 }
319 }
320 }
321 finally
322 {
323 in.close();
324 }
325 }
326 catch (Exception e)
327 {
328 if (_LOG.isLoggable(Level.WARNING))
329 {
330 _LOG.log(Level.WARNING, "Error parsing URL: " + url, e);
331 }
332 }
333 }
334 while(urls.hasMoreElements());
335
336 if (services.size() == 1)
337 {
338 return Collections.singletonList(services.get(0));
339 }
340
341 return Collections.unmodifiableList(services);
342 }
343 }
344 catch (IOException e)
345 {
346 if (_LOG.isLoggable(Level.SEVERE))
347 {
348 _LOG.log(Level.SEVERE, "Error loading Resource: " + serviceUri, e);
349 }
350 }
351
352 return Collections.emptyList();
353 }
354
355 private static String _parseLine(String line)
356 {
357
358 int hashIndex = line.indexOf('#');
359 if (hashIndex >= 0)
360 {
361 line = line.substring(0, hashIndex);
362 }
363
364
365 line = line.trim();
366 if (line.length() > 0)
367 {
368 return line;
369 }
370
371 return null;
372 }
373
374 private static Object _getClass(ClassLoader loader, String className)
375 throws ClassNotFoundException, InstantiationException,
376 IllegalAccessException
377 {
378 Class<?> clazz = loader.loadClass(className);
379 return clazz.newInstance();
380 }
381
382 private static void _checkResourceName(String name)
383 {
384 if ((name != null) && name.startsWith("/"))
385 {
386 if (_LOG.isLoggable(Level.WARNING))
387 {
388 _LOG.log(Level.WARNING, "Resource name not portable: " +name);
389 }
390 }
391 }
392
393 private static final Logger _LOG = Logger.getLogger(ClassLoaderUtils.class.getName());
394 }