/**
*
*Copyright (C) 2000-2003 Anthony Eden.
*All rights reserved.
*
*Redistribution and use in source and binary forms, with or without
*modification, are permitted provided that the following conditions
*are met:
*
*1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
*2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the disclaimer that follows
* these conditions in the documentation and/or other materials
* provided with the distribution.
*
*3. The name "EdenLib" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact me@anthonyeden.com.
*
*4. Products derived from this software may not be called "EdenLib", nor
* may "EdenLib" appear in their name, without prior written permission
* from Anthony Eden (me@anthonyeden.com).
*
*In addition, I request (but do not require) that you include in the
*end-user documentation provided with the redistribution and/or in the
*software itself an acknowledgement equivalent to the following:
* "This product includes software developed by
* Anthony Eden (http://www.anthonyeden.com/)."
*
*THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
*INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
*SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
*HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
*STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
*IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*POSSIBILITY OF SUCH DAMAGE.
*
*For more information on EdenLib, please see <http://edenlib.sf.net/>.
*
*/
package org.jrack.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Useful class management utilities.
*
* @author Anthony Eden
* @author Florin PATRASCU
*/
public class ClassUtilities {
private static Logger log = LoggerFactory.getLogger(ClassUtilities.class);
/**
* Load the specified class name. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the ClassUtilities
* class loader is used.
*
* @param className The class name
* @return The Class
* @throws ClassNotFoundException
*/
public static Class loadClass(String className)
throws ClassNotFoundException {
return loadClass(className, null);
}
/**
* Load the specified class name. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param className The class name
* @param requestor The object requesting the class or null
* @return The Class
* @throws ClassNotFoundException
*/
public static Class loadClass(String className, Object requestor) throws ClassNotFoundException {
Class requestorClass = requestor == null ? ClassUtilities.class : requestor.getClass();
return loadClass(className, requestorClass);
}
/**
* Load the specified class name. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param className The class name
* @param requestor The class of the object requesting the class or null
* @return The Class
* @throws ClassNotFoundException
*/
public static Class loadClass(String className, Class requestor)
throws ClassNotFoundException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
return cl.loadClass(className);
} catch (ClassNotFoundException e) {
// log.warn(className + "; ClassNotFoundException using thread context class loader");
cl = requestor.getClass().getClassLoader();
return cl.loadClass(className);
} catch (SecurityException e) {
// log.warn(className + "; SecurityException using thread context class loader");
cl = requestor.getClass().getClassLoader();
return cl.loadClass(className);
}
}
/**
* Load the specified resource. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the ClassUtilities
* class loader is used.
*
* @param name The resource name
* @return The resource URL or null
*/
public static URL getResource(String name) {
return getResource(name, null);
}
/**
* Load the specified resource. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param name The resource name
* @param requestor The object requesting the resource or null
* @return The resource URL or null
*/
public static URL getResource(String name, Object requestor) {
Class requestorClass = requestor == null ? ClassUtilities.class : requestor.getClass();
return getResource(name, requestorClass);
}
/**
* Load the specified resource. This method will first attempt to load
* the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param name The resource name
* @param requestor The class of the object requesting the resource or null
* @return The resource URL or null
*/
public static URL getResource(String name, Class requestor) {
URL resource;
ClassLoader cl = Thread.currentThread().getContextClassLoader();
resource = cl.getResource(name);
if (resource == null) {
cl = requestor.getClass().getClassLoader();
resource = cl.getResource(name);
}
return resource;
}
/**
* Load the specified resource stream. This method will first attempt to
* load the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then ClassUtilities class
* loader is used.
*
* @param name The resource name
* @return The resource stream or null
*/
public static InputStream getResourceAsStream(String name) {
return getResourceAsStream(name, null);
}
/**
* Load the specified resource stream. This method will first attempt to
* load the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param name The class name
* @param requestor The object requesting the resource or null
* @return The resource stream or null
*/
public static InputStream getResourceAsStream(String name,
Object requestor) {
Class requestorClass = requestor == null ? ClassUtilities.class : requestor.getClass();
return getResourceAsStream(name, requestorClass);
}
/**
* Load the specified resource stream. This method will first attempt to
* load the class using the context class loader. If that fails due to a
* ClassNotFoundException or a SecurityException then the requestor's
* class loader is used. If the requestor object is null then the
* ClassUtilities class loader is used.
*
* @param name The class name
* @param requestor The class of the object requesting the resource or null
* @return The resource stream or null
*/
public static InputStream getResourceAsStream(String name,
Class requestor) {
InputStream resourceStream = null;
ClassLoader cl = Thread.currentThread().getContextClassLoader();
resourceStream = cl.getResourceAsStream(name);
if (resourceStream == null) {
cl = requestor.getClass().getClassLoader();
resourceStream = cl.getResourceAsStream(name);
}
return resourceStream;
}
/**
* Find all super classes and implemented interfaces for the given
* class.
*
* @param startClass The class
* @return A List of Class objects
*/
public static List getAllClassesAndInterfaces(Class startClass) {
ArrayList classes = new ArrayList();
addClassesAndInterfaces(startClass, classes);
return classes;
}
/**
* Add all super classes and interfaces of the given class to the given
* List.
*
* @param c The Class
* @param classes An List of Classes
*/
protected static void addClassesAndInterfaces(Class c, List classes) {
if (c != null) {
Class superClass = c.getSuperclass();
Class[] interfaces = c.getInterfaces();
if (superClass != null && !classes.contains(superClass)) {
classes.add(superClass);
}
for (Class anInterface : interfaces) {
if (anInterface != null && !classes.contains(anInterface)) {
classes.add(anInterface);
}
}
addClassesAndInterfaces(superClass, classes);
for (Class anInterface : interfaces) {
addClassesAndInterfaces(anInterface, classes);
}
}
}
}