1 package org.apache.velocity.tools;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.InputStream;
23 import java.io.IOException;
24 import java.lang.reflect.Field;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Modifier;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Enumeration;
34 import java.util.Iterator;
35 import java.util.LinkedHashSet;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 import org.apache.velocity.util.ArrayIterator;
40 import org.apache.velocity.util.EnumerationIterator;
41
42
43
44
45
46
47
48 public class ClassUtils
49 {
50 public static final ClassUtils INSTANCE = new ClassUtils();
51
52 private ClassUtils() {}
53
54 public ClassUtils getInstance()
55 {
56 return INSTANCE;
57 }
58
59
60 private static final ClassLoader getThreadContextLoader()
61 {
62 return Thread.currentThread().getContextClassLoader();
63 }
64
65 private static final ClassLoader getClassLoader()
66 {
67 return ClassUtils.class.getClassLoader();
68 }
69
70 private static final ClassLoader getCallerLoader(Object caller)
71 {
72 if (caller instanceof Class)
73 {
74 return ((Class)caller).getClassLoader();
75 }
76 else
77 {
78 return caller.getClass().getClassLoader();
79 }
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public static Class getClass(String name) throws ClassNotFoundException
97 {
98 try
99 {
100 return getThreadContextLoader().loadClass(name);
101 }
102 catch (ClassNotFoundException e)
103 {
104 try
105 {
106 return Class.forName(name);
107 }
108 catch (ClassNotFoundException ex)
109 {
110 return getClassLoader().loadClass(name);
111 }
112 }
113 }
114
115 public static Object getInstance(String classname)
116 throws ClassNotFoundException, IllegalAccessException,
117 InstantiationException
118 {
119 return getClass(classname).newInstance();
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public static List<URL> getResources(String name, Object caller)
139 {
140 Set<String> urls = new LinkedHashSet<String>();
141
142
143 addResources(name, urls, getThreadContextLoader());
144
145
146 if (!addResources(name, urls, getClassLoader()))
147 {
148
149 addResource(name, urls, ClassUtils.class);
150 }
151
152
153 if (!addResources(name, urls, getCallerLoader(caller)))
154 {
155
156 addResource(name, urls, caller.getClass());
157 }
158
159 if (!urls.isEmpty())
160 {
161 List<URL> result = new ArrayList<URL>(urls.size());
162 try
163 {
164 for (String url : urls)
165 {
166 result.add(new URL(url));
167 }
168 }
169 catch (MalformedURLException mue)
170 {
171 throw new IllegalStateException("A URL could not be recreated from its own toString() form", mue);
172 }
173 return result;
174 }
175 else if (!name.startsWith("/"))
176 {
177
178 return getResources("/"+name, caller);
179 }
180 else
181 {
182 return Collections.emptyList();
183 }
184 }
185
186 private static final void addResource(String name, Set<String> urls, Class c)
187 {
188 URL url = c.getResource(name);
189 if (url != null)
190 {
191 urls.add(url.toString());
192 }
193 }
194
195 private static final boolean addResources(String name, Set<String> urls,
196 ClassLoader loader)
197 {
198 boolean foundSome = false;
199 try
200 {
201 Enumeration<URL> e = loader.getResources(name);
202 while (e.hasMoreElements())
203 {
204 urls.add(e.nextElement().toString());
205 foundSome = true;
206 }
207 }
208 catch (IOException ioe)
209 {
210
211 }
212 return foundSome;
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 public static URL getResource(String name, Object caller)
231 {
232 URL url = getThreadContextLoader().getResource(name);
233 if (url == null)
234 {
235 url = getClassLoader().getResource(name);
236 if (url == null)
237 {
238 url = ClassUtils.class.getResource(name);
239 if (url == null && caller != null)
240 {
241 Class callingClass = caller.getClass();
242 if (callingClass == Class.class)
243 {
244 callingClass = (Class)caller;
245 }
246 url = callingClass.getResource(name);
247 }
248 }
249 }
250 return url;
251 }
252
253
254
255
256
257
258
259
260
261 public static InputStream getResourceAsStream(String name, Object caller)
262 {
263 URL url = getResource(name, caller);
264 try
265 {
266 return (url == null) ? null : url.openStream();
267 }
268 catch (IOException e)
269 {
270 return null;
271 }
272 }
273
274 public static Method findMethod(Class clazz, String name, Class[] params)
275 throws SecurityException
276 {
277 try
278 {
279
280 return clazz.getMethod(name, params);
281 }
282 catch (NoSuchMethodException nsme)
283 {
284
285 }
286 return findDeclaredMethod(clazz, name, params);
287 }
288
289 public static Method findDeclaredMethod(Class clazz, String name, Class[] params)
290 throws SecurityException
291 {
292 try
293 {
294
295 Method method = clazz.getDeclaredMethod(name, params);
296 if (method != null)
297 {
298
299 method.setAccessible(true);
300 return method;
301 }
302 }
303 catch (NoSuchMethodException nsme)
304 {
305
306 }
307
308
309 Class supclazz = clazz.getSuperclass();
310 if (supclazz != null)
311 {
312
313 return findDeclaredMethod(supclazz, name, params);
314 }
315
316 return null;
317 }
318
319 public static Object getFieldValue(String fieldPath)
320 throws ClassNotFoundException, NoSuchFieldException,
321 SecurityException, IllegalAccessException
322 {
323 int lastDot = fieldPath.lastIndexOf('.');
324 String classname = fieldPath.substring(0, lastDot);
325 String fieldname = fieldPath.substring(lastDot + 1, fieldPath.length());
326
327 Class clazz = getClass(classname);
328 return getFieldValue(clazz, fieldname);
329 }
330
331 public static Object getFieldValue(Class clazz, String fieldname)
332 throws NoSuchFieldException, SecurityException, IllegalAccessException
333 {
334 Field field = clazz.getField(fieldname);
335 int mod = field.getModifiers();
336 if (!Modifier.isStatic(mod))
337 {
338 throw new UnsupportedOperationException("Field "+fieldname+" in class "+clazz.getName()+" is not static. Only static fields are supported.");
339 }
340 return field.get(null);
341 }
342
343
344
345
346
347 public static Iterator getIterator(Object obj)
348 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
349 {
350 if (obj.getClass().isArray())
351 {
352 return new ArrayIterator(obj);
353 }
354 else if (obj instanceof Collection)
355 {
356 return ((Collection) obj).iterator();
357 }
358 else if (obj instanceof Map)
359 {
360 return ((Map) obj).values().iterator();
361 }
362 else if (obj instanceof Iterator)
363 {
364 return ((Iterator) obj);
365 }
366 else if (obj instanceof Iterable)
367 {
368 return ((Iterable)obj).iterator();
369 }
370 else if (obj instanceof Enumeration)
371 {
372 return new EnumerationIterator((Enumeration) obj);
373 }
374 else
375 {
376
377
378
379 Method iter = obj.getClass().getMethod("iterator");
380 if (Iterator.class.isAssignableFrom(iter.getReturnType()))
381 {
382 return (Iterator)iter.invoke(obj);
383 }
384 else
385 {
386 return null;
387 }
388 }
389 }
390
391 }