just to share with everybody how, at Apache Any23[1], we created a
simple-yet-powerful dynamic CLI, using JCommander :)
Getting advantage from the JCommander command syntax[2], we defined a
simple Tool interface:
+----+
public interface Tool {
void run() throws Exception;
}
+----+
each Tool concrete impl is annotated with JCommander annotations:
+----+
@Parameters(commandNames = { "vocab" }, commandDescription = "Prints
out the RDF Schema of the vocabularies used by Any23.")
public class VocabPrinter implements Tool {
@Parameter(
names = { "-f", "--format" },
description = "Vocabulary output format",
converter = VocabularyFormatConverter.class
)
private VocabularyFormat format = RDFSchemaUtils.VocabularyFormat.NQuads;
public void run() throws Exception {
...
}
+----+
letting users free to define their own tool, we discover and register
Tools using the SPI pattern (in a simplified way)
+----+
JCommander commander = new JCommander(new ToolRunner());
// add all plugins first
final Iterator<Tool> tools = ServiceLoader.load(Tool.class);
while (tools.hasNext()) {
Tool tool = tools.next();
commander.addCommand(tool);
}
+----+
and then run the proper Tool when launched (simplified):
+----+
Map<String, JCommander> commands = commander.getCommands();
String parsedCommand = commander.getParsedCommand();
Tool.class.cast( commands.get( parsedCommand
).getObjects().get( 0 ) ).run();
+----+
So we have a CLI that can be dynamically enriched :) under the hood we
have a primordial plugin management that doesn't involve all the OSGi
complexity, but it fits for our needs.
Thanks a lot Cédric once again for the JCommander flexibility!!!
All the best,
-Simo
PS for the curious that would like to read the code/participate:
https://svn.apache.org/repos/asf/incubator/any23/trunk
[1] http://incubator.apache.org/any23/
[2] http://jcommander.org/#Complex
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/