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