summaryrefslogtreecommitdiffstats
path: root/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java
diff options
context:
space:
mode:
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.java174
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();
+ }
+ }
}