読者です 読者をやめる 読者になる 読者になる

プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

Javaでコマンドラインから受け取った引数処理するクラス作ってみた

 コマンドラインから受け取った引数を簡単に処理したいという話。
 
 結論から言えば、すでに作られているライブラリ使うといいよ!!!
 参考:Javaでコマンドライン引数を処理する


 
 まぁ~、車輪の再々再発明なんだけど、MITライセンスのライセンスすら嫌じゃん。URLとか、ライセンス書かないといけないし。ぶっちぇけここしか外部ライブラリ使ってないし、そのためにいちいちライブラリ情報書くのもなー。
 というわけで、著作権放棄のライセンス(CC0 1.0 Universal)で作ってみた。よっぽどライセンスが緩すぎるものしか使いたくねぇ!って人は選択肢になるかもしれないよ。


 nodamushi/NArguments · GitHub

 Java6対象。(ワークステーションのLinuxがJava6だったのよっ。)
 ただし、Pathを使ってるから、コンパイルするときは、JDK7以上にするか、Path関連全部削除するか。

 基本的な思想はたぶん、arg4jと同じ。(使ったことないけど)
 簡単な使い方はDemo.javaを見ればわかるかなーってくらい、単純。ドキュメントなんていらない。
 私しか使わねぇから、ドキュメントも用意するの面倒くさいとか、そういう理由では断じてない。私は嘘はつかないっ(`・д´・ )



public static void main(String[] args){
    final NArgument<Args> nArgument = new NArgument<Args>(new Args());
    nArgument.setIgnoreConvertException(false);
    try {
      nArgument.addArguments(args);
    } catch (final ConvertException e) {
      System.out.println("Parse error:"+e.getMessage());
      System.out.println(nArgument.getDescription());
      return;
    } catch (final ReflectionException e) {
      e.printStackTrace();
      return;
    }

    final Args a = nArgument.get();
    System.out.println(a);
    if(a.help){
      System.out.println();
      System.out.println(nArgument.getDescription());
    }

  }


 Argsってのは、自分で定義するデータ格納クラスです。こんな(↓)感じで定義。
 使える型はString以外に、intなどのprimitiveと、Path,File,Charsetが使えます。
 Argumentsで正規表現で受け取る受けとらないを選択できるのが地味に便利かなぁと思っています。


@Description(
    "demo arguments.\n"
    + "[-a String]* [(-b|--bbb|--bbbb)] [-c] [-d] [(-e|--encoding) File Encoding] "
    + "[-i Integer] [(-h|--help)] [-n Number] [InputFiles]+")
class Args{
  @Option(value="-a",description="multi string option")
  private List<String> strs;

  @Option(value="-b",alias={"--bbb","--bbbb"},description="flag option")
  private boolean flagB;

  @Option("-c")
  private boolean flagC;

  @Option("-d")
  private boolean flagD;

  @Option(value="-e",alias="--encoding",description="text file charset")
  private Charset charset;

  @Option(value="-i")
  private String integer;
  //setterがある場合はsetterを優先的に使う。たとえprivateであっても。
  //従って、integerはStringであるが、setterがintになっているので、int型のOptionと判定される
  private void setInteger(final int i){
    integer = "input integer value is '"+String.valueOf(i)+"'";
  }

  //@Optionはmethodにも付加可能
  public boolean help;
  @Option(value="-h",alias="--help",description="show this help")
  private void setHelp(final boolean b){
    help = b;
  }

  @Option("-n")
  private double number;

  @Arguments(match="\\.txt$")
  private List<Path> inputTextFiles;

  @Arguments
  private List<File> inputFiles;


  @Override
  public String toString(){
    final StringBuilder sb=new StringBuilder();
    sb.append("Options\n");
    sb.append("-a = ").append(strs).append("\n");
    sb.append("-b = ").append(flagB).append("\n");
    sb.append("-c = ").append(flagC).append("\n");
    sb.append("-d = ").append(flagD).append("\n");
    sb.append("-e = ").append(charset).append("\n");
    sb.append("-i = ").append(integer).append("\n");
    sb.append("-h = ").append(help).append("\n");
    sb.append("-n = ").append(number).append("\n\n");
    sb.append("Arguments\n");
    sb.append("text files = ").append(inputTextFiles).append("\n");
    sb.append("else files = ").append(inputFiles);
    return sb.toString();
  }
}


 Demo.javaに次のような引数を与えて実行するとこんな感じになる。

-a a1 -a a2 -a a3 --bbb -cd --encoding shift-jis -i 200 --help -n 20.1 test/test1.txt img/img.jpg test/test2.txt

f:id:nodamushi:20151103211142p:plain

Options
-a = [a1, a2, a3]
-b = true
-c = true
-d = true
-e = Shift_JIS
-i = input integer value is '200'
-h = true
-n = 20.1

Arguments
text files = [test\test1.txt, test\test2.txt]
else files = [img\img.jpg]

demo arguments.
[-a String]* [(-b|--bbb|--bbbb)] [-c] [-d] [(-e|--encoding) File Encoding] [-i Integer] [(-h|--help)] [-n Number] [InputFiles]+

   Options:
      -a        :multi string option

      -b
      --bbb
      --bbbb    :flag option

      -c        :

      -d        :

      -e
      --encoding:text file charset

      -h
      --help    :show this help

      -i        :

      -n        :