001: package com.opensymphony.module.sitemesh.util;
002:
003: import java.net.URL;
004: import java.io.InputStream;
005: import java.io.IOException;
006:
007: /**
008: * This class is extremely useful for loading resources and classes in a fault tolerant manner
009: * that works across different applications servers.
010: *
011: * It has come out of many months of frustrating use of multiple application servers at Atlassian,
012: * please don't change things unless you're sure they're not going to break in one server or another!
013: */
014: public class ClassLoaderUtil {
015:
016: /**
017: * Load a given resource.
018: *
019: * This method will try to load the resource using the following methods (in order):
020: * <ul>
021: * <li>From Thread.currentThread().getContextClassLoader()
022: * <li>From ClassLoaderUtil.class.getClassLoader()
023: * <li>callingClass.getClassLoader()
024: * </ul>
025: *
026: * @param resourceName The name of the resource to load
027: * @param callingClass The Class object of the calling object
028: */
029: public static URL getResource(String resourceName,
030: Class callingClass) {
031: URL url = Thread.currentThread().getContextClassLoader()
032: .getResource(resourceName);
033:
034: if (url == null) {
035: url = ClassLoaderUtil.class.getClassLoader().getResource(
036: resourceName);
037: }
038:
039: if (url == null) {
040: ClassLoader cl = callingClass.getClassLoader();
041:
042: if (cl != null) {
043: url = cl.getResource(resourceName);
044: }
045: }
046:
047: if ((url == null) && (resourceName != null)
048: && (resourceName.charAt(0) != '/')) {
049: return getResource('/' + resourceName, callingClass);
050: }
051:
052: return url;
053: }
054:
055: /**
056: * This is a convenience method to load a resource as a stream.
057: *
058: * The algorithm used to find the resource is given in getResource()
059: *
060: * @param resourceName The name of the resource to load
061: * @param callingClass The Class object of the calling object
062: */
063: public static InputStream getResourceAsStream(String resourceName,
064: Class callingClass) {
065: URL url = getResource(resourceName, callingClass);
066:
067: try {
068: return (url != null) ? url.openStream() : null;
069: } catch (IOException e) {
070: return null;
071: }
072: }
073:
074: /**
075: * Load a class with a given name.
076: *
077: * It will try to load the class in the following order:
078: * <ul>
079: * <li>From Thread.currentThread().getContextClassLoader()
080: * <li>Using the basic Class.forName()
081: * <li>From ClassLoaderUtil.class.getClassLoader()
082: * <li>From the callingClass.getClassLoader()
083: * </ul>
084: *
085: * @param className The name of the class to load
086: * @param callingClass The Class object of the calling object
087: * @throws ClassNotFoundException If the class cannot be found anywhere.
088: */
089: public static Class loadClass(String className, Class callingClass)
090: throws ClassNotFoundException {
091: try {
092: return Thread.currentThread().getContextClassLoader()
093: .loadClass(className);
094: } catch (ClassNotFoundException e) {
095: try {
096: return Class.forName(className);
097: } catch (ClassNotFoundException ex) {
098: try {
099: return ClassLoaderUtil.class.getClassLoader()
100: .loadClass(className);
101: } catch (ClassNotFoundException exc) {
102: return callingClass.getClassLoader().loadClass(
103: className);
104: }
105: }
106: }
107: }
108: }
|