1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.ws.security.util;
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.net.URL;
24 import java.security.AccessController;
25 import java.security.PrivilegedAction;
26
27 /**
28 * Load resources (or images) from various sources.
29 * <p/>
30 *
31 * @author Davanum Srinivas (dims@yahoo.com).
32 */
33 public final class Loader {
34 private static org.apache.commons.logging.Log log =
35 org.apache.commons.logging.LogFactory.getLog(Loader.class);
36
37 private Loader() {
38 // Complete
39 }
40
41 /**
42 * This method will search for <code>resource</code> in different
43 * places. The search order is as follows:
44 * <ol>
45 * <p><li>Search for <code>resource</code> using the thread context
46 * class loader under Java2.
47 * <p><li>Try one last time with
48 * <code>ClassLoader.getSystemResource(resource)</code>, that is is
49 * using the system class loader in JDK 1.2 and virtual machine's
50 * built-in class loader in JDK 1.1.
51 * </ol>
52 * <p/>
53 *
54 * @param resource
55 * @return TODO
56 */
57 public static URL getResource(String resource) {
58 URL url = null;
59 try {
60 ClassLoader classLoader = getTCL();
61 if (classLoader != null) {
62 log.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
63 url = classLoader.getResource(resource);
64 if (url == null && resource.startsWith("/")) {
65 //certain classloaders need it without the leading /
66 url = classLoader.getResource(resource.substring(1));
67 }
68 if (url != null) {
69 return url;
70 }
71 }
72 } catch (Throwable t) {
73 log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
74 }
75
76 ClassLoader cluClassloader = Loader.class.getClassLoader();
77 if (cluClassloader == null) {
78 cluClassloader = ClassLoader.getSystemClassLoader();
79 }
80 url = cluClassloader.getResource(resource);
81 if (url == null && resource.startsWith("/")) {
82 //certain classloaders need it without the leading /
83 url = cluClassloader.getResource(resource.substring(1));
84 }
85 if (url != null) {
86 return url;
87 }
88
89 // Last ditch attempt: get the resource from the class path. It
90 // may be the case that clazz was loaded by the Extension class
91 // loader which the parent of the system class loader. Hence the
92 // code below.
93 log.debug("Trying to find [" + resource + "] using ClassLoader.getSystemResource().");
94 return ClassLoader.getSystemResource(resource);
95 }
96
97
98 /**
99 * This method will search for <code>resource</code> in different
100 * places. The search order is as follows:
101 * <ol>
102 * <p><li>Search for <code>resource</code> using the supplied class loader.
103 * If that fails, search for <code>resource</code> using the thread context
104 * class loader.
105 * <p><li>Try one last time with
106 * <code>ClassLoader.getSystemResource(resource)</code>, that is is
107 * using the system class loader in JDK 1.2 and virtual machine's
108 * built-in class loader in JDK 1.1.
109 * </ol>
110 * <p/>
111 *
112 * @param resource
113 * @return TODO
114 */
115 public static URL getResource(ClassLoader loader, String resource) {
116 URL url = null;
117 try {
118 if (loader != null) {
119 log.debug("Trying to find [" + resource + "] using " + loader + " class loader.");
120 url = loader.getResource(resource);
121 if (url == null && resource.startsWith("/")) {
122 //certain classloaders need it without the leading /
123 url = loader.getResource(resource.substring(1));
124 }
125 if (url != null) {
126 return url;
127 }
128 }
129 } catch (Throwable t) {
130 log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
131 }
132 return getResource(resource);
133 }
134
135 /**
136 * Get the Thread context class loader.
137 * <p/>
138 *
139 * @return the Thread context class loader
140 * @throws IllegalAccessException
141 * @throws InvocationTargetException
142 */
143 public static ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
144 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
145 public ClassLoader run() {
146 return Thread.currentThread().getContextClassLoader();
147 }
148 });
149 }
150
151 /**
152 * Get the class loader of the class argument
153 * <p/>
154 *
155 * @return the class loader of the argument
156 */
157 public static ClassLoader getClassLoader(final Class<?> clazz) {
158 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
159 public ClassLoader run() {
160 return clazz.getClassLoader();
161 }
162 });
163 }
164
165 /**
166 * Try the specified classloader and then fall back to the loadClass
167 * <p/>
168 *
169 * @param loader
170 * @param clazz
171 * @return Class
172 * @throws ClassNotFoundException
173 */
174 public static Class<?> loadClass(ClassLoader loader, String clazz) throws ClassNotFoundException {
175 try {
176 if (loader != null) {
177 Class<?> c = loader.loadClass(clazz);
178 if (c != null) {
179 return c;
180 }
181 }
182 } catch (Throwable e) {
183 log.warn(e.getMessage(), e);
184 }
185 return loadClass(clazz, true);
186 }
187
188 /**
189 * Try the specified classloader and then fall back to the loadClass
190 * <p/>
191 *
192 * @param loader
193 * @param clazz
194 * @param type
195 * @return Class
196 * @throws ClassNotFoundException
197 */
198 public static <T> Class<? extends T> loadClass(ClassLoader loader,
199 String clazz,
200 Class<T> type) throws ClassNotFoundException {
201 try {
202 if (loader != null) {
203 Class<?> c = loader.loadClass(clazz);
204 if (c != null) {
205 return c.asSubclass(type);
206 }
207 }
208 } catch (Throwable e) {
209 log.warn(e.getMessage(), e);
210 }
211 return loadClass(clazz, true, type);
212 }
213 /**
214 * If running under JDK 1.2 load the specified class using the
215 * <code>Thread</code> <code>contextClassLoader</code> if that
216 * fails try Class.forname.
217 * <p/>
218 *
219 * @param clazz
220 * @return TODO
221 * @throws ClassNotFoundException
222 */
223 public static Class<?> loadClass(String clazz) throws ClassNotFoundException {
224 return loadClass(clazz, true);
225 }
226 /**
227 * If running under JDK 1.2 load the specified class using the
228 * <code>Thread</code> <code>contextClassLoader</code> if that
229 * fails try Class.forname.
230 * <p/>
231 *
232 * @param clazz
233 * @param type Type to cast it to
234 * @return TODO
235 * @throws ClassNotFoundException
236 */
237 public static <T> Class<? extends T> loadClass(String clazz, Class<T> type)
238 throws ClassNotFoundException {
239 return loadClass(clazz, true, type);
240 }
241
242 public static <T> Class<? extends T> loadClass(String clazz,
243 boolean warn,
244 Class<T> type) throws ClassNotFoundException {
245 return loadClass(clazz, warn).asSubclass(type);
246 }
247 public static Class<?> loadClass(String clazz, boolean warn) throws ClassNotFoundException {
248 try {
249 ClassLoader tcl = getTCL();
250
251 if (tcl != null) {
252 Class<?> c = tcl.loadClass(clazz);
253 if (c != null) {
254 return c;
255 }
256 }
257 } catch (Throwable e) {
258 if (warn) {
259 log.warn(e.getMessage(), e);
260 } else {
261 log.debug(e.getMessage(), e);
262 }
263 }
264
265 return loadClass2(clazz, null);
266 }
267
268 private static Class<?> loadClass2(String className, Class<?> callingClass)
269 throws ClassNotFoundException {
270 try {
271 return Class.forName(className);
272 } catch (ClassNotFoundException ex) {
273 try {
274 if (Loader.class.getClassLoader() != null) {
275 return Loader.class.getClassLoader().loadClass(className);
276 }
277 } catch (ClassNotFoundException exc) {
278 if (callingClass != null && callingClass.getClassLoader() != null) {
279 return callingClass.getClassLoader().loadClass(className);
280 }
281 }
282 throw ex;
283 }
284 }
285 }