Switched our code over to the new command line style (gnu style args), added the initial logger code, and added apache commons CLI to the IVY script.

There will be a slow conversion of all the System.out and System.err in other files to the logger style output.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@145 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
aaron 2009-03-22 21:06:22 +00:00
parent 38f18c8679
commit 046cecb067
4 changed files with 692 additions and 84 deletions

View File

@ -1,133 +1,151 @@
package org.broadinstitute.sting.gatk;
import edu.mit.broad.picard.reference.ReferenceSequence;
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
import edu.mit.broad.picard.reference.ReferenceSequenceFileFactory;
import net.sf.samtools.SAMFileReader.ValidationStringency;
import net.sf.samtools.SAMSequenceRecord;
import net.sf.samtools.util.RuntimeIOException;
import edu.mit.broad.picard.cmdline.CommandLineProgram;
import edu.mit.broad.picard.cmdline.Usage;
import edu.mit.broad.picard.cmdline.Option;
import edu.mit.broad.picard.reference.ReferenceSequenceFileFactory;
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
import edu.mit.broad.picard.reference.ReferenceSequence;
import org.broadinstitute.sting.utils.*;
import org.broadinstitute.sting.gatk.walkers.*;
import org.apache.log4j.Logger;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
import org.broadinstitute.sting.gatk.refdata.rodDbSNP;
import org.broadinstitute.sting.gatk.refdata.rodGFF;
import org.broadinstitute.sting.gatk.iterators.ReferenceIterator;
import org.broadinstitute.sting.utils.Utils;
import org.broadinstitute.sting.gatk.walkers.LocusWalker;
import org.broadinstitute.sting.gatk.walkers.ReadWalker;
import org.broadinstitute.sting.utils.FastaSequenceFile2;
import org.broadinstitute.sting.utils.GenomeLoc;
import org.broadinstitute.sting.utils.Utils;
import org.broadinstitute.sting.utils.cmdLine.CommandLineProgram;
import java.io.*;
import java.util.*;
import java.util.List;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import java.util.HashMap;
import java.util.List;
public class GenomeAnalysisTK extends CommandLineProgram {
// Usage and parameters
@Usage(programVersion="0.1") public String USAGE = "Genome Analysis Toolkit\n";
@Option(shortName="I", doc="SAM or BAM file for validation") public File INPUT_FILE;
@Option(shortName="M", doc="Maximum number of reads to process before exiting", optional=true) public String MAX_READS_ARG = "-1";
@Option(shortName="S", doc="How strict should we be with validation", optional=true) public String STRICTNESS_ARG = "strict";
@Option(shortName="R", doc="Reference sequence file", optional=true) public File REF_FILE_ARG = null;
@Option(shortName="B", doc="Debugging output", optional=true) public String DEBUGGING_STR = null;
@Option(shortName="L", doc="Genome region to operation on: from chr:start-end", optional=true) public String REGION_STR = null;
@Option(shortName="INT", doc="File containing list of genomic intervals to operate on. line := <contig> <start> <end>\n", optional=true) public String INTERVALS_FILE = null;
@Option(shortName="T", doc="Type of analysis to run") public String Analysis_Name = null;
@Option(shortName="DBSNP", doc="DBSNP file", optional=true) public String DBSNP_FILE = null;
@Option(shortName="THREADED_IO", doc="If true, enables threaded I/O operations", optional=true) public String ENABLED_THREADED_IO = "false";
@Option(shortName="U", doc="If true, enables unsafe operations, nothing will be checked at runtime. You better know what you are doing if you set this flag.", optional=false) public String UNSAFE = "false";
@Option(shortName="SORT_ON_FLY", doc="If true, enables on fly sorting of reads file.", optional=false) public String ENABLED_SORT_ON_FLY = "false";
@Option(shortName="PLUGINS", doc="Directory where plugin class files live.", optional=true)
public String pluginPathName = null;
// parameters and their defaults
public File INPUT_FILE;
public String MAX_READS_ARG = "-1";
public String STRICTNESS_ARG = "strict";
public File REF_FILE_ARG = null;
public String DEBUGGING_STR = null;
public String REGION_STR = null;
public String Analysis_Name = null;
public String DBSNP_FILE = null;
public Boolean ENABLED_THREADED_IO = false;
public Boolean UNSAFE = false;
public Boolean ENABLED_SORT_ON_FLY = false;
public String INTERVALS_FILE = null;
// our walker manager
private WalkerManager walkerManager = null;
public String pluginPathName = null;
private TraversalEngine engine = null;
public boolean DEBUGGING = false;
/** Required main method implementation. */
public static void main(String[] argv) {
System.exit(new GenomeAnalysisTK().instanceMain(argv));
/**
* our log, which we want to capture anything from this class
*/
private static Logger logger = Logger.getLogger(GenomeAnalysisTK.class);
/**
* setup our arguments, both required and optional
* <p/>
* Flags don't take an argument, the associated Boolean gets set to true if the flag appears on the command line.
*/
protected void setupArgs() {
m_parser.addRequiredlArg("input_file", "I", "SAM or BAM file for validation", "INPUT_FILE");
m_parser.addOptionalArg("maximum_reads", "M", "Maximum number of reads to process before exiting", "MAX_READS_ARG");
m_parser.addOptionalArg("validation_strictness", "S", "How strict should we be with validation", "STRICTNESS_ARG");
m_parser.addOptionalArg("reference_sequence", "R", "Reference sequence file", "REF_FILE_ARG");
m_parser.addOptionalArg("genome_region", "L", "Genome region to operation on: from chr:start-end", "REGION_STR");
m_parser.addRequiredlArg("analysis_type", "T", "Type of analysis to run", "Analysis_Name");
m_parser.addOptionalArg("DBSNP", "D", "DBSNP file", "DBSNP_FILE");
m_parser.addOptionalFlag("Threaded_IO", "P", "If set, enables threaded I/O operations", "ENABLED_THREADED_IO");
m_parser.addOptionalFlag("Unsafe", "U", "If set, enables unsafe operations, nothing will be checked at runtime.", "UNSAFE");
m_parser.addOptionalFlag("Sort_on_the_fly", "F", "If set, enables on fly sorting of reads file.", "ENABLED_SORT_ON_FLY");
m_parser.addOptionalArg("intervals_file", "V", "File containing list of genomic intervals to operate on. line := <contig> <start> <end>", "INTERVALS_FILE");
}
protected int doWork() {
walkerManager = new WalkerManager(pluginPathName);
/**
* Required main method implementation.
*/
public static void main(String[] argv) {
start(new GenomeAnalysisTK(), argv);
}
//testNewReferenceFeatures(REF_FILE_ARG);
protected int execute() {
walkerManager = new WalkerManager(pluginPathName);
final boolean TEST_ROD = false;
ReferenceOrderedData[] rods = null;
if ( TEST_ROD ) {
ReferenceOrderedData gff = new ReferenceOrderedData(new File("trunk/data/gFFTest.gff"), rodGFF.class );
if (TEST_ROD) {
ReferenceOrderedData gff = new ReferenceOrderedData(new File("trunk/data/gFFTest.gff"), rodGFF.class);
gff.testMe();
//ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("trunk/data/dbSNP_head.txt"), rodDbSNP.class );
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("/Volumes/Users/mdepristo/broad/ATK/exampleSAMs/dbSNP_chr20.txt"), rodDbSNP.class );
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("/Volumes/Users/mdepristo/broad/ATK/exampleSAMs/dbSNP_chr20.txt"), rodDbSNP.class);
//dbsnp.testMe();
rods = new ReferenceOrderedData[] { dbsnp }; // { gff, dbsnp };
}
else if ( DBSNP_FILE != null ) {
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File(DBSNP_FILE), rodDbSNP.class );
rods = new ReferenceOrderedData[]{dbsnp}; // { gff, dbsnp };
} else if (DBSNP_FILE != null) {
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File(DBSNP_FILE), rodDbSNP.class);
//dbsnp.testMe();
rods = new ReferenceOrderedData[] { dbsnp }; // { gff, dbsnp };
}
else {
rods = new ReferenceOrderedData[] {}; // { gff, dbsnp };
rods = new ReferenceOrderedData[]{dbsnp}; // { gff, dbsnp };
} else {
rods = new ReferenceOrderedData[]{}; // { gff, dbsnp };
}
this.engine = new TraversalEngine(INPUT_FILE, REF_FILE_ARG, rods);
// Prepare the sort ordering w.r.t. the sequence dictionary
final ReferenceSequenceFile refFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(REF_FILE_ARG);
List<SAMSequenceRecord> refContigs = refFile.getSequenceDictionary().getSequences();
HashMap<String, Integer> refContigOrdering = new HashMap<String, Integer>();
int i = 0;
for ( SAMSequenceRecord contig : refContigs ) {
refContigOrdering.put(contig.getSequenceName(), i);
i++;
}
GenomeLoc.setContigOrdering(refContigOrdering);
if (REF_FILE_ARG != null) {
final ReferenceSequenceFile refFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(REF_FILE_ARG);
List<SAMSequenceRecord> refContigs = refFile.getSequenceDictionary().getSequences();
HashMap<String, Integer> refContigOrdering = new HashMap<String, Integer>();
int i = 0;
for (SAMSequenceRecord contig : refContigs) {
refContigOrdering.put(contig.getSequenceName(), i);
i++;
}
GenomeLoc.setContigOrdering(refContigOrdering);
}
ValidationStringency strictness;
if ( STRICTNESS_ARG == null ) {
if (STRICTNESS_ARG == null) {
strictness = ValidationStringency.STRICT;
}
else if ( STRICTNESS_ARG.toLowerCase().equals("lenient") ) {
strictness = ValidationStringency.LENIENT;
}
else if ( STRICTNESS_ARG.toLowerCase().equals("silent") ) {
strictness = ValidationStringency.SILENT;
}
else {
} else if (STRICTNESS_ARG.toLowerCase().equals("lenient")) {
strictness = ValidationStringency.LENIENT;
} else if (STRICTNESS_ARG.toLowerCase().equals("silent")) {
strictness = ValidationStringency.SILENT;
} else {
strictness = ValidationStringency.STRICT;
}
System.err.println("Strictness is " + strictness);
}
logger.info("Strictness is " + strictness);
engine.setStrictness(strictness);
engine.setDebugging(! ( DEBUGGING_STR == null || DEBUGGING_STR.toLowerCase().equals("true")));
engine.setDebugging(!(DEBUGGING_STR == null || DEBUGGING_STR.toLowerCase().equals("true")));
engine.setMaxReads(Integer.parseInt(MAX_READS_ARG));
if ( REGION_STR != null ) {
if (REGION_STR != null) {
engine.setLocation(REGION_STR);
}
if (INTERVALS_FILE != null)
{
if (INTERVALS_FILE != null) {
engine.setLocationFromFile(INTERVALS_FILE);
}
engine.setSafetyChecking(!UNSAFE);
engine.setSortOnFly(ENABLED_SORT_ON_FLY);
engine.setSafetyChecking(! UNSAFE.toLowerCase().equals("true"));
engine.setSortOnFly(ENABLED_SORT_ON_FLY.toLowerCase().equals("true"));
engine.initialize(ENABLED_THREADED_IO.toLowerCase().equals("true"));
engine.initialize(ENABLED_THREADED_IO);
//engine.testReference();
//LocusWalker<Integer,Integer> walker = new PileupWalker();
@ -137,17 +155,17 @@ public class GenomeAnalysisTK extends CommandLineProgram {
if (walkerManager.doesWalkerExist(Analysis_Name)) {
my_walker = walkerManager.getWalkerByName(Analysis_Name);
} else {
System.out.println("Could not find walker "+Analysis_Name);
logger.fatal("Could not find walker " + Analysis_Name);
return 0;
}
try {
LocusWalker<?, ?> walker = (LocusWalker<?, ?>)my_walker;
LocusWalker<?, ?> walker = (LocusWalker<?, ?>) my_walker;
engine.traverseByLoci(walker);
}
catch ( java.lang.ClassCastException e ) {
catch (java.lang.ClassCastException e) {
// I guess we're a read walker LOL
ReadWalker<?, ?> walker = (ReadWalker<?, ?>)my_walker;
ReadWalker<?, ?> walker = (ReadWalker<?, ?>) my_walker;
engine.traverseByRead(walker);
}
@ -234,7 +252,7 @@ public class GenomeAnalysisTK extends CommandLineProgram {
refFile.seekToContig(targetChr);
} catch ( IOException e ){
System.out.printf("Failured to seek to %s%n", targetChr);
e.printStackTrace();
e.printStackTrace();
}
System.exit(1);
*/

View File

@ -0,0 +1,343 @@
package org.broadinstitute.sting.utils.cmdLine;
import org.apache.commons.cli.*;
import org.apache.log4j.Logger;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
/**
* User: aaron
* Date: Mar 19, 2009
* Time: 6:54:15 PM
* <p/>
* The Broad Institute
* SOFTWARE COPYRIGHT NOTICE AGREEMENT
* This software and its documentation are copyright 2009 by the
* Broad Institute/Massachusetts Institute of Technology. All rights are reserved.
* <p/>
* This software is supplied without any warranty or guaranteed support whatsoever. Neither
* the Broad Institute nor MIT can be responsible for its use, misuse, or functionality.
*/
public class ArgumentParser {
// what program are we parsing for
private String programName;
// our m_options
private ArrayList<String> m_option_names = new ArrayList<String>();
// where we eventually want the values to land
private HashMap<String, Field> m_storageLocations = new HashMap<String, Field>();
// create Options object
protected Options m_options = new Options();
/**
* our log, which we want to capture anything from org.broadinstitute.sting
*/
protected static Logger logger = Logger.getLogger(ArgumentParser.class);
// the reference to the command line program to fill in
CommandLineProgram prog;
public ArgumentParser(String programName, CommandLineProgram prog) {
this.programName = programName;
this.prog = prog;
}
/**
* print out the help information
*/
public void printHelp() {
// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(100,
"java -Xmx4096m -jar dist/GenomeAnalysisTK.jar",
"",
m_options,
"",
true);
}
/**
* addOptionalArg
* <p/>
* Adds an optional argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname the field to set when we've parsed this option
*/
public void addOptionalArg(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.withLongOpt(name).withArgName(name)
.hasArg()
.withDescription(description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* Used locally to add to the options storage we have, for latter processing
*
* @param name the name of the option
* @param letterform it's short form
* @param fieldname what field it should be stuck into on the calling class
* @param opt the option
*/
private void AddToOptionStorage(String name, String letterform, String fieldname, Option opt) {
// add to the option list
m_options.addOption(opt);
// add the object with it's name to the storage location
try {
m_storageLocations.put(name, prog.getClass().getField(fieldname));
} catch (NoSuchFieldException e) {
logger.fatal("Failed to find the field specified by the fieldname parameter.");
throw new RuntimeException(e.getMessage());
}
// add to the list of m_options
m_option_names.add(letterform);
}
/**
* addRequiredlArg
* <p/>
* Adds a required argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname what field it should be stuck into on the calling class
*/
public void addRequiredlArg(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.isRequired()
.withLongOpt(name)
.withArgName(name)
.hasArg()
.withDescription("(Required Option) " + description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* addOptionalArg
* <p/>
* Adds an optional argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname what field it should be stuck into on the calling class
*/
public void addOptionalArgList(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.withLongOpt(name).withArgName(name)
.hasArgs()
.withDescription(description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* addRequiredlArg
* <p/>
* Adds a required argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname what field it should be stuck into on the calling class
*/
public void addRequiredlArgList(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.isRequired()
.withLongOpt(name)
.withArgName(name)
.hasArgs()
.withDescription("(Required Option) " + description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* addOptionalFlag
* <p/>
* Adds an optional argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname what field it should be stuck into on the calling class
*/
public void addOptionalFlag(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.withLongOpt(name)
.withDescription(description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* addRequiredlFlag
* <p/>
* Adds a required argument to check on the command line
*
* @param name the name of the argument, the long name
* @param letterform the short form
* @param description the description of the argument
* @param fieldname what field it should be stuck into on the calling class
*/
public void addRequiredlFlag(String name, String letterform, String description, String fieldname) {
// we always want the help option to be available
Option opt = OptionBuilder.isRequired()
.withLongOpt(name)
.withDescription("(Required Flag) " + description)
.create(letterform);
// add it to the option
AddToOptionStorage(name, letterform, fieldname, opt);
}
/**
* This function is called to validate all the arguments to the program.
* If a required Arg isn't found, we generate the help message, and
* exit the program
*
* @param args the command line arguments we recieved
*/
protected void processArgs(String[] args) {
CommandLineParser parser = new PosixParser();
try {
Collection<Option> opts = m_options.getOptions();
CommandLine cmd = parser.parse(m_options, args);
// logger.info("We have " + opts.size() + " options");
for (Option opt : opts) {
if (cmd.hasOption(opt.getOpt())) {
if (opt.hasArg()) {
//logger.info("looking at " + m_storageLocations.get(opt.getLongOpt()));
Field f = m_storageLocations.get(opt.getLongOpt());
try {
f.set(prog, constructFromString(f, cmd.getOptionValue(opt.getOpt())));
} catch (IllegalAccessException e) {
logger.fatal("processArgs: cannot convert field " + f.toString());
throw new RuntimeException("processArgs: Failed conversion " + e.getMessage());
}
}
else {
Field f = m_storageLocations.get(opt.getLongOpt());
try {
//logger.fatal("about to parse field " + f.getName());
f.set(prog, new Boolean(true));
} catch (IllegalAccessException e) {
logger.fatal("processArgs: cannot convert field " + f.toString());
throw new RuntimeException("processArgs: Failed conversion " + e.getMessage());
}
}
}
}
} catch (ParseException e) {
// we didn't get all the required arguments,
// print out the help
this.printHelp();
System.exit(1);
}
}
private Object constructFromString(Field f, String str) {
Type type = f.getType();
// lets go through the types we support
if (type == Boolean.TYPE) {
boolean b = false;
if (str.toLowerCase().equals("true")) {
b = true;
}
Boolean bool = new Boolean(b);
return bool;
} else if (type == Integer.TYPE) {
Integer in = Integer.valueOf(str);
return in;
} else if (type == Float.TYPE) {
Float fl = Float.valueOf(str);
return fl;
} else {
Constructor ctor = null;
try {
ctor = f.getType().getConstructor(String.class);
return ctor.newInstance(str);
} catch (NoSuchMethodException e) {
logger.fatal("constructFromString: cannot convert field " + f.toString());
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
} catch (IllegalAccessException e) {
logger.fatal("constructFromString: cannot convert field " + f.toString());
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
} catch (InvocationTargetException e) {
logger.fatal("constructFromString: cannot convert field " + f.toString());
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
} catch (InstantiationException e) {
logger.fatal("constructFromString: cannot convert field " + f.toString());
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
}
}
}
}
/**
public static void main(String[] args) {
ArgumentParser p = new ArgumentParser("CrapApp");
p.setupDefaultArgs();
p.addRequiredlArg("Flag","F","a required arg");
p.addRequiredlFlag("Sub","S","a required flag");
p.addOptionalArg("Boat","T","Maybe you want a boat?");
String[] str = {"--Flag","rrr","-T","ppp", "--Flag","ttt"};
p.processArgs(str);
Iterator<String> r = map.keySet().iterator();
while (r.hasNext()) {
String key = r.next();
String[] q = map.get(key);
if (q != null) {
for (String mystr : q) {
System.err.println("key: " + key + " val: " + mystr);
}
}
}
}
*/

View File

@ -0,0 +1,246 @@
package org.broadinstitute.sting.utils.cmdLine;
import org.apache.log4j.*;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* User: aaron
* Date: Mar 19, 2009
* Time: 3:54:56 PM
* <p/>
* The Broad Institute
* SOFTWARE COPYRIGHT NOTICE AGREEMENT
* This software and its documentation are copyright 2009 by the
* Broad Institute/Massachusetts Institute of Technology. All rights are reserved.
* <p/>
* This software is supplied without any warranty or guaranteed support whatsoever. Neither
* the Broad Institute nor MIT can be responsible for its use, misuse, or functionality.
* <p/>
* <p/>
* This class is our implementation of the command line parser, similar to Pickard's. We instead
* support GNU style command line arguements, and use this class to setup the global parser.
*/
public abstract class CommandLineProgram {
/**
* Our Argument parser, which handles parsing the command line in GNU format
*/
protected ArgumentParser m_parser;
/**
* our log, which we want to capture anything from org.broadinstitute.sting
*/
private static Logger logger = Logger.getRootLogger();// .getLogger(CommandLineProgram.class);
/**
* the default log level
*/
public String logging_level = "ERROR";
/**
* where to send the output of our logger
*/
public String toFile = null;
/**
* do we want to silence the command line output
*/
public Boolean quietMode = false;
/**
* do we want to generate debugging information with the logs
*/
public Boolean debugMode = false;
/**
* our logging output patterns
*/
private static String patternString = "%p %m %n";
private static String debugPatternString = "%n[level] %p%n[date]\t\t %d{dd MMM yyyy HH:mm:ss,SSS} %n[class]\t\t %C %n[location]\t %l %n[line number]\t %L %n[message]\t %m %n";
/**
* the contract for the inheriting class is that they have a setupArgs()
* function which sets up the args to the specific program.
*/
protected abstract void setupArgs();
/**
* this is the function that the inheriting class can expect to have called
* when all the argument processing is done
*
* @return the return code to exit the program with
*/
protected abstract int execute();
/**
* this is used to indicate if they've asked for help
*/
public Boolean help = false;
/**
* This function is called to start processing the command line, and kick
* off the execute message of the program.
*
* @param clp the command line program to execute
* @param args the command line arguments passed in
*/
public static void start(CommandLineProgram clp, String[] args) {
try {
// setup a basic log configuration
BasicConfigurator.configure();
// setup our log layout
PatternLayout layout = new PatternLayout();
// setup the parser
clp.m_parser = new ArgumentParser(clp.getClass().getName(), clp);
// setup the default help and logging args controlled by the base class
clp.setupDefaultArgs();
// setup the args
clp.setupArgs();
// process the args
clp.m_parser.processArgs(args);
// if we're in debug mode, set the mode up
if (clp.debugMode) {
//logger.info("Setting debug");
layout.setConversionPattern(debugPatternString);
} else {
//logger.info("not Setting debug");
layout.setConversionPattern(patternString);
}
// if they set the mode to quiet
if (clp.quietMode) {
// the only appender we should have is stdout, the following meathod is
// deprecated, but the standard remove all appenders doesn't seem to work
// TODO: find the right function
//Category root = Category.getRoot();
//root.removeAllAppenders();
//logger.removeAllAppenders();
}
// they asked for help, give it to them
if (clp.help) {
clp.m_parser.printHelp();
System.exit(1);
}
// if they specify a log location, output our data there
if (clp.toFile != null) {
FileAppender appender = null;
try {
appender = new FileAppender(layout, clp.toFile, false);
logger.addAppender(appender);
} catch (IOException e) {
throw new RuntimeException("Unable to re-route log output to " + clp.toFile + " make sure the destination exists");
}
}
// regardless of what happens next, generate the header information
generateHeaderInformation(clp, args);
// set the default logger level
clp.setupLoggerLevel();
// call the execute
int result = clp.execute();
// return the result
System.exit(result);
}
catch (Exception e) {
// we catch all exceptions here. if it makes it to this level, we're in trouble. Let's bail!
// TODO: what if the logger is the exception? hmm...
logger.fatal("Exception caught by base Command Line Program, with message: " + e.getMessage());
logger.fatal("with cause: " + e.getCause());
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* generateHeaderInformation
* <p/>
*
* Generate a standard header for the logger
* @param clp the command line program to execute
* @param args the command line arguments passed in
*
**/
protected static void generateHeaderInformation(CommandLineProgram clp, String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
java.util.Date date = new java.util.Date();
logger.info("-------------------------------------------------------");
logger.info("Program Name: " + clp.getClass().getName());
String output = "";
for (String str : args) {
output = output + str + " ";
}
logger.info("Program Args: " + output);
logger.info("Time/Date: " + dateFormat.format(date));
logger.info("-------------------------------------------------------");
}
/**
* this function checks the logger level passed in on the command line, taking the lowest
* level that was provided.
*/
private void setupLoggerLevel() {
Level par = Level.ERROR;
if (logging_level.equals("DEBUG")) {
par = Level.DEBUG;
}
if (logging_level.equals("ERROR")) {
par = Level.ERROR;
}
if (logging_level.equals("FATAL")) {
par = Level.FATAL;
}
if (logging_level.equals("INFO")) {
par = Level.INFO;
}
if (logging_level.equals("WARN")) {
par = Level.WARN;
}
if (logging_level.equals("OFF")) {
par = Level.OFF;
}
logger.setLevel(par);
}
/**
* we have some default options that should always get checked for in the
* arguments provided to the program
*/
private void setupDefaultArgs() {
m_parser.addOptionalFlag("help", "h", "Generate this help message", "help");
m_parser.addOptionalArg("logging_level", "l", "Set the logging level", "logging_level");
m_parser.addOptionalArg("log_to_file", "log", "Set the logging location", "toFile");
m_parser.addOptionalFlag("quiet_output_mode", "quiet", "Set the logging to quiet mode, no output to stdout", "quietMode");
m_parser.addOptionalFlag("debug_mode", "debug", "Set the logging file string to include a lot of debugging information (SLOW!)", "debugMode");
}
}

View File

@ -7,5 +7,6 @@
<dependency org="junit" name="junit" rev="4.4" />
<dependency org="log4j" name="log4j" rev="1.2.15" />
<dependency org="colt" name="colt" rev="1.2.0" />
<dependency org="commons-cli" name="commons-cli" rev="1.1" />
</dependencies>
</ivy-module>