@Required / @Allows flags for main arguments.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@751 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-05-19 23:26:17 +00:00
parent 40dbc21df7
commit 01a3cb27c7
19 changed files with 309 additions and 60 deletions

View File

@ -13,6 +13,7 @@ import org.broadinstitute.sting.gatk.walkers.*;
import org.broadinstitute.sting.utils.GenomeLoc;
import org.broadinstitute.sting.utils.StingException;
import org.broadinstitute.sting.utils.Utils;
import org.broadinstitute.sting.utils.cmdLine.ArgumentException;
import java.util.ArrayList;
import java.util.List;
@ -76,6 +77,9 @@ public class GenomeAnalysisEngine {
// parse out the rod bindings
ReferenceOrderedData.parseBindings(logger, argCollection.RODBindings, rods);
// Validate the walker inputs against the walker.
validateInputsAgainstWalker(my_walker, argCollection, rods);
// create the output streams
initializeOutputStreams( my_walker );
@ -84,8 +88,7 @@ public class GenomeAnalysisEngine {
// if we're a read or a locus walker, we use the new system. Right now we have complicated
// branching based on the input data, but this should disapear when all the traversals are switched over
if ((my_walker instanceof LocusWalker && !(argCollection.samFiles == null || argCollection.samFiles.size() == 0)) ||
my_walker instanceof ReadWalker) {
if (my_walker instanceof LocusWalker || my_walker instanceof ReadWalker) {
microScheduler = createMicroscheduler(my_walker, rods);
} else { // we have an old style traversal, once we're done return
legacyTraversal(my_walker, rods);
@ -125,18 +128,6 @@ public class GenomeAnalysisEngine {
private void legacyTraversal(Walker my_walker, List<ReferenceOrderedData<? extends ReferenceOrderedDatum>> rods) {
if (my_walker instanceof LocusWindowWalker) {
this.engine = new TraverseByLocusWindows(argCollection.samFiles, argCollection.referenceFile, rods);
} else if (my_walker instanceof LocusWalker) {
if (argCollection.referenceFile == null)
Utils.scareUser(String.format("Locus-based traversals require a reference file but none was given"));
if (argCollection.samFiles == null || argCollection.samFiles.size() == 0) {
if (((LocusWalker) my_walker).requiresReads())
Utils.scareUser(String.format("Analysis %s requires reads, but none were given", argCollection.analysisName));
this.engine = new TraverseByReference(null, argCollection.referenceFile, rods);
} else {
if (((LocusWalker) my_walker).cannotHandleReads())
Utils.scareUser(String.format("Analysis %s doesn't support SAM/BAM reads, but a read file %s was provided", argCollection.analysisName, argCollection.samFiles));
this.engine = new TraverseByLoci(argCollection.samFiles, argCollection.referenceFile, rods);
}
} else if (my_walker instanceof DuplicateWalker) {
// we're a duplicate walker
this.engine = new TraverseDuplicates(argCollection.samFiles, argCollection.referenceFile, rods);
@ -174,12 +165,6 @@ public class GenomeAnalysisEngine {
// we need to verify different parameter based on the walker type
if (my_walker instanceof LocusWalker) {
// some warnings
if (argCollection.referenceFile == null)
Utils.scareUser(String.format("Locus-based traversals require a reference file but none was given"));
if (((LocusWalker) my_walker).cannotHandleReads())
Utils.scareUser(String.format("Analysis %s doesn't support SAM/BAM reads, but a read file %s was provided", argCollection.analysisName, argCollection.samFiles));
// create the MicroScheduler
if( argCollection.walkAllLoci )
Utils.scareUser("Argument --all_loci is deprecated. Please annotate your walker with @By(DataSource.REFERENCE) to perform a by-reference traversal.");
@ -238,6 +223,42 @@ public class GenomeAnalysisEngine {
return locs;
}
private void validateInputsAgainstWalker(Walker walker,
GATKArgumentCollection arguments,
List<ReferenceOrderedData<? extends ReferenceOrderedDatum>> rods) {
String walkerName = WalkerManager.getWalkerName(walker.getClass());
// Check what the walker says is required against what was provided on the command line.
if( WalkerManager.isRequired(walker,DataSource.READS) && (arguments.samFiles == null || arguments.samFiles.size() == 0) )
throw new ArgumentException(String.format("Walker %s requires reads but none were provided. If this is incorrect, alter the walker's @Requires annotation.",walkerName));
if( WalkerManager.isRequired(walker,DataSource.REFERENCE) && arguments.referenceFile == null )
throw new ArgumentException(String.format("Walker %s requires a reference but none was provided. If this is incorrect, alter the walker's @Requires annotation.",walkerName));
// Check what the walker says is allowed against what was provided on the command line.
if( (arguments.samFiles != null && arguments.samFiles.size() > 0) && !WalkerManager.isAllowed(walker,DataSource.READS) )
throw new ArgumentException(String.format("Walker %s does not allow reads but reads were provided. If this is incorrect, alter the walker's @Allows annotation",walkerName));
if( arguments.referenceFile != null && !WalkerManager.isAllowed(walker,DataSource.REFERENCE) )
throw new ArgumentException(String.format("Walker %s does not allow a reference but one was provided. If this is incorrect, alter the walker's @Allows annotation",walkerName));
// Check to make sure that all required metadata is present.
List<RMD> allRequired = WalkerManager.getRequiredMetaData(walker);
for( RMD required: allRequired ) {
boolean found = false;
for( ReferenceOrderedData<? extends ReferenceOrderedDatum> rod: rods ) {
if( rod.matches(required.name(),required.type()) )
found = true;
}
if( !found )
throw new ArgumentException(String.format("Unable to find reference metadata (%s,%s)",required.name(),required.type()));
}
// Check to see that no forbidden rods are present.
for( ReferenceOrderedData<? extends ReferenceOrderedDatum> rod: rods ) {
if( !WalkerManager.isAllowed(walker,rod) )
throw new ArgumentException(String.format("Walker does not allow access to metadata: %s. If this is correct, change the @Allows metadata",rod.getName()));
}
}
/**
* Default to ValidationStringency.STRICT.
*

View File

@ -5,18 +5,23 @@ import net.sf.functionalj.reflect.JdkStdReflect;
import net.sf.functionalj.FunctionN;
import net.sf.functionalj.Functions;
import java.lang.reflect.Modifier;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import org.broadinstitute.sting.gatk.walkers.Walker;
import org.broadinstitute.sting.gatk.walkers.WalkerName;
import org.broadinstitute.sting.gatk.walkers.DataSource;
import org.broadinstitute.sting.gatk.walkers.By;
import org.broadinstitute.sting.gatk.walkers.Allows;
import org.broadinstitute.sting.gatk.walkers.Requires;
import org.broadinstitute.sting.gatk.walkers.RMD;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
import org.broadinstitute.sting.utils.JVMUtils;
import org.broadinstitute.sting.utils.PathUtils;
import org.broadinstitute.sting.utils.StingException;
@ -120,6 +125,71 @@ public class WalkerManager {
return byDataSource.value();
}
/**
* Determine whether the given walker supports the given data source.
* @param walker Walker to query.
* @param dataSource Source to check for .
* @return True if the walker forbids this data type. False otherwise.
*/
public static boolean isAllowed(Walker walker, DataSource dataSource) {
Allows allowsDataSource = getWalkerAllowed(walker);
// Allows is less restrictive than requires. If an allows
// clause is not specified, any kind of data is allowed.
if( allowsDataSource == null )
return true;
return Arrays.asList(allowsDataSource.value()).contains(dataSource);
}
/**
* Determine whether the given walker supports the given reference ordered data.
* @param walker Walker to query.
* @param rod Source to check.
* @return True if the walker forbids this data type. False otherwise.
*/
public static boolean isAllowed(Walker walker, ReferenceOrderedData<? extends ReferenceOrderedDatum> rod) {
Allows allowsDataSource = getWalkerAllowed(walker);
// Allows is less restrictive than requires. If an allows
// clause is not specified, any kind of data is allowed.
if( allowsDataSource == null )
return true;
// The difference between unspecified RMD and the empty set of metadata can't be detected.
// Treat an empty 'allows' as 'allow everything'. Maybe we can have a special RMD flag to account for this
// case in the future.
if( allowsDataSource.referenceMetaData().length == 0 )
return true;
for( RMD allowed: allowsDataSource.referenceMetaData() ) {
if( rod.matches(allowed.name(),allowed.type()) )
return true;
}
return false;
}
/**
* Determine whether the given walker requires the given data source.
* @param walker Walker to query.
* @param dataSource Source to check for.
* @return True if the walker allows this data type. False otherwise.
*/
public static boolean isRequired(Walker walker, DataSource dataSource) {
Requires requiresDataSource = getWalkerRequirements(walker);
return Arrays.asList(requiresDataSource.value()).contains(dataSource);
}
/**
* Get a list of RODs required by the walker.
* @param walker Walker to query.
* @return True if the walker allows this data type. False otherwise.
*/
public static List<RMD> getRequiredMetaData(Walker walker) {
Requires requiresDataSource = getWalkerRequirements(walker);
return Arrays.asList(requiresDataSource.referenceMetaData());
}
/**
* Load classes internal to the classpath from an arbitrary location.
*
@ -173,7 +243,7 @@ public class WalkerManager {
* @param walkerType The type of walker.
* @return A name for this type of walker.
*/
public static String getWalkerName(Class<Walker> walkerType) {
public static String getWalkerName(Class<? extends Walker> walkerType) {
String walkerName = "";
if (walkerType.getAnnotation(WalkerName.class) != null)
@ -187,4 +257,29 @@ public class WalkerManager {
return walkerName;
}
/**
* Utility to get the requires attribute from the walker.
* Throws an exception if requirements are missing.
* @param walker Walker to query for required data.
* @return Required data attribute.
*/
private static Requires getWalkerRequirements(Walker walker) {
Class<? extends Walker> walkerClass = walker.getClass();
Requires requiresDataSource = walkerClass.getAnnotation(Requires.class);
if( requiresDataSource == null )
throw new StingException( "Unable to find data types required by walker class " + walkerClass.getName());
return requiresDataSource;
}
/**
* Utility to get the forbidden attribute from the walker.
* @param walker Walker to query for required data.
* @return Required data attribute. Null if forbidden info isn't present.
*/
private static Allows getWalkerAllowed(Walker walker) {
Class<? extends Walker> walkerClass = walker.getClass();
Allows allowsDataSource = walkerClass.getAnnotation(Allows.class);
return allowsDataSource;
}
}

View File

@ -1,11 +1,16 @@
package org.broadinstitute.sting.gatk.dataSources.providers;
import org.broadinstitute.sting.gatk.iterators.StingSAMIterator;
import org.broadinstitute.sting.gatk.iterators.NullSAMIterator;
import org.broadinstitute.sting.gatk.dataSources.shards.Shard;
import org.broadinstitute.sting.gatk.dataSources.simpleDataSources.SAMDataSource;
import org.broadinstitute.sting.gatk.Reads;
import org.broadinstitute.sting.utils.fasta.IndexedFastaSequenceFile;
import org.broadinstitute.sting.utils.GenomeLoc;
import net.sf.samtools.SAMRecord;
import java.io.File;
import java.util.ArrayList;
/**
* User: hanna
* Date: May 8, 2009
@ -99,7 +104,7 @@ public class ShardDataProvider {
public ShardDataProvider( Shard shard, SAMDataSource reads, IndexedFastaSequenceFile reference ) {
this.shard = shard;
// Provide basic reads information.
this.reads = reads.seek( shard );
this.reads = (reads != null) ? reads.seek( shard ) : new NullSAMIterator(new Reads(new ArrayList<File>()));
this.referenceProvider = (reference != null) ? new ReferenceProvider(reference,shard) : null;
}

View File

@ -149,6 +149,10 @@ public abstract class MicroScheduler {
* @return A data source for the given set of reads.
*/
private SAMDataSource getReadsDataSource( Reads reads ) {
// By reference traversals are happy with no reads. Make sure that case is handled.
if( reads.getReadsFiles().size() == 0 )
return null;
SAMDataSource dataSource = new SAMDataSource( reads );
// Side effect: initialize the traversal engine with reads data.

View File

@ -0,0 +1,36 @@
package org.broadinstitute.sting.gatk.iterators;
import org.broadinstitute.sting.gatk.Reads;
import net.sf.samtools.SAMRecord;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* User: hanna
* Date: May 19, 2009
* Time: 6:47:16 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 placeholder for an iterator with no data.
*/
public class NullSAMIterator implements StingSAMIterator {
private Reads reads = null;
public NullSAMIterator( Reads reads ) { this.reads = reads; }
public Reads getSourceInfo() { return reads; }
public Iterator<SAMRecord> iterator() { return this; }
public void close() { /* NO-OP */ }
public boolean hasNext() { return false; }
public SAMRecord next() { throw new NoSuchElementException("No next element is available."); }
public void remove() { throw new UnsupportedOperationException("Cannot remove from a StingSAMIterator"); }
}

View File

@ -138,6 +138,17 @@ public class ReferenceOrderedData<ROD extends ReferenceOrderedDatum> implements
public String getName() { return name; }
/**
* Special equals override to see if this ROD is of type name, type.
* Implemented to preserve data hiding whenever possible.
* @param name Name to check.
* @param type Type to check.
* @return True if these parameters imply this rod. False otherwise.
*/
public boolean matches( String name, Class<? extends ReferenceOrderedDatum> type ) {
return this.name.equals(name) && this.type.equals(type);
}
public RODIterator iterator() {
return new RODIterator(new SimpleRODIterator());
}

View File

@ -0,0 +1,32 @@
package org.broadinstitute.sting.gatk.walkers;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
/**
* User: hanna
* Date: May 19, 2009
* Time: 10:05:01 AM
* 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.
*/
/**
* Determines what data sources are allowed by a given walker.
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Allows {
DataSource[] value();
RMD[] referenceMetaData() default {};
}

View File

@ -1,7 +1,5 @@
package org.broadinstitute.sting.gatk.walkers;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker;
import org.broadinstitute.sting.gatk.LocusContext;
import org.broadinstitute.sting.utils.GenomeLoc;
@ -16,20 +14,13 @@ import net.sf.samtools.SAMRecord;
* Time: 2:52:28 PM
* To change this template use File | Settings | File Templates.
*/
@Requires({DataSource.READS,DataSource.REFERENCE})
public abstract class DuplicateWalker<MapType, ReduceType> extends Walker<MapType, ReduceType> {
// Do we actually want to operate on the context?
public boolean filter(GenomeLoc loc, byte[] refBases, LocusContext context, List<SAMRecord> duplicateReads) {
return true; // We are keeping all the reads
}
/**
* These two functions state whether we're don't make any sense without reads (requiresRead())
* or whether we can't take any reads at all (cannotHandleRead())
*/
public boolean requiresReads() { return true; }
public boolean cannotHandleReads() { return false; }
/**
* Called by the traversal engine to decide whether to send non-duplicates as lists of
* singleton reads to the map function. By default it's false.

View File

@ -11,19 +11,13 @@ import org.broadinstitute.sting.gatk.LocusContext;
* To change this template use File | Settings | File Templates.
*/
@By(DataSource.READS)
@Requires({DataSource.READS,DataSource.REFERENCE})
public abstract class LocusWalker<MapType, ReduceType> extends Walker<MapType, ReduceType> {
// Do we actually want to operate on the context?
public boolean filter(RefMetaDataTracker tracker, char ref, LocusContext context) {
return true; // We are keeping all the reads
}
/**
* These two functions state whether we're don't make any sense without reads (requiresRead())
* or whether we can't take any reads at all (cannotHandleRead())
*/
public boolean requiresReads() { return false; }
public boolean cannotHandleReads() { return false; }
// Map over the org.broadinstitute.sting.gatk.LocusContext
public abstract MapType map(RefMetaDataTracker tracker, char ref, LocusContext context);
}

View File

@ -0,0 +1,24 @@
package org.broadinstitute.sting.gatk.walkers;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
/**
* User: hanna
* Date: May 19, 2009
* Time: 1:34:15 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 data type representing reference-ordered data.
*/
public @interface RMD {
String name();
Class<? extends ReferenceOrderedDatum> type();
}

View File

@ -1,7 +1,6 @@
package org.broadinstitute.sting.gatk.walkers;
import net.sf.samtools.SAMRecord;
import org.broadinstitute.sting.gatk.LocusContext;
/**
* Created by IntelliJ IDEA.
@ -10,6 +9,7 @@ import org.broadinstitute.sting.gatk.LocusContext;
* Time: 2:52:28 PM
* To change this template use File | Settings | File Templates.
*/
@Requires(DataSource.READS)
public abstract class ReadWalker<MapType, ReduceType> extends Walker<MapType, ReduceType> {
public boolean requiresOrderedReads() { return false; }

View File

@ -1,10 +1,5 @@
package org.broadinstitute.sting.gatk.walkers;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.LocusContext;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: mdepristo
@ -12,7 +7,8 @@ import java.util.List;
* Time: 2:52:28 PM
* To change this template use File | Settings | File Templates.
*/
@By(DataSource.REFERENCE)
@Requires(DataSource.REFERENCE)
@Allows(DataSource.REFERENCE)
public abstract class RefWalker<MapType, ReduceType> extends LocusWalker<MapType, ReduceType> {
public boolean requiresReads() { return false; }
public boolean cannotHandleReads() { return true; }
}

View File

@ -0,0 +1,32 @@
package org.broadinstitute.sting.gatk.walkers;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
/**
* User: hanna
* Date: May 19, 2009
* Time: 10:06:47 AM
* 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.
*/
/**
* Determines what data sources are mandated by a given walker.
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Requires {
DataSource[] value();
RMD[] referenceMetaData() default {};
}

View File

@ -16,6 +16,7 @@ import org.broadinstitute.sting.utils.ReadBackedPileup;
* Time: 3:22:14 PM
* To change this template use File | Settings | File Templates.
*/
@Requires(value={DataSource.READS,DataSource.REFERENCE},referenceMetaData=@RMD(name="pileup",type=rodSAMPileup.class))
public class ValidatingPileupWalker extends LocusWalker<Integer, ValidationStats> {
@Argument(fullName="continue_after_error",doc="Continue after an error",required=false)
public boolean CONTINUE_AFTER_AN_ERROR = false;

View File

@ -9,9 +9,15 @@ import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker;
import org.broadinstitute.sting.gatk.refdata.rodSAMPileup;
import org.broadinstitute.sting.gatk.refdata.Genotype;
import org.broadinstitute.sting.gatk.walkers.RefWalker;
import org.broadinstitute.sting.gatk.walkers.Requires;
import org.broadinstitute.sting.gatk.walkers.DataSource;
import org.broadinstitute.sting.gatk.walkers.RMD;
import org.broadinstitute.sting.playground.utils.TrioConcordanceRecord;
import org.broadinstitute.sting.utils.cmdLine.Argument;
@Requires(value=DataSource.REFERENCE,referenceMetaData={@RMD(name="mother",type=rodSAMPileup.class),
@RMD(name="father",type=rodSAMPileup.class),
@RMD(name="daughter",type=rodSAMPileup.class)})
public class MendelianInheritanceWalker extends RefWalker<TrioConcordanceRecord, TrioConcordanceRecord> {
@Argument(fullName="consensus_cutoff", shortName="XC", doc="consensus cutoff", required=true ) public Double CONS_CUTOFF;

View File

@ -2,7 +2,8 @@ package org.broadinstitute.sting.playground.indels;
import java.io.File;
import edu.mit.broad.picard.reference.*;
import edu.mit.broad.picard.reference.ReferenceSequenceFileFactory;
import edu.mit.broad.picard.reference.ReferenceSequenceFileWalker;
import edu.mit.broad.picard.cmdline.CommandLineProgram;
import edu.mit.broad.picard.cmdline.Option;
import edu.mit.broad.picard.cmdline.Usage;

View File

@ -5,8 +5,8 @@ import org.broadinstitute.sting.utils.StingException;
/**
* Generic class for handling misc parsing exceptions.
*/
public class ParseException extends StingException {
public ParseException( String message ) {
public class ArgumentException extends StingException {
public ArgumentException( String message ) {
super( message );
}
}

View File

@ -239,7 +239,7 @@ public abstract class CommandLineProgram {
// return the result
System.exit(result);
}
catch (ParseException e) {
catch (ArgumentException e) {
clp.parser.printHelp( clp.getRunningInstructions() );
// Rethrow the exception to exit with an error.
throw e;
@ -302,7 +302,7 @@ public abstract class CommandLineProgram {
* this function checks the logger level passed in on the command line, taking the lowest
* level that was provided.
*/
private void setupLoggerLevel() throws ParseException {
private void setupLoggerLevel() {
Level par = Level.ERROR;
if (logging_level.equals("DEBUG")) {
@ -325,7 +325,7 @@ public abstract class CommandLineProgram {
}
else {
// we don't understand the logging level, let's get out of here
throw new ParseException("Unable to match: " + logging_level + " to a logging level, make sure it's a valid level (INFO, DEBUG, ERROR, FATAL, OFF)");
throw new ArgumentException("Unable to match: " + logging_level + " to a logging level, make sure it's a valid level (INFO, DEBUG, ERROR, FATAL, OFF)");
}
logger.setLevel(par);

View File

@ -457,7 +457,7 @@ public class ParsingEngine {
/**
* An exception indicating that some required arguments are missing.
*/
class MissingArgumentException extends ParseException {
class MissingArgumentException extends ArgumentException {
public MissingArgumentException( Collection<ArgumentDefinition> missingArguments ) {
super( formatArguments(missingArguments) );
}
@ -477,7 +477,7 @@ class MissingArgumentException extends ParseException {
/**
* An exception for undefined arguments.
*/
class InvalidArgumentException extends ParseException {
class InvalidArgumentException extends ArgumentException {
public InvalidArgumentException( Collection<ArgumentMatch> invalidArguments ) {
super( formatArguments(invalidArguments) );
}
@ -493,7 +493,7 @@ class InvalidArgumentException extends ParseException {
/**
* An exception for values whose format is invalid.
*/
class InvalidArgumentValueException extends ParseException {
class InvalidArgumentValueException extends ArgumentException {
public InvalidArgumentValueException( Collection<Pair<ArgumentDefinition,String>> invalidArgumentValues ) {
super( formatArguments(invalidArgumentValues) );
}
@ -514,7 +514,7 @@ class InvalidArgumentValueException extends ParseException {
/**
* An exception for values that can't be mated with any argument.
*/
class UnmatchedArgumentException extends ParseException {
class UnmatchedArgumentException extends ArgumentException {
public UnmatchedArgumentException( ArgumentMatch invalidValues ) {
super( formatArguments(invalidValues) );
}
@ -531,7 +531,7 @@ class UnmatchedArgumentException extends ParseException {
/**
* An exception indicating that too many values have been provided for the given argument.
*/
class TooManyValuesForArgumentException extends ParseException {
class TooManyValuesForArgumentException extends ArgumentException {
public TooManyValuesForArgumentException( Collection<ArgumentMatch> arguments ) {
super( formatArguments(arguments) );
}
@ -547,7 +547,7 @@ class TooManyValuesForArgumentException extends ParseException {
/**
* An exception indicating that mutually exclusive options have been passed in the same command line.
*/
class ArgumentsAreMutuallyExclusiveException extends ParseException {
class ArgumentsAreMutuallyExclusiveException extends ArgumentException {
public ArgumentsAreMutuallyExclusiveException( Collection<Pair<ArgumentMatch,ArgumentMatch>> arguments ) {
super( formatArguments(arguments) );
}