Author: [log in to unmask]
Date: Tue Nov 3 11:32:25 2015
New Revision: 3686
Log:
[HPSJAVA-623] Add event printing and other updates to job manager; source code formatting.
Added:
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventPrintLoopAdapter.java
Modified:
projects/lcsim/trunk/job-manager/pom.xml
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/AidaSaveDriver.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventMarkerDriver.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/IParameterConverter.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlDriver.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlManager.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/LCSimClassLoader.java
projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/ParameterConverters.java
Modified: projects/lcsim/trunk/job-manager/pom.xml
=============================================================================
--- projects/lcsim/trunk/job-manager/pom.xml (original)
+++ projects/lcsim/trunk/job-manager/pom.xml Tue Nov 3 11:32:25 2015
@@ -1,23 +1,19 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
<modelVersion>4.0.0</modelVersion>
<artifactId>lcsim-job-manager</artifactId>
<name>job-manager</name>
<description>job manager allowing XML steering using a command line utility</description>
-
<parent>
<groupId>org.lcsim</groupId>
<artifactId>lcsim-parent</artifactId>
<version>3.1.6-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
-
<scm>
<url>http://java.freehep.org/svn/repos/lcdet/list/projects/lcsim/trunk/job-manager/</url>
<connection>scm:svn:svn://svn.freehep.org/lcdet/projects/lcsim/trunk/job-manager/</connection>
<developerConnection>scm:svn:svn://svn.freehep.org/lcdet/projects/lcsim/trunk/job-manager/</developerConnection>
</scm>
-
<dependencies>
<dependency>
<groupId>org.lcsim</groupId>
@@ -30,8 +26,7 @@
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
- <version>1.0</version>
+ <version>1.3</version>
</dependency>
</dependencies>
-
</project>
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/AidaSaveDriver.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/AidaSaveDriver.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/AidaSaveDriver.java Tue Nov 3 11:32:25 2015
@@ -5,34 +5,28 @@
import org.lcsim.util.Driver;
import org.lcsim.util.aida.AIDA;
-public class AidaSaveDriver extends Driver
-{
+public class AidaSaveDriver extends Driver {
+
String outputFileName = "plots.aida";
boolean verbose = false;
- public AidaSaveDriver()
- {}
+ public AidaSaveDriver() {
+ }
- public void setOutputFileName(String outputFileName)
- {
+ public void setOutputFileName(String outputFileName) {
this.outputFileName = outputFileName;
}
-
- public void setVerbose(boolean verbose)
- {
+
+ public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
- public void endOfData()
- {
- try
- {
+ public void endOfData() {
+ try {
if (verbose)
System.out.println("Saving AIDA file to " + outputFileName + " ...");
AIDA.defaultInstance().saveAs(outputFileName);
- }
- catch (IOException x)
- {
+ } catch (IOException x) {
throw new RuntimeException("Problem saving AIDA file to " + outputFileName + ".", x);
}
}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventMarkerDriver.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventMarkerDriver.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventMarkerDriver.java Tue Nov 3 11:32:25 2015
@@ -7,7 +7,9 @@
* Driver to print markers during event processing.
*
* @author Jeremy McCormick <[log in to unmask]>
+ * @deprecated Use built-in command line option of {@link JobManager} instead.
*/
+@Deprecated
public class EventMarkerDriver extends Driver {
private int interval = 1;
@@ -32,7 +34,7 @@
protected void process(EventHeader event) {
if (nEvents % interval == 0) {
getLogger().info(marker + "Event " + event.getEventNumber() + " with sequence " + nEvents);
- }
+ }
nEvents++;
}
Added: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventPrintLoopAdapter.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventPrintLoopAdapter.java (added)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/EventPrintLoopAdapter.java Tue Nov 3 11:32:25 2015
@@ -0,0 +1,64 @@
+package org.lcsim.job;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.freehep.record.loop.RecordEvent;
+import org.freehep.record.loop.RecordListener;
+import org.lcsim.event.EventHeader;
+
+/**
+ * Prints out information from event processing such as the event number at a specified interval.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+class EventPrintLoopAdapter implements RecordListener {
+
+ /**
+ * Setup the logger.
+ */
+ private static Logger LOGGER = Logger.getLogger(EventPrintLoopAdapter.class.getName());
+ static {
+ if (LOGGER.getLevel() == null) {
+ System.out.println("EventPrintLoopAdapter: set level to ALL");
+ LOGGER.setLevel(Level.ALL);
+ } else {
+ System.out.println("EventPrintLoopAdapter: level " + LOGGER.getLevel() + " from config");
+ }
+ }
+
+ /**
+ * Sequence number of events processed.
+ */
+ private long eventSequence = 0;
+
+ /**
+ * Event print interval which means every Nth event will be printed.
+ */
+ private long printInterval = 1;
+
+ /**
+ * Class constructor.
+ * @param printInterval the event print interval
+ */
+ EventPrintLoopAdapter(long printInterval) {
+ this.printInterval = printInterval;
+ }
+
+ /**
+ * Process an event and print the event information.
+ */
+ @Override
+ public void recordSupplied(RecordEvent recordEvent) {
+ Object record = recordEvent.getRecord();
+ if (record instanceof EventHeader) {
+ EventHeader event = (EventHeader) recordEvent.getRecord();
+ //System.out.println("EventPrintLoopAdapter.recordSupplied - " + event.getEventNumber());
+ if (eventSequence % printInterval == 0) {
+ LOGGER.info("event: " + event.getEventNumber() + "; time: " + event.getTimeStamp() + "; seq: "
+ + eventSequence);
+ }
+ ++eventSequence;
+ }
+ }
+}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/IParameterConverter.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/IParameterConverter.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/IParameterConverter.java Tue Nov 3 11:32:25 2015
@@ -5,22 +5,25 @@
/**
* Interface for converting from XML to typed objects for input to LCSim Drivers.
+ *
* @author jeremym
*/
-public interface IParameterConverter
-{
- /**
- * This method returns true if the converter can handle the given type.
- * @param propertyType The class of the parameter.
- * @return True if converter handles the given type; False if no.
- */
- public boolean handles(Class propertyType);
-
- /**
- * Convert an XML element parameter to a specific type and return as an Object.
- * @param factory The expression factory to be used for variable evaluation.
- * @param parameterElement The XML parameter data.
- * @return Parameter converted to specific type. Returned as generic object.
- */
- public Object convert(JDOMExpressionFactory factory, Element parameterElement);
+public interface IParameterConverter {
+
+ /**
+ * This method returns true if the converter can handle the given type.
+ *
+ * @param propertyType The class of the parameter.
+ * @return True if converter handles the given type; False if no.
+ */
+ public boolean handles(Class propertyType);
+
+ /**
+ * Convert an XML element parameter to a specific type and return as an Object.
+ *
+ * @param factory The expression factory to be used for variable evaluation.
+ * @param parameterElement The XML parameter data.
+ * @return Parameter converted to specific type. Returned as generic object.
+ */
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement);
}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlDriver.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlDriver.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlDriver.java Tue Nov 3 11:32:25 2015
@@ -6,51 +6,42 @@
import org.lcsim.util.Driver;
/**
- * Extend this driver to run an xml recon job in JAS3.
- * Your driver needs to call <code>super.process()</code>
- * in its <code>process()</code> method for this to work.
+ * Extend this driver to run an xml recon job in JAS3. Your driver needs to call <code>super.process()</code> in its
+ * <code>process()</code> method for this to work. The only sections that will be used are <drivers>, <execute>,
+ * <control>, and <define>. The <code>numberOfEvents</code> parameter will be ignored. Non-standard jar files need to be
+ * added to the ~/.JAS3/extensions directory.
*
- * The only sections that will be used are <drivers>,
- * <execute>, <control>, and <define>. The <code>numberOfEvents</code>
- * parameter will be ignored. Non-standard jar files need
- * to be added to the ~/.JAS3/extensions directory.
- *
* @author jeremym
*/
-public class JobControlDriver extends Driver
-{
- JobControlManager mgr = new JobControlManager();
-
- private boolean wasSetup = false;
-
- public JobControlDriver()
- {}
-
- public JobControlDriver(File steering)
- {
- setup(steering);
- }
-
- public void setup(File steering)
- {
- if (wasSetup)
- return;
- else
- wasSetup = true;
- mgr.setup(steering);
- for (Driver driver : mgr.getDriverExecList())
- {
- this.add(driver);
- }
- }
-
- public JobControlManager getManager()
- {
- return this.mgr;
- }
+public class JobControlDriver extends Driver {
- public void process(EventHeader event)
- {
- super.process(event);
- }
+ JobControlManager mgr = new JobControlManager();
+
+ private boolean wasSetup = false;
+
+ public JobControlDriver() {
+ }
+
+ public JobControlDriver(File steering) {
+ setup(steering);
+ }
+
+ public void setup(File steering) {
+ if (wasSetup)
+ return;
+ else
+ wasSetup = true;
+ mgr.setup(steering);
+ for (Driver driver : mgr.getDriverExecList()) {
+ this.add(driver);
+ }
+ }
+
+ public JobControlManager getManager() {
+ return this.mgr;
+ }
+
+ public void process(EventHeader event) {
+ super.process(event);
+ }
}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlManager.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlManager.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/JobControlManager.java Tue Nov 3 11:32:25 2015
@@ -10,7 +10,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
@@ -38,7 +37,6 @@
import org.apache.commons.cli.PosixParser;
import org.freehep.record.loop.RecordEvent;
import org.jdom.Attribute;
-import org.jdom.DataConversionException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Text;
@@ -46,13 +44,12 @@
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.lcsim.conditions.ConditionsManager;
-import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
import org.lcsim.event.EventHeader;
import org.lcsim.units.Constants;
import org.lcsim.util.Driver;
import org.lcsim.util.DriverAdapter;
import org.lcsim.util.cache.FileCache;
-import org.lcsim.util.log.LogUtil;
import org.lcsim.util.loop.LCIOEventSource;
import org.lcsim.util.loop.LCSimConditionsManagerImplementation;
import org.lcsim.util.loop.LCSimLoop;
@@ -61,443 +58,1021 @@
/**
* <p>
- * This class provides a frontend for running and managing LCSim jobs using an XML steering format.
- * </p>
+ * This class provides a front end for running and managing LCSim event processing jobs using XML steering files.
* <p>
- * The command line syntax is:
- * </p>
+ * More details about this XML format can be found at the<br/>
+ * <a href="https://confluence.slac.stanford.edu/display/ilc/lcsim+xml">LCSim XML Confluence Page</a>.
* <p>
- * <code>java -jar ./lib/lcsim-bin.jar steeringFile.xml [options]</code>
- * </p>
+ * The command line syntax is:<br/>
+ * <code>java org.lcsim.job.JobManager steeringFile.xml [options]</code>
* <p>
* To see the available command line options with descriptions, run with "-h" as the only option.
- * </p>
* <p>
- * In the XML file, variables have the format <code>${variableName}</code>. No nested variable
- * definitions are allowed (e.g. no variables within variables).
- * </p>
- * <p>
- * Command-line parameters that can be defined using switches are overridden by the corresponding
- * settings in the job XML file, if they are present. This means that if these parameters are to be
- * taken from the CL, the matching settings should be left out of the XML job file. This is not the
- * case, however, for input files specified by the "-i" option, which are appended to the ones
- * listed in the steering file.
- * </p>
- *
+ * Command-line parameters that can be defined using switches are overridden by the corresponding settings in the job
+ * XML file, if they are present. This means that if these parameters are to be taken from the CL, the matching settings
+ * should be left out of the XML job file. This is not the case, however, for input files specified by the "-i" option,
+ * which are appended to the ones listed in the steering file.
+ *
* @version $Id: JobControlManager.java,v 1.65 2013/02/14 22:30:07 jeremy Exp $
* @author Jeremy McCormick
*/
-// FIXME: Command line arguments should probably override the steering file when applicable.
@SuppressWarnings({"unchecked", "rawtypes"})
public class JobControlManager {
- protected static Logger logger = LogUtil.create(JobControlManager.class);
- static {
- logger.setLevel(Level.ALL);
- }
-
- // The LCIO record loop.
- protected LCSimLoop loop;
-
- // Driver management.
- protected Map<String, Driver> driverMap = new LinkedHashMap<String, Driver>();
- protected List<Driver> driverExec = new ArrayList<Driver>();
- protected Map<String, String> availableDrivers = new HashMap<String, String>();
-
- // Run parameters.
- protected List<File> inputFiles = new ArrayList<File>();
- protected int numberOfEvents = -1;
- protected int skipEvents = -1;
- protected File rewriteFile;
-
- // Variables and constants.
- protected Map<String, String> variableMap = new HashMap<String, String>();
- protected Map<String, Double> constantsMap = new HashMap<String, Double>();
-
- // Boolean job options.
- protected boolean performDryRun;
- protected boolean rewrite;
- protected boolean useSteeringResource;
- protected boolean dummyDetector;
-
- // Settings effecting logging verbosity.
- protected boolean printInputFiles;
- protected boolean printDriverStatistics;
- protected boolean printSystemProperties;
- protected boolean printUserClassPath;
- protected boolean printDriversDetailed;
- // private boolean printVersion;
- protected boolean verbose;
-
- // File caching.
- protected File cacheDirectory;
- protected FileCache fileCache; // Start with default dir.
-
- // True once job parameters are setup from CL and XML.
- protected boolean wasSetup;
-
- // The manager's class loader.
- protected ClassLoader loader;
-
- // The log stream for messages.
- protected PrintStream logStream = System.out;
-
- // Root node of XML job file.
- protected Element root;
-
- // XML utils.
- protected JDOMExpressionFactory factory = new JDOMExpressionFactory();
- protected ParameterConverters paramConverter = new ParameterConverters(factory);
-
- // Command line options.
- protected static final Options options = createCommandLineOptions();
-
- // Reg exp to extract variables from a string with the form "${varName}".
- protected static final Pattern varPattern = Pattern.compile("[$][{][a-zA-Z_-]*[}]");
-
- protected DriverAdapter driverAdapter = null;
+ /**
+ * Initialize the logger which uses the package name.
+ */
+ protected static final Logger LOGGER = Logger.getLogger(JobControlManager.class.getPackage().getName());
+
+ /**
+ * The command line options.
+ */
+ private static final Options OPTIONS = createCommandLineOptions();
+
+ /**
+ * The regular expression for extracting the variables from an XML file.
+ */
+ private static final Pattern VARIABLE_PATTERN = Pattern.compile("[$][{][a-zA-Z_-]*[}]");
+
+ /**
+ * Create the command line options.
+ *
+ * @return The command line options for the manager.
+ */
+ private static Options createCommandLineOptions() {
+ final Options options = new Options();
+ options.addOption(new Option("p", "properties", true, "Load a properties file containing variable definitions"));
+ options.addOption(new Option("D", "define", true, "Define a variable with form [name]=[value]"));
+ options.addOption(new Option("w", "rewrite", true, "Rewrite the XML file with variables resolved"));
+ options.addOption(new Option("s", "skip", true, "Set the number of events to skip"));
+ options.addOption(new Option("n", "nevents", true, "Set the max number of events to process"));
+ options.addOption(new Option("x", "dry-run", false, "Perform a dry run which does not process events"));
+ options.addOption(new Option("i", "input-file", true, "Add an LCIO input file to process"));
+ options.addOption(new Option("r", "resource", false, "Use a steering resource rather than a file"));
+ options.addOption(new Option("b", "batch", false, "Run in batch mode in which plots will not be shown."));
+ options.addOption(new Option("e", "event-print", true, "Event print interval"));
+ options.addOption(new Option("d", "detector", true, "user supplied detector name (careful!)"));
+ options.addOption(new Option("R", "run", true, "user supplied run number (careful!)"));
+ return options;
+ }
+
+ /**
+ * Get the Java primitive type class from a type name.
+ *
+ * @param name The name of the type.
+ * @return The primitive type class.
+ */
+ private static Class getPrimitiveType(final String name) {
+ if (name.equals("byte")) {
+ return byte.class;
+ }
+ if (name.equals("short")) {
+ return short.class;
+ }
+ if (name.equals("int")) {
+ return int.class;
+ }
+ if (name.equals("long")) {
+ return long.class;
+ }
+ if (name.equals("char")) {
+ return char.class;
+ }
+ if (name.equals("float")) {
+ return float.class;
+ }
+ if (name.equals("double")) {
+ return double.class;
+ }
+ if (name.equals("boolean")) {
+ return boolean.class;
+ }
+ if (name.equals("String")) {
+ return String.class;
+ }
+ return null;
+ }
+
+ /**
+ * Run from the command line.
+ * <p>
+ * Takes command-line options (use -h option to see them).
+ *
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ final JobControlManager mgr = new JobControlManager();
+ mgr.parse(args);
+ mgr.run();
+ }
+
+ /**
+ * Print help and exit.
+ */
+ private static void printHelp() {
+ LOGGER.info("java " + JobControlManager.class.getCanonicalName() + " [options] steeringFile.xml");
+ final HelpFormatter help = new HelpFormatter();
+ help.printHelp(" ", OPTIONS);
+ System.exit(1);
+ }
+
+ /**
+ * Root directory for file caching.
+ */
+ private File cacheDirectory;
+
+ /**
+ * The class loader that will be used for the job.
+ */
+ private ClassLoader classLoader;
+
+ /**
+ * Command line that is setup from <code>main</code> arguments.
+ */
+ CommandLine commandLine = null;
+
+ /**
+ * Map of constants definitions.
+ */
+ private final Map<String, Double> constantsMap = new HashMap<String, Double>();
+
+ /**
+ * User supplied detector name.
+ */
+ private String detectorName = null;
+
+ /**
+ * A driver adapter created on the fly in case it is needed by an external program.
+ */
+ private DriverAdapter driverAdapter = null;
+
+ /**
+ * List of drivers to execute in the job.
+ */
+ private final List<Driver> driverExec = new ArrayList<Driver>();
+
+ /**
+ * Map of driver names to objects.
+ */
+ private final Map<String, Driver> driverMap = new LinkedHashMap<String, Driver>();
+
+ /**
+ * Enable dry run so no events are processed.
+ */
+ private boolean dryRun;
+
+ /**
+ * Setup a "dummy" detector in the conditions system.
+ */
+ private boolean dummyDetector;
+
+ /**
+ * Event printing interval (null means no event printing).
+ */
+ private Long eventPrintInterval = null;
+
+ /**
+ * JDOM expression factory for variables.
+ */
+ private final JDOMExpressionFactory factory = new JDOMExpressionFactory();
+
+ /**
+ * File cache.
+ */
+ private FileCache fileCache; // Start with default dir.
+
+ /**
+ * List of input LCIO files.
+ */
+ private final List<File> inputFiles = new ArrayList<File>();
+
+ /**
+ * Flag set to <code>true</code> after setup is performed.
+ */
+ private boolean isSetup;
+
+ /**
+ * The job end timestamp in ms.
+ */
+ private long jobEnd = 0;
+
+ /**
+ * The job start timestamp in ms.
+ */
+ private long jobStart = 0;
+
+ /**
+ * The LCIO record loop.
+ */
+ private LCSimLoop loop;
+
+ /**
+ * Number of events to run before stopping job.
+ */
+ private int numberOfEvents = -1;
+
+ /**
+ * Helper for converting Driver parameters.
+ */
+ private final ParameterConverters paramConverter = new ParameterConverters(factory);
+
+ /**
+ * Set to <code>true</code> to print out driver statistics at the end of the job.
+ */
+ private boolean printDriverStatistics;
+
+ /**
+ * Path for rewriting steering file with variables resolved.
+ */
+ private File rewriteFile;
+
+ /**
+ * Enable rewriting of the steering file to a new path with variables resolved.
+ */
+ private boolean rewriteSteering;
+
+ /**
+ * The root node of the XML document providing config to the manager.
+ */
+ private Element root;
+
+ /**
+ * User supplied run number.
+ */
+ private Integer runNumber = null;
+
+ /**
+ * Number of events to skip at start of job.
+ */
+ private int skipEvents = -1;
+
+ /**
+ * Interpret steering file argument as a resource rather than file path.
+ */
+ private boolean useSteeringResource;
+
+ /**
+ * Map of variable names to their values.
+ */
+ private final Map<String, String> variableMap = new HashMap<String, String>();
/**
* The default constructor.
*/
public JobControlManager() {
+
try {
fileCache = new FileCache();
- } catch (IOException x) {
+ } catch (final IOException x) {
throw new RuntimeException(x);
}
+
+ // FIXME: Should this instead be done when the job is started?
LCSimConditionsManagerImplementation.register();
}
/**
- * Run the manager using a main. Takes command-line options (use -h option to see them).
- * @param args The command line arguments.
- */
- public static void main(String args[]) {
- JobControlManager mgr = new JobControlManager();
- mgr.run(args);
- }
-
- public void run(String args[]) {
- if (args.length == 0) {
- logStream.println("java -jar lcsim-bin.jar [options] steeringFile.xml");
- HelpFormatter help = new HelpFormatter();
- help.printHelp(" ", options);
- System.exit(1);
- }
- parseCommandLineOptions(args);
- run();
- }
-
- /**
- * Create the command line options.
- *
- * @return The command line options for the manager.
- */
- private static Options createCommandLineOptions() {
- Options options = new Options();
- options.addOption(new Option("p", true, "Load a properties file containing variable definitions"));
- options.addOption(new Option("D", true, "Define a variable with form [name]=[value]"));
- options.addOption(new Option("w", true, "Rewrite the XML file with variables resolved"));
- options.addOption(new Option("v", false, "Turn on verbose mode"));
- options.addOption(new Option("s", true, "Set the number of events to skip"));
- options.addOption(new Option("n", true, "Set the max number of events to process"));
- options.addOption(new Option("x", false, "Perform a dry run which does not process events"));
- options.addOption(new Option("q", false, "Turn on quiet mode"));
- options.addOption(new Option("i", true, "Add an LCIO input file to process"));
- options.addOption(new Option("r", false, "Use a steering resource rather than a file"));
- options.addOption(new Option("b", false, "Run in headless mode in which plots will not be shown."));
- return options;
- }
-
- /**
- * Parse command-line options and setup job state from them. This method calls
- * {@link #setup(File)} to load the steering paramters from an XML file, after processing other
- * command line options. This method is private so that callers must all use the
- * {@link #main(String[])} routine as the primary entry point.
- *
- * @param args The command line arguments.
- */
- private void parseCommandLineOptions(String args[]) {
- // Setup parser.
- CommandLineParser parser = new PosixParser();
-
- // CommandLine to be loaded.
- CommandLine cl = null;
-
- // Parse CL arguments.
- try {
- cl = parser.parse(options, args);
- } catch (ParseException x) {
- throw new RuntimeException("Problem parsing command line options.", x);
- }
-
- // Turn on verbose mode. This setting may be overridden by control section from XML.
- if (cl.hasOption("v")) {
- setVerbose(true);
- }
- // Turn on quiet mode. If "-v" is also specified, this will have no effect.
- else if (cl.hasOption("q")) {
- setVerbose(false);
- }
-
- // Load properties file containing variable definitions.
- if (cl.hasOption("p")) {
- String[] propValues = cl.getOptionValues("p");
- for (String propFileName : propValues) {
- InputStream in = null;
- try {
- in = new FileInputStream(propFileName);
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
- }
- Properties props = new Properties();
- try {
- props.load(in);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- for (Entry<Object, Object> entry : props.entrySet()) {
- String key = (String) entry.getKey();
- String value = (String) entry.getValue();
- addVariableDefinition(key, value);
- }
- }
- }
-
- // Process user variable definitions.
- if (cl.hasOption("D")) {
- String[] defValues = cl.getOptionValues("D");
- for (String def : defValues) {
- String[] s = def.split("=");
- if (s.length != 2) {
- throw new RuntimeException("Bad variable format: " + def);
- }
- String key = s[0];
- String value = s[1];
- addVariableDefinition(key, value);
- }
- }
-
- // Rewrite XML file with variables resolved.
- if (cl.hasOption("w")) {
- this.rewrite = true;
- String rewritePath = cl.getOptionValue("w");
- this.rewriteFile = new File(rewritePath);
- if (this.rewriteFile.exists()) {
- throw new RuntimeException("Rewrite file already exists: " + rewritePath);
- }
- }
-
- // Set max number of events to run.
- if (cl.hasOption("n")) {
- this.numberOfEvents = Integer.valueOf(cl.getOptionValue("n"));
- }
-
- // Set number of events to skip.
- if (cl.hasOption("s")) {
- this.skipEvents = Integer.valueOf(cl.getOptionValue("s"));
- }
-
- // Perform a dry run, not processing any events but doing job setup.
- if (cl.hasOption("x")) {
- this.performDryRun = true;
- }
-
- if (cl.hasOption("r")) {
- this.useSteeringResource = true;
- }
-
- // Check that there is exactly one extra argument for the XML steering file.
- if (cl.getArgList().size() == 0) {
- throw new RuntimeException("Missing LCSim XML file argument.");
- } else if (cl.getArgList().size() > 1) {
- throw new RuntimeException("Too many extra arguments.");
- }
-
- // Local LCIO files to process.
- if (cl.hasOption("i")) {
- String[] files = cl.getOptionValues("i");
- for (String fileName : files) {
- File file = new File(fileName);
- if (!file.exists()) {
- throw new RuntimeException("File given as command line option does not exist: " + fileName);
- }
- inputFiles.add(new File(fileName));
- }
- }
-
- // Run in headless mode in which plots will not show.
- if (cl.hasOption("b")) {
- enableHeadlessMode();
- }
-
- // Steering argument points to either a file or embedded resource.
- String steering = (String) cl.getArgList().get(0);
-
- // Using an embedded resource in the jar for steering.
- if (this.useSteeringResource) {
- setup(steering);
- // Steering from a local file.
- } else {
- File xmlRunControlFile = new File(steering);
- if (!xmlRunControlFile.exists()) {
- throw new RuntimeException("The steering file " + args[0] + " does not exist!");
- }
- setup(xmlRunControlFile);
- }
- }
-
- public void enableHeadlessMode() {
- System.setProperty("hep.aida.IAnalysisFactory", BatchAnalysisFactory.class.getName());
- }
-
- /**
- * Add a variable definition to be substituted into the job's XML file. This method is public
- * so that caller's not using the CL can still define necessary variables for the steering
- * file.
- *
+ * Add a Driver to the internal Driver map.
+ *
+ * @param name the unique name of the Driver
+ * @param driver the instance of the Driver
+ */
+ private void addDriver(final String name, final Driver driver) {
+ if (driverMap.containsKey(name)) {
+ throw new RuntimeException("Duplicate driver name: " + name);
+ }
+ driverMap.put(name, driver);
+ }
+
+ /**
+ * Add an input LCIO file to be proceesed.
+ *
+ * @param inputFile The input LCIO file.
+ */
+ public void addInputFile(final File inputFile) {
+ if (isSetup) {
+ throw new RuntimeException("Input files cannot be added when manager has already been setup.");
+ }
+ inputFiles.add(inputFile);
+ }
+
+ /**
+ * Add a variable definition to be substituted into the job's XML file. This method is public so that caller's not
+ * using the CL can still define necessary variables for the steering file.
+ *
* @param key The variable name.
* @param value The variable's value.
*/
- public void addVariableDefinition(String key, String value) {
- if (verbose) {
- logStream.println(key + " = " + value);
- }
+ public void addVariableDefinition(final String key, final String value) {
+ LOGGER.config(key + " = " + value);
if (!this.variableMap.containsKey(key)) {
variableMap.put(key, value);
} else {
throw new RuntimeException("Duplicate variable definition: " + key);
}
}
-
- /**
- * Add an input LCIO file to be proceesed.
- * @param inputFile The input LCIO file.
- */
- public void addInputFile(File inputFile) {
- if (wasSetup) {
- throw new RuntimeException("Input files cannot be added when manager has already been setup.");
- }
- inputFiles.add(inputFile);
+
+ /**
+ * Configure start of job (usually done automatically).
+ */
+ public void configure() {
+ this.getDriverAdapter().start(null);
+ }
+
+ /**
+ * Create a driver adapter.
+ */
+ private void createDriverAdapter() {
+ if (this.isSetup == false) {
+ throw new IllegalStateException("The job manager was never setup.");
+ }
+ final Driver topDriver = new Driver();
+ for (final Driver driver : this.getDriverExecList()) {
+ topDriver.add(driver);
+ }
+ driverAdapter = new DriverAdapter(topDriver);
+ }
+
+ /**
+ * Create the <code>Driver</code> execution list.
+ */
+ private void createDriverExecList() {
+ // Make a list of Drivers to be executed.
+ final List<Element> exec = root.getChild("execute").getChildren("driver");
+ for (final Element execDriver : exec) {
+ final String driverName = execDriver.getAttributeValue("name");
+ final Driver driverFind = driverMap.get(driverName);
+ if (driverFind != null) {
+ driverExec.add(driverFind);
+ } else {
+ throw new RuntimeException("A Driver called " + driverName + " was not found.");
+ }
+ }
+
+ // Add the drivers to the LCSimLoop.
+ for (final Driver driver : driverExec) {
+ loop.add(driver);
+ }
+ }
+
+ /**
+ * Turn on the batch analysis factory so plots are not shown on the screen even when <code>Plotter.show()</code> is
+ * called.
+ */
+ public void enableHeadlessMode() {
+ System.setProperty("hep.aida.IAnalysisFactory", BatchAnalysisFactory.class.getName());
+ }
+
+ /**
+ * Activate end of job hooks (usually done automatically).
+ */
+ public void finish() {
+ this.getDriverAdapter().finish(null);
+ }
+
+ /**
+ * Get a <code>DriverAdapter</code> from the currently configured Driver list.
+ *
+ * @return the driver adapter
+ */
+ public DriverAdapter getDriverAdapter() {
+ if (driverAdapter == null) {
+ // Driver adapter created on demand.
+ this.createDriverAdapter();
+ }
+ return driverAdapter;
+ }
+
+ /**
+ * Return a list of Drivers to be executed. This can be used from an external framework like JAS3. The list will be
+ * empty unless the <code>setup()</code> method has been called.
+ *
+ * @return A <code>List</code> of <code>Drivers</code>.
+ */
+ public List<Driver> getDriverExecList() {
+ return this.driverExec;
+ }
+
+ /**
+ * Get the <code>LCSimLoop</code> of this JobManager.
+ *
+ * @return The LCSimLoop.
+ */
+ public LCSimLoop getLCSimLoop() {
+ return loop;
+ }
+
+ /**
+ * Get a list of a class's setter methods.
+ *
+ * @param klass The class.
+ * @return A list of setter methods.
+ */
+ private List<Method> getSetterMethods(final Class klass) {
+ final List<Method> methods = new ArrayList<Method>();
+ Class currentClass = klass;
+ while (currentClass != null) {
+ for (final Method method : currentClass.getMethods()) {
+ if (method.getName().startsWith("set") && !methods.contains(method)) {
+ methods.add(method);
+ }
+ }
+ currentClass = currentClass.getSuperclass();
+ }
+ return methods;
+ }
+
+ /**
+ * Initialize the <code>LCSimLoop</code>.
+ */
+ private void initializeLoop() {
+ LOGGER.config("initializing LCSim loop");
+ loop = new LCSimLoop();
+ if (this.eventPrintInterval != null) {
+ loop.addRecordListener(new EventPrintLoopAdapter(this.eventPrintInterval));
+ LOGGER.config("enabled event marker printing with interval " + eventPrintInterval);
+ } else {
+ LOGGER.config("no event printing enabled");
+ }
+ }
+
+ /**
+ * Parse command-line options and setup job state from them. This method calls {@link #setup(File)} to load the
+ * steering paramters from an XML file, after processing other command line options. This method is private so that
+ * callers must all use the {@link #main(String[])} routine as the primary entry point.
+ *
+ * @param args The command line arguments.
+ */
+ public void parse(final String args[]) {
+
+ LOGGER.config("parsing command line arguments");
+
+ // Print help and exit.
+ if (args.length == 0) {
+ printHelp();
+ }
+
+ // Setup parser.
+ final CommandLineParser parser = new PosixParser();
+
+ // Parse the command line arguments.
+ try {
+ commandLine = parser.parse(OPTIONS, args);
+ } catch (final ParseException x) {
+ throw new RuntimeException("Problem parsing command line options.", x);
+ }
+
+ // Load a properties file containing variable definitions.
+ if (commandLine.hasOption("p")) {
+ final String[] propValues = commandLine.getOptionValues("p");
+ for (final String propFileName : propValues) {
+ InputStream in = null;
+ try {
+ in = new FileInputStream(propFileName);
+ } catch (final FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ final Properties props = new Properties();
+ try {
+ props.load(in);
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ for (final Entry<Object, Object> entry : props.entrySet()) {
+ final String key = (String) entry.getKey();
+ final String value = (String) entry.getValue();
+ this.addVariableDefinition(key, value);
+ }
+ LOGGER.config("loaded variable definitions from " + propFileName);
+ }
+ }
+
+ // Process the user variable definitions.
+ if (commandLine.hasOption("D")) {
+ final String[] defValues = commandLine.getOptionValues("D");
+ for (final String def : defValues) {
+ final String[] s = def.split("=");
+ if (s.length != 2) {
+ throw new RuntimeException("Bad variable format: " + def);
+ }
+ final String key = s[0];
+ final String value = s[1];
+ this.addVariableDefinition(key, value);
+ LOGGER.config("defined " + key + " = " + value);
+ }
+ }
+
+ // Rewrite XML file with variables resolved.
+ if (commandLine.hasOption("w")) {
+ this.rewriteSteering = true;
+ final String rewritePath = commandLine.getOptionValue("w");
+ this.rewriteFile = new File(rewritePath);
+ if (this.rewriteFile.exists()) {
+ throw new RuntimeException("Rewrite file already exists: " + rewritePath);
+ }
+ LOGGER.config("XML will be rewritten to " + this.rewriteFile.getPath());
+ }
+
+ // Set max number of events to run.
+ if (commandLine.hasOption("n")) {
+ this.numberOfEvents = Integer.valueOf(commandLine.getOptionValue("n"));
+ LOGGER.config("max number of events set to " + this.numberOfEvents);
+ }
+
+ // Set number of events to skip.
+ if (commandLine.hasOption("s")) {
+ this.skipEvents = Integer.valueOf(commandLine.getOptionValue("s"));
+ LOGGER.config("skip events set to " + this.skipEvents);
+ }
+
+ // Perform a dry run, not processing any events but doing job setup.
+ if (commandLine.hasOption("x")) {
+ this.dryRun = true;
+ LOGGER.config("dry run is enabled");
+ }
+
+ // Interpret steering argument as a resource rather than file path.
+ if (commandLine.hasOption("r")) {
+ this.useSteeringResource = true;
+ LOGGER.config("steering resource enabled");
+ }
+
+ // Check that there is exactly one extra argument for the XML steering file.
+ if (commandLine.getArgList().size() == 0) {
+ throw new RuntimeException("Missing LCSim XML file argument.");
+ } else if (commandLine.getArgList().size() > 1) {
+ throw new RuntimeException("Too many extra arguments.");
+ }
+
+ // Local LCIO files to process.
+ if (commandLine.hasOption("i")) {
+ final String[] files = commandLine.getOptionValues("i");
+ for (final String fileName : files) {
+ final File file = new File(fileName);
+ if (!file.exists()) {
+ throw new RuntimeException("File given as command line option does not exist: " + fileName);
+ }
+ inputFiles.add(new File(fileName));
+ LOGGER.config("added input file " + fileName);
+ }
+ }
+
+ // Run in headless mode in which plots will not show.
+ if (commandLine.hasOption("b")) {
+ this.enableHeadlessMode();
+ LOGGER.config("headless mode enabled");
+ }
+
+ // Steering argument points to either a file or embedded resource.
+ final String steering = (String) commandLine.getArgList().get(0);
+
+ if (commandLine.hasOption("e")) {
+ this.eventPrintInterval = Long.parseLong(commandLine.getOptionValue("e"));
+ LOGGER.config("eventPrintInterval: " + this.eventPrintInterval);
+ if (this.eventPrintInterval <= 0) {
+ throw new IllegalArgumentException("The event print interval must be > 0.");
+ }
+ }
+
+ if (commandLine.hasOption("d")) {
+ this.detectorName = commandLine.getOptionValue("d");
+ LOGGER.config("detector: " + this.detectorName);
+ }
+
+ if (commandLine.hasOption("R")) {
+ this.runNumber = Integer.parseInt(commandLine.getOptionValue("R"));
+ LOGGER.config("runNumber: " + this.runNumber);
+ }
+
+ if (this.detectorName != null && this.runNumber == null ||
+ this.runNumber != null && this.detectorName == null) {
+ throw new IllegalArgumentException("The detector name and run number must be given together.");
+ }
+
+ // This will actually initialize everything from the steering file so it must come last.
+ if (this.useSteeringResource) {
+ // Using an embedded resource in the jar for steering.
+ LOGGER.config("initializing from steering resource " + steering);
+ this.setup(steering);
+ } else {
+ // Steering from a local file.
+ final File xmlRunControlFile = new File(steering);
+ if (!xmlRunControlFile.exists()) {
+ throw new RuntimeException("The steering file " + args[0] + " does not exist!");
+ }
+ LOGGER.config("initializing from steering file " + xmlRunControlFile.getPath());
+ this.setup(xmlRunControlFile);
+ }
+ }
+
+ /**
+ * Print the list of input files.
+ */
+ private void printInputFileList() {
+ final StringBuffer sb = new StringBuffer();
+ sb.append('\n');
+ sb.append("--- Input Files ---");
+ for (final File file : inputFiles) {
+ sb.append(file.getAbsolutePath());
+ sb.append('\n');
+ }
+ LOGGER.config(sb.toString());
+ }
+
+ /**
+ * Print out extra URLs added to the classpath from the XML.
+ */
+ private void printUserClasspath() {
+ final StringBuffer sb = new StringBuffer();
+ final URL[] urls = ((URLClassLoader) classLoader).getURLs();
+ if (urls.length > 0) {
+ for (final URL url : ((URLClassLoader) classLoader).getURLs()) {
+ sb.append(url + " ");
+ }
+ sb.append('\n');
+ LOGGER.config("Extra classpath URLs:" + sb.toString());
+ }
+ }
+
+ /**
+ * Create the constants from the XML file.
+ */
+ private void processConstants() {
+ final Element define = root.getChild("define");
+ if (define != null) {
+ for (final Object o : define.getChildren()) {
+ final Element e = (Element) o;
+ final Text txt = (Text) e.getContent().get(0);
+ final double dval = factory.computeDouble(txt.getValue());
+ this.constantsMap.put(e.getName(), dval);
+ factory.addConstant(e.getName(), dval);
+ }
+ }
+ }
+
+ /**
+ * A fairly ugly method to process the provided XML parameters on a <code>Driver</code>.
+ *
+ * @param driverClass the Java class of the driver
+ * @param newDriver the instantiated Driver
+ * @param parameters the list of XML parameters
+ */
+ private void processDriverParameters(final Class driverClass, final Driver newDriver, final List<Element> parameters) {
+ // Process the parameter elements.
+ for (final Element parameterElement : parameters) {
+
+ // The parameter's setter method that we will try to find.
+ Method setter = null;
+
+ // The parameter's type that will be inferred from the method or provided by an XML attribute.
+ Class propertyType = null;
+
+ // Get the parameter's name.
+ final String pname = parameterElement.getName();
+
+ // Find setter methods that look like good matches for this parameter.
+ final List<Method> methods = this.getSetterMethods(driverClass);
+ final List<Method> methodCandidates = new ArrayList<Method>();
+ for (final Method method : methods) {
+ String propHack = method.getName().replaceFirst("set", "");
+ propHack = propHack.substring(0, 1).toLowerCase() + propHack.substring(1);
+ if (propHack.equals(pname)) {
+ methodCandidates.add(method);
+ }
+ }
+ if (methodCandidates.size() == 1) {
+ // Found the single setter method so try to use it.
+ setter = methodCandidates.get(0);
+ if (setter.getParameterTypes().length > 1) {
+ throw new RuntimeException("The set method has too many arguments for parameter: " + pname);
+ }
+ propertyType = setter.getParameterTypes()[0];
+ } else if (methodCandidates.size() > 1) {
+ // Found several, overloaded methods. Try to disambiguate them if possible.
+ if (parameterElement.getAttribute("type") == null) {
+ throw new RuntimeException("Parameter " + pname + " in Driver " + driverClass.getCanonicalName()
+ + " is overloaded, but a type field is missing from the parameter's XML element.");
+ }
+ try {
+ // Try a primitive type first.
+ propertyType = getPrimitiveType(parameterElement.getAttribute("type").getValue());
+
+ // If type is null, then parameter is an Object and not a primitive, or it
+ // is not a valid type.
+ if (propertyType == null) {
+ propertyType = Class.forName(parameterElement.getAttribute("type").getValue());
+ }
+ } catch (final ClassNotFoundException x) {
+ throw new RuntimeException("Bad type " + parameterElement.getAttribute("type").getValue()
+ + " given for parameter " + pname + ".");
+ }
+ // Find a method that matches the user type.
+ for (final Method candidateMethod : methodCandidates) {
+ if (candidateMethod.getParameterTypes().length == 1
+ && candidateMethod.getParameterTypes()[0].equals(propertyType)) {
+ setter = candidateMethod;
+ break;
+ }
+ }
+ } else if (methodCandidates.size() == 0) {
+ // No method found. The parameter name is probably invalid.
+ throw new RuntimeException("Set method for Driver parameter " + pname + " was not found.");
+ }
+
+ // No setter method found.
+ if (setter == null) {
+ throw new RuntimeException("Unable to find set method for parameter " + pname + ".");
+ }
+
+ // Convert the parameter to the appropriate type.
+ final IParameterConverter converter = paramConverter.getConverterForType(propertyType);
+ if (converter == null) {
+ throw new RuntimeException("No converter found for parameter " + parameterElement.getName()
+ + " with type " + propertyType.getName() + ".");
+ }
+ final Object nextParameter = converter.convert(factory, parameterElement);
+
+ // Call the setter with the parameter as argument.
+ final Object pargs[] = new Object[1];
+ pargs[0] = nextParameter;
+ try {
+ // This invokes the setter method of the driver.
+ setter.invoke(newDriver, pargs);
+
+ // Print parameters and values as they are set.
+ LOGGER.fine(" " + pname + " = " + parameterElement.getText().trim());
+
+ } catch (final Exception x) {
+ throw new RuntimeException("Problem processing parameter " + parameterElement.getName() + ".", x);
+ }
+ } // parameter loop
+ }
+
+ /**
+ * Process a single event.
+ *
+ * @param event
+ */
+ public void processEvent(final EventHeader event) {
+ this.getDriverAdapter().recordSupplied(new RecordEvent(loop, event));
+ }
+
+ /**
+ * Create a <code>File</code> object from the text in an XML element.
+ *
+ * @param fileElement The element containing a file path or URL.
+ * @param fileList List to append new <code>File</code>.
+ * @return The <code>File</code> object.
+ */
+ private File processFileElement(final Element fileElement, final List<File> fileList) {
+
+ final String fileLoc = this.processPath(fileElement.getText().trim());
+ File file = null;
+
+ // Try to process the file text as a URL.
+ try {
+ final URL fileURL = new URL(fileLoc);
+
+ // Local file URL.
+ if (fileLoc.startsWith("file:")) {
+ file = new File(fileURL.getPath());
+ } else {
+ // Remote file URL.
+ try {
+ file = this.fileCache.getCachedFile(fileURL);
+ } catch (final IOException x) {
+ throw new RuntimeException("Unable to fetch file " + fileLoc + " to the cache directory.", x);
+ }
+ }
+ } catch (final MalformedURLException x) {
+ // Interpret as local file.
+ file = new File(fileLoc);
+ }
+
+ // Add to the list.
+ if (fileList != null) {
+ fileList.add(file);
+ }
+
+ return file;
+ }
+
+ /**
+ * Cleanup file text and add to the file list.
+ *
+ * @param fileText the text containing the file's path from the XML
+ * @param fileList the list of files to which the new file will be appended
+ * @return the file that was created from the text
+ */
+ private File processFileText(final String fileText, final List<File> fileList) {
+ final Element fileElement = new Element("file");
+ fileElement.setText(fileText.trim());
+ return this.processFileElement(fileElement, fileList);
+ }
+
+ /**
+ * Process the file path string to substitute in the user's home directory for the "~" character. This is needed if
+ * running on Windows.
+ *
+ * @param path The original path.
+ * @return The path with home dir substitution.
+ */
+ private String processPath(final String path) {
+ if (path.startsWith("~")) {
+ return path.replaceFirst("~", System.getProperty("user.home"));
+ } else {
+ return path;
+ }
+ }
+
+ /**
+ * Rewrite the XML steering file after resolving variables (done externally). The output path is set by command line
+ * argument to "-w".
+ *
+ * @param doc The XML steering doc with variables substituted.
+ */
+ private void rewriteXMLSteering(final Document doc) {
+ LOGGER.info("Rewriting XML to " + this.rewriteFile);
+ final XMLOutputter outputter = new XMLOutputter();
+ outputter.setFormat(Format.getPrettyFormat());
+ try {
+ final FileOutputStream out = new FileOutputStream(this.rewriteFile);
+ outputter.output(doc, out);
+ out.close();
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
}
/**
* Execute a job using the current parameters.
*/
public boolean run() {
-
+
// If setup was not called first, then abort the job.
- if (!wasSetup) {
- logStream.println("Aborting job! Setup was never called.");
+ if (!isSetup) {
+ LOGGER.info("Aborting job! Setup was never called.");
return false;
}
- // Dry run selected. No events will be processed here.
- if (performDryRun) {
- logStream.println("Executed dry run. No events processed!");
+ // Dry run selected. No events will be processed.
+ if (dryRun) {
+ LOGGER.info("Executed dry run. No events processed!");
return false;
}
-
+
+ boolean okay = true;
+
try {
// Add the LCIO files to the loop.
loop.setLCIORecordSource(new LCIOEventSource(this.getClass().getSimpleName(), inputFiles));
+
+ // Set up user supplied conditions information (already checked that these were both given if one was used).
+ initializeConditions();
// Setup dummy detector if selected.
if (dummyDetector) {
- logStream.println("Using dummy detector for conditions system!");
+ LOGGER.info("Using dummy detector for conditions system!");
loop.setDummyDetector("dummy");
}
- // Driver statistics printout.
- PrintStream statsStream = null;
- if (printDriverStatistics) {
- statsStream = logStream;
- }
-
- if (verbose) {
- logStream.println("Start time: " + (new Date()));
- logStream.println();
- }
-
- if (skipEvents > 0) {
- if (verbose) {
- logStream.println("Skipping " + skipEvents + " events.");
- }
+ this.jobStart = System.currentTimeMillis();
+
+ LOGGER.info("Job started: " + new Date(jobStart));
+
+ if (this.skipEvents > 0) {
+ LOGGER.info("Skipping " + skipEvents + " events.");
loop.skip(skipEvents);
}
// Execute the loop.
- long processedEvents = loop.loop(numberOfEvents, statsStream);
- if (processedEvents != numberOfEvents) {
- logStream.println("End of file reached");
- } else if (verbose) {
- logStream.println();
- logStream.println("End time: " + (new Date()));
- }
- }
- // Catch other fatal exceptions thrown from the loop.
- catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- // Cleanup the loop.
- loop.dispose();
- //loop = null;
-
- // Job was successful.
- return true;
- }
-
- /**
- * Get the <code>LCSimLoop</code> of this JobManager.
- *
- * @return The LCSimLoop.
- */
- public LCSimLoop getLCSimLoop() {
- return loop;
- }
-
- /**
- * Return a list of Drivers to be executed. This can be used from an external framework like
- * JAS3. The list will be empty unless the <code>setup()</code> method has been called.
- *
- * @return A <code>List</code> of <code>Drivers</code>.
- */
- public List<Driver> getDriverExecList() {
- return this.driverExec;
+ final long processedEvents = loop.loop(numberOfEvents, this.printDriverStatistics ? System.out : null);
+ if (numberOfEvents != -1 && processedEvents != numberOfEvents) {
+ LOGGER.info("End of file was reached.");
+ }
+ LOGGER.info("Job processed " + processedEvents + " events.");
+ this.jobEnd = System.currentTimeMillis();
+
+ LOGGER.info("Job ended: " + new Date(this.jobEnd));
+ final long elapsed = this.jobStart - this.jobEnd;
+ LOGGER.info("Job took " + elapsed + " which is " + elapsed / processedEvents + " ms/event.");
+
+ } catch (final Exception e) {
+ LOGGER.log(Level.SEVERE, "A fatal error occurred during the job.", e);
+ okay = false;
+ } finally {
+ try {
+ // Dispose of the loop.
+ loop.dispose();
+ } catch (final Exception e) {
+ LOGGER.log(Level.WARNING, "An error occurred during job cleanup.", e);
+ okay = false;
+ }
+ }
+
+ // Return true or false depending on whether job was successfully executed.
+ return okay;
+ }
+
+ /**
+ * Set whether a dry run should be performed which will only perform setup and not process any events.
+ *
+ * @param dryRun <code>true</code> to enable a dry run
+ */
+ public void setDryRun(final boolean dryRun) {
+ this.dryRun = dryRun;
+ }
+
+ /**
+ * Set the number of events to run on the loop before ending the job. This should be called after the
+ * {@link #setup(File)} method is called or it will be overridden.
+ */
+ public void setNumberOfEvents(final int numberOfEvents) {
+ this.numberOfEvents = numberOfEvents;
+ }
+
+ /**
+ * Setup the job parameters from an XML Document.
+ * <p>
+ * This method contains the primary logic for setting up job parameters from an XML file. The other setup methods
+ * such as {@link #setup(InputStream)}, {@link #setup(String)} and {@link #setup(File)} all call this method.
+ *
+ * @param xmlDocument The lcsim recon XML document describing the job.
+ */
+ private void setup(final Document xmlDocument) {
+
+ // This method should not be called more than once.
+ if (isSetup) {
+ throw new IllegalStateException("The job manager was already setup.");
+ }
+
+ // Set the root element from the XML document.
+ root = xmlDocument.getRootElement();
+
+ // Do variable substitutions into the document first.
+ this.substituteVariables(xmlDocument);
+
+ // Rewrite XML after variable substitution.
+ if (this.rewriteSteering) {
+ this.rewriteXMLSteering(xmlDocument);
+ }
+
+ // Setup the job control parameters.
+ this.setupJobControlParameters();
+
+ // Setup the class loader.
+ this.setupClassLoader();
+
+ // Setup system of units.
+ this.setupUnits();
+
+ // Process the constant definitions.
+ this.processConstants();
+
+ // Initialize the LCSimLoop.
+ this.initializeLoop();
+
+ // Setup drivers with parameters and execution order.
+ this.setupDrivers();
+
+ // Setup the file cache.
+ this.setupFileCache();
+
+ // Setup the input files.
+ this.setupInputFiles();
+
+ // Throw an error if there were no files provided and dry run is not enabled.
+ if (inputFiles.size() == 0 && !this.dryRun) {
+ LOGGER.severe("No input files provided and dry run is not enabled.");
+ throw new IllegalStateException("No input files to process.");
+ }
+
+ // Flag JobManager as setup.
+ isSetup = true;
}
/**
* Setup job parameters from a <code>File</code>.
- *
- * @param file
- */
- public void setup(File file) {
+ *
+ * @param file the path to the XML file
+ */
+ public void setup(final File file) {
try {
- setup((new FileInputStream(file)));
- } catch (FileNotFoundException x) {
+ this.setup(new FileInputStream(file));
+ } catch (final FileNotFoundException x) {
throw new RuntimeException(x);
}
}
/**
- * Setup job parameters from an embedded resource. This method calls
- * {@link #setup(InputStream)}.
- */
- public void setup(String resourceURL) {
- setup(this.getClass().getResourceAsStream(resourceURL));
- }
-
- /**
- * Setup job parameters from an <code>InputStream</code> with XML text.
- *
- * @param in The XML input stream.
- */
- public void setup(InputStream in) {
+ * Setup job parameters from an <code>InputStream</code> that should be valid XML text.
+ *
+ * @param in the XML input stream
+ */
+ public void setup(final InputStream in) {
// Make the Document builder.
- SAXBuilder builder = new SAXBuilder();
+ final SAXBuilder builder = new SAXBuilder();
// Setup XML schema validation.
builder.setEntityResolver(new ClasspathEntityResolver());
@@ -511,429 +1086,163 @@
Document doc = null;
try {
doc = builder.build(in);
- } catch (Exception x) {
+ } catch (final Exception x) {
throw new RuntimeException(x);
}
// Setup the JobControlManager from the XML file.
- setup(doc);
- }
-
- /**
- * Setup the job parameters from an XML Document. Though it isn't publically accessible, this
- * method contains the primary logic for setting up job parameters from an XML file. The other
- * setup methods, namely, {@link #setup(InputStream)}, {@link #setup(String)} and
- * {@link #setup(File)}, all eventually call this method.
- *
- * @param doc The lcsim recon XML document describing the job.
- */
- private void setup(Document doc) {
- if (wasSetup) {
- logStream.println("Ignoring call to setup as it was already called.");
+ this.setup(doc);
+ }
+
+ /**
+ * Setup job parameters from an embedded resource. This method calls {@link #setup(InputStream)}.
+ */
+ public void setup(final String resourceURL) {
+ this.setup(this.getClass().getResourceAsStream(resourceURL));
+ }
+
+ /**
+ * Setup the manager's class loader.
+ */
+ private void setupClassLoader() {
+
+ if (classLoader != null) {
+ LOGGER.info("The ClassLoader was already set externally, so custom classpaths will be ignored!");
return;
}
-
- // Set the root element.
- root = doc.getRootElement();
-
- // Do variable substitutions.
- substituteVariables(doc);
-
- // Rewrite XML after variable substitution. Correctness of values,
- // such as existence of input file paths, is NOT checked.
- if (this.rewrite) {
- rewriteXMLSteering(doc);
- }
-
- // Setup the job control parameters.
- setupJobControlParameters();
-
- // Print system properties.
- if (printSystemProperties) {
- printSystemProperties(logStream);
- }
-
- // Setup the class loader.
- setupClassLoader();
-
- // Setup units.
- setupUnits();
-
- // Process the variable definitions.
- processConstants();
-
- // Check for required conditions.
- checkConditions();
-
- // Setup drivers with parameters and execution order.
- setupDrivers();
-
- // Setup the file cache.
- setupFileCache();
-
- // Setup the input files.
- setupInputFiles();
-
- // Check if a dry run should be performed when no input files are present.
- if (inputFiles.size() == 0) {
- performDryRun = true;
- logStream.println("No input files provided by XML or command line. Dry run will be enabled.");
- }
-
- // Flag JobManager as setup.
- wasSetup = true;
- }
-
- /**
- * Perform variable substitution within all text data in a entire document.
- *
- * @param doc The XML document.
- */
- private void substituteVariables(Document doc) {
- substituteVariables(doc.getRootElement());
- }
-
- /**
- * Substitute values from the <code>variableMap</code> into an XML element and all its
- * children, recursively.
- *
- * @param element The XML element.
- * @throw RuntimeException If a variable does not exist in the <code>variableMap</code>.
- */
- private void substituteVariables(Element element) {
- String text = element.getTextNormalize();
- if (text.length() != 0) {
- // Create a new matcher.
- Matcher match = varPattern.matcher(text);
-
- // No variables were used.
- if (!match.find())
- return;
-
- // Text data on which to perform substitutions.
- String newText = new String(text);
-
- // Reset the matcher.
- match.reset();
-
- // Loop over the matches.
- while (match.find()) {
-
- // Variable string with ${...} enclosure included.
- String var = match.group();
-
- // The name of the variable for lookup.
- String varName = var.substring(2, var.length() - 1);
-
- // The value of the variable.
- String varValue = variableMap.get(varName);
-
- // If a variable was not defined, then the application will immediately exit here.
- if (varValue == null) {
- throw new RuntimeException("Variable not defined: " + varName);
- }
-
- // Substitute this variable's value into the text.
- newText = newText.replace(var, varValue);
- }
-
- // Set this element's new text value.
- element.setText(newText);
- }
-
- // Recursively process all child elements of this one.
- for (Iterator it = element.getChildren().iterator(); it.hasNext();) {
- substituteVariables((Element) it.next());
- }
- }
-
- /**
- * Rewrite the XML steering file after resolving variables (done externally). The output path
- * is set by command line argument to "-w".
- *
- * @param doc The XML steering doc with variables substituted.
- */
- private void rewriteXMLSteering(Document doc) {
- if (verbose) {
- logStream.println("Rewriting XML to " + this.rewriteFile + " ...");
- }
- XMLOutputter outputter = new XMLOutputter();
- outputter.setFormat(Format.getPrettyFormat());
- try {
- FileOutputStream out = new FileOutputStream(this.rewriteFile);
- outputter.output(doc, out);
- out.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Setup the drivers from the XML job file, adding them to the JobManager's
- * <code>driverMap</code> .
+
+ final Element classpath = root.getChild("classpath");
+ final List<URL> urlList = new ArrayList<URL>();
+ if (classpath != null) {
+ for (final Object jarObject : classpath.getChildren("jar")) {
+ final Element jarElement = (Element) jarObject;
+ try {
+ urlList.add(new File(this.processPath(jarElement.getText())).toURI().toURL());
+ } catch (final Exception x) {
+ throw new RuntimeException("Bad jar location: " + jarElement.getText(), x);
+ }
+ }
+ for (final Object jarUrlObject : classpath.getChildren("jarUrl")) {
+ final Element jarUrlElement = (Element) jarUrlObject;
+ try {
+ urlList.add(new URL(jarUrlElement.getText()));
+ } catch (final Exception x) {
+ throw new RuntimeException("Bad jar URL: " + jarUrlElement.getText(), x);
+ }
+ }
+ for (final Object cpDirObject : classpath.getChildren("directory")) {
+ final Element cpDirElement = (Element) cpDirObject;
+ try {
+ final File cpFile = new File(this.processPath(cpDirElement.getText()));
+ if (!cpFile.isDirectory()) {
+ throw new RuntimeException("The classpath component " + cpFile.getPath()
+ + " is not a valid directory!");
+ }
+ urlList.add(cpFile.toURI().toURL());
+ } catch (final Exception x) {
+ throw new RuntimeException("Bad classpath directory: " + cpDirElement.getText(), x);
+ }
+ }
+ }
+ final URL[] urls = urlList.toArray(new URL[] {});
+
+ classLoader = new LCSimClassLoader(urls);
+
+ // Print extra user classpath entries.
+ this.printUserClasspath();
+ }
+
+ /**
+ * Create the drivers from the XML.
*/
private void setupDrivers() {
- if (printDriversDetailed) {
- logStream.println("--- Drivers ---");
- }
-
- // Instantiate the LCSimLoop here in case subsequently created Drivers want to override
- // its default conditions implementation.
- loop = new LCSimLoop();
-
+
// Loop over the list of driver elements.
- List<Element> drivers = root.getChild("drivers").getChildren("driver");
- for (Element driver : drivers) {
+ final List<Element> drivers = root.getChild("drivers").getChildren("driver");
+ for (final Element driver : drivers) {
// Get the name of the Driver.
- String name = driver.getAttributeValue("name");
+ final String name = driver.getAttributeValue("name");
// Get the fully qualified type of the Driver. ([packageName].[className])
- String type = driver.getAttributeValue("type");
-
- // Translate from a short name (optional).
- if (availableDrivers.get(type) != null) {
- type = availableDrivers.get(type);
- }
-
- //
- // Get Class, BeanInfo, and Constructor, and setup the new Driver instance.
- //
-
- // Class of the Driver.
+ final String type = driver.getAttributeValue("type");
+
+ // Get the Java class of the Driver.
Class driverClass;
try {
- driverClass = loader.loadClass(type);
- } catch (ClassNotFoundException x) {
+ driverClass = classLoader.loadClass(type);
+ } catch (final ClassNotFoundException x) {
throw new RuntimeException("The Driver class " + type + " was not found.", x);
}
- if (printDriversDetailed)
- logStream.println(driverClass.getCanonicalName());
-
- // The Driver instance.
+ LOGGER.fine("adding driver " + driverClass.getCanonicalName());
+
+ // Create an instance of the driver.
Driver newDriver;
try {
newDriver = (Driver) driverClass.newInstance();
- } catch (InstantiationException x) {
- throw new RuntimeException("Failed to create a Driver of class " + type + ". " + "This class might be missing a public constructor with no arguments.", x);
- } catch (IllegalAccessException x) {
- throw new RuntimeException("Cannot access Driver type " + type + ". " + "You may need to make this class or its constructor public.", x);
- }
-
- // Get a list of Driver parameters.
- List<Element> parameters = driver.getChildren();
-
- // Process the parameters.
- for (Element parameterElement : parameters) {
- // The parameter's setter method that we will find.
- Method setter = null;
-
- // The parameter's type that will be inferred from the method or is given by a type
- // string in the case of an overloaded method.
- Class propertyType = null;
-
- // Get the parameter name.
- String pname = parameterElement.getName();
-
- // Find setter methods that look like good matches for this parameter.
- List<Method> methods = getSetterMethods(driverClass);
- List<Method> methodCandidates = new ArrayList<Method>();
- for (Method method : methods) {
- String propHack = method.getName().replaceFirst("set", "");
- propHack = propHack.substring(0, 1).toLowerCase() + propHack.substring(1);
- if (propHack.equals(pname)) {
- methodCandidates.add(method);
- }
- } if (methodCandidates.size() == 1) {
- // Found the single setter method.
- setter = methodCandidates.get(0);
- if (setter.getParameterTypes().length > 1) {
- throw new RuntimeException("The set method has too many arguments for parameter: " + pname);
- }
- propertyType = setter.getParameterTypes()[0];
- } else if (methodCandidates.size() > 1) {
- // Found several, overloaded methods. Try to disambiguate them.
- if (parameterElement.getAttribute("type") == null)
- throw new RuntimeException("Parameter " + pname + " in Driver " + driverClass.getCanonicalName() + " is overloaded, but a type field is missing from the parameter's XML element.");
- try {
- // Try a primitive type first.
- propertyType = getPrimitiveType(parameterElement.getAttribute("type").getValue());
-
- // If type is null, then parameter is an Object and not a primitive, or it
- // is not a
- // valid type.
- if (propertyType == null)
- propertyType = Class.forName(parameterElement.getAttribute("type").getValue());
- } catch (ClassNotFoundException x) {
- throw new RuntimeException("Bad user type: " + parameterElement.getAttribute("type").getValue() + " for parameter " + pname + ".");
- }
- // Find a method that matches the user type.
- for (Method candidateMethod : methodCandidates) {
- if (candidateMethod.getParameterTypes().length == 1 && candidateMethod.getParameterTypes()[0].equals(propertyType)) {
- setter = candidateMethod;
- break;
- }
- }
- } else if (methodCandidates.size() == 0) {
- // No method found. The parameter name is probably invalid.
- throw new RuntimeException("Set method was not found: " + driverClass.getSimpleName() + "." + pname);
- }
-
- // No setter method found.
- if (setter == null) {
- throw new RuntimeException("Unable to find set method for parameter: " + pname);
- }
-
- // Convert the parameter to the appropriate type.
- IParameterConverter converter = paramConverter.getConverterForType(propertyType);
- if (converter == null) {
- throw new RuntimeException("No converter found for parameter " + parameterElement.getName() + " with type " + propertyType.getName() + ".");
- }
- Object nextParameter = converter.convert(factory, parameterElement);
-
- // Call the setter with the parameter as argument.
- Object pargs[] = new Object[1];
- pargs[0] = nextParameter;
- try {
- // This invokes the setter method of the driver.
- setter.invoke(newDriver, pargs);
-
- // Print parameters and values as they are set.
- if (printDriversDetailed)
- logStream.println(" " + pname + " = " + parameterElement.getText().trim());
- } catch (Exception x) {
- throw new RuntimeException("Problem processing parameter " + parameterElement.getName() + ".", x);
- }
- } // parameter loop
-
- // Add a driver to the manager.
- addDriver(name, newDriver);
+ } catch (final InstantiationException x) {
+ throw new RuntimeException("Failed to create a Driver of class " + type + ".", x);
+ } catch (final IllegalAccessException x) {
+ throw new RuntimeException("Cannot access Driver type " + type + ".", x);
+ }
+
+ // Get the list of Driver parameters from the XML.
+ final List<Element> parameters = driver.getChildren();
+
+ // Process the parameters provided for the driver.
+ this.processDriverParameters(driverClass, newDriver, parameters);
+
+ // Add the driver to the manager.
+ this.addDriver(name, newDriver);
+
} // driver loop
- if (printDriversDetailed) {
- logStream.println("--- End Drivers ---");
- }
-
- // Make a list of Drivers to be executed.
- List<Element> exec = root.getChild("execute").getChildren("driver");
- for (Element execDriver : exec) {
- String driverName = execDriver.getAttributeValue("name");
- Driver driverFind = driverMap.get(driverName);
- if (driverFind != null) {
- driverExec.add(driverFind);
- } else {
- throw new RuntimeException("A Driver called " + driverName + " was not found.");
- }
- }
-
- // Add the drivers to the LCSimLoop.
- for (Driver driver : driverExec) {
- loop.add(driver);
- }
- }
-
- /**
- * Add a Driver to the Driver map.
- *
- * @param name The unique name of the Driver.
- * @param driver The instance of the Driver.
- */
- private void addDriver(String name, Driver driver) {
- if (driverMap.containsKey(name)) {
- throw new RuntimeException("Duplicate driver name: " + name);
- }
- driverMap.put(name, driver);
- }
-
- private void printSystemProperties(PrintStream ps) {
- logStream.println("--- System Properties ---");
- for (Entry<Object, Object> entry : System.getProperties().entrySet()) {
- logStream.println(entry.getKey() + " = " + entry.getValue());
- }
- logStream.println("-- End System Properties");
- logStream.println();
- }
-
- /**
- * Cleaup file text and add to file list.
- *
- * @param fileText The file's raw text path from XML file.
- * @param fileList The list files to which new file will be appended.
- * @return The file that was created from the text.
- */
- private File processFileText(String fileText, List<File> fileList) {
- Element fileElement = new Element("file");
- fileElement.setText(fileText.trim());
- return processFileElement(fileElement, fileList);
- }
-
- /**
- * Create a <code>File</code> object from the text in an XML element.
- *
- * @param fileElement The element containing a file path or URL.
- * @param fileList List to append new <code>File</code>.
- * @return The <code>File</code> object.
- */
- private File processFileElement(Element fileElement, List<File> fileList) {
- String fileLoc = processPath(fileElement.getText().trim());
- File file = null;
-
- // Try to process the file text as a URL.
- try {
- URL fileURL = new URL(fileLoc);
-
- // Local file URL.
- if (fileLoc.startsWith("file:")) {
- file = new File(fileURL.getPath());
- }
- // Remote file URL.
- else {
- try {
- file = this.fileCache.getCachedFile(fileURL);
- } catch (IOException x) {
- throw new RuntimeException("Unable to fetch file " + fileLoc + " to the cache directory.", x);
- }
- }
- }
- // Text is not a URL. Attempt to process as local file.
- catch (MalformedURLException x) {
- file = new File(fileLoc);
- }
-
- // Add to list.
- if (fileList != null) {
- fileList.add(file);
- }
-
- return file;
+ // Make the list of drivers to execute.
+ this.createDriverExecList();
+ }
+
+ /**
+ * Setup the file cache.
+ */
+ private void setupFileCache() {
+ if (cacheDirectory != null) {
+ try {
+ fileCache = new FileCache();
+ fileCache.setCacheDirectory(cacheDirectory);
+ fileCache.setPrintStream(null);
+ LOGGER.config("File cache created at " + cacheDirectory);
+ } catch (final IOException x) {
+ throw new RuntimeException(x);
+ }
+ }
}
/**
* Setup the list of input files to be processed from the XML job file.
*/
- @SuppressWarnings("unchecked")
- protected void setupInputFiles() {
+ private void setupInputFiles() {
+
if (root.getChild("inputFiles") == null) {
- logStream.println("No input files in XML file.");
- // this.performDryRun = true;
+ // This is not a warning because input files can be provided via the command line.
+ LOGGER.config("No input files in XML file.");
return;
}
// Process the <file> elements.
- List<Element> files = root.getChild("inputFiles").getChildren("file");
- for (Element fileElem : files) {
- processFileElement(fileElem, this.inputFiles);
+ final List<Element> files = root.getChild("inputFiles").getChildren("file");
+ for (final Element fileElem : files) {
+ this.processFileElement(fileElem, this.inputFiles);
}
// Read lists of file locations given by <fileList> elements.
- List<Element> fileLists = root.getChild("inputFiles").getChildren("fileList");
- for (Element fileList : fileLists) {
- String filePath = fileList.getText();
+ final List<Element> fileLists = root.getChild("inputFiles").getChildren("fileList");
+ for (final Element fileList : fileLists) {
+ final String filePath = fileList.getText();
BufferedReader input;
try {
input = new BufferedReader(new FileReader(new File(filePath)));
- } catch (FileNotFoundException x) {
+ } catch (final FileNotFoundException x) {
throw new RuntimeException("File not found: " + filePath, x);
}
String line = null;
@@ -941,15 +1250,15 @@
// Read the next file, turn the text into an XML element, and process it using
// common method.
while ((line = input.readLine()) != null) {
- processFileText(line.trim(), inputFiles);
- }
- } catch (IOException x) {
+ this.processFileText(line.trim(), inputFiles);
+ }
+ } catch (final IOException x) {
throw new RuntimeException(x);
} finally {
if (input != null) {
try {
input.close();
- } catch (IOException e) {
+ } catch (final IOException e) {
e.printStackTrace();
}
}
@@ -957,91 +1266,61 @@
}
// Process <fileSet> elements.
- List<Element> fileSets = (List<Element>) root.getChild("inputFiles").getChildren("fileSet");
- for (Element fileSet : fileSets) {
- Attribute basedirAttrib = fileSet.getAttribute("baseDir");
+ final List<Element> fileSets = root.getChild("inputFiles").getChildren("fileSet");
+ for (final Element fileSet : fileSets) {
+ final Attribute basedirAttrib = fileSet.getAttribute("baseDir");
String basedir = "";
if (basedirAttrib != null) {
basedir = basedirAttrib.getValue();
}
- List<Element> fsFiles = fileSet.getChildren("file");
- for (Element file : fsFiles) {
- String filePath = basedir + File.separator + file.getText().trim();
- processFileText(filePath, inputFiles);
+ final List<Element> fsFiles = fileSet.getChildren("file");
+ for (final Element file : fsFiles) {
+ final String filePath = basedir + File.separator + file.getText().trim();
+ this.processFileText(filePath, inputFiles);
}
}
// Read <fileRegExp> elements, which may only reference local files, not URLs.
- List<Element> fileRegExps = (List<Element>) root.getChild("inputFiles").getChildren("fileRegExp");
- for (Element fileRegExp : fileRegExps) {
- Pattern pattern = Pattern.compile(fileRegExp.getText());
- String basedir = fileRegExp.getAttributeValue("baseDir");
- File dir = new File(basedir);
- if (!dir.isDirectory())
+ final List<Element> fileRegExps = root.getChild("inputFiles").getChildren("fileRegExp");
+ for (final Element fileRegExp : fileRegExps) {
+ final Pattern pattern = Pattern.compile(fileRegExp.getText());
+ final String basedir = fileRegExp.getAttributeValue("baseDir");
+ final File dir = new File(basedir);
+ if (!dir.isDirectory()) {
throw new RuntimeException(basedir + " is not a valid directory!");
- String dirlist[] = dir.list();
- if (verbose) {
- logStream.println();
- }
- for (String file : dirlist) {
+ }
+ final String dirlist[] = dir.list();
+ for (final String file : dirlist) {
if (file.endsWith(".slcio")) {
- Matcher matcher = pattern.matcher(file);
+ final Matcher matcher = pattern.matcher(file);
if (matcher.matches()) {
- processFileText(basedir + File.separator + file, inputFiles);
- if (verbose) {
- logStream.println("Matched file <" + file.toString() + "> to pattern <" + pattern.toString() + ">");
- }
+ this.processFileText(basedir + File.separator + file, inputFiles);
+ LOGGER.fine("Matched file <" + file.toString() + "> to pattern <" + pattern.toString() + ">");
} else {
- if (verbose) {
- logStream.println("Did NOT match file <" + file.toString() + "> to pattern <" + pattern.toString() + ">");
- }
+ LOGGER.fine("Did NOT match file <" + file.toString() + "> to pattern <" + pattern.toString()
+ + ">");
}
}
}
}
// Check that all the files exist if job is not a dry run.
- if (!performDryRun) {
- for (File file : inputFiles) {
+ if (!dryRun) {
+ for (final File file : inputFiles) {
if (!file.exists()) {
- logStream.println("The input file " + file.getAbsolutePath() + " does not exist.");
+ LOGGER.info("The input file " + file.getAbsolutePath() + " does not exist.");
throw new RuntimeException("The input file " + file.getAbsolutePath() + " does not exist!");
}
}
}
// Print out the input file list.
- if (printInputFiles) {
- logStream.println();
- logStream.println("--- Input Files ---");
- int index = 1;
- for (File file : inputFiles) {
- logStream.println("[" + index + "] " + file.getAbsolutePath());
- ++index;
- }
- logStream.println("--- End Input Files ---");
- logStream.println();
- }
+ this.printInputFileList();
if (inputFiles.size() == 0) {
- logStream.println("No input files were given in the steering file or command line options. Dry run will be enabled.");
- this.performDryRun = true;
- }
- }
-
- /**
- * Set logging verbosity.
- *
- * @param verbose True to turn on verbose mode; false to turn on quiet mode.
- */
- private void setVerbose(boolean verbose) {
- this.verbose = verbose;
- this.printInputFiles = verbose;
- this.printDriversDetailed = verbose;
- this.printDriverStatistics = verbose;
- this.printSystemProperties = verbose;
- this.printUserClassPath = verbose;
- // this.printVersion = verbose;
+ LOGGER.info("No input files were provided by the steering file or command line options. Dry run will be enabled.");
+ this.dryRun = true;
+ }
}
/**
@@ -1049,228 +1328,59 @@
*/
private void setupJobControlParameters() {
- Element control = root.getChild("control");
- if (control == null)
+ final Element control = root.getChild("control");
+
+ if (control == null) {
+ // The control element is optional.
return;
-
- // Verbose mode.
- Element verboseElement = control.getChild("verbose");
- if (verboseElement != null) {
- verbose = Boolean.valueOf(verboseElement.getText());
- setVerbose(verbose);
- }
-
- // Log file setup needs to come first.
- Element logFileElement = control.getChild("logFile");
- String logFilePath = null;
- if (logFileElement != null) {
- logFilePath = logFileElement.getText();
- File logFile = new File(logFilePath);
- try {
- logFile.createNewFile();
- logStream = new PrintStream(new FileOutputStream(logFile));
-
- // Redirect standard out and err to log file.
- System.setOut(logStream);
- System.setErr(logStream);
- } catch (IOException x) {
- throw new RuntimeException("Error creating log file: " + logFile.toString(), x);
- }
}
// Print hello world message to appear at top of log.
- if (verbose) {
- logStream.println(this.getClass().getCanonicalName() + " is initialized.");
- logStream.println();
- logStream.println("--- Job Control Parameters ---");
- }
-
- // Print log file path now that PrintStream is set.
- if (verbose)
- logStream.println("logFile = " + logFilePath);
+ LOGGER.config(this.getClass().getCanonicalName() + " is initialized.");
// Number of events to run.
- Element controlElement = control.getChild("numberOfEvents");
+ final Element controlElement = control.getChild("numberOfEvents");
if (controlElement != null) {
numberOfEvents = Integer.valueOf(controlElement.getText());
- if (verbose)
- logStream.println("numberOfEvents = " + numberOfEvents);
- }
-
- Element skipElement = control.getChild("skipEvents");
+ LOGGER.config("numberOfEvents: " + numberOfEvents);
+ }
+
+ final Element skipElement = control.getChild("skipEvents");
if (skipElement != null) {
skipEvents = Integer.valueOf(skipElement.getText());
- if (verbose)
- logStream.println("skipEvents = " + skipEvents);
- }
-
- Element dryRunElement = control.getChild("dryRun");
+ LOGGER.config("skipEvents: " + skipEvents);
+ }
+
+ final Element dryRunElement = control.getChild("dryRun");
if (dryRunElement != null) {
- performDryRun = Boolean.valueOf(dryRunElement.getText());
- if (verbose)
- logStream.println("dryRun = " + performDryRun);
+ dryRun = Boolean.valueOf(dryRunElement.getText());
+ LOGGER.config("dryRun: " + dryRun);
}
// The cache directory. Defaults to the current directory.
- Element cacheDirElement = control.getChild("cacheDirectory");
+ final Element cacheDirElement = control.getChild("cacheDirectory");
if (cacheDirElement != null) {
cacheDirectory = new File(cacheDirElement.getText());
- if (!cacheDirectory.exists())
+ if (!cacheDirectory.exists()) {
throw new RuntimeException("cacheDirectory does not exist at location: " + cacheDirElement.getText());
+ }
} else {
- // Default to the user dir if cacheDirectory was not set explicitly.
- // FIXME: Better default might be current directory.
+ // Cache directory defaults to user home dir.
cacheDirectory = new File(System.getProperties().get("user.dir").toString());
}
- if (verbose)
- logStream.println("cacheDirectory = " + cacheDirectory);
-
- Element printInputFilesElement = control.getChild("printInputFiles");
- if (printInputFilesElement != null) {
- printInputFiles = Boolean.valueOf(printInputFilesElement.getText());
- }
-
- if (verbose)
- logStream.println("printInputFiles = " + printInputFiles);
-
- Element printStatisticsElement = control.getChild("printDriverStatistics");
+ LOGGER.config("cacheDirectory: " + cacheDirectory);
+
+ final Element printStatisticsElement = control.getChild("printDriverStatistics");
if (printStatisticsElement != null) {
printDriverStatistics = Boolean.valueOf(printStatisticsElement.getText());
- }
-
- if (verbose)
- logStream.println("printDriverStatistics = " + printDriverStatistics);
-
- Element printSystemPropertiesElement = control.getChild("printSystemProperties");
- if (printSystemPropertiesElement != null) {
- printSystemProperties = Boolean.valueOf(printSystemPropertiesElement.getText());
- }
-
- if (verbose)
- logStream.println("printSystemProperties = " + printSystemProperties);
-
- Element printUserClassPathElement = control.getChild("printUserClassPath");
- if (printUserClassPathElement != null)
- printUserClassPath = Boolean.valueOf(printUserClassPathElement.getText());
-
- if (verbose)
- logStream.println("printUserClassPath = " + printUserClassPath);
-
- // Element printVersionElement = control.getChild("printVersion");
- // if (printVersionElement != null) {
- // printVersion = Boolean.valueOf(printVersionElement.getText());
- // }
-
- Element printDriversDetailedElement = control.getChild("printDriversDetailed");
- if (printDriversDetailedElement != null)
- printDriversDetailed = Boolean.valueOf(printDriversDetailedElement.getText());
-
- if (verbose) {
- logStream.println("printDriversDetailed = " + printDriversDetailed);
- logStream.println("--- End Job Control Parameters ---");
- logStream.println();
- }
-
- Element dummyDetectorElement = control.getChild("dummyDetector");
- if (dummyDetectorElement != null)
+ LOGGER.config("printDriverStatistics: " + printDriverStatistics);
+ }
+
+ final Element dummyDetectorElement = control.getChild("dummyDetector");
+ if (dummyDetectorElement != null) {
dummyDetector = Boolean.valueOf(dummyDetectorElement.getText());
- }
-
- /**
- * Setup the manager's class loader.
- */
- private void setupClassLoader() {
-
- if (loader != null) {
- logStream.println("The ClassLoader was already set externally, so custom classpaths will be ignored!");
- return;
- }
-
- Element classpath = root.getChild("classpath");
- List<URL> urlList = new ArrayList<URL>();
- if (classpath != null) {
- for (Object jarObject : classpath.getChildren("jar")) {
- Element jarElement = (Element) jarObject;
- try {
- urlList.add((new File(processPath(jarElement.getText())).toURL()));
- } catch (Exception x) {
- throw new RuntimeException("Bad jar location: " + jarElement.getText(), x);
- }
- }
- for (Object jarUrlObject : classpath.getChildren("jarUrl")) {
- Element jarUrlElement = (Element) jarUrlObject;
- try {
- urlList.add(new URL(jarUrlElement.getText()));
- } catch (Exception x) {
- throw new RuntimeException("Bad jar URL: " + jarUrlElement.getText(), x);
- }
- }
- for (Object cpDirObject : classpath.getChildren("directory")) {
- Element cpDirElement = (Element) cpDirObject;
- try {
- File cpFile = new File(processPath(cpDirElement.getText()));
- if (!cpFile.isDirectory())
- throw new RuntimeException("The classpath component " + cpFile.getPath() + " is not a valid directory!");
- urlList.add(cpFile.toURL());
- } catch (Exception x) {
- throw new RuntimeException("Bad classpath directory: " + cpDirElement.getText(), x);
- }
- }
- }
- URL[] urls = urlList.toArray(new URL[] {});
-
- // Running in JAS. Jars need to already be on classpath.
- // FIXME This creates a dep on freehep/JAS3 jars not used elsewhere in this package.
- // if (Studio.getApplication() != null) {
- // FreeHEPLookup fhl = ((Studio) Studio.getApplication()).getLookup();
- // loader = ((DynamicClassLoader)fhl.lookup(DynamicClassLoader.class)).getClassLoader();
- // }
- // Running in batch.
- // else {
-
- loader = new LCSimClassLoader(urls);
- // }
-
- // Print user classpath entries.
- if (printUserClassPath) {
- logStream.println("-- Extra Classpath URLs --");
- for (URL url : ((URLClassLoader) loader).getURLs()) {
- logStream.println(url);
- }
- logStream.println("-- End Extra Classpath URLs --");
- logStream.println();
- }
- }
-
- /**
- * Setup the file cache.
- */
- private void setupFileCache() {
- if (cacheDirectory == null)
- return;
- try {
- fileCache = new FileCache();
- fileCache.setCacheDirectory(cacheDirectory);
- fileCache.setPrintStream(null);
- } catch (IOException x) {
- throw new RuntimeException(x);
- }
- }
-
- /**
- * Create the constants from the XML file.
- */
- private void processConstants() {
- Element define = root.getChild("define");
- if (define != null) {
- for (Object o : define.getChildren()) {
- Element e = (Element) o;
- Text txt = (Text) e.getContent().get(0);
- double dval = factory.computeDouble(txt.getValue());
- this.constantsMap.put(e.getName(), dval);
- factory.addConstant(e.getName(), dval);
- }
+ LOGGER.config("dummyDetector: " + dummyDetector);
}
}
@@ -1278,261 +1388,107 @@
* Setup the system of units.
*/
private void setupUnits() {
- Constants constants = Constants.getInstance();
- for (Entry<String, Double> unit : constants.entrySet()) {
+ final Constants constants = Constants.getInstance();
+ for (final Entry<String, Double> unit : constants.entrySet()) {
factory.addConstant(unit.getKey(), unit.getValue());
- }
- }
-
- /**
- * Get the Java primitive type class from a type name.
+ LOGGER.finest(unit.getKey() + " = " + unit.getValue());
+ }
+ }
+
+ /**
+ * Perform variable substitution within all text data in a entire document.
+ *
+ * @param doc The XML document.
+ */
+ private void substituteVariables(final Document doc) {
+ this.substituteVariables(doc.getRootElement());
+ }
+
+ /**
+ * Substitute values from the <code>variableMap</code> into an XML element and all its children, recursively.
+ *
+ * @param element The XML element.
+ * @throw RuntimeException If a variable does not exist in the <code>variableMap</code>.
+ */
+ private void substituteVariables(final Element element) {
+
+ final String text = element.getTextNormalize();
+
+ if (text.length() != 0) {
+
+ // Create a new matcher.
+ final Matcher match = VARIABLE_PATTERN.matcher(text);
+
+ // No variables were used.
+ if (!match.find()) {
+ return;
+ }
+
+ // Text data on which to perform substitutions.
+ String newText = new String(text);
+
+ // Reset the matcher.
+ match.reset();
+
+ // Loop over the matches.
+ while (match.find()) {
+
+ // Variable string with ${...} enclosure included.
+ final String var = match.group();
+
+ // The name of the variable for lookup.
+ final String varName = var.substring(2, var.length() - 1);
+
+ // The value of the variable.
+ final String varValue = variableMap.get(varName);
+
+ // If a variable was not defined, then the application will immediately exit here.
+ if (varValue == null) {
+ throw new RuntimeException("Required variable was not defined: " + varName);
+ }
+
+ // Substitute this variable's value into the text.
+ newText = newText.replace(var, varValue);
+ }
+
+ // Set this element's new text value.
+ element.setText(newText);
+ }
+
+ // Recursively process all child elements of this one.
+ for (final Iterator it = element.getChildren().iterator(); it.hasNext();) {
+ this.substituteVariables((Element) it.next());
+ }
+ }
+
+ /**
+ * Initialize the conditions system before the job starts.
+ * <p>
+ * Sub-classes should override this if custom conditions system initialization is required.
*
- * @param name The name of the type.
- * @return The primitive type class.
- */
- private static Class getPrimitiveType(String name) {
- if (name.equals("byte"))
- return byte.class;
- if (name.equals("short"))
- return short.class;
- if (name.equals("int"))
- return int.class;
- if (name.equals("long"))
- return long.class;
- if (name.equals("char"))
- return char.class;
- if (name.equals("float"))
- return float.class;
- if (name.equals("double"))
- return double.class;
- if (name.equals("boolean"))
- return boolean.class;
- if (name.equals("String"))
- return String.class;
- return null;
- }
-
- /**
- * Get a list of a class's setter methods.
- *
- * @param klass The class.
- * @return A list of setter methods.
- */
- private List<Method> getSetterMethods(Class klass) {
- List<Method> methods = new ArrayList<Method>();
- Class currentClass = klass;
- while (currentClass != null) {
- for (Method method : currentClass.getMethods()) {
- if (method.getName().startsWith("set") && !methods.contains(method)) {
- methods.add(method);
- }
- }
- currentClass = currentClass.getSuperclass();
- }
- return methods;
- }
-
- /**
- * Process the file path string to substitute in the user's home directory for the "~"
- * character. This is needed if running on Windows.
- *
- * @param path The original path.
- * @return The path with home dir substitution.
- */
- private String processPath(String path) {
- if (path.startsWith("~")) {
- return path.replaceFirst("~", System.getProperty("user.home"));
- } else {
- return path;
- }
- }
-
- // Wrap Drivers with a DriverAdapter. Only one will be created per job.
- public DriverAdapter getDriverAdapter() {
- if (driverAdapter == null) {
- Driver topDriver = new Driver();
- for (Driver driver : getDriverExecList()) {
- topDriver.add(driver);
- }
- driverAdapter = new DriverAdapter(topDriver);
- }
- return driverAdapter;
- }
-
- // Process a single LCSim event using the DriverAdapter.
- public void processEvent(EventHeader event) {
- getDriverAdapter().recordSupplied(new RecordEvent(loop, event));
- }
-
- /**
- * Reset the class's state so another job can be run.
- */
- public synchronized void reset() {
-
- driverAdapter = null;
- loop = null;
-
- driverMap = new LinkedHashMap<String, Driver>();
- driverExec = new ArrayList<Driver>();
- availableDrivers = new HashMap<String, String>();
-
- // Run parameters.
- inputFiles = new ArrayList<File>();
- numberOfEvents = -1;
- skipEvents = -1;
-
- rewriteFile = null;
-
- // Variables and constants.
- variableMap = new HashMap<String, String>();
- constantsMap = new HashMap<String, Double>();
-
- // Boolean job options.
- performDryRun = false;
- rewrite = false;
-
- // Settings effecting logging verbosity.
- printInputFiles = false;
- printDriverStatistics = false;
- printSystemProperties = false;
- printUserClassPath = false;
- printDriversDetailed = false;
- // printVersion = false;
- verbose = false;
-
- // File caching.
- cacheDirectory = null;
-
- // The manager's class loader.
- loader = null;
-
- // The log stream for messages.
- logStream = System.out;
-
- // Root node of XML job file.
- root = null;
-
- // XML utils.
- factory = new JDOMExpressionFactory();
- paramConverter = new ParameterConverters(factory);
-
- // True once job parameters are setup from CL and XML.
- wasSetup = false;
- }
-
- public void configure() {
- getDriverAdapter().start(null);
- }
-
- public void reconfigure() {
- getDriverAdapter().start(null);
- }
-
- public void suspend() {
- getDriverAdapter().suspend(null);
- }
-
- public void finish() {
- getDriverAdapter().finish(null);
- }
-
- public void setPerformDryRun(boolean d) {
- this.performDryRun = d;
+ * @throws ConditionsNotFoundException if some conditions were not found
+ */
+ protected void initializeConditions() throws ConditionsNotFoundException {
+ // Set up user supplied conditions information (we already checked that these were both given if one was provided).
+ if (this.detectorName != null) {
+ LOGGER.config("initializing conditions system with detector " + this.detectorName + " and run " + this.runNumber);
+ ConditionsManager.defaultInstance().setDetector(this.detectorName, this.runNumber);
+ }
}
- public void setClassLoader(ClassLoader loader) {
- if (loader == null)
- throw new IllegalArgumentException("The ClassLoader argument points to null.");
- this.loader = loader;
- logStream.println("Set ClassLoader to " + loader.getClass().getCanonicalName());
- }
-
- private void checkConditions() {
-
- // Get conditions element if it is there; otherwise return.
- Element conditionsElement = root.getChild("conditions");
- if (conditionsElement == null)
- return;
-
- // Get the list of valid detectors for this steering file.
- Element detectorsElement = conditionsElement.getChild("detectors");
-
- if (detectorsElement != null) {
- String detectors = detectorsElement.getTextNormalize();
-
- String[] detectorNames = detectors.split(" ");
-
- // Loop over detector names and check for required conditions in each.
- for (String detector : detectorNames) {
- logStream.println("Looking up required conditions for " + detector + " ...");
- ConditionsManager mgr = ConditionsManager.defaultInstance();
- try {
- mgr.setDetector(detector, 0);
- } catch (ConditionsManager.ConditionsNotFoundException e) {
- throw new RuntimeException(e);
- }
- for (Object condition : conditionsElement.getChildren()) {
- Element conditionElement = (Element) condition;
- boolean required = true;
- try {
- required = conditionElement.getAttribute("required").getBooleanValue();
- } catch (DataConversionException e) {
- } catch (NullPointerException e) {
- }
- try {
- mgr.getRawConditions(conditionElement.getTextTrim());
- logStream.println(conditionElement.getTextTrim() + " - OKAY");
- } catch (ConditionsSetNotFoundException e) {
- logStream.println(conditionElement.getTextTrim() + " - NOT FOUND");
- if (required)
- throw new RuntimeException("Required conditions " + conditionElement.getTextTrim() + " are missing from detector " + detector + ".");
- }
- }
- }
- }
-
- logStream.println("Adding ConditionsCheckDriver to front of Driver exec list.");
- ConditionsCheckDriver d = createConditionsCheckDriver();
- if (d != null) {
- if (detectorsElement == null) {
- // No detector names provided, so individual detectors will have all conditions
- // checked.
- d.setCheckDetector(false);
- d.setCheckConditions(true);
- } else {
- // Detectors already checked by name so just check that detector names in the job
- // are okay.
- d.setCheckConditions(false);
- d.setCheckDetector(true);
- }
- driverExec.add(d);
- }
- }
-
- private ConditionsCheckDriver createConditionsCheckDriver() {
- ConditionsCheckDriver driver = new ConditionsCheckDriver();
- Element conditionsElement = root.getChild("conditions");
- if (conditionsElement == null)
- return null;
- for (Object condition : conditionsElement.getChildren()) {
- Element conditionElement = (Element) condition;
- driver.setCondition(conditionElement.getTextTrim());
- }
- if (conditionsElement.getChild("detectors") != null) {
- String[] detectorNames = conditionsElement.getChild("detectors").getText().split(" +");
- for (String detector : detectorNames) {
- driver.setDetector(detector);
- }
- }
- return driver;
+ /**
+ * Get the run number set by the command line options.
+ * @return the run number or <code>null</code> if not set
+ */
+ protected Integer getRunNumber() {
+ return this.runNumber;
}
/**
- * Set the number of events to run on the loop before ending the job.
- * This should be called after the {@link #setup(File)} method
- * is called or it will be overridden.
- */
- public void setNumberOfEvents(int numberOfEvents) {
- this.numberOfEvents = numberOfEvents;
+ * Get the detector name set by the command line options.
+ * @return the detector name or <code>null</code> if not set
+ */
+ protected String getDetectorName() {
+ return this.detectorName;
}
}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/LCSimClassLoader.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/LCSimClassLoader.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/LCSimClassLoader.java Tue Nov 3 11:32:25 2015
@@ -5,18 +5,17 @@
/**
* A simple class loader that accepts URLs and extends the system class loader.
+ *
* @author jeremym
* @version $id: $
*/
-class LCSimClassLoader extends URLClassLoader
-{
- LCSimClassLoader(URL[] urls)
- {
- super(urls, ClassLoader.getSystemClassLoader());
- }
+class LCSimClassLoader extends URLClassLoader {
- public void addURL(URL url)
- {
- this.addURL(url);
- }
-}
+ LCSimClassLoader(URL[] urls) {
+ super(urls, ClassLoader.getSystemClassLoader());
+ }
+
+ public void addURL(URL url) {
+ this.addURL(url);
+ }
+}
Modified: projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/ParameterConverters.java
=============================================================================
--- projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/ParameterConverters.java (original)
+++ projects/lcsim/trunk/job-manager/src/main/java/org/lcsim/job/ParameterConverters.java Tue Nov 3 11:32:25 2015
@@ -14,431 +14,360 @@
import org.lcsim.util.xml.JDOMExpressionFactory;
/**
- * Converter utilities for making Java Beans arguments from LCSim XML Driver parameters,
- * using a JDOM factory to do expression evaluation.
+ * Converter utilities for making Java Beans arguments from LCSim XML Driver parameters, using a JDOM factory to do
+ * expression evaluation.
+ *
* @author jeremym
*/
-public class ParameterConverters
-{
- List<IParameterConverter> converters = new ArrayList<IParameterConverter>();
- JDOMExpressionFactory factory;
-
- public ParameterConverters(JDOMExpressionFactory factory)
- {
- this.factory = factory;
-
- add(new IntegerConverter());
- add(new StringConverter());
- add(new DoubleConverter());
- add(new FloatConverter());
- add(new BooleanConverter());
- add(new Hep3VectorConverter());
- add(new DoubleArray1DConverter());
- add(new IntegerArray1DConverter());
- add(new FloatArray1DConverter());
- add(new StringArray1DConverter());
- add(new BooleanArray1DConverter());
- add(new FileConverter());
- add(new URLConverter());
- add(new IntegerArray2DConverter());
- add(new DoubleArray2DConverter());
- }
-
- public Object convert(Class propertyType, Element parameterElement)
- {
- IParameterConverter p = getConverterForType(propertyType);
- if (p != null)
- {
- return p.convert(factory, parameterElement);
- }
- else
- {
- return null;
- }
- }
-
- protected void add(IParameterConverter converter)
- {
- converters.add(converter);
- }
-
- public List<IParameterConverter> getConverters()
- {
- return converters;
- }
-
- public IParameterConverter getConverterForType(Class propertyType)
- {
- for (IParameterConverter p : converters)
- {
- if (p.handles(propertyType))
- return p;
- }
- return null;
- }
-
- public class IntegerConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(int.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return Integer.valueOf((int)factory.computeDouble(parameterElement.getValue()));
- }
- }
-
- public class StringConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(String.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return parameterElement.getValue();
- }
- }
-
- public class DoubleConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(double.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return Double.valueOf(factory.computeDouble(parameterElement.getValue()));
- }
- }
-
- public class FloatConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(float.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return Float.valueOf(factory.computeFloat(parameterElement.getValue()));
- }
- }
-
- public class BooleanConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(boolean.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return Boolean.valueOf(parameterElement.getValue());
- }
- }
-
- public class Hep3VectorConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(Hep3Vector.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- double x = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
- double y = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
- double z = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
- return new BasicHep3Vector(x, y, z);
- }
- }
-
- public class DoubleArray1DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[D");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- int size = tokenize.countTokens();
- double da[] = new double[size];
- int i = 0;
- while (tokenize.hasMoreTokens())
- {
- da[i] = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
- ++i;
- }
- return da;
- }
- }
-
- public class IntegerArray1DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[I");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- int size = tokenize.countTokens();
- int ia[] = new int[size];
- int i = 0;
- while (tokenize.hasMoreTokens())
- {
- ia[i] = Integer.valueOf((int)factory.computeDouble(tokenize.nextToken()));
- ++i;
- }
- return ia;
- }
- }
-
- public class FloatArray1DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[F");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- int size = tokenize.countTokens();
- float fa[] = new float[size];
- int i = 0;
- while (tokenize.hasMoreTokens())
- {
- fa[i] = Float.valueOf(factory.computeFloat(tokenize.nextToken()));
- ++i;
- }
- return fa;
- }
- }
-
- public class StringArray1DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[Ljava.lang.String;");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- int size = tokenize.countTokens();
- String sa[] = new String[size];
- int i = 0;
- while (tokenize.hasMoreTokens())
- {
- sa[i] = tokenize.nextToken();
- ++i;
- }
- return sa;
- }
- }
-
- public class BooleanArray1DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[Z");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
- int size = tokenize.countTokens();
- boolean ba[] = new boolean[size];
- int i = 0;
- while (tokenize.hasMoreTokens())
- {
- ba[i] = Boolean.valueOf(tokenize.nextToken());
- ++i;
- }
- return ba;
- }
- }
-
- public class FileConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(File.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return new File(parameterElement.getValue());
- }
- }
-
- public class URLConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(URL.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- try
- {
- return new URL(parameterElement.getValue());
- }
- catch (MalformedURLException x)
- {
- throw new RuntimeException("Bad URL " + parameterElement.getValue() + " in XML job description.",x);
- }
- }
- }
- public class DoubleArray2DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[[D");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- // Parse into a list of list of doubles.
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue(), ";");
- int length = tokenize.countTokens();
- int ir = 0;
- List<List<Double>> rows = new ArrayList<List<Double>>(length);
- while (tokenize.hasMoreTokens())
- {
- String rowStr = tokenize.nextToken();
- StringTokenizer tokenize2 = new StringTokenizer(rowStr);
- rows.add(new ArrayList<Double>());
- List<Double> row = rows.get(ir);
- while (tokenize2.hasMoreTokens())
- {
- String entry = tokenize2.nextToken();
- Double d = factory.computeDouble(entry);
- row.add(d);
- }
- ++ir;
- }
-
- // Convert list of doubles into 2D array, checking for wrong sized rows.
- double arr[][] = new double[rows.size()][rows.get(0).size()];
- int jcheck = rows.get(0).size() - 1;
- int i=0;
- int j=0;
- for (List<Double> aa : rows)
- {
- for (Double a : aa)
- {
- if (j > jcheck)
- {
- throw new RuntimeException(
- "Row " + j + " of array " +
- parameterElement.getName() +
- "with length " + aa.size() +
- " is too long.");
- }
- arr[i][j] = a;
- ++j;
- }
- if (j < jcheck)
- {
- throw new RuntimeException(
- "Row " + j + " of array " +
- parameterElement.getName() +
- "with length " + aa.size() +
- "is too short.");
- }
- j=0;
- ++i;
- }
- return arr;
- }
- }
-
- public class IntegerArray2DConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.getName().equals("[[I");
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- // Parse into a list of list of doubles.
- StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue(), ";");
- int length = tokenize.countTokens();
- int ir = 0;
- List<List<Integer>> rows = new ArrayList<List<Integer>>(length);
- while (tokenize.hasMoreTokens())
- {
- String rowStr = tokenize.nextToken();
- StringTokenizer tokenize2 = new StringTokenizer(rowStr);
- rows.add(new ArrayList<Integer>());
- List<Integer> row = rows.get(ir);
- while (tokenize2.hasMoreTokens())
- {
- String entry = tokenize2.nextToken();
- Integer d = Integer.valueOf(entry);
- row.add(d);
- }
- ++ir;
- }
-
- // Convert list of doubles into 2D array, checking for wrong sized rows.
- int arr[][] = new int[rows.size()][rows.get(0).size()];
- int jcheck = rows.get(0).size() - 1;
- int i=0;
- int j=0;
- for (List<Integer> aa : rows)
- {
- for (Integer a : aa)
- {
- if (j > jcheck)
- {
- throw new RuntimeException(
- "Row " + j + " of array " +
- parameterElement.getName() +
- "with length " + aa.size() +
- " is too long.");
- }
- arr[i][j] = a;
- ++j;
- }
- if (j < jcheck)
- {
- throw new RuntimeException(
- "Row " + j + " of array " +
- parameterElement.getName() +
- "with length " + aa.size() +
- "is too short.");
- }
- j=0;
- ++i;
- }
- return arr;
- }
- }
-
- public class ElementConverter implements IParameterConverter
- {
- public boolean handles(Class propertyType)
- {
- return propertyType.equals(Element.class);
- }
-
- public Object convert(JDOMExpressionFactory factory, Element parameterElement)
- {
- return parameterElement;
- }
- }
+public class ParameterConverters {
+
+ List<IParameterConverter> converters = new ArrayList<IParameterConverter>();
+ JDOMExpressionFactory factory;
+
+ public ParameterConverters(JDOMExpressionFactory factory) {
+ this.factory = factory;
+
+ add(new IntegerConverter());
+ add(new StringConverter());
+ add(new DoubleConverter());
+ add(new FloatConverter());
+ add(new BooleanConverter());
+ add(new Hep3VectorConverter());
+ add(new DoubleArray1DConverter());
+ add(new IntegerArray1DConverter());
+ add(new FloatArray1DConverter());
+ add(new StringArray1DConverter());
+ add(new BooleanArray1DConverter());
+ add(new FileConverter());
+ add(new URLConverter());
+ add(new IntegerArray2DConverter());
+ add(new DoubleArray2DConverter());
+ }
+
+ public Object convert(Class propertyType, Element parameterElement) {
+ IParameterConverter p = getConverterForType(propertyType);
+ if (p != null) {
+ return p.convert(factory, parameterElement);
+ } else {
+ return null;
+ }
+ }
+
+ protected void add(IParameterConverter converter) {
+ converters.add(converter);
+ }
+
+ public List<IParameterConverter> getConverters() {
+ return converters;
+ }
+
+ public IParameterConverter getConverterForType(Class propertyType) {
+ for (IParameterConverter p : converters) {
+ if (p.handles(propertyType))
+ return p;
+ }
+ return null;
+ }
+
+ public class IntegerConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(int.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return Integer.valueOf((int) factory.computeDouble(parameterElement.getValue()));
+ }
+ }
+
+ public class StringConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(String.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return parameterElement.getValue();
+ }
+ }
+
+ public class DoubleConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(double.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return Double.valueOf(factory.computeDouble(parameterElement.getValue()));
+ }
+ }
+
+ public class FloatConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(float.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return Float.valueOf(factory.computeFloat(parameterElement.getValue()));
+ }
+ }
+
+ public class BooleanConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(boolean.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return Boolean.valueOf(parameterElement.getValue());
+ }
+ }
+
+ public class Hep3VectorConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(Hep3Vector.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ double x = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
+ double y = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
+ double z = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
+ return new BasicHep3Vector(x, y, z);
+ }
+ }
+
+ public class DoubleArray1DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[D");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ int size = tokenize.countTokens();
+ double da[] = new double[size];
+ int i = 0;
+ while (tokenize.hasMoreTokens()) {
+ da[i] = Double.valueOf(factory.computeDouble(tokenize.nextToken()));
+ ++i;
+ }
+ return da;
+ }
+ }
+
+ public class IntegerArray1DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[I");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ int size = tokenize.countTokens();
+ int ia[] = new int[size];
+ int i = 0;
+ while (tokenize.hasMoreTokens()) {
+ ia[i] = Integer.valueOf((int) factory.computeDouble(tokenize.nextToken()));
+ ++i;
+ }
+ return ia;
+ }
+ }
+
+ public class FloatArray1DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[F");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ int size = tokenize.countTokens();
+ float fa[] = new float[size];
+ int i = 0;
+ while (tokenize.hasMoreTokens()) {
+ fa[i] = Float.valueOf(factory.computeFloat(tokenize.nextToken()));
+ ++i;
+ }
+ return fa;
+ }
+ }
+
+ public class StringArray1DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[Ljava.lang.String;");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ int size = tokenize.countTokens();
+ String sa[] = new String[size];
+ int i = 0;
+ while (tokenize.hasMoreTokens()) {
+ sa[i] = tokenize.nextToken();
+ ++i;
+ }
+ return sa;
+ }
+ }
+
+ public class BooleanArray1DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[Z");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue());
+ int size = tokenize.countTokens();
+ boolean ba[] = new boolean[size];
+ int i = 0;
+ while (tokenize.hasMoreTokens()) {
+ ba[i] = Boolean.valueOf(tokenize.nextToken());
+ ++i;
+ }
+ return ba;
+ }
+ }
+
+ public class FileConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(File.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return new File(parameterElement.getValue());
+ }
+ }
+
+ public class URLConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(URL.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ try {
+ return new URL(parameterElement.getValue());
+ } catch (MalformedURLException x) {
+ throw new RuntimeException("Bad URL " + parameterElement.getValue() + " in XML job description.", x);
+ }
+ }
+ }
+
+ public class DoubleArray2DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[[D");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ // Parse into a list of list of doubles.
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue(), ";");
+ int length = tokenize.countTokens();
+ int ir = 0;
+ List<List<Double>> rows = new ArrayList<List<Double>>(length);
+ while (tokenize.hasMoreTokens()) {
+ String rowStr = tokenize.nextToken();
+ StringTokenizer tokenize2 = new StringTokenizer(rowStr);
+ rows.add(new ArrayList<Double>());
+ List<Double> row = rows.get(ir);
+ while (tokenize2.hasMoreTokens()) {
+ String entry = tokenize2.nextToken();
+ Double d = factory.computeDouble(entry);
+ row.add(d);
+ }
+ ++ir;
+ }
+
+ // Convert list of doubles into 2D array, checking for wrong sized rows.
+ double arr[][] = new double[rows.size()][rows.get(0).size()];
+ int jcheck = rows.get(0).size() - 1;
+ int i = 0;
+ int j = 0;
+ for (List<Double> aa : rows) {
+ for (Double a : aa) {
+ if (j > jcheck) {
+ throw new RuntimeException("Row " + j + " of array " + parameterElement.getName()
+ + "with length " + aa.size() + " is too long.");
+ }
+ arr[i][j] = a;
+ ++j;
+ }
+ if (j < jcheck) {
+ throw new RuntimeException("Row " + j + " of array " + parameterElement.getName() + "with length "
+ + aa.size() + "is too short.");
+ }
+ j = 0;
+ ++i;
+ }
+ return arr;
+ }
+ }
+
+ public class IntegerArray2DConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.getName().equals("[[I");
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ // Parse into a list of list of doubles.
+ StringTokenizer tokenize = new StringTokenizer(parameterElement.getValue(), ";");
+ int length = tokenize.countTokens();
+ int ir = 0;
+ List<List<Integer>> rows = new ArrayList<List<Integer>>(length);
+ while (tokenize.hasMoreTokens()) {
+ String rowStr = tokenize.nextToken();
+ StringTokenizer tokenize2 = new StringTokenizer(rowStr);
+ rows.add(new ArrayList<Integer>());
+ List<Integer> row = rows.get(ir);
+ while (tokenize2.hasMoreTokens()) {
+ String entry = tokenize2.nextToken();
+ Integer d = Integer.valueOf(entry);
+ row.add(d);
+ }
+ ++ir;
+ }
+
+ // Convert list of doubles into 2D array, checking for wrong sized rows.
+ int arr[][] = new int[rows.size()][rows.get(0).size()];
+ int jcheck = rows.get(0).size() - 1;
+ int i = 0;
+ int j = 0;
+ for (List<Integer> aa : rows) {
+ for (Integer a : aa) {
+ if (j > jcheck) {
+ throw new RuntimeException("Row " + j + " of array " + parameterElement.getName()
+ + "with length " + aa.size() + " is too long.");
+ }
+ arr[i][j] = a;
+ ++j;
+ }
+ if (j < jcheck) {
+ throw new RuntimeException("Row " + j + " of array " + parameterElement.getName() + "with length "
+ + aa.size() + "is too short.");
+ }
+ j = 0;
+ ++i;
+ }
+ return arr;
+ }
+ }
+
+ public class ElementConverter implements IParameterConverter {
+
+ public boolean handles(Class propertyType) {
+ return propertyType.equals(Element.class);
+ }
+
+ public Object convert(JDOMExpressionFactory factory, Element parameterElement) {
+ return parameterElement;
+ }
+ }
}
########################################################################
Use REPLY-ALL to reply to list
To unsubscribe from the LCDET-SVN list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCDET-SVN&A=1
|