diff options
Diffstat (limited to 'gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java')
-rw-r--r-- | gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java | 174 |
1 files changed, 171 insertions, 3 deletions
diff --git a/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java b/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java index d5a2a98ff9..de2f7e98eb 100644 --- a/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java +++ b/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java @@ -42,13 +42,19 @@ import com.google.inject.assistedinject.Assisted; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.IllegalAnnotationError; +import org.kohsuke.args4j.NamedOptionDef; import org.kohsuke.args4j.Option; import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.BooleanOptionHandler; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; +import java.io.StringWriter; import java.io.Writer; +import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.ResourceBundle; /** @@ -60,6 +66,7 @@ import java.util.ResourceBundle; * args4j style format prior to invoking args4j for parsing. */ public class CmdLineParser { + public interface Factory { CmdLineParser create(Object bean); } @@ -102,6 +109,19 @@ public class CmdLineParser { parser.printUsage(out, rb); } + public void printDetailedUsage(String name, StringWriter out) { + out.write(name); + printSingleLineUsage(out, null); + out.write('\n'); + out.write('\n'); + printUsage(out, null); + out.write('\n'); + } + + public boolean wasHelpRequestedByOption() { + return parser.help.value; + } + public void parseArgument(final String... args) throws CmdLineException { final ArrayList<String> tmp = new ArrayList<String>(args.length); for (int argi = 0; argi < args.length; argi++) { @@ -123,13 +143,86 @@ public class CmdLineParser { tmp.add(str); } + parser.parseArgument(tmp.toArray(new String[tmp.size()])); + } + public void parseOptionMap(Map<String, String[]> parameters) + throws CmdLineException { + ArrayList<String> tmp = new ArrayList<String>(); + for (Map.Entry<String, String[]> ent : parameters.entrySet()) { + String name = ent.getKey(); + if (!name.startsWith("-")) { + if (name.length() == 1) { + name = "-" + name; + } else { + name = "--" + name; + } + } + + if (findHandler(name) instanceof BooleanOptionHandler) { + boolean on = false; + for (String value : ent.getValue()) { + on = toBoolean(ent.getKey(), value); + } + if (on) { + tmp.add(name); + } + } else { + for (String value : ent.getValue()) { + tmp.add(name); + tmp.add(value); + } + } + } parser.parseArgument(tmp.toArray(new String[tmp.size()])); } + @SuppressWarnings("rawtypes") + private OptionHandler findHandler(String name) { + for (OptionHandler handler : parser.options) { + if (handler.option instanceof NamedOptionDef) { + NamedOptionDef def = (NamedOptionDef) handler.option; + if (name.equals(def.name())) { + return handler; + } + for (String alias : def.aliases()) { + if (name.equals(alias)) { + return handler; + } + } + } + } + return null; + } + + private boolean toBoolean(String name, String value) throws CmdLineException { + if ("true".equals(value) || "t".equals(value) + || "yes".equals(value) || "y".equals(value) + || "on".equals(value) + || "1".equals(value) + || value == null || "".equals(value)) { + return true; + } + + if ("false".equals(value) || "f".equals(value) + || "no".equals(value) || "n".equals(value) + || "off".equals(value) + || "0".equals(value)) { + return false; + } + + throw new CmdLineException(parser, String.format( + "invalid boolean \"%s=%s\"", name, value)); + } + private class MyParser extends org.kohsuke.args4j.CmdLineParser { + @SuppressWarnings("rawtypes") + private List<OptionHandler> options; + private HelpOption help; + MyParser(final Object bean) { super(bean); + ensureOptionsInitialized(); } @SuppressWarnings({"unchecked", "rawtypes"}) @@ -137,7 +230,7 @@ public class CmdLineParser { protected OptionHandler createOptionHandler(final OptionDef option, final Setter setter) { if (isHandlerSpecified(option) || isEnum(setter) || isPrimitive(setter)) { - return super.createOptionHandler(option, setter); + return add(super.createOptionHandler(option, setter)); } final Key<OptionHandlerFactory<?>> key = @@ -145,12 +238,28 @@ public class CmdLineParser { Injector i = injector; while (i != null) { if (i.getBindings().containsKey(key)) { - return i.getInstance(key).create(this, option, setter); + return add(i.getInstance(key).create(this, option, setter)); } i = i.getParent(); } - return super.createOptionHandler(option, setter); + return add(super.createOptionHandler(option, setter)); + } + + @SuppressWarnings("rawtypes") + private OptionHandler add(OptionHandler handler) { + ensureOptionsInitialized(); + options.add(handler); + return handler; + } + + @SuppressWarnings("rawtypes") + private void ensureOptionsInitialized() { + if (options == null) { + help = new HelpOption(); + options = new ArrayList<OptionHandler>(); + addOption(help, help); + } } private boolean isHandlerSpecified(final OptionDef option) { @@ -165,4 +274,63 @@ public class CmdLineParser { return setter.getType().isPrimitive(); } } + + private static class HelpOption implements Option, Setter<Boolean> { + private boolean value; + + @Override + public String name() { + return "--help"; + } + + @Override + public String[] aliases() { + return new String[] {"-h"}; + } + + @Override + public String usage() { + return "display this help text"; + } + + @Override + public void addValue(Boolean val) { + value = val; + } + + @Override + public Class<? extends OptionHandler<Boolean>> handler() { + return BooleanOptionHandler.class; + } + + @Override + public String metaVar() { + return ""; + } + + @Override + public boolean multiValued() { + return false; + } + + @Override + public boolean required() { + return false; + } + + @Override + public Class<? extends Annotation> annotationType() { + return Option.class; + } + + @Override + public Class<Boolean> getType() { + return Boolean.class; + } + + @Override + public boolean isMultiValued() { + return multiValued(); + } + } } |