Interface skeleton for a new command line argument parser. Nowhere near the point of being a drop-in replacement for apache cli yet.
git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@588 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
parent
6e38966349
commit
4f2ccda56a
|
|
@ -0,0 +1,81 @@
|
|||
package org.broadinstitute.sting.utils.cmdLine;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mhanna
|
||||
* Date: May 3, 2009
|
||||
* Time: 6:02:04 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.
|
||||
*/
|
||||
/**
|
||||
* A collection of argument definitions.
|
||||
*/
|
||||
class ArgumentDefinitions {
|
||||
/**
|
||||
* Backing data set of argument stored by short name.
|
||||
*/
|
||||
private Map<String,ArgumentDefinition> argumentsByShortName = new HashMap<String,ArgumentDefinition>();
|
||||
|
||||
/**
|
||||
* Does this set of argument definitions specify an argument with the given short name?
|
||||
* @param shortName The short name.
|
||||
* @return True if it contains the definition. False otherwise.
|
||||
*/
|
||||
public boolean hasArgumentWithShortName( String shortName ) {
|
||||
return argumentsByShortName.containsKey( shortName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument with the given short name.
|
||||
* @param shortName Argument short name.
|
||||
* @return The argument definition, or null if nothing matches.
|
||||
*/
|
||||
public ArgumentDefinition getArgumentWithShortName( String shortName ) {
|
||||
return argumentsByShortName.get( shortName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an argument to the this argument definition list.
|
||||
* @param argument The argument to add.
|
||||
* @param sourceClass Class where the argument was defined.
|
||||
* @param sourceField Field in which the argument was defined.
|
||||
*/
|
||||
public void add( Argument argument, Class sourceClass, Field sourceField ) {
|
||||
argumentsByShortName.put( argument.shortName(),
|
||||
new ArgumentDefinition( argument, sourceClass, sourceField ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A specific argument definition. Maps one-to-one with a field in some class.
|
||||
*/
|
||||
class ArgumentDefinition {
|
||||
public final Argument argument;
|
||||
public final Class sourceClass;
|
||||
public final Field sourceField;
|
||||
|
||||
/**
|
||||
* Creates a new argument definition.
|
||||
* @param argument Attributes of the argument, read from the source field.
|
||||
* @param sourceClass Source class for the argument, provided to the ParsingEngine.
|
||||
* @param sourceField Source field for the argument, extracted from the sourceClass.
|
||||
*/
|
||||
public ArgumentDefinition( Argument argument, Class sourceClass, Field sourceField ) {
|
||||
this.argument = argument;
|
||||
this.sourceClass = sourceClass;
|
||||
this.sourceField = sourceField;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package org.broadinstitute.sting.utils.cmdLine;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator; /**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mhanna
|
||||
* Date: May 3, 2009
|
||||
* Time: 6:36:43 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a list of potential matches between the arguments defined
|
||||
* by the argument sources and the arguments passed in via the command line.
|
||||
*/
|
||||
public class ArgumentMatches implements Iterable<ArgumentMatch> {
|
||||
/**
|
||||
* Collection matches from argument definition to argument value.
|
||||
* Package protected access is deliberate.
|
||||
*/
|
||||
Set<ArgumentMatch> argumentMatches = new HashSet<ArgumentMatch>();
|
||||
|
||||
void add( ArgumentDefinition definition, String value ) {
|
||||
argumentMatches.add( new ArgumentMatch( definition, value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator cycling through command-line argument <-> definition matches.
|
||||
* @return Iterator over all argument matches.
|
||||
*/
|
||||
public Iterator<ArgumentMatch> iterator() {
|
||||
return argumentMatches.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An individual match from argument definition to argument value.
|
||||
*/
|
||||
class ArgumentMatch {
|
||||
public final ArgumentDefinition definition;
|
||||
public final String value;
|
||||
|
||||
public ArgumentMatch( ArgumentDefinition definition, String value ) {
|
||||
this.definition = definition;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ public class ArgumentParser {
|
|||
parser.parse(m_options, args, false);
|
||||
}
|
||||
catch( ParseException e ) {
|
||||
boolean isIncomplete = e instanceof MissingArgumentException ||
|
||||
boolean isIncomplete = e instanceof org.apache.commons.cli.MissingArgumentException ||
|
||||
e instanceof MissingOptionException ||
|
||||
e instanceof UnrecognizedOptionException;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
package org.broadinstitute.sting.utils.cmdLine;
|
||||
|
||||
import org.broadinstitute.sting.utils.StingException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mhanna
|
||||
* Date: May 3, 2009
|
||||
* Time: 4:35:25 PM
|
||||
* BROAD INSTITUTE SOFTWARE COPYRIGHT NOTICE AND AGREEMENT
|
||||
* Software and documentation are copyright 2005 by the Broad Institute.
|
||||
* All rights are reserved.
|
||||
*
|
||||
* Users acknowledge that this software is supplied without any warranty or support.
|
||||
* The Broad Institute is not responsible for its use, misuse, or
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A parser for Sting command-line arguments.
|
||||
*/
|
||||
public class ParsingEngine {
|
||||
/**
|
||||
* A list of defined arguments against which command lines are matched.
|
||||
*/
|
||||
private ArgumentDefinitions argumentDefinitions = new ArgumentDefinitions();
|
||||
|
||||
/**
|
||||
* Add an argument source. Argument sources are expected to have
|
||||
* any number of fields with an @Argument annotation attached.
|
||||
* @param sources A list of argument sources from which to extract
|
||||
* command-line arguments.
|
||||
*/
|
||||
public void addArgumentSources( Class... sources ) {
|
||||
for( Class source: sources ) {
|
||||
Field[] fields = source.getFields();
|
||||
for( Field field: fields ) {
|
||||
Argument argument = field.getAnnotation(Argument.class);
|
||||
if(argument != null)
|
||||
argumentDefinitions.add( argument, source, field );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given set of command-line arguments, returning
|
||||
* an ArgumentMatches object describing the best fit of these
|
||||
* command-line arguments to the arguments that are actually
|
||||
* required.
|
||||
* @param arguments Command-line arguments.
|
||||
* @return A object indicating which matches are best. Might return
|
||||
* an empty object, but will never return null.
|
||||
*/
|
||||
public ArgumentMatches parse( String[] arguments ) {
|
||||
ArgumentMatches argumentMatches = new ArgumentMatches();
|
||||
|
||||
for( int i = 0; i < arguments.length; i++ ) {
|
||||
String argument = arguments[i].trim();
|
||||
if( argument.startsWith("-") ) {
|
||||
String shortName = argument.substring(1);
|
||||
if( argumentDefinitions.hasArgumentWithShortName(shortName) ) {
|
||||
ArgumentDefinition definition = argumentDefinitions.getArgumentWithShortName(shortName);
|
||||
argumentMatches.add( definition, arguments[i+1].trim() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return argumentMatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the list of command-line argument matches. On
|
||||
* failure ...TBD...
|
||||
*/
|
||||
public void validate( ArgumentMatches argumentMatches ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a set of matched command-line arguments into the given object.
|
||||
* @param object Object into which to add arguments.
|
||||
* @param argumentMatches List of matches.
|
||||
*/
|
||||
public void loadArgumentsIntoObject( Object object, ArgumentMatches matches ) {
|
||||
for( ArgumentMatch match: matches ) {
|
||||
if( object.getClass().equals(match.definition.sourceClass) ) {
|
||||
try {
|
||||
match.definition.sourceField.set( object, match.value );
|
||||
}
|
||||
catch( IllegalAccessException ex ) {
|
||||
//logger.fatal("processArgs: cannot convert field " + field.toString());
|
||||
throw new StingException("processArgs: Failed conversion " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package org.broadinstitute.sting.utils.cmdLine;
|
||||
|
||||
import org.broadinstitute.sting.BaseTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
import org.junit.Assert;
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mhanna
|
||||
* Date: May 3, 2009
|
||||
* Time: 6:05:33 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.
|
||||
*/
|
||||
/**
|
||||
* Test suite for the parsing engine.
|
||||
*/
|
||||
public class ParsingEngineTest extends BaseTest {
|
||||
private ParsingEngine parsingEngine;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
parsingEngine = new ParsingEngine();
|
||||
}
|
||||
|
||||
private class InputFileArgProvider {
|
||||
@Argument(fullName="input_file",shortName="I")
|
||||
public String inputFile;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shortNameArgumentTest() {
|
||||
final String[] commandLine = new String[] {"-I","na12878.bam"};
|
||||
|
||||
parsingEngine.addArgumentSources( InputFileArgProvider.class );
|
||||
ArgumentMatches argumentMatches = parsingEngine.parse( commandLine );
|
||||
parsingEngine.validate(argumentMatches);
|
||||
|
||||
InputFileArgProvider argProvider = new InputFileArgProvider();
|
||||
parsingEngine.loadArgumentsIntoObject( argProvider, argumentMatches);
|
||||
|
||||
Assert.assertEquals("Argument is not correctly initialized", "na12878.bam", argProvider.inputFile );
|
||||
}
|
||||
|
||||
// To test
|
||||
// 'Composite' short names
|
||||
// long names
|
||||
// flags
|
||||
// flags with arguments at every point on the line
|
||||
// flags with arguments at the end of the line
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void shortNameCompositeArgumentTest() {
|
||||
final String[] commandLine = new String[] {"-I na12878.bam"};
|
||||
|
||||
parsingEngine.addArgumentSources( InputFileArgProvider.class );
|
||||
ArgumentMatches argumentMatches = parsingEngine.parse( commandLine );
|
||||
parsingEngine.validate(argumentMatches);
|
||||
|
||||
InputFileArgProvider argProvider = new InputFileArgProvider();
|
||||
parsingEngine.loadArgumentsIntoObject( argProvider, argumentMatches);
|
||||
|
||||
Assert.assertEquals("Argument is not correctly initialized", "na12878.bam" );
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue