Author: nbubna
Date: Mon Aug 6 14:02:42 2007
New Revision: 563279
URL: http://svn.apache.org/viewvc?view=rev&rev=563279
Log:
flesh out ClassUtils to be more robust and especially to better support loading
of resources from the classpath
Modified:
velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ClassUtils.java
Modified:
velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ClassUtils.java
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ClassUtils.java?view=diff&rev=563279&r1=563278&r2=563279
==============================================================================
---
velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ClassUtils.java
(original)
+++
velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ClassUtils.java
Mon Aug 6 14:02:42 2007
@@ -19,12 +19,21 @@
* under the License.
*/
+import java.io.InputStream;
+import java.io.IOException;
import java.lang.reflect.Method;
+import java.net.URL;
import java.text.NumberFormat;
import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
/**
* Repository for common class and reflection methods.
@@ -34,11 +43,26 @@
*/
public class ClassUtils
{
+ // shortcuts for readability...
+ private static final ClassLoader getThreadContextLoader()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ private static final ClassLoader getClassLoader()
+ {
+ return ClassUtils.class.getClassLoader();
+ }
+
/**
- * Return the <code>Class</code> object for the specified fully qualified
- * class name, from this thread's current class loader. If no
- * class loader is set for the current thread, then the class loader
- * that loaded this class will be used.
+ * Load a class with a given name.
+ * <p/>
+ * It will try to load the class in the following order:
+ * <ul>
+ * <li>From [EMAIL PROTECTED]
Thread.currentThread().getContextClassLoader()}
+ * <li>Using the basic [EMAIL PROTECTED] Class#forName(java.lang.String) }
+ * <li>From [EMAIL PROTECTED] ClassUtils.class.getClassLoader()}
+ * </ul>
*
* @param name Fully qualified class name to be loaded
* @return Class object
@@ -46,12 +70,21 @@
*/
public static Class getClass(String name) throws ClassNotFoundException
{
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (loader == null)
+ try
{
- loader = ClassUtils.class.getClassLoader();
+ return getThreadContextLoader().loadClass(name);
+ }
+ catch (ClassNotFoundException e)
+ {
+ try
+ {
+ return Class.forName(name);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ return getClassLoader().loadClass(name);
+ }
}
- return loader.loadClass(name);
}
public static Object getInstance(String classname)
@@ -59,6 +92,107 @@
InstantiationException
{
return getClass(classname).newInstance();
+ }
+
+ /**
+ * Load all resources with the specified name. If none are found, we
+ * prepend the name with '/' and try again.
+ *
+ * This will attempt to load the resources from (in this order):
+ * <ul>
+ * <li>the result Thread.currentThread().getContextClassLoader()</li>
+ * <li>the result of ClassUtils.class.getClassLoader()</li>
+ * </ul>
+ *
+ * @param name The name of the resources to load
+ */
+ public static List<URL> getResources(String name)
+ {
+ Set<URL> urls = new LinkedHashSet<URL>();
+
+ Enumeration<URL> e;
+ try
+ {
+ e = getThreadContextLoader().getResources(name);
+ while (e.hasMoreElements())
+ {
+ urls.add(e.nextElement());
+ }
+ }
+ catch (IOException ioe)
+ {
+ // ignore
+ }
+
+ try
+ {
+ e = getClassLoader().getResources(name);
+ while (e.hasMoreElements())
+ {
+ urls.add(e.nextElement());
+ }
+ }
+ catch (IOException ioe)
+ {
+ // ignore
+ }
+
+ if (!urls.isEmpty())
+ {
+ List<URL> result = new ArrayList<URL>(urls.size());
+ result.addAll(urls);
+ return result;
+ }
+ else if (!name.startsWith("/"))
+ {
+ // try again with a / in front of the name
+ return getResources("/"+name);
+ }
+ else
+ {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Load a given resource.
+ * <p/>
+ * This method will try to load the resource using the following methods
(in order):
+ * <ul>
+ * <li>From [EMAIL PROTECTED]
Thread.currentThread().getContextClassLoader()}
+ * <li>From [EMAIL PROTECTED] ClassUtils.class.getClassLoader()}
+ * </ul>
+ *
+ * @param name The name of the resource to load
+ */
+ public static URL getResource(String name)
+ {
+ URL url = getThreadContextLoader().getResource(name);
+ if (url == null)
+ {
+ url = getClassLoader().getResource(name);
+ }
+ return url;
+ }
+
+ /**
+ * This is a convenience method to load a resource as a stream.
+ * <p/>
+ * The algorithm used to find the resource is given in getResource()
+ *
+ * @param name The name of the resource to load
+ */
+ public static InputStream getResourceAsStream(String name)
+ {
+ URL url = getResource(name);
+ try
+ {
+ return (url != null) ? url.openStream() : null;
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
}
public static Method findMethod(Class clazz, String name, Class[] params)