From bffca12600e4eeb77545ac5a7a6273beabd232fe Mon Sep 17 00:00:00 2001 From: "Carlos A. Munoz" Date: Fri, 4 Oct 2013 15:58:30 +1000 Subject: [PATCH] Prototype bridge between args4j and aesh. --- .../org/zanata/console/ZanataConsole.java | 21 +-- .../console/util/Args4jCommandGenerator.java | 135 ++++++++++++++++++ .../console/util/GenericBridgeCommand.java | 44 ++++++ .../console/util/GetStatisticsConsoleCmd.java | 106 ++++++++++++++ .../console/GetStatisticsConsoleCmd.java | 3 +- 5 files changed, 299 insertions(+), 10 deletions(-) create mode 100644 zanata-cli/src/main/java/org/zanata/console/util/Args4jCommandGenerator.java create mode 100644 zanata-cli/src/main/java/org/zanata/console/util/GenericBridgeCommand.java create mode 100644 zanata-cli/src/main/java/org/zanata/console/util/GetStatisticsConsoleCmd.java diff --git a/zanata-cli/src/main/java/org/zanata/console/ZanataConsole.java b/zanata-cli/src/main/java/org/zanata/console/ZanataConsole.java index 8fb52858..a1a17c33 100644 --- a/zanata-cli/src/main/java/org/zanata/console/ZanataConsole.java +++ b/zanata-cli/src/main/java/org/zanata/console/ZanataConsole.java @@ -24,6 +24,7 @@ import org.jboss.aesh.cl.Arguments; import org.jboss.aesh.cl.CommandDefinition; import org.jboss.aesh.cl.Option; +import org.jboss.aesh.cl.parser.CommandLineParser; import org.jboss.aesh.console.AeshCommandRegistryBuilder; import org.jboss.aesh.console.AeshConsole; import org.jboss.aesh.console.AeshConsoleBuilder; @@ -36,7 +37,9 @@ import org.jboss.aesh.terminal.CharacterType; import org.jboss.aesh.terminal.Color; import org.jboss.aesh.terminal.TerminalCharacter; -import org.zanata.client.console.GetStatisticsConsoleCmd; +import org.zanata.client.commands.stats.GetStatisticsOptionsImpl; +import org.zanata.console.util.Args4jCommandGenerator; +import org.zanata.console.util.GetStatisticsConsoleCmd; import java.io.File; import java.io.IOException; @@ -67,13 +70,15 @@ public static void main(String[] args) AeshConsole aeshConsole = new AeshConsoleBuilder().settings(settings) .prompt(prompt) .commandRegistry( - new AeshCommandRegistryBuilder() - .command(GetStatisticsConsoleCmd.class) - .command(ExitCommand.class) - .command(LsCommand.class) - .command(SampleCommand.class) - .command(HelpCommand.class) - .create()) + new AeshCommandRegistryBuilder() + .command(new CommandLineParser(Args4jCommandGenerator.generateCommand("stats", "", + GetStatisticsOptionsImpl.class)), new GetStatisticsConsoleCmd()) + //.command(GetStatisticsConsoleCmd.class) + .command(ExitCommand.class) + .command(LsCommand.class) + .command(SampleCommand.class) + .command(HelpCommand.class) + .create()) .create(); aeshConsole.start(); diff --git a/zanata-cli/src/main/java/org/zanata/console/util/Args4jCommandGenerator.java b/zanata-cli/src/main/java/org/zanata/console/util/Args4jCommandGenerator.java new file mode 100644 index 00000000..d2603a9a --- /dev/null +++ b/zanata-cli/src/main/java/org/zanata/console/util/Args4jCommandGenerator.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package org.zanata.console.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.net.URL; + +import org.jboss.aesh.cl.builder.CommandBuilder; +import org.jboss.aesh.cl.builder.OptionBuilder; +import org.jboss.aesh.cl.converter.CLConverter; +import org.jboss.aesh.cl.exception.CommandLineParserException; +import org.jboss.aesh.cl.exception.OptionParserException; +import org.jboss.aesh.cl.internal.ProcessedCommand; +import org.jboss.aesh.cl.internal.ProcessedOption; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; +import org.zanata.console.converter.URLConverter; + +/** + * Generates AEsh commands from Args4j annotated classes. + * + * @author Carlos Munoz camunoz@redhat.com + */ +public class Args4jCommandGenerator { + + public static final ProcessedCommand generateCommand(String name, + String description, Class args4jAnnotatedCls) { + try { + CommandBuilder commandBuilder = + new CommandBuilder().name(name).description(description); + + // recursively process all the methods/fields. + for (Class c = args4jAnnotatedCls; c != null; c = c.getSuperclass()) { + for (Method m : c.getDeclaredMethods()) { + Option o = m.getAnnotation(Option.class); + if (o != null) { + commandBuilder.addOption(generateOption(o, m)); + } + Argument a = m.getAnnotation(Argument.class); + if (a != null) { + // commandBuilder.addOption( generateOption(a) ) + } + } + + for (Field f : c.getDeclaredFields()) { + Option o = f.getAnnotation(Option.class); + if (o != null) { + commandBuilder.addOption(generateOption(o, f)); + } + Argument a = f.getAnnotation(Argument.class); + if (a != null) { + // commandBuilder.addArgument? + } + } + } + + return commandBuilder.generateParameter(); + } catch (CommandLineParserException e) { + throw new RuntimeException(e); + } + } + + private static final ProcessedOption generateOption(Option args4jOpt, + Member member) throws OptionParserException { + String optName = args4jOpt.name(); + if (optName.startsWith("--")) { + optName = optName.replaceFirst("\\-\\-", ""); + } + + Class optionType = getOptionType(member); + OptionBuilder optionBuilder = + new OptionBuilder().name(optName) + .description(args4jOpt.usage()).type(optionType) + .fieldName(getFieldName(member)) + .converter(getConverter(optionType)); + + if (optName.equals("errors")) { + optionBuilder.shortName('X'); + } + + return optionBuilder.create(); + } + + private static CLConverter getConverter(Class optType) { + if (optType == URL.class) { + return new URLConverter(); + } + return null; + } + + private static Class getOptionType(Member m) { + if (m instanceof Field) { + return ((Field) m).getType(); + } else { + return ((Method) m).getParameterTypes()[0]; // should be a + // setter + } + } + + private static String getFieldName(Member m) { + if (m instanceof Field) { + return m.getName(); + } + // Getter or Setter + else if (m instanceof Method) { + if (m.getName().startsWith("set") || m.getName().startsWith("get")) { + return m.getName().substring(3, 4).toLowerCase() + + m.getName().substring(4); + } + return m.getName(); + } + return null; + } +} diff --git a/zanata-cli/src/main/java/org/zanata/console/util/GenericBridgeCommand.java b/zanata-cli/src/main/java/org/zanata/console/util/GenericBridgeCommand.java new file mode 100644 index 00000000..a66a48e8 --- /dev/null +++ b/zanata-cli/src/main/java/org/zanata/console/util/GenericBridgeCommand.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package org.zanata.console.util; + +import org.zanata.client.commands.ConfigurableCommand; +import org.zanata.client.commands.ConfigurableOptions; + +/** + * This is a bridge command between args4j and AEsh. + * @author Carlos Munoz camunoz@redhat.com + */ +public class GenericBridgeCommand> +{ + private COMMAND command; + + public GenericBridgeCommand(COMMAND command) + { + this.command = command; + } + + public OPTIONS getOptions() + { + return command.getOpts(); + } + +} diff --git a/zanata-cli/src/main/java/org/zanata/console/util/GetStatisticsConsoleCmd.java b/zanata-cli/src/main/java/org/zanata/console/util/GetStatisticsConsoleCmd.java new file mode 100644 index 00000000..6afe8c7c --- /dev/null +++ b/zanata-cli/src/main/java/org/zanata/console/util/GetStatisticsConsoleCmd.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013, Red Hat, Inc. and individual contributors as indicated by the + * @author tags. See the copyright.txt file in the distribution for a full + * listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF + * site: http://www.fsf.org. + */ +package org.zanata.console.util; + +import java.io.IOException; + +import org.jboss.aesh.console.AeshConsole; +import org.jboss.aesh.console.Command; +import org.jboss.aesh.console.CommandResult; +import org.jboss.aesh.console.operator.ControlOperator; +import org.zanata.client.commands.stats.GetStatisticsCommand; +import org.zanata.client.commands.stats.GetStatisticsOptions; +import org.zanata.client.commands.stats.GetStatisticsOptionsImpl; + +/** + * @author Carlos Munoz camunoz@redhat.com + */ +public class GetStatisticsConsoleCmd implements + Command { + + private boolean includeDetails; + private boolean includeWordLevelStats; + private String format; + private String documentId; + private String proj; + private java.io.File projectConfig; + private String projectVersion; + private String projectType; + private org.zanata.client.config.LocaleList localeMapList; + private String key; + private java.net.URL url; + private java.io.File userConfig; + private String username; + private boolean logHttp; + private boolean disableSSLCert; + private Boolean debug = null; + private Boolean errors = null; + private boolean help; + private Boolean quiet = null; + private boolean interactiveMode; + + @Override + public CommandResult execute(AeshConsole aeshConsole, + ControlOperator operator) throws IOException { + + try { + new GetStatisticsCommand(this.toOptions()).run(); + } catch (Exception e) { + e.printStackTrace(); + return CommandResult.FAILURE; + } + return CommandResult.SUCCESS; + } + + /* + * This is the only way to convert to an options implementation as the + * methods cannot be overriden because they would lose their args4j + * annotations. + */ + private GetStatisticsOptions toOptions() { + GetStatisticsOptions options = new GetStatisticsOptionsImpl(); + options.setIncludeDetails(includeDetails); + options.setIncludeWordLevelStats(includeWordLevelStats); + options.setFormat(format); + options.setDocumentId(documentId); + options.setProj(proj); + options.setProjectConfig(projectConfig); + options.setProjectVersion(projectVersion); + options.setProjectType(projectType); + options.setLocaleMapList(localeMapList); + options.setKey(key); + options.setUrl(url); + options.setUserConfig(userConfig); + options.setUsername(username); + options.setLogHttp(logHttp); + options.setDisableSSLCert(disableSSLCert); + if( debug != null ) + options.setDebug(debug); + if( errors != null ) + options.setErrors(errors); + options.setHelp(help); + if( quiet != null ) + options.setQuiet(quiet); + options.setInteractiveMode(interactiveMode); + return options; + } +} diff --git a/zanata-client-commands/src/main/java/org/zanata/client/console/GetStatisticsConsoleCmd.java b/zanata-client-commands/src/main/java/org/zanata/client/console/GetStatisticsConsoleCmd.java index 94f39a93..922ba127 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/console/GetStatisticsConsoleCmd.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/console/GetStatisticsConsoleCmd.java @@ -34,7 +34,6 @@ import org.zanata.client.commands.stats.GetStatisticsCommand; import org.zanata.client.commands.stats.GetStatisticsOptions; import org.zanata.client.config.LocaleList; -import org.zanata.client.console.converter.URLConverter; /** * @author Carlos Munoz camunoz@redhat.com @@ -52,7 +51,7 @@ public class GetStatisticsConsoleCmd implements Command, GetStatisticsOptions @Option private String projectType; @Option private LocaleList localeMapList; @Option private String key; - @Option(converter = URLConverter.class) private URL url; + @Option(/*converter = URLConverter.class*/) private URL url; @Option private File userConfig; @Option private String username; @Option private boolean logHttp;