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:
parent
38f18c8679
commit
046cecb067
|
|
@ -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);
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue