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