package org.oddjob.oddballs; import java.io.File; import java.util.Arrays; import org.apache.log4j.Logger; import org.oddjob.arooa.ArooaDescriptor; import org.oddjob.arooa.deploy.ArooaDescriptorBean; import org.oddjob.arooa.deploy.ArooaDescriptorFactory; import org.oddjob.arooa.deploy.ListDescriptor; /** * @oddjob.description Create Oddjob job definition descriptors from any * number of directories that follow the Oddball format. * <p> * The Oddball directory structure is: * * <code><pre> * myball * classes * com * acme * MyStuff.class * lib * someutil.jar * </pre></code> * * You can have either a <code>lib</code> or <code>classes</code> or both * but you must have something. * <p> * Additionally there can be as many <code>META-INF/arooa.xml</code> resources * on that confirm to the {@link ArooaDescriptorBean} format for defining * element mappings and conversions. * * @oddjob.example * * Loading two Oddballs. * * {@oddjob.xml.resource org/oddjob/oddballs/OddballsExample.xml} * * This is equivalent to launching Oddjob with the oddball path option * set as in: * * <code><pre> * java -jar run-oddjob.jar \ * -op test/oddballs/apple:test/oddballs/orange \ * -f test/launch/oddballs-launch.xml * </pre></code> * * Or if the <code>test/oddballs</code> directory only contains these two * directories, then using the oddball directory option: * * <code><pre> * java -jar run-oddjob.jar \ * -ob test/oddballs \ * -f test/launch/oddballs-launch.xml * </pre></code> * * If the <code>apple</code> and <code>orange</code> directories were * copied to Oddjob's Oddballs directory they would be loaded by default. * * @author rob * */ public class OddballsDescriptorFactory implements ArooaDescriptorFactory { private static final Logger logger = Logger.getLogger(OddballsDescriptorFactory.class); /** * @oddjob.property * @oddjob.description The Oddball directory or directories. * @oddjob.required Yes. */ private File[] files; /** * @oddjob.property * @oddjob.description The factory that will create the Oddball from the * file specification. At the moment this defaults to the only * implementation which is to load an Oddball from a directory. In future * it is hoped to support loading Oddballs from archives. Following the * existing java naming convention for archives they will probably be * called .oar files. * * @oddjob.required No. Defaults to a directory loading factory. */ private OddballFactory oddballFactory; public OddballsDescriptorFactory() { this(null, null); } public OddballsDescriptorFactory(File[] files) { this(files, null); } public OddballsDescriptorFactory(File[] files, OddballFactory oddballFactory) { this.files = files; this.oddballFactory = oddballFactory; } public File[] getFiles() { return files; } public void setFiles(File[] baseDir) { this.files = baseDir; } public OddballFactory getOddballFactory() { return oddballFactory; } public void setOddballFactory(OddballFactory oddballFactory) { this.oddballFactory = oddballFactory; } public ArooaDescriptor createDescriptor(ClassLoader classLoader) { if (files == null) { throw new NullPointerException("No Oddball directories given."); } OddballFactory oddballFactory = this.oddballFactory; if (oddballFactory == null) { oddballFactory = new DirectoryOddball(); } ListDescriptor descriptor = new ListDescriptor(); for (File file : files) { Oddball oddball = oddballFactory.createFrom(file, classLoader); if (oddball == null) { continue; } descriptor.addDescriptor(oddball.getArooaDescriptor()); } if (descriptor.size() == 0) { logger.info("No Oddballs found for [" + Arrays.toString(files) + "]"); return null; } else { return descriptor; } } public String toString() { return getClass().getName() + ". " + (files == null ? "No Oddball directories!" : "Odball directories: " + Arrays.toString(files)); } }