1. 序章

このチュートリアルでは、コマンドラインインターフェイス(CLI)を構築するための注釈駆動型JavaライブラリであるAirlineを紹介します。

2. シナリオ

コマンドラインアプリケーションを構築するときは、ユーザーが必要に応じて出力を作成できるように、シンプルなインターフェイスを作成するのが自然です。 ほとんどの人がGitCLIで遊んだことがあり、それがいかに強力でありながらシンプルであるかに関係することができます。 残念ながら、そのようなインターフェイスを構築するときに役立つツールはほとんどありません。

航空会社は、Java のCLIに通常関連付けられているボイラープレートコードを削減することを目的としています。最も一般的な動作は、アノテーションとゼロユーザーコードで実現できるためです。

Airlineの機能を利用して一般的なCLIを模倣する小さなJavaプログラムを実装します。 データベースのURL、クレデンシャル、ロガーの詳細度の定義など、プログラム構成をセットアップするためのユーザーコマンドを公開します。 また、ライブラリの表面を掘り下げて、その基本以上のものを使用して、複雑さを処理できるかどうかを調べます。

3. 設定

開始するには、Airline依存関係をpom.xmlに追加しましょう。

<dependency>
    <groupId>com.github.rvesse</groupId>
    <artifactId>airline</artifactId>
    <version>2.7.2</version>
</dependency>

4. シンプルなCLI

アプリケーションのエントリポイントであるCommandLineクラスを作成しましょう。

@Cli(name = "baeldung-cli",
  description = "Baeldung Airline Tutorial",
  defaultCommand = Help.class)
public class CommandLine {
    public static void main(String[] args) {
        Cli<Runnable> cli = new Cli<>(CommandLine.class);
        Runnable cmd = cli.parse(args);
        cmd.run();
    }
}

単純な@Cliアノテーションを使用して、アプリケーションで実行されるデフォルトのコマンドHelpコマンドを定義しました。

Help クラスは、Airlineライブラリの一部として提供され、 -hまたは–helpオプションを使用してデフォルトのヘルプコマンドを公開します。

ちょうどそのように、基本的なセットアップが行われます。

5. 私たちの最初のコマンド

最初のコマンドである、ログの詳細度を制御する単純なLoggingCommandクラスを実装しましょう。 クラスに@Commandの注釈を付けて、ユーザーがsetup-logを呼び出したときに正しいコマンドが適用されるようにします。

@Command(name = "setup-log", description = "Setup our log")
public class LoggingCommand implements Runnable {

    @Inject
    private HelpOption<LoggingCommand> help;
	
    @Option(name = { "-v", "--verbose" }, 
      description = "Set log verbosity on/off")
    private boolean verbose = false;

    @Override
    public void run() {
        if (!help.showHelpIfRequested())
            System.out.println("Verbosity: " + verbose);
        }
    }
}

コマンドの例を詳しく見てみましょう。

まず、説明を設定して、インジェクションのおかげで、ヘルパーが要求されたときにコマンドオプションを表示するようにしました。

次に、 boolean変数verbose を宣言し、 @Option で注釈を付けて、名前、説明、およびエイリアス-vを付けました。 / –verbose は、冗長性を制御するためのコマンドラインオプションを表します。

最後に、 run メソッド内で、ユーザーがヘルプを要求するたびに停止するようにコマンドに指示しました。

ここまでは順調ですね。 次に、@ Cli アノテーションを変更して、新しいコマンドをメインインターフェイスに追加する必要があります。

@Cli(name = "baeldung-cli",
description = "Baeldung Airline Tutorial",
defaultCommand = Help.class,
commands = { LoggingCommand.class, Help.class })
public class CommandLine {
    public static void main(String[] args) {
        Cli<Runnable> cli = new Cli<>(CommandLine.class);
        Runnable cmd = cli.parse(args);
        cmd.run();
    }
}

ここで、 setup-log -v をプログラムに渡すと、ロジックが実行されます。

6. 制約など

AirlineがCLIを完璧に生成する方法を見てきましたが、…もっとあります!

許可された値、要件、依存関係などを処理するために、パラメーターに制約(または制限)を指定できます。

DatabaseSetupCommand クラスを作成します。このクラスは、setup-dbコマンドに応答します。 以前と同じですが、スパイスを追加します。

最初に、データベースのタイプを要求し、@AllowedRawValuesを介して3つの有効な値のみを受け入れます。

