/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.soa.esb.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.log4j.Logger;
/**
* Utility methods to aid in class/resource loading.
*
* @author kevin
*/
public class ClassUtil
{
private static Logger logger = Logger.getLogger(ClassUtil.class);
/**
* Load the specified class.
*
* @param className The name of the class to load.
* @param caller The class of the caller.
* @return The specified class.
* @throws ClassNotFoundException If the class cannot be found.
*/
public static Class forName(final String className, final Class caller) throws ClassNotFoundException
{
final ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
if (threadClassLoader != null)
{
try
{
return Class.forName(className, true, threadClassLoader);
}
catch (final ClassNotFoundException cnfe)
{
if (cnfe.getException() != null)
{
throw cnfe;
}
}
}
final ClassLoader classLoader = caller.getClassLoader();
if (classLoader != null)
{
try
{
return Class.forName(className, true, classLoader);
}
catch (final ClassNotFoundException cnfe)
{
if (cnfe.getException() != null)
{
throw cnfe;
}
}
}
return Class.forName(className, true, ClassLoader.getSystemClassLoader());
}
/**
* Resolve a proxy for the specified interfaces.
*
* @param interfaces The interfaces associated with the proxy.
* @param caller The class of the caller.
* @return The specified proxy class.
* @throws ClassNotFoundException If the class cannot be found.
*/
public static Class resolveProxy(final String[] interfaces, final Class caller) throws ClassNotFoundException
{
final int numInterfaces = (interfaces == null ? 0 : interfaces.length);
if (numInterfaces == 0)
{
throw new ClassNotFoundException("Cannot generate proxy with no interfaces");
}
final Class[] interfaceClasses = new Class[numInterfaces];
for (int count = 0; count < numInterfaces; count++)
{
interfaceClasses[count] = forName(interfaces[count], caller);
}
final ClassLoader proxyClassLoader;
final ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
if (threadClassLoader != null)
{
proxyClassLoader = threadClassLoader;
}
else
{
final ClassLoader classLoader = caller.getClassLoader();
if (classLoader != null)
{
proxyClassLoader = classLoader;
}
else
{
proxyClassLoader = ClassLoader.getSystemClassLoader();
}
}
return Proxy.getProxyClass(proxyClassLoader, interfaceClasses);
}
/**
* Get the specified resource as a stream.
*
* @param resourceName The name of the class to load.
* @param caller The class of the caller.
* @return The input stream for the resource or null if not found.
*/
public static InputStream getResourceAsStream(final String resourceName, final Class caller)
{
final String resource;
if (resourceName.startsWith("/"))
{
resource = resourceName.substring(1);
}
else
{
final Package callerPackage = caller.getPackage();
if (callerPackage != null)
{
resource = callerPackage.getName().replace('.', '/') + '/' + resourceName;
}
else
{
resource = resourceName;
}
}
final ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
if (threadClassLoader != null)
{
final InputStream is = threadClassLoader.getResourceAsStream(resource);
if (is != null)
{
return is;
}
}
final ClassLoader classLoader = caller.getClassLoader();
if (classLoader != null)
{
final InputStream is = classLoader.getResourceAsStream(resource);
if (is != null)
{
return is;
}
}
return ClassLoader.getSystemResourceAsStream(resource);
}
public static URL getResource(final String resourceName, final Class<?> caller)
{
final String resource;
if (resourceName.startsWith("/"))
{
resource = resourceName.substring(1);
}
else
{
final Package callerPackage = caller.getPackage();
if (callerPackage != null)
{
resource = callerPackage.getName().replace('.', '/') + '/' + resourceName;
}
else
{
resource = resourceName;
}
}
final ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
if (threadClassLoader != null)
{
final URL url = threadClassLoader.getResource(resource);
if (url != null)
{
return url;
}
}
final ClassLoader classLoader = caller.getClassLoader();
if (classLoader != null)
{
final URL url = classLoader.getResource(resource);
if (url != null)
{
return url;
}
}
return ClassLoader.getSystemResource(resource);
}
public static List<URL> getResources(String resourcePath, Class<?> caller) throws IOException
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (resourcePath.startsWith("/"))
{
resourcePath = resourcePath.substring(1);
}
if (classLoader != null)
{
return toList(classLoader.getResources(resourcePath));
}
classLoader = caller.getClassLoader();
if (classLoader != null)
{
return toList(classLoader.getResources(resourcePath));
}
return new ArrayList<URL>();
}
private static <T> List<T> toList(Enumeration<T> objects)
{
List<T> theList = new ArrayList<T>();
while (objects.hasMoreElements())
{
theList.add(objects.nextElement());
}
return theList;
}
/**
* Get a package name and convert it to a path value, so it can be used in calls to methods like
* {@link #getResourceAsStream}.
* <p/>
* Adds a '/' prefix and converts all '." characters to '/'. Doesn't add a trailing slash.
*
* @param packageObj The package.
* @return The package path.
*/
public static String getPath(Package packageObj)
{
return "/" + packageObj.getName().replace('.', '/');
}
public static List<String> getResourceList(String regex, Class caller)
{
ClasspathResourceFilter filter = new ClasspathResourceFilter(regex);
ClassLoader classLoader;
classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader instanceof URLClassLoader)
{
filter.filter((URLClassLoader) classLoader);
}
classLoader = caller.getClassLoader();
if (classLoader instanceof URLClassLoader)
{
filter.filter((URLClassLoader) classLoader);
}
return filter.getResourceList();
}
private static class ClasspathResourceFilter
{
private List<String> resourceList = new ArrayList<String>();
private Pattern pattern;
private ClasspathResourceFilter(String regex)
{
pattern = Pattern.compile(regex);
}
private void filter(URLClassLoader classLoader)
{
URL[] cpUrls = classLoader.getURLs();
for (int i = 0; i < cpUrls.length; i++)
{
try
{
File file = new File(cpUrls[i].toURI());
if (file.isDirectory())
{
searchClasspathDirTree(file, "");
}
else
{
searchArchive(file);
}
}
catch (URISyntaxException e)
{
logger.warn("Error searching classpath resource URL '" + cpUrls[i] + "' for resource '"
+ pattern.pattern() + "': " + e.getMessage());
}
catch (IOException e)
{
logger.warn("Error searching classpath resource URL '" + cpUrls[i] + "' for resource '"
+ pattern.pattern() + "': " + e.getMessage());
}
}
}
private void searchClasspathDirTree(File rootDir, String subDir)
{
File currentDir = new File(rootDir, subDir);
File[] contents = currentDir.listFiles();
for (File file : contents)
{
if (file.isDirectory())
{
String subSubDir = subDir + "/" + file.getName();
searchClasspathDirTree(rootDir, subSubDir);
}
else
{
String resClasspathPath = file.toURI().toString()
.substring(rootDir.toURI().toString().length() - 1);
if (isToBeAdded(resClasspathPath))
{
resourceList.add(resClasspathPath);
}
}
}
}
private void searchArchive(File archiveFile) throws IOException
{
ZipFile zip = new ZipFile(archiveFile);
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
String resClasspathPath = "/" + entry.getName();
if (isToBeAdded(resClasspathPath))
{
resourceList.add(resClasspathPath);
}
}
}
private boolean isToBeAdded(String resClasspathPath)
{
if (resourceList.contains(resClasspathPath))
{
// Already in the list e.g. same resource in different archives...
return false;
}
Matcher matcher = pattern.matcher(resClasspathPath);
return matcher.matches();
}
private List<String> getResourceList()
{
return resourceList;
}
}
}
ClassUtil
最新推荐文章于 2021-02-21 11:10:00 发布