EMMA Coverage Report (generated Fri Feb 14 08:28:31 UTC 2014)
[all classes][org.qedeq.base.io]

COVERAGE SUMMARY FOR SOURCE FILE [ResourceLoaderUtility.java]

nameclass, %method, %block, %line, %
ResourceLoaderUtility.java100% (1/1)73%  (8/11)46%  (118/256)47%  (30.5/65)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ResourceLoaderUtility100% (1/1)73%  (8/11)46%  (118/256)47%  (30.5/65)
ResourceLoaderUtility (): void 0%   (0/1)0%   (0/3)0%   (0/2)
loadClass (String): Class 0%   (0/1)0%   (0/4)0%   (0/1)
loadClass (String, ClassLoader): Class 0%   (0/1)0%   (0/26)0%   (0/11)
checkResourceName (String): void 100% (1/1)37%  (7/19)67%  (2/3)
getResourceFile (File, String, String): File 100% (1/1)43%  (41/96)67%  (10/15)
getResourceUrl (String): URL 100% (1/1)58%  (7/12)58%  (0.6/1)
getContextClassLoader (): ClassLoader 100% (1/1)60%  (18/30)20%  (2/10)
getResourceAsStream (String, ClassLoader): InputStream 100% (1/1)62%  (16/26)70%  (7/10)
getResourceUrl (String, ClassLoader): URL 100% (1/1)62%  (16/26)70%  (7/10)
<static initializer> 100% (1/1)90%  (9/10)90%  (0.9/1)
getResourceAsStream (String): InputStream 100% (1/1)100% (4/4)100% (1/1)

1/* This file is part of the project "Hilbert II" - http://www.qedeq.org
2 *
3 * Copyright 2000-2014,  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 
16package org.qedeq.base.io;
17 
18import java.io.File;
19import java.io.IOException;
20import java.io.InputStream;
21import java.lang.reflect.InvocationTargetException;
22import java.lang.reflect.Method;
23import java.net.URL;
24 
25import 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 */
34public 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    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    public static Class loadClass(final String name) throws ClassNotFoundException {
56        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    public static URL getResourceUrl(final String name) {
68        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    public static InputStream getResourceAsStream(final String name) {
80        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    public static Class loadClass(final String name, final ClassLoader callerClassLoader)
95            throws ClassNotFoundException {
96        Class clazz = null;
97 
98        try {
99            final ClassLoader loader = getContextClassLoader();
100 
101            if (loader != null) {
102                clazz = loader.loadClass(name);
103            }
104        } catch (ClassNotFoundException e) {
105            // treat as though loader not set
106        }
107 
108        if (clazz == null) {
109            if (callerClassLoader != null) {
110                clazz = callerClassLoader.loadClass(name);
111            } else {
112                clazz = Class.forName(name);
113            }
114        }
115 
116        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    public static URL getResourceUrl(final String name, final ClassLoader callerClassLoader) {
130        checkResourceName(name);
131 
132        URL url = null;
133 
134        final ClassLoader loader = getContextClassLoader();
135 
136        if (loader != null) {
137            url = loader.getResource(name);
138        }
139 
140        if (url == null) {
141            // no success, now we try the given class loader
142            if (callerClassLoader != null) {
143                url = callerClassLoader.getResource(name);
144            } else {
145                // last try: get resource via classpath
146                url = ClassLoader.getSystemResource(name);
147            }
148        }
149        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    public static InputStream getResourceAsStream(final String name,
163            final ClassLoader callerClassLoader) {
164        checkResourceName(name);
165 
166        InputStream stream = null;
167 
168        final ClassLoader loader = getContextClassLoader();
169 
170        if (loader != null) {
171            stream = loader.getResourceAsStream(name);
172        }
173        if (stream == null) {
174            if (callerClassLoader != null) {
175                stream = callerClassLoader.getResourceAsStream(name);
176            } else {
177                stream = ClassLoader.getSystemResourceAsStream(name);
178            }
179        }
180 
181        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    public static ClassLoader getContextClassLoader() {
192        try {
193            final Method method = Thread.class.getMethod("getContextClassLoader", null);
194            return (ClassLoader) method.invoke(Thread.currentThread(), null);
195        } catch (RuntimeException e) {
196            return null;
197        } catch (IllegalAccessException e) {
198            return null;
199        } catch (InvocationTargetException e) {
200            return null;
201        } catch (NoSuchMethodException e) {
202            return null;
203        }
204    }
205 
206    private static void checkResourceName(final String name) {
207        if ((name != null) && name.startsWith("/")) {
208            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    public static File getResourceFile(final File startDirectory,
225            final String resourceDirectoryName, final String resourceName) {
226        final File resourceDir = new File(startDirectory, resourceDirectoryName);
227        final File resource = new File(resourceDir, resourceName);
228        if (!resource.exists()) {
229            final URL url = getResourceUrl(resourceDirectoryName + "/" + resourceName);
230            if (url == null) {
231                Trace.info(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
232                    "URL not found for: " + resourceDirectoryName + "/" + resourceName);
233                return null;
234            }
235            try {
236                if (!resourceDir.exists()) {
237                    if (!resourceDir.mkdirs()) {
238                        Trace.info(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
239                            "creation failed: " + resourceDir);
240                    }
241                }
242                IoUtility.saveFile(url, resource);
243            } catch (IOException e) {
244                Trace.fatal(ResourceLoaderUtility.class, "getResourceUrlAndMakeLocalCopy",
245                    "resource can not be saved", e);
246            }
247        }
248        return resource;
249    }
250 
251}

[all classes][org.qedeq.base.io]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov