Commons CLI 入門及代碼簡單分析

前言

之前寫過一些命令行程序,在須要帶參數的時候都是本身來判斷args,致使程序光解析args都佔了好大一堆,並且解析代碼也不美觀。
偶然間發現了apache公共庫中的cli庫,在這裏分享給你們。apache

入門

commons-cli中把解釋參數分爲三種狀態,分別是定義、解釋和詢問交互。maven

接下來,我以一個例子作一下說明:函數

maven庫:測試

<dependency>
        <groupId>commons-cli</groupId>
        <artifactId>commons-cli</artifactId>
        <version>1.3.1</version>
</dependency>
import org.apache.commons.cli.*;

public class CLI {
    public static void main(String[] args) throws ParseException {
        //定義
        Options options = new Options();
        options.addOption("h",false,"list help");//false表明不強制有
        options.addOption("t",true,"set time on system");

        //解析
        //1.3.1中已經棄用針對不一樣格式入參對應的解析器
        //CommandLineParser parser = new PosixParser();
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options,args);

        //查詢交互
        //你的程序應當寫在這裏,從這裏啓動
        if (cmd.hasOption("h")){
            String formatstr = "CLI  cli  test";
            HelpFormatter hf = new HelpFormatter();
            hf.printHelp(formatstr, "", options, "");
            return;
        }

        if (cmd.hasOption("t")){
            System.out.printf("system time has setted  %s \n",cmd.getOptionValue("t"));
            return;
        }

        System.out.println("error");
    }
}

在另外一個類中作一下測試ui

String argss[]={"-t  1000"};
CLI.main(argss);

結果是:this

system time has setted 1000spa

String argss[]={"-h"};
CLI.main(argss);

結果是:命令行

usage: CLI cli test
-h list help
-t <arg> set time on systemcode

好啦,入門就到這裏了。orm

代碼結構分析

包組織結構:

commons-cli-1.3.1.jar
org.apache.commons.cli

在cli包中,包含了全部的類,包括定義,解析,查詢交互和Exception

類的關係結構圖以下

172127_eb48_1983603.png

定義

在定義這一部分,最重要的類是Option,Option類中定義了一個基本的選項,例如-t xxx ,是否爲必選項,該命令的解釋等等。

Option重寫了不少構造函數,可是最終都調用下面這個構造函數:

public Option(String opt, String longOpt, boolean hasArg, String description)
           throws IllegalArgumentException
    {
        //寫這個代碼的人之前應該是寫C++的。。。
        // 判斷短選項是否包含非法字符,若是包含拋出異常
        OptionValidator.validateOption(opt);
        //短選項
        this.opt = opt;
        //長選項
        this.longOpt = longOpt;

        // 是不是必要選項
        if (hasArg)
        {
            this.numberOfArgs = 1;
        }
        //選項描述
        this.description = description;
    }

OptionsGroup類中包含了許多個Option,並能夠對多個Option進行一些處理。其實現是採用一個HashMap來存儲Option的,key是Option中的長選項或者短選項的第一個字符,若是短選項存在,則優先選擇短選項。

OptionGroup類還包含了一個組描述和組是否必須存在,至關於對一羣Option的羣組操做。

Options類是被解析的對象,使用者能夠在Options實例中直接添加命令,也能夠添加Option實例,也能夠添加OptionGroup實例。

其addOption方法最終調用了其重寫的一個方法:

public Options addOption(Option opt)
    {
        String key = opt.getKey();

        // add it to the long option list
        if (opt.hasLongOpt())
        {
            longOpts.put(opt.getLongOpt(), opt);
        }

        // if the option is required add it to the required list
        if (opt.isRequired())
        {
            if (requiredOpts.contains(key))
            {
                requiredOpts.remove(requiredOpts.indexOf(key));
            }
            requiredOpts.add(key);
        }

        shortOpts.put(key, opt);

        return this;
    }

添加GroupOption方法以下:

public Options addOptionGroup(OptionGroup group)
    {
        if (group.isRequired())
        {
            requiredOpts.add(group);
        }

        for (Option option : group.getOptions())
        {
            // an Option cannot be required if it is in an
            // OptionGroup, either the group is required or
            // nothing is required
            option.setRequired(false);
            addOption(option);

            optionGroups.put(option.getKey(), group);
        }

        return this;
    }

解析

接下來就是CommandLineParser接口,在1.3.1版本中取消了Parser抽象類,GnuParserBasicParserPosixParser類,取而代之的是DefaultParser類。DefaultParser類提供了對Options實例的解析,即對入參命令和Options實例之間對應關係的解析,返回的類是CommandLine。若是入參命令與Options實例對應不上就會拋出解析異常。

DefaultParser類解析方法最基本的方法是handleToken(String token),token是每個入參字符串。這個方法會在解析錯誤的時候拋出解析異常。

查詢交互

CommandLine能夠對入參命令進行判斷解析,例如能夠查詢是否存在某個選項,以及獲取這個選項的值。

總結

cli包仍是至關簡單的,你們也能夠本身看一看commons庫的源碼。

更多文章:http://blog.gavinzh.com

相關文章
相關標籤/搜索