package org.oddjob.oddballs;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.log4j.Logger;
import org.oddjob.arooa.ArooaDescriptor;
import org.oddjob.arooa.deploy.ClassPathDescriptorFactory;
import org.oddjob.arooa.deploy.ClassesOnlyDescriptor;
/**
* An implementation of an {@link OddballFactory} that creates an
* {@link Oddball} from a directory.
* <p>
* If the given file is not a directory no Oddball is created.
*
* @author rob
*
*/
public class DirectoryOddball implements OddballFactory {
private static final Logger logger = Logger.getLogger(DirectoryOddball.class);
/*
* (non-Javadoc)
* @see org.oddjob.oddballs.OddballFactory#createFrom(java.io.File, java.lang.ClassLoader)
*/
public Oddball createFrom(final File file, ClassLoader parentLoader) {
if (!file.isDirectory()) {
return null;
}
URL[] urls = null;
try {
urls = classpathURLs(file);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (urls.length == 0) {
return null;
}
logger.info("Addding Oddall [" + file.getPath() + "]");
final URLClassLoader classLoader = new URLClassLoader(
urls, parentLoader) {
@Override
public String toString() {
return "Oddball ClassLoader for " + file.getPath();
}
};
ClassPathDescriptorFactory descriptorFactory =
new ClassPathDescriptorFactory();
descriptorFactory.setExcludeParent(true);
ArooaDescriptor maybeDescriptor =
descriptorFactory.createDescriptor(classLoader);
if (maybeDescriptor == null) {
logger.debug("No arooa.xml in Oddball. Using for classes only.");
maybeDescriptor = new ClassesOnlyDescriptor(classLoader);
}
final ArooaDescriptor descriptor = maybeDescriptor;
return new Oddball() {
public ClassLoader getClassLoader() {
return classLoader;
}
public ArooaDescriptor getArooaDescriptor() {
return descriptor;
}
};
}
URL[] classpathURLs(File parent) throws IOException {
File[] jars = new File(parent, "lib").listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
// no lib dir.
if (jars == null) {
jars = new File[0];
}
int offset;
URL[] urls;
File classesDir = new File(parent, "classes");
if (classesDir.exists()) {
urls = new URL[jars.length + 1];
urls[0] = classesDir.getCanonicalFile().toURI().toURL();
offset = 1;
}
else {
urls = new URL[jars.length];
offset = 0;
}
for (int i = 0; i < jars.length; ++i) {
urls[i+offset] = jars[i].getCanonicalFile().toURI().toURL();
}
return urls;
}
}