@AllowedRawValues(allowedValues = { "mysql", "postgresql", "mongodb" })
@Option(type = OptionType.COMMAND,
  name = {"-d", "--database"},
  description = "Type of RDBMS.",
  title = "RDBMS type: mysql|postgresql|mongodb")
protected String rdbmsMode;

データベース接続を使用する場合、間違いなく、ユーザーはエンドポイントとそれにアクセスするためのいくつかの資格情報を提供する必要があります。 これをCLIに1つ( URLモード)または複数のパラメーター(ホストモード)で処理させます。 このために、 @MutuallyExclusiveWith アノテーションを使用して、各パラメーターに同じタグを付けます。

@Option(type = OptionType.COMMAND,
  name = {"--rdbms:url", "--url"},
  description = "URL to use for connection to RDBMS.",
  title = "RDBMS URL")
@MutuallyExclusiveWith(tag="mode")
@Pattern(pattern="^(http://.*):(d*)(.*)u=(.*)&p=(.*)")
protected String rdbmsUrl = "";
	
@Option(type = OptionType.COMMAND,
  name = {"--rdbms:host", "--host"},
  description = "Host to use for connection to RDBMS.",
  title = "RDBMS host")
@MutuallyExclusiveWith(tag="mode")
protected String rdbmsHost = "";

@Pattern デコレータを使用したことに注意してください。これは、URL文字列形式の定義に役立ちます。

プロジェクトのドキュメントを見ると、要件、オカレンス、許可された値、特定のケースなどを処理するための他の貴重なツールが見つかり、カスタムルールを定義できます。

最後に、ユーザーがホストモードを選択した場合は、資格情報を提供するように依頼する必要があります。 このように、1つのオプションは別のオプションに依存しています。 この動作は、@RequiredOnlyIfアノテーションを使用して実現できます。

@RequiredOnlyIf(names={"--rdbms:host", "--host"})
@Option(type = OptionType.COMMAND,
  name = {"--rdbms:user", "-u", "--user"},
  description = "User for login to RDBMS.",
  title = "RDBMS user")
protected String rdbmsUser;

@RequiredOnlyIf(names={"--rdbms:host", "--host"})
@Option(type = OptionType.COMMAND,
  name = {"--rdbms:password", "--password"},
  description = "Password for login to RDBMS.",
  title = "RDBMS password")
protected String rdbmsPassword;

DB接続を処理するためにいくつかのドライバーを使用する必要がある場合はどうなりますか? また、1つのパラメーターで複数の値を受け取る必要があるとします。 オプションタイプをOptionType.ARGUMENTSに変更するか、さらに良いことに、値のリストを受け入れることができます。

@Option(type = OptionType.COMMAND,
  name = {"--driver", "--jars"},
  description = "List of drivers",
  title = "--driver <PATH_TO_YOUR_JAR> --driver <PATH_TO_YOUR_JAR>")
protected List<String> jars = new ArrayList<>();

ここで、データベース設定コマンドをメインクラスに追加することを忘れないでください。 それ以外の場合は、CLIで使用できません。

7. 走る

やりました! プロジェクトが終了し、実行できるようになりました。

予想どおり、パラメーターを渡さずに、Helpが呼び出されます。

$ baeldung-cli

usage: baeldung-cli <command> [ <args> ]

Commands are:
    help        Display help information
    setup-db    Setup our database
    setup-log   Setup our log

See 'baeldung-cli help <command>' for more information on a specific command.

代わりにsetup-log–help を実行すると、次のようになります。

$ baeldung-cli setup-log --help

NAME
        baeldung-cli setup-log - Setup our log

SYNOPSIS
        baeldung-cli setup-log [ {-h | --help} ] [ {-v | --verbose} ]

OPTIONS
        -h, --help
            Display help information

        -v, --verbose
            Set log verbosity on/off

最後に、これらのコマンドにパラメーターを指定すると、正しいビジネスロジックが実行されます。

8. 結論

この記事では、コーディングがほとんどない、シンプルでありながら強力なコマンドラインインターフェイスを構築しました。

強力な機能を備えたAirlineライブラリは、CLIを簡素化し、一般的でクリーンで再利用可能なインフラストラクチャを提供します。 これにより、開発者は、些細なことを設計することに時間を費やすのではなく、ビジネスロジックに集中することができます。

いつものように、コードはGitHubにあります。