JCommando 网站 上将JCommando描述为“命令行参数的Java参数解析器”。 JCommando读取XML配置以生成一个Java类,该类处理Java应用程序中的解析。 在提供XML配置的 Java命令行解析库的本系列文章中,以前涵盖的唯一基于Java的库是JSAP ,但这是该库的第二种配置形式, 我在JSAP的文章中并未介绍XML配置。
由于JCommando使用XML来指定要解析的命令行选项,因此JCommando的“定义”阶段是通过XML规范完成的。 与本系列中的前几篇文章一样, 本篇文章中的示例基于文件路径,名称和详细程度的命令行选项,它们在JCommando兼容XML中的定义显示在下一个代码清单( options.xml
)中。
JCommando通过“定义”阶段的XML部分: options.xml
<jcommando>
<option id="file" long="file" short="f" type="String">
<description>Path and name of file</description>
</option>
<option id="verbose" long="verbose" short="v">
<description>Verbosity enabled</description>
</option>
<commandless id="execute" allow-optionless="true">
<or>
<option-ref id="file" />
</or>
</commandless>
</jcommando>
JCommando使用XML文件作为输入,并基于该XML生成一个Java源代码文件,该文件分析XML中指定的选项。 有两种方法可以指示JCommando解析此XML并使用详细信息生成Java源代码。 一种方法是使用JCommando发行版随附的可执行jcomgen可执行文件(在其bin目录中)。 从XML生成Java类的第二种方法是此处显示的方法:使用Apache Ant和JCommando提供的Ant任务。 下一个XML / Ant清单对此进行了演示。
使用JCommando从XML生成源的Ant目标
<target name="generateSourceForJCommando"
description="Generate command line parsing source code that uses JCommando">
<taskdef name="jcommando" classname="org.jcommando.ant.JCommando">
<classpath>
<pathelement location="C:\lib\jcommando-1.2\lib\jcommando.jar"/>
</classpath>
</taskdef>
<jcommando inputfile="jcommando/options.xml"
classname="MainParser"
destdir="src"
packagename="examples.dustin.commandline.jcommando"/>
</target>
上述Ant目标节目JCommando如何允许输入XML文件( options.xml
)被指定为“ inputfile
”,并且将所生成的Java源代码文件将被放置在所述src
目录中的子目录结构相匹配的指定包“ examples.dustin.commandline.jcommando
”。 下一个屏幕快照显示了Ant目标和源代码生成的执行。
这个Ant目标的结果是生成的Java源类MainParser.java
其清单如下所示。
生成的Java源类MainParser.java
/*
* THIS IS A GENERATED FILE. DO NOT EDIT.
*
* JCommando (http://jcommando.sourceforge.net)
*/
package examples.dustin.commandline.jcommando;
import org.jcommando.Command;
import org.jcommando.JCommandParser;
import org.jcommando.Option;
import org.jcommando.Grouping;
import org.jcommando.And;
import org.jcommando.Or;
import org.jcommando.Xor;
import org.jcommando.Not;
/**
* JCommando generated parser class.
*/
public abstract class MainParser extends JCommandParser
{
/**
* JCommando generated constructor.
*/
public MainParser()
{
Option file = new Option();
file.setId("file");
file.setShortMnemonic("f");
file.setLongMnemonic("file");
file.setDescription("Path and name of file");
addOption(file);
Option verbose = new Option();
verbose.setId("verbose");
verbose.setShortMnemonic("v");
verbose.setLongMnemonic("verbose");
verbose.setDescription("Verbosity enabled");
addOption(verbose);
Command execute = new Command();
execute.setName("commandless");
execute.setId("execute");
execute.addOption(file);
execute.setGrouping( createExecuteGrouping() );
addCommand(execute);
}
/**
* Called by parser to set the 'file' property.
*
* @param file the value to set.
*/
public abstract void setFile(String file);
/**
* Called by parser to set the 'verbose' property.
*
*/
public abstract void setVerbose();
/**
* Called by parser to perform the 'execute' command.
*
*/
public abstract void doExecute();
/**
* Generate the grouping for the 'execute' command.
*/
private Grouping createExecuteGrouping()
{
Or or1 = new Or();
or1.addOption(getOptionById("file"));
return or1;
}
}
生成Java源代码后,我们现在有了选项定义。 编写自定义类以扩展生成的MainParser
并访问其父级进行解析。 在自定义编写的Main
类的下一个代码清单中对此进行了演示,该类扩展了所生成的MainParser
类。
自定义类扩展生成的类
package examples.dustin.commandline.jcommando;
import static java.lang.System.out;
/**
* Demonstrates JCommando-based parsing of command-line
* arguments from Java code.
*/
public class Main extends MainParser
{
private String file;
private boolean verbose;
@Override
public void setFile(final String newFilePathAndName)
{
file = newFilePathAndName;
}
@Override
public void setVerbose()
{
verbose = true;
}
public static void main(final String[] arguments)
{
final Main instance = new Main();
instance.parse(arguments);
}
/**
* Called by parser to execute the 'command'.
*/
public void doExecute()
{
out.println("File path/name is " + file + " and verbosity is " + verbose);
}
}
如上面显示的自定义Main.java
源代码所示,“解析”阶段是通过执行parse(String[])
方法在JCommando中完成的,该方法继承自JCommando基于配置XML生成的类(以及生成的类)从其父级JCommandParser类获取其对该parse
方法的定义)。
扩展生成的类的自定义类需要具有用于实现选项的“设置”方法。 有了这些适当的实现,基于JCommando的应用程序中的“询问”阶段就很容易访问那些自定义实现的“设置”方法所设置的字段。 最后代码清单中显示的doExecute()
方法对此进行了演示。 由于在配置XML中指定了id
为“ execute
”的<commandless>
元素,因此doExecute
方法在生成的父类中作为abstract
方法生成。
自定义类最终扩展的JCommandParser类具有方法printUsage() ,可用于将“帮助” /“使用”输出写入标准输出。 可以从GitHub上 Main.java
的源代码中看到。
接下来的两个屏幕快照演示了如何执行本文中讨论的示例代码。 第一个屏幕快照显示“可以自动打印的使用信息,在这种情况下,如果未指定所需的”文件”选项。 第二个屏幕快照演示了“ vile”和“ verbose”选项的长名称和短名称的组合。
本文总结了使用JCommando涉及的步骤。
- 在XML文件中定义选项。
- 使用两种方法之一从XML生成Java解析器源代码。
- 使用
jcomgen
的bin
目录中提供的jcomgen
工具。 - 如本文所展示的,将Ant目标与JCommand提供的Ant任务一起使用。
- 使用
- 编写扩展生成的解析器类的Java类。
选择用于帮助Java进行命令行解析的框架或库时,需要考虑JCommando的特征。
- JCommando是开源的,可在zlib / libpng许可(Zlib)下获得 。
- jcommando.jar JAR的大小约为27 KB,并且没有第三方依赖性。
- 通过XML在JCommando中定义选项是与本系列文章中介绍的其他库不同的方法,但是我发现JCommando的选项定义更有趣的是能够轻松表达选项之间的关系,例如“和”,“或”,“异或” ”,以及这些的嵌套组合。
JCommando在基于Java的命令行选项解析方面实现了一些新颖的概念。 它要求对潜在的命令行选项进行XML配置,但使在这些选项之间建立关系变得容易。 JCommando从XML选项配置生成Java源,并且自定义解析类扩展了该生成的类。 JCommando也是本系列中第一个使用Zlib许可证的库 。
其他参考
翻译自: https://www.javacodegeeks.com/2017/10/java-command-line-interfaces-part-25-jcommando.html