diff --git a/src/main/java/org/cyclopsgroup/jcli/annotation/Option.java b/src/main/java/org/cyclopsgroup/jcli/annotation/Option.java index abcaed6..b7b5810 100644 --- a/src/main/java/org/cyclopsgroup/jcli/annotation/Option.java +++ b/src/main/java/org/cyclopsgroup/jcli/annotation/Option.java @@ -45,4 +45,9 @@ * @return True if option has to be specified explicitly */ boolean required() default false; + + /** + * @return Array of conflicting options + */ + String[] conflicts() default { }; } diff --git a/src/main/java/org/cyclopsgroup/jcli/impl/AnnotationOption.java b/src/main/java/org/cyclopsgroup/jcli/impl/AnnotationOption.java index b2564cc..00636c2 100644 --- a/src/main/java/org/cyclopsgroup/jcli/impl/AnnotationOption.java +++ b/src/main/java/org/cyclopsgroup/jcli/impl/AnnotationOption.java @@ -13,7 +13,7 @@ class AnnotationOption private final Option option; - AnnotationOption( Option option, boolean flag, boolean multiValue ) + AnnotationOption( Option option, boolean flag, boolean multiValue) { this.option = option; this.flag = flag; @@ -109,5 +109,13 @@ public boolean isRequired() { return option.required(); } + + /** + * @inheritDoc + */ + @Override + public String[] getConflicts(){ + return option.conflicts(); + } } diff --git a/src/main/java/org/cyclopsgroup/jcli/impl/DefaultBeanProcessor.java b/src/main/java/org/cyclopsgroup/jcli/impl/DefaultBeanProcessor.java index 2a0b927..02940f8 100644 --- a/src/main/java/org/cyclopsgroup/jcli/impl/DefaultBeanProcessor.java +++ b/src/main/java/org/cyclopsgroup/jcli/impl/DefaultBeanProcessor.java @@ -1,12 +1,14 @@ package org.cyclopsgroup.jcli.impl; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.cyclopsgroup.jcli.spi.CommandLine; import org.cyclopsgroup.jcli.spi.CommandLineParser; +import org.cyclopsgroup.jcli.spi.Option; class DefaultBeanProcessor { @@ -49,6 +51,24 @@ static void process( AnnotationParsingContext context, List argum MultiValueReference ref = (MultiValueReference) context.lookupReference( entry.getKey(), false ); ref.setValues( bean, entry.getValue() ); } + //END of data load into bean + for(CommandLine.OptionValue ov : cli.getOptionValues()) + { + Option cmOption; + for(Option contextOption: context.options()) + { + Reference ref = context.lookupReference( contextOption.getName(), false ); + if(ref instanceof SingleValueReference && ( (SingleValueReference) ref ).getValue( bean ) == null) + { + continue; + } + + if((cmOption = context.optionWithShortName(ov.name)) != null && + Arrays.asList(cmOption.getConflicts()).contains(contextOption.getName())) + throw new AssertionError("grande errore cmOption: " + cmOption.getName() + " : " + contextOption.getName()); + } + } + // Reference ref = context.lookupReference( DefaultArgumentProcessor.ARGUMENT_REFERNCE_NAME, false ); if ( ref == null ) { diff --git a/src/main/java/org/cyclopsgroup/jcli/impl/OptionHelp.java b/src/main/java/org/cyclopsgroup/jcli/impl/OptionHelp.java index 0e72d8c..180e15e 100644 --- a/src/main/java/org/cyclopsgroup/jcli/impl/OptionHelp.java +++ b/src/main/java/org/cyclopsgroup/jcli/impl/OptionHelp.java @@ -10,7 +10,7 @@ * * @author Jiaqi Guo */ -@FixLengthType( length = 256 ) +@FixLengthType( length = 485 ) public class OptionHelp { private final Option option; @@ -23,7 +23,7 @@ public class OptionHelp /** * @return Description of option */ - @FixLengthField( start = 26, length = 228 ) + @FixLengthField( start = 26, length = 256 ) public String getDescription() { String desc = option.getDescription(); @@ -31,6 +31,10 @@ public String getDescription() { desc += "(Default value is " + option.getDefaultValue() + ")"; } + if(option.getConflicts().length > 0) + { + desc += ", conflicts [\"" + StringUtils.join(option.getConflicts(), "\",\"" ) + "\"]"; + } return desc; } diff --git a/src/main/java/org/cyclopsgroup/jcli/impl/SingleValueReference.java b/src/main/java/org/cyclopsgroup/jcli/impl/SingleValueReference.java index ea0adec..8547691 100644 --- a/src/main/java/org/cyclopsgroup/jcli/impl/SingleValueReference.java +++ b/src/main/java/org/cyclopsgroup/jcli/impl/SingleValueReference.java @@ -21,4 +21,9 @@ void setValue( T bean, String value ) { ref.writeValue( converter.fromCharacters( value ), bean ); } + + public Object getValue( T bean) + { + return ref.isReadable() ? ref.readValue( bean ) : null; + } } diff --git a/src/main/java/org/cyclopsgroup/jcli/spi/Option.java b/src/main/java/org/cyclopsgroup/jcli/spi/Option.java index 03e07c6..0a7c714 100644 --- a/src/main/java/org/cyclopsgroup/jcli/spi/Option.java +++ b/src/main/java/org/cyclopsgroup/jcli/spi/Option.java @@ -46,4 +46,9 @@ public interface Option * @return True if option is required */ boolean isRequired(); + + /** + * @return Array of conflicting options + */ + String[] getConflicts(); } diff --git a/src/test/java/org/cyclopsgroup/jcli/GnuParserTest.java b/src/test/java/org/cyclopsgroup/jcli/GnuParserTest.java index 4a803a8..e57994d 100644 --- a/src/test/java/org/cyclopsgroup/jcli/GnuParserTest.java +++ b/src/test/java/org/cyclopsgroup/jcli/GnuParserTest.java @@ -17,6 +17,32 @@ */ public class GnuParserTest { + + /** + * Verify use cases with all possible types of arguments + */ + @Test + public void testConflict() + { + ArgumentProcessor p = ArgumentProcessor.newInstance( Simple.class, new GnuParser() ); + Simple b = new Simple(); + boolean thrown = false; + try{ + p.process( new String[] { "-c", "123", "a", "-f", "abc"}, b ); + }catch(AssertionError e){ + thrown = true; + } + assertTrue("Conflict not detected", thrown); + thrown = false; + p = ArgumentProcessor.newInstance( Simple.class, new GnuParser() ); + try{ + p.process( new String[] { "-c", "123", "a", "--field1", "abc"}, b ); + }catch(AssertionError e){ + thrown = true; + } + assertTrue("Conflict not detected with long name", thrown); + } + /** * Verify use cases with all possible types of arguments */ diff --git a/src/test/java/org/cyclopsgroup/jcli/Simple.java b/src/test/java/org/cyclopsgroup/jcli/Simple.java index c82ff89..c08915a 100644 --- a/src/test/java/org/cyclopsgroup/jcli/Simple.java +++ b/src/test/java/org/cyclopsgroup/jcli/Simple.java @@ -66,7 +66,17 @@ else if ( optionName.equals( "f" ) ) private String stringFIeld2; private List values; + + private String conflictFieldValue; + /** + * @return An integer option + */ + public final String getFieldWithConflict() + { + return conflictFieldValue; + } + /** * @return An integer option */ @@ -106,6 +116,15 @@ public final boolean isBooleanField() { return booleanField; } + + /** + * @param conflict test + */ + @Option( name = "c", longName = "conflict", description = "Test conflicts", conflicts = {"f"}) + public final void setFieldWithConflict( String conflictFieldValue ) + { + this.conflictFieldValue = conflictFieldValue; + } /** * @param booleanField A flag option