Skip to content

Commit

Permalink
CommandMetadata has positional arguments info (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
rvesse committed Apr 15, 2019
1 parent e5e5b38 commit 4a1a0a0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public CommandMetadata(String name,
throw new IllegalArgumentException("Command name may not be null/empty");
if (StringUtils.containsWhitespace(name))
throw new IllegalArgumentException("Command name may not contain whitespace");

this.name = name;
this.description = description;
this.hidden = hidden;
Expand All @@ -73,6 +73,27 @@ public CommandMetadata(String name,
this.positionalArgs = positionalArguments;
this.arguments = arguments;

// Check that we don't have required positional/non-positional arguments
// after optional positional arguments
boolean posArgsRequired = false;
for (int i = 0; i < this.positionalArgs.size(); i++) {
if (i == 0) {
posArgsRequired = this.positionalArgs.get(i).isRequired();
} else if (!posArgsRequired && this.positionalArgs.get(i).isRequired()) {
throw new IllegalArgumentException(String.format(
"Positional argument %d (%s) is declared as @Required but one/more preceeding positional arguments are optional",
i, this.positionalArgs.get(i).getTitle()));
} else {
posArgsRequired = this.positionalArgs.get(i).isRequired();
}
}
if (this.positionalArgs.size() > 0 && !posArgsRequired) {
if (this.arguments.isRequired()) {
throw new IllegalArgumentException(
"Non-positional arguments are declared as required but one/more preceding positional arguments are optional");
}
}

if (this.defaultOption != null && this.arguments != null) {
throw new IllegalArgumentException("Command cannot declare both @Arguments and @DefaultOption");
}
Expand Down Expand Up @@ -129,7 +150,7 @@ public List<OptionMetadata> getCommandOptions() {
public OptionMetadata getDefaultOption() {
return defaultOption;
}

public List<ArgumentMetadata> getPositionalArguments() {
return positionalArgs;
}
Expand All @@ -153,6 +174,7 @@ public List<String> getGroupNames() {
public List<Group> getGroups() {
return groups;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
Expand All @@ -170,15 +192,17 @@ public String toString() {
sb.append('}');
return sb.toString();
}

@Override
public boolean equals(Object other) {
if (this == other) return true;

if (!(other instanceof CommandMetadata)) return false;

if (this == other)
return true;

if (!(other instanceof CommandMetadata))
return false;

CommandMetadata cmd = (CommandMetadata) other;

// TODO This should ideally be more robust
return StringUtils.equals(this.name, cmd.name) && this.type.equals(cmd.type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,19 +733,22 @@ public static void loadInjectionMetadata(Class<?> type, InjectionMetadata inject
throw new IllegalArgumentException(String.format(
"Field %s annotated with @DefaultOption must also have an @Option annotation", field));
}

// Process positional arguments annotations
PositionalArgument positionalArgumentAnnotation = field.getAnnotation(PositionalArgument.class);
if (field.isAnnotationPresent(PositionalArgument.class)) {
String title = positionalArgumentAnnotation.title();
if (StringUtils.isBlank(title)) {
title = field.getName();
}

TypeConverterProvider provider = ParserUtil.createInstance(positionalArgumentAnnotation.typeConverterProvider());

List<ArgumentsRestriction> restrictions = collectArgumentRestrictions(field);


TypeConverterProvider provider = ParserUtil
.createInstance(positionalArgumentAnnotation.typeConverterProvider());

// Collect restrictions, note that @Partials/@Partial does
// not make sense for positional arguments
List<ArgumentsRestriction> restrictions = collectArgumentRestrictions(field, false);

//@formatter:off
injectionMetadata.positionalArgs.add(new ArgumentMetadata(positionalArgumentAnnotation.position(),
title,
Expand Down Expand Up @@ -779,7 +782,7 @@ public static void loadInjectionMetadata(Class<?> type, InjectionMetadata inject
TypeConverterProvider provider = ParserUtil
.createInstance(argumentsAnnotation.typeConverterProvider());

List<ArgumentsRestriction> restrictions = collectArgumentRestrictions(field);
List<ArgumentsRestriction> restrictions = collectArgumentRestrictions(field, true);

//@formatter:off
injectionMetadata.arguments.add(new ArgumentsMetadata(titles,
Expand All @@ -793,16 +796,16 @@ public static void loadInjectionMetadata(Class<?> type, InjectionMetadata inject
}
}

public static List<ArgumentsRestriction> collectArgumentRestrictions(Field field) {
Map<Class<? extends Annotation>, Set<Integer>> partials = loadPartials(field);
private static List<ArgumentsRestriction> collectArgumentRestrictions(Field field, boolean allowPartials) {
Map<Class<? extends Annotation>, Set<Integer>> partials = allowPartials ? loadPartials(field)
: Collections.<Class<? extends Annotation>, Set<Integer>> emptyMap();
List<ArgumentsRestriction> restrictions = new ArrayList<>();
for (Class<? extends Annotation> annotationClass : RestrictionRegistry
.getArgumentsRestrictionAnnotationClasses()) {
Annotation annotation = field.getAnnotation(annotationClass);
if (annotation == null)
continue;
ArgumentsRestriction restriction = RestrictionRegistry.getArgumentsRestriction(annotationClass,
annotation);
ArgumentsRestriction restriction = RestrictionRegistry.getArgumentsRestriction(annotationClass, annotation);
if (restriction != null) {
// Adjust for partial if necessary
if (partials.containsKey(annotationClass))
Expand Down Expand Up @@ -962,7 +965,7 @@ private static List<ArgumentMetadata> overridePositionalArgumentSet(List<Argumen
i, StringUtils.join(argsIndex.keySet(), ", ")));
}
}

return ListUtils.unmodifiableList(posArgs);
}

Expand Down Expand Up @@ -1206,8 +1209,6 @@ private static class InjectionMetadata {
private List<ArgumentMetadata> positionalArgs = new ArrayList<>();
private List<ArgumentsMetadata> arguments = new ArrayList<>();
private List<Accessor> metadataInjections = new ArrayList<>();



private void compact() {
globalOptions = overrideOptionSet(globalOptions);
Expand Down

0 comments on commit 4a1a0a0

Please sign in to comment.