Clover Coverage Report
Coverage timestamp: Fri May 24 2013 13:47:27 UTC
../../../../img/srcFileCovDistChart5.png 87% of files have more coverage
56   251   31   5.6
28   120   0.55   10
10     3.1  
1    
 
  ResourceLoaderUtility       Line # 34 56 31 50% 0.5
 
  (3)
 
1    /* This file is part of the project "Hilbert II" - http://www.qedeq.org
2    *
3    * Copyright 2000-2013, Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10    * This program is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    * GNU General Public License for more details.
14    */
15   
16    package org.qedeq.base.io;
17   
18    import java.io.File;
19    import java.io.IOException;
20    import java.io.InputStream;
21    import java.lang.reflect.InvocationTargetException;
22    import java.lang.reflect.Method;
23    import java.net.URL;
24   
25    import org.qedeq.base.trace.Trace;
26   
27   
28    /**
29    * Utility methods for accessing classes and resources using an appropriate class loader.
30    * Adapted from org.apache.myfaces.trinidad.util.ClassLoaderUtils.
31    *
32    * @author Michael Meyling
33    */
 
34    public final class ResourceLoaderUtility {
35   
36    /** This class. */
37    private static final Class CLASS = ResourceLoaderUtility.class;
38   
39    /**
40    * Constructor, should never be called.
41    */
 
42  0 toggle private ResourceLoaderUtility() {
43    // don't call me
44    }
45   
46    /**
47    * Loads the class with the specified name. For Java 2 callers, the current thread's context
48    * class loader is preferred, falling back on the system class loader of the caller when the
49    * current thread's context is not set, or the caller is pre Java 2.
50    *
51    * @param name Name of class to load.
52    * @return The resulting <code>Class</code> object
53    * @exception ClassNotFoundException Class was not found.
54    */
 
55  0 toggle public static Class loadClass(final String name) throws ClassNotFoundException {
56  0 return loadClass(name, null);
57    }
58   
59    /**
60    * Locates the resource with the specified name. For Java 2 callers, the current thread's
61    * context class loader is preferred, falling back on the system class loader of the caller when
62    * the current thread's context is not set, or the caller is pre Java 2.
63    *
64    * @param name Resource name.
65    * @return Resulting <code>URL</code> object. Maybe <code>null</code>.
66    */
 
67  2 toggle public static URL getResourceUrl(final String name) {
68  2 return getResourceUrl(name, ResourceLoaderUtility.class.getClassLoader());
69    }
70   
71    /**
72    * Locates the stream resource with the specified name. For Java 2 callers, the current thread's
73    * context class loader is preferred, falling back on the system class loader of the caller when
74    * the current thread's context is not set, or the caller is pre Java 2.
75    *
76    * @param name the name of the resource
77    * @return the resulting <code>InputStream</code> object
78    */
 
79  1 toggle public static InputStream getResourceAsStream(final String name) {
80  1 return getResourceAsStream(name, null);
81    }
82   
83    /**
84    * Loads the class with the specified name. For Java 2 callers, the current thread's context
85    * class loader is preferred, falling back on the class loader of the caller when the current
86    * thread's context is not set, or the caller is pre Java 2. If the callerClassLoader is null,
87    * then fall back on the system class loader.
88    *
89    * @param name the name of the class
90    * @param callerClassLoader the calling class loader context
91    * @return the resulting <code>Class</code> object
92    * @exception ClassNotFoundException if the class was not found
93    */
 
94  0 toggle public static Class loadClass(final String name, final ClassLoader callerClassLoader)
95    throws ClassNotFoundException {
96  0 Class clazz = null;
97   
98  0 try {
99  0 final ClassLoader loader = getContextClassLoader();
100   
101  0 if (loader != null) {
102  0 clazz = loader.loadClass(name);
103    }
104    } catch (ClassNotFoundException e) {
105    // treat as though loader not set
106    }
107   
108  0 if (clazz == null) {
109  0 if (callerClassLoader != null) {
110  0 clazz = callerClassLoader.loadClass(name);
111    } else {
112  0 clazz = Class.forName(name);
113    }
114    }
115   
116  0 return clazz;
117    }
118   
119    /**
120    * Locates the resource with the specified name. For Java 2 callers, the current thread's
121    * context class loader is preferred, falling back on the class loader of the caller when the
122    * current thread's context is not set, or the caller is pre Java 2. If the callerClassLoader is
123    * null, then fall back on the system class loader.
124    *
125    * @param name the name of the resource
126    * @param callerClassLoader the calling class loader context
127    * @return the resulting <code>URL</code> object
128    */
 
129  2 toggle public static URL getResourceUrl(final String name, final ClassLoader callerClassLoader) {
130  2 checkResourceName(name);
131   
132  2 URL url = null;
133   
134  2 final ClassLoader loader = getContextClassLoader();
135   
136  2 if (loader != null) {
137  2 url = loader.getResource(name);
138    }
139   
140  2 if (url == null) {
141    // no success, now we try the given class loader
142  0 if (callerClassLoader != null) {
143  0 url = callerClassLoader.getResource(name);
144    } else {
145    // last try: get resource via classpath
146  0 url = ClassLoader.getSystemResource(name);
147    }
148    }
149  2 return url;
150    }
151   
152    /**
153    * Locates the resource stream with the specified name. For Java 2 callers, the current thread's
154    * context class loader is preferred, falling back on the class loader of the caller when the
155    * current thread's context is not set, or the caller is pre Java 2. If the callerClassLoader is
156    * null, then fall back on the system class loader.
157    *
158    * @param name the name of the resource
159    * @param callerClassLoader the calling class loader context
160    * @return the resulting <code>InputStream</code> object
161    */
 
162  1 toggle public static InputStream getResourceAsStream(final String name,
163    final ClassLoader callerClassLoader) {
164  1 checkResourceName(name);
165   
166  1 InputStream stream = null;
167   
168  1 final ClassLoader loader = getContextClassLoader();
169   
170  1 if (loader != null) {
171  1 stream = loader.getResourceAsStream(name);
172    }
173  1 if (stream == null) {
174  0 if (callerClassLoader != null) {
175  0 stream = callerClassLoader.getResourceAsStream(name);
176    } else {
177  0 stream = ClassLoader.getSystemResourceAsStream(name);
178    }
179    }
180   
181  1 return stream;
182    }
183   
184    /**
185    * Dynamically accesses the current context class loader. Returns <code>null</code> if there is
186    * no per-thread context class loader. Also if the JRE is below 1.2 or something else went wrong
187    * the method returns <code>null</code>.
188    *
189    * @return ClassLoader.
190    */
 
191  3 toggle public static ClassLoader getContextClassLoader() {
192  3 try {
193  3 final Method method = Thread.class.getMethod("getContextClassLoader", null);
194  3 return (ClassLoader) method.invoke(Thread.currentThread(), null);
195    } catch (RuntimeException e) {
196  0 return null;
197    } catch (IllegalAccessException e) {
198  0 return null;
199    } catch (InvocationTargetException e) {
200  0 return null;
201    } catch (NoSuchMethodException e) {
202  0 return null;
203    }
204    }
205   
 
206  3 toggle private static void checkResourceName(final String name) {
207  3 if ((name != null) && name.startsWith("/")) {
208  0 Trace.info(CLASS, "ClassLoaderUtility", "checkResourceName",
209    "resource name not portable: " + name);
210   
211    }
212    }
213   
214    /**
215    * Get resource file. The resource is located within the file system if it exists already.
216    * If not it is loaded as resource and then saved as a file.
217    *
218    * @param startDirectory Start looking from this directory.
219    * @param resourceDirectoryName Within this directory
220    * (relative to <code>startDirectory</code>).
221    * @param resourceName Look for this resource file.
222    * @return Resource file.
223    */
 
224  3 toggle public static File getResourceFile(final File startDirectory,
225    final String resourceDirectoryName, final String resourceName) {
226  3 final File resourceDir = new File(startDirectory, resourceDirectoryName);
227  3 final File resource = new File(resourceDir, resourceName);
228  3 if (!resource.exists()) {
229  1 final URL url = getResourceUrl(resourceDirectoryName + "/" + resourceName);
230  1 if (url == null) {
231  0 Trace.info(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
232    "URL not found for: " + resourceDirectoryName + "/" + resourceName);
233  0 return null;
234    }
235  1 try {
236  1 if (!resourceDir.exists()) {
237  1 if (!resourceDir.mkdirs()) {
238  0 Trace.info(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
239    "creation failed: " + resourceDir);
240    }
241    }
242  1 IoUtility.saveFile(url, resource);
243    } catch (IOException e) {
244  0 Trace.fatal(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
245    "resource can not be saved", e);
246    }
247    }
248  3 return resource;
249    }
250   
251    }