DATE : 2006/04/01 (Sat)
私用で Java のコマンドラインアプリケーションを作っています。
コマンドラインアプリケーションといえば、「-a」や「--version」、「-D 1234」などのオプション。
これをわざわざ自前で解析するのは非常に面倒です。
そこで、Apache Jakarta Commons-CLI (以下、CLI)というライブラリを使ってみました。
とりあえず、使ってみた範囲でメモしておきます。
なお、CLI のバージョンは1.0です。
ちなみに、英語の分かる方は公式ページを見たほうが正確ですし、有意義だと思います。(ちなみに私は英語が分からないので、このような記事を書いているわけです(;^ω^))
コマンドラインオプションの準備
まず、どのようなコマンドラインオプションを用意するかを定義します。
ここでは、次のようなオプションを考えます。
(・∀・)オプションの内容に深い意味はありません。
- -a, --all
- 全てを出力する。
- -n <番号>
- 番号を指定する。(2番を指定する例:-n 2)
- -help
- ヘルプを出力する。
オプションが用意できたら、CLI にその定義を教えます。
ここでは、 org.apache.commons.cli.Option を使います。
Option all = new Option("a", "all", false, "全てを出力する。"); Option n = new Option("n", true, "番号を指定する。(2番を指定する例:-n 2)"); n.setArgs(1); n.setArgName("番号");
Option help = new Option("help", "ヘルプを出力する。");
Option には3つのコンストラクタがあります。ですので、それぞれ違ったコンストラクタで生成してみました。
コンストラクタでは、オプションの名前(「a」や「n」など)やその説明などを定義しています。
コンストラクタの中で true や false と指定している部分は、そのオプションに引数があるかないかを定義しています。-a オプションには引数がないため false 、-n オプションにはあるため true となります。
前述の通り、-n オプションには引数があります。そこで、Option#setArgs(int) で引数の数を、Option#setArgName(String) で引数の説明を設定しています。
なお、ここで定義したオプションは全て、 org.apache.commons.cli.Options に登録しておきます。
Options options = new Options(); options.addOption(all); options.addOption(n); options.addOption(help);
ちなみに、org.apache.commons.cli.OptionGroup を使えば、どちらか一方しか指定できないオプションを定義できるようです。
コマンドラインパーサの準備
コマンドライン引数の解析方法を定義するコマンドラインパーサを準備します。「-a -b -c 100 -d」というオプションがあった場合に、「 -a オプション、-b オプション、 -c オプションの引数100、-d オプションがある」と解析するわけです。
コマンドラインパーサは、 org.apache.commons.cli.CommandLineParser インタフェースですので、自作することも可能です。
しかし通常は、すでに実装されているパーサを使用することになると思います。
用意されているパーサは以下の通りです。
- org.apache.commons.cli.BasicParser
- org.apache.commons.cli.GnuParser
- org.apache.commons.cli.PosixParser
ここでは、 GnuParser を使うことにします。
CommandLineParser parser = new GnuParser();
ちなみに、「-a」、「-b」オプションを同時に「ab」と指定できるコマンドラインアプリケーションがあります。そのようなアプリケーションを作る場合は、PosixParser を使うようです。
コマンドライン引数の解析
実際にコマンドライン引数を CLI に解析させてみます。
CommandLine commandLine = parser.parse(options, args, true);
先程指定した GnuParser インスタンスの parse メソッドを呼び出しています。
args は、 main メソッドの引数です。main メソッドの引数 args には、コマンドライン引数が格納されているので、そのまま CommandLineParser#parse(org.apache.commons.cli.Options, String[], boolean) に渡しています。
最後の引数(boolean)は、定義されていないオプションがある場合に、解析を中止するかどうかを指定しています。ここでは、とりあえず true を指定しています。
オプションがあるかどうか調べる
コマンドライン引数にオプションがあるかどうかを調べてみます。
オプションがあるかどうかを調べるには、org.apache.commons.cli.CommandLine#hasOption(String) を使います。引数にオプションを指定して、そのオプションがコマンドライン引数にあれば true 、なければ false を返します。
今回の例では、次のようなコードになります。
if (commandLine.hasOption("a")) { // -a オプションがある場合の処理 } if (commandLine.hasOption("n")) { // -n オプションがある場合の処理 } if (commandLine.hasOption("help")) { // -help オプションがある場合の処理 }
オプションの引数を取り出す
例の中で、-n オプションは「-n <番号>」という形で番号を指定できました。
この引数を取り出すには、 CommandLine#getOptionValue(String) を使います。
String argument = commandLine.getOptionValue("n");
引数が指定されていない場合は、 null が返ります。
引数が複数ある場合は、CommandLine#getOptionValues(String)を使うとよいかもしれません。
また CLI には、引数がない場合の標準値を設定できるメソッドもあります。
ヘルプを表示する
Option オブジェクトを生成した際に、コンストラクタでそのオプションの説明も付け加えました。
( ・∀・)これは、ヘルプを表示するための布石だったりします。
CLI には、ヘルプを出力する機能もあります。
ヘルプを表示するには、 org.apache.commons.cli.HelpFormatter を使います。
HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("example [option]...", options);
HelpFormatter#printHelp メソッドにはいくつか種類があります。この他にも、使い方を指定できたり、ヘルプの前や後に好きな文字列を表示するように指定できるメソッドもあります。
ちなみに上のコード例を実行すると、次のようなヘルプが表示されます。
usage: example [option]... -a,--all 全てを出力する。 -help ヘルプを出力する。 -n <番号> 番号を指定する。(2番を指定する例:-n 2)