Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Prototype bridge between args4j and aesh.
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlos A. Munoz committed Oct 4, 2013
1 parent 2d3d420 commit bffca12
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 10 deletions.
21 changes: 13 additions & 8 deletions zanata-cli/src/main/java/org/zanata/console/ZanataConsole.java
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
@@ -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 <a
* href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
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;
}
}
@@ -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 <a href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
public class GenericBridgeCommand<OPTIONS extends ConfigurableOptions, COMMAND extends ConfigurableCommand<OPTIONS>>
{
private COMMAND command;

public GenericBridgeCommand(COMMAND command)
{
this.command = command;
}

public OPTIONS getOptions()
{
return command.getOpts();
}

}
@@ -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 <a
* href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
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;
}
}
Expand Up @@ -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 <a href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
Expand All @@ -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;
Expand Down

0 comments on commit bffca12

Please sign in to comment.