View Javadoc

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 }