Args4j 条件付きチェックを実装する


Agrs4j を使っている CLI ツールで、条件付きチェックを実装したくなり、実装方法を調べてみました。
調べた結果を記載します。

条件付きチェック といってもいろいろあるので、パターン分けして記載します。


B は A に 依存していて B を指定する場合は、 A が必須

Option アノテーションに、depends を指定します。
以下では、-filePath オプションに、 depends として -format オプションを指定しています。

    @Option(name = "-format", usage = "Format of output ",
            metaVar = "[console or json]") private Format format = Format.CONSOLE;

    @Option(name = "-filePath", usage = "File name of json ", metaVar = "<filename>",
            depends = {"-format"}) private String filePath = null;

上記指定で、-filepath のみ指定してコマンドを実行すると、

java -jar build/libs/xyz.monotalk.google.webmaster.cli-0.0.1.jar -filePath aaaa.json

下記のエラーが出力されます。

option "-filePath" requires the option(s) [-format]


A と B の両方は指定できない

検索したところ、以下 StackOverFlow の記事が見つかりました。
java - args4j: How to make an argument required if another argument is/isn’t given? - Stack Overflow

forbids には一緒に指定できないOption の名前を指定します。
以下のように、-siteUrl の、forbids には -format を指定し、-formatforbids には -siteUrl を指定します。

    @Option(name = "-siteUrl", usage = "Url of site", metaVar = "<siteUrl>",
            handler = URLOptionHandler.class, forbids = {"-format"}) private URL siteUrl = null;

    @Option(name = "-format", usage = "Format of output ",
            metaVar = "[console or json]", forbids = {"-siteUrl"}) private Format format = null;

上記指定で、以下のコマンドを実行すると、

java -jar build/libs/xyz.monotalk.google.webmaster.cli-0.0.1.jar webmasters.sitemaps.list -format CONSOLE -siteUrl https://kemsakurai.github.io/

以下のエラーメッセージが出力されます。

 option "-siteUrl" cannot be used with the option(s) [-format]

StackOverFlow の 記事には、A と B の両方は指定できず、いずれか必須 を表現するため、として Null チェック実装 を追加する例が記載されています。

if (siteUrl == null && format == null) {
    throw new CmdLineException();
}


A の 値 が 「あ」だったら、B が必須

これはアノテーションだけでの指定方法がわからず、実装と組み合わせて行いました。
Enum Format が JSON の場合、ファイルパスが必須です。

    @Option(name = "-format", usage = "Format of output ",
            metaVar = "[console or json]") private Format format = Format.CONSOLE;

    @Option(name = "-filePath", usage = "File name of json ", metaVar = "<filename>",
            depends = {"-format"}) private String filePath = null;

以下、実装側の条件分岐になります。
Enum 値 が JSON の場合、filepath をチェックして、Nullまたは空であれば、例外をスローしています。

    switch (format) {
        // for format console
        case CONSOLE:
            System.out.println(response.toPrettyString());
            break;
        // for format json
        case JSON:
            if (StringUtils.isEmpty(filePath)) {
                throw new CmdLineArgmentException("For JSON format, filepath is mandatory.");
            }
            .....
            break;
    }

条件付きチェックは、だんだんと実装の手が止まってきます。
以上です。

コメント