Disable support for short name values directly abutting their arguments.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@740 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-05-17 16:09:32 +00:00
parent 4ab9bfe662
commit 7161b8f927
3 changed files with 30 additions and 128 deletions

View File

@ -58,8 +58,8 @@ public class ParsingEngine {
protected static Logger logger = Logger.getLogger(ParsingEngine.class); protected static Logger logger = Logger.getLogger(ParsingEngine.class);
public ParsingEngine() { public ParsingEngine() {
parsingMethods.add( new FullNameParsingMethod() ); parsingMethods.add( ParsingMethod.FullNameParsingMethod );
parsingMethods.add( new ShortNameParsingMethod() ); parsingMethods.add( ParsingMethod.ShortNameParsingMethod );
} }
/** /**

View File

@ -2,19 +2,33 @@ package org.broadinstitute.sting.utils.cmdLine;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.List;
import java.util.ArrayList;
/** /**
* Holds a pattern, along with how to get to the argument definitions that could match that pattern. * Holds a pattern, along with how to get to the argument definitions that could match that pattern.
*/ */
interface ParsingMethod { public abstract class ParsingMethod {
private final Pattern pattern;
private final DefinitionMatcher definitionMatcher;
/**
* Create a new parsing method with the given identifying / validating pattern and definition matcher.
* @param pattern The pattern
* @param definitionMatcher The definition matcher.
*/
private ParsingMethod( Pattern pattern, DefinitionMatcher definitionMatcher ) {
this.pattern = pattern;
this.definitionMatcher = definitionMatcher;
}
/** /**
* Can the given token be parsed by this parsing method? * Can the given token be parsed by this parsing method?
* @param token Token to validate. * @param token Token to validate.
* @return True if the given token matches. * @return True if the given token matches.
*/ */
public abstract boolean matches( String token ); public boolean matches( String token ) {
Matcher matcher = pattern.matcher(token);
return matcher.matches();
}
/** /**
* Find the best match for a given token at a given position from among the provided * Find the best match for a given token at a given position from among the provided
@ -27,21 +41,6 @@ interface ParsingMethod {
* @return An argument match. Definition field will be populated if a match was found or * @return An argument match. Definition field will be populated if a match was found or
* empty if no appropriate definition could be found. * empty if no appropriate definition could be found.
*/ */
public abstract ArgumentMatch match( ArgumentDefinitions definitions, String token, int position );
}
/**
* Instructions for how to parse a command-line argument passed by full name into a match.
*/
class FullNameParsingMethod implements ParsingMethod {
private static final Pattern pattern = Pattern.compile("\\s*--([\\w\\.\\-]+)\\s*");
private static final DefinitionMatcher definitionMatcher = ArgumentDefinitions.FullNameDefinitionMatcher;
public boolean matches( String token ) {
Matcher matcher = pattern.matcher(token);
return matcher.matches();
}
public ArgumentMatch match( ArgumentDefinitions definitions, String token, int position ) { public ArgumentMatch match( ArgumentDefinitions definitions, String token, int position ) {
// If the argument is valid, parse out the argument. // If the argument is valid, parse out the argument.
Matcher matcher = pattern.matcher(token); Matcher matcher = pattern.matcher(token);
@ -61,59 +60,9 @@ class FullNameParsingMethod implements ParsingMethod {
return argumentMatch; return argumentMatch;
} }
}
public static ParsingMethod FullNameParsingMethod = new ParsingMethod(Pattern.compile("\\s*--([\\w\\.\\-]+)\\s*"),
/** ArgumentDefinitions.FullNameDefinitionMatcher) {};
* Instructions for how to parse a command-line argument passed by short name into a match. public static ParsingMethod ShortNameParsingMethod = new ParsingMethod(Pattern.compile("\\s*-([\\w\\-]+)\\s*"),
*/ ArgumentDefinitions.ShortNameDefinitionMatcher) {};
class ShortNameParsingMethod implements ParsingMethod {
private static final Pattern standalonePattern = Pattern.compile("\\s*-([\\w\\-]+)\\s*");
private static final Pattern embeddedValuePattern = Pattern.compile("\\s*-([\\w\\.])([\\w/:\\.\\-]+)\\s*");
private static final DefinitionMatcher definitionMatcher = ArgumentDefinitions.ShortNameDefinitionMatcher;
public boolean matches( String token ) {
return standalonePattern.matcher(token).matches() || embeddedValuePattern.matcher(token).matches();
}
public ArgumentMatch match( ArgumentDefinitions definitions, String token, int position ) {
// Didn't match? Must be bad input.
if( !matches(token) )
throw new IllegalArgumentException( String.format("Unable to parse token %s with pattern %s", token, embeddedValuePattern.pattern()) );
// Build the best possible standalone match given the available data.
Matcher standaloneMatcher = standalonePattern.matcher(token);
ArgumentMatch standaloneMatch = null;
if( standaloneMatcher.matches() ) {
String argument = standaloneMatcher.group(1).trim();
ArgumentDefinition argumentDefinition = definitions.findArgumentDefinition(argument,definitionMatcher);
standaloneMatch = new ArgumentMatch( argument, argumentDefinition, position );
}
// Build the best possible embedded value match given the available data.
Matcher embeddedValueMatcher = embeddedValuePattern.matcher(token);
ArgumentMatch embeddedValueMatch = null;
if( embeddedValueMatcher.matches() ) {
String argument = embeddedValueMatcher.group(1).trim();
String value = embeddedValueMatcher.group(2).trim();
ArgumentDefinition argumentDefinition = definitions.findArgumentDefinition(argument,definitionMatcher);
embeddedValueMatch = new ArgumentMatch( argument, argumentDefinition, position );
if( embeddedValueMatch != null && value != null )
embeddedValueMatch.addValue( position, value );
}
// Prefer the standalone match...
ArgumentMatch bestMatch = standaloneMatch;
// ...But if the embedded value match is clearly better, choose it as the best match instead.
if( (standaloneMatch == null || standaloneMatch.definition == null) &&
(embeddedValueMatch != null && embeddedValueMatch.definition != null) )
bestMatch = embeddedValueMatch;
return bestMatch;
}
} }

View File

@ -52,53 +52,6 @@ public class ParsingEngineTest extends BaseTest {
Assert.assertEquals("Argument is not correctly initialized", "na12878.bam", argProvider.inputFile ); Assert.assertEquals("Argument is not correctly initialized", "na12878.bam", argProvider.inputFile );
} }
@Test
public void shortNameCompositeArgumentTest() {
final String[] commandLine = new String[] {"-Ina12878.bam"};
parsingEngine.addArgumentSource( InputFileArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
InputFileArgProvider argProvider = new InputFileArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals("Argument is not correctly initialized", "na12878.bam", argProvider.inputFile );
}
@Test
public void absolutePathnameInCompositeArgumentTest() {
final String[] commandLine = new String[] {"-I/broad/1KG/legacy_data/trio/na12878.bam"};
parsingEngine.addArgumentSource( InputFileArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
InputFileArgProvider argProvider = new InputFileArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals("Argument is not correctly initialized", "/broad/1KG/legacy_data/trio/na12878.bam", argProvider.inputFile );
}
@Test
public void chrRangeInCompositeArgumentTest() {
final String[] commandLine = new String[] {"-Lchr1:10000-11000"};
parsingEngine.addArgumentSource( ChrRangeArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
ChrRangeArgProvider argProvider = new ChrRangeArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals("Argument is not correctly initialized", "chr1:10000-11000", argProvider.REGION_STR );
}
private class ChrRangeArgProvider {
@Argument(fullName="genome_region", shortName="L", doc="Genome region to operation on: from chr:start-end")
public String REGION_STR = null;
}
@Test @Test
public void multiCharShortNameArgumentTest() { public void multiCharShortNameArgumentTest() {
final String[] commandLine = new String[] {"-out","out.txt"}; final String[] commandLine = new String[] {"-out","out.txt"};
@ -168,7 +121,7 @@ public class ParsingEngineTest extends BaseTest {
@Test @Test
public void arrayTest() { public void arrayTest() {
final String[] commandLine = new String[] {"-Ifoo.txt", "--input_file", "bar.txt"}; final String[] commandLine = new String[] {"-I", "foo.txt", "--input_file", "bar.txt"};
parsingEngine.addArgumentSource( MultiValueArgProvider.class ); parsingEngine.addArgumentSource( MultiValueArgProvider.class );
parsingEngine.parse( commandLine ); parsingEngine.parse( commandLine );
@ -189,7 +142,7 @@ public class ParsingEngineTest extends BaseTest {
@Test @Test
public void typedCollectionTest() { public void typedCollectionTest() {
final String[] commandLine = new String[] { "-N2", "-N4", "-N6", "-N8", "-N10" }; final String[] commandLine = new String[] { "-N","2","-N","4","-N","6","-N","8","-N","10" };
parsingEngine.addArgumentSource( IntegerListArgProvider.class ); parsingEngine.addArgumentSource( IntegerListArgProvider.class );
parsingEngine.parse( commandLine ); parsingEngine.parse( commandLine );
@ -214,7 +167,7 @@ public class ParsingEngineTest extends BaseTest {
@Test @Test
public void untypedCollectionTest() { public void untypedCollectionTest() {
final String[] commandLine = new String[] { "-N2", "-N4", "-N6", "-N8", "-N10" }; final String[] commandLine = new String[] { "-N","2","-N","4","-N","6","-N","8","-N","10" };
parsingEngine.addArgumentSource( UntypedListArgProvider.class ); parsingEngine.addArgumentSource( UntypedListArgProvider.class );
parsingEngine.parse( commandLine ); parsingEngine.parse( commandLine );
@ -365,7 +318,7 @@ public class ParsingEngineTest extends BaseTest {
@Test(expected=UnmatchedArgumentException.class) @Test(expected=UnmatchedArgumentException.class)
public void extraValueTest() { public void extraValueTest() {
final String[] commandLine = new String[] {"-Ifoo.txt", "bar.txt"}; final String[] commandLine = new String[] {"-I", "foo.txt", "bar.txt"};
parsingEngine.addArgumentSource( InputFileArgProvider.class ); parsingEngine.addArgumentSource( InputFileArgProvider.class );
parsingEngine.parse( commandLine ); parsingEngine.parse( commandLine );
@ -481,7 +434,7 @@ public class ParsingEngineTest extends BaseTest {
@Test(expected=TooManyValuesForArgumentException.class) @Test(expected=TooManyValuesForArgumentException.class)
public void invalidParseForAnalysisTypeTest() { public void invalidParseForAnalysisTypeTest() {
final String[] commandLine = new String[] {"--analysis_type", "Pileup", "-TCountReads" }; final String[] commandLine = new String[] {"--analysis_type", "Pileup", "-T", "CountReads" };
parsingEngine.addArgumentSource( AnalysisTypeArgProvider.class ); parsingEngine.addArgumentSource( AnalysisTypeArgProvider.class );
parsingEngine.parse( commandLine ); parsingEngine.parse( commandLine );