/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* Load classes from a custom class path. This loader first delegates to the
* parent loader in the usual way. If no parent can load the class, this loader
* will then search the path in the order given. Each element of the path may
* name a directory (which will be searched for .class files) or a JAR file
* (likewise searched for .class files). Searching consists of converting the
* binary name of the class to a path within the directory or archive, and looking
* it up there, as with the system class path. The only reason that this loader
* exists is to facilitate the loading of classes into a Servlet application from
* paths other than the class path established by the servlet container -- for
* example, paths provided by the application's private configuration.
*
* @author Mark H. Wood
*/
public class PathsClassLoader
extends ClassLoader
{
/** Filesystem paths to be searched. */
private final String[] classpath;
/**
* Instantiate to use a custom class path.
*
* @param parent delegate to this ClassLoader first.
* @param classpath filesystem paths to be searched for classes and JARs.
*/
PathsClassLoader(ClassLoader parent, String[] classpath)
{
super(parent);
this.classpath = classpath;
}
@Override
protected Class findClass(String name) throws ClassNotFoundException
{
Class found = null;
for (String aPath : classpath)
{
String bodyPath = name.replace('.', '/');
File pathFile = new File(aPath);
if (pathFile.isDirectory())
{
byte[] body;
int bodySize;
File bodyFile = new File(pathFile, bodyPath + ".class");
if (!bodyFile.exists())
{
continue;
}
bodySize = (int) bodyFile.length();
body = new byte[bodySize];
FileInputStream bodyStream = null;
try
{
bodyStream = new FileInputStream(bodyFile);
int pos = 0;
int len;
do
{
len = bodyStream.read(body, pos, bodySize);
pos += len;
} while (pos < bodySize);
} catch (IOException e)
{
throw new ClassNotFoundException("Class body not read", e);
} finally
{
if (null != bodyStream)
{
try
{
bodyStream.close();
} catch (IOException ex)
{
/* don't care */
}
}
}
found = defineClass(name, body, 0, bodySize);
break;
}
else if (pathFile.isFile())
{
byte[] body;
int bodySize;
InputStream bodyStream = null;
JarFile jar = null;
try
{
jar = new JarFile(pathFile);
JarEntry entry = jar.getJarEntry(bodyPath + ".class");
if (null == entry)
{
continue;
}
bodyStream = jar.getInputStream(entry);
bodySize = (int) entry.getSize();
body = new byte[bodySize];
int pos = 0;
int len;
do
{
len = bodyStream.read(body, pos, bodySize);
pos += len;
} while (pos < bodySize);
} catch (IOException e)
{
throw new ClassNotFoundException("Class body not read", e);
} finally
{
if (null != bodyStream)
{
try
{
bodyStream.close();
} catch (IOException e)
{
/* don't care */
}
}
if (null != jar)
{
try
{
jar.close();
} catch (IOException e)
{
/* don't care */
}
}
}
found = defineClass(name, body, 0, bodySize);
break;
}
else
{
// Just skip this path element -- probably just file not found here.
}
}
if (null == found)
{
throw new ClassNotFoundException(name);
}
else
{
resolveClass(found);
return found;
}
}
/*
@Override
public URL getResource(String name)
{
}
*/
}