这里说明一下Option类及其如何设置一个Option类的实例。在buildGeneralOptions()方法接收Options opts然后又返回了opts,在这个过程中已经改变了opts的值。如下所示:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/**
*Specifypropertiesofeachgenericoption
*/
@SuppressWarnings("static-access")
privateOptionsbuildGeneralOptions(Optionsopts){
Optionfs=OptionBuilder.withArgName("local|namenode:port")
.hasArg()
.withDescription("specifyanamenode")
.create("fs");
Optionjt=OptionBuilder.withArgName("local|jobtracker:port")
.hasArg()
.withDescription("specifyajobtracker")
.create("jt");
Optionoconf=OptionBuilder.withArgName("configurationfile")
.hasArg()
.withDescription("specifyanapplicationconfigurationfile")
.create("conf");
Optionproperty=OptionBuilder.withArgName("property=value")
.hasArgs()
.withArgPattern("=",1)
.withDescription("usevalueforgivenproperty")
.create('D');
opts.addOption(fs);
opts.addOption(jt);
opts.addOption(oconf);
opts.addOption(property);
returnopts;
}
*Specifypropertiesofeachgenericoption
*/
@SuppressWarnings("static-access")
privateOptionsbuildGeneralOptions(Optionsopts){
Optionfs=OptionBuilder.withArgName("local|namenode:port")
.hasArg()
.withDescription("specifyanamenode")
.create("fs");
Optionjt=OptionBuilder.withArgName("local|jobtracker:port")
.hasArg()
.withDescription("specifyajobtracker")
.create("jt");
Optionoconf=OptionBuilder.withArgName("configurationfile")
.hasArg()
.withDescription("specifyanapplicationconfigurationfile")
.create("conf");
Optionproperty=OptionBuilder.withArgName("property=value")
.hasArgs()
.withArgPattern("=",1)
.withDescription("usevalueforgivenproperty")
.create('D');
opts.addOption(fs);
opts.addOption(jt);
opts.addOption(oconf);
opts.addOption(property);
returnopts;
}
开始传进来一个opts,它并没有任何内容(是指Option类的对象,即一个选项),因为从开始实例化就没有配置过Options opts。但是,在上面代码的后面部分,已经为opts设置内容了,其实就是设置添加Option类的对象到Options中去。
看看具体都添加了一些什么信息。拿出一项来看看:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Optionfs=OptionBuilder.withArgName("local|namenode:port")
.hasArg()
.withDescription("specifyanamenode")
.create("fs");
opts.addOption(fs);
.hasArg()
.withDescription("specifyanamenode")
.create("fs");
opts.addOption(fs);
Option代表了一个命令行,我们看一下Option类的定义:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->packageorg.apache.commons.cli;
importjava.util.ArrayList;
importjava.util.regex.Pattern;
publicclassOption{
//参数值没有被指定时,用-1表示
publicstaticfinalintUNINITIALIZED=-1;
//参数值为无穷时使用-2表示
publicstaticfinalintUNLIMITED_VALUES=-2;
//标识一个Option的字符串名称
privateStringopt;
//Option使用长名称表示
privateStringlongOpt;
//表明一个Option是否有一个相关的参数
privatebooleanhasArg;
//表明一个Option的参数的名称
privateStringargName="arg";
//一个Option的描述信息
privateStringdescription;
//一个Option是否是必须指定的
privatebooleanrequired;
//是否一个Option的参数值是可选的
privatebooleanoptionalArg;
//一个Option可以具有参数值的个数
privateintnumberOfArgs=UNINITIALIZED;
//一个Option的类型
privateObjecttype;
//参数值列表
privateArrayListvalues=newArrayList();
//指定用作分隔符的字符
privatecharvaluesep;
//参数样式及其它出现的次数
privatePatternargPattern;
privateintlimit;
/**
*构造一个Option.
*
*@paramopt标识一个Option的名称
*@paramdescription一个Option的描述信息
*/
publicOption(Stringopt,Stringdescription)
throwsIllegalArgumentException
{
this(opt,null,false,description);//调用其他构造方法
}
//另一种构造方法
publicOption(Stringopt,booleanhasArg,Stringdescription)
throwsIllegalArgumentException
{
this(opt,null,hasArg,description);
}
//还是构造一个Option
publicOption(Stringopt,StringlongOpt,booleanhasArg,
Stringdescription)
throwsIllegalArgumentException
{
//验证一个Option是合法的
OptionValidator.validateOption(opt);
this.opt=opt;
this.longOpt=longOpt;
//ifhasArgissetthenthenumberofargumentsis1
if(hasArg)
{
this.numberOfArgs=1;
}
this.hasArg=hasArg;
this.description=description;
}
//返回Option的ID
publicintgetId()
{
returngetKey().charAt(0);
}
/**
*Returnsthe'unique'Optionidentifier.
*
*@returnthe'unique'Optionidentifier
*/
StringgetKey()
{
//if'opt'isnull,thenitisa'long'option
if(opt==null)
{
returnthis.longOpt;
}
returnthis.opt;
}
/**
*返回一个Option的name
*/
publicStringgetOpt()
{
returnthis.opt;
}
/**
*返回一个Option的类型
*/
publicObjectgetType()
{
returnthis.type;
}
/**
*设置一个Option的类型
*/
publicvoidsetType(Objecttype)
{
this.type=type;
}
/**
*返回一个Option的长名称
*/
publicStringgetLongOpt()
{
returnthis.longOpt;
}
/**
*设置一个Option的长名称
*/
publicvoidsetLongOpt(StringlongOpt)
{
this.longOpt=longOpt;
}
/**
*设置一个Option是否具有一个可选的参数
*/
publicvoidsetOptionalArg(booleanoptionalArg)
{
this.optionalArg=optionalArg;
}
/**
*返回一个Option的是否具有可选的参数
*/
publicbooleanhasOptionalArg()
{
returnthis.optionalArg;
}
/**
*是否Option具有一个长名称
*/
publicbooleanhasLongOpt()
{
return(this.longOpt!=null);
}
/**
*是否一个Option有一个必需的参数
*/
publicbooleanhasArg()
{
return(this.numberOfArgs>0)||(numberOfArgs==UNLIMITED_VALUES);
}
//返回一个Option的描述信息
publicStringgetDescription()
{
returnthis.description;
}
//设置一个Option的描述信息
publicvoidsetDescription(Stringdescription)
{
this.description=description;
}
//是否一个Option需要指定一个参数
publicbooleanisRequired()
{
returnthis.required;
}
//设置一个Option的参数是否必需
publicvoidsetRequired(booleanrequired)
{
this.required=required;
}
//设置这个参数值的显示名称
publicvoidsetArgName(StringargName)
{
this.argName=argName;
}
//返回这个参数值的显示名称
publicStringgetArgName()
{
returnthis.argName;
}
//是否这个参数值的显示名称已经被设置了
publicbooleanhasArgName()
{
return(this.argName!=null&&this.argName.length()>0);
}
//是否一个Option可以具有多个参数值
publicbooleanhasArgs()
{
return(this.numberOfArgs>1)
||(this.numberOfArgs==UNLIMITED_VALUES);
}
//设置一个Option具有的参数值的个数
publicvoidsetArgs(intnum)
{
this.numberOfArgs=num;
}
//设置值的分隔符字符
publicvoidsetValueSeparator(charsep)
{
this.valuesep=sep;
}
//返回值的分隔符字符
publicchargetValueSeparator()
{
returnthis.valuesep;
}
//是否一个Option指定了值的分隔符字符
publicbooleanhasValueSeparator()
{
return(this.valuesep>0);
}
//一个Option是否指定多了参数的样式
publicbooleanhasArgPattern()
{
return(limit!=0&&argPattern!=null);
}
publicvoidsetArgPattern(StringargPattern,intlimit)
{
if(argPattern==null||argPattern.length()==0||limit==0)
return;
this.argPattern=Pattern.compile(argPattern);
this.limit=limit;
}
//返回一个Option具有参数的个数
publicintgetArgs()
{
returnthis.numberOfArgs;
}
//设置一个Option的值
voidaddValue(Stringvalue)
{
switch(numberOfArgs)
{
caseUNINITIALIZED:
thrownewRuntimeException("NO_ARGS_ALLOWED");
default:
processValue(value);
}
}
//检查参数样式
privatevoidcheckArgPattern(Stringarg){
if(!hasArgPattern()){
add(arg);
}else{
String[]tokens=argPattern.split(arg,-1);
if(tokens.length!=limit+1)
thrownewRuntimeException("ARG_PATTERN_NOT_MATCH");
for(inti=0;i<=limit;i++){
add(tokens[i]);
}
}
}
//处理一个Option的值
privatevoidprocessValue(Stringvalue)
{
//thisOptionhasaseparatorcharacter
if(hasValueSeparator())
{
//gettheseparatorcharacter
charsep=getValueSeparator();
//storetheindexforthevalueseparator
intindex=value.indexOf(sep);
//whiletherearemorevalueseparators
while(index!=-1)
{
//nextvaluetobeadded
if(values.size()/(limit+1)==(numberOfArgs-1))
{
break;
}
//store
checkArgPattern(value.substring(0,index));
//parse
value=value.substring(index+1);
//getnewindex
index=value.indexOf(sep);
}
}
//checkiftheargmentmatchesspecifiedpattern;ifyes,
//storetheactualvalueorthelastvaluethathasbeenparsed
checkArgPattern(value);
}
//向一个Option添加值,如果参数的个数大于0并且有足够的列表的时候才可以添加
privatevoidadd(Stringvalue)
{
if((numberOfArgs>0)&&(values.size()>(numberOfArgs-1)))
{
thrownewRuntimeException("Cannotaddvalue,listfull.");
}
this.values.add(value);
}
//返回Option的值
publicStringgetValue()
{
returnhasNoValues()?null:(String)this.values.get(0);
}
//返回指定的Option的值
publicStringgetValue(intindex)
throwsIndexOutOfBoundsException
{
returnhasNoValues()?null:(String)this.values.get(index);
}
//返回一个Option的值,或者第一个值,如果它没有值就返回一个默认值
publicStringgetValue(StringdefaultValue)
{
Stringvalue=getValue();
return(value!=null)?value:defaultValue;
}
//以一个字符串数组的形式返回一个Option的所有值
publicString[]getValues()
{
returnhasNoValues()
?null:(String[])this.values.toArray(newString[]{});
}
//以列表的形式返回一个Option的所有值
publicjava.util.ListgetValuesList()
{
returnthis.values;
}
//用于调试使用的
publicStringtoString()
{
StringBufferbuf=newStringBuffer().append("[option:");
buf.append(this.opt);
if(this.longOpt!=null)
{
buf.append("").append(this.longOpt);
}
buf.append("");
if(hasArg)
{
buf.append("+ARG");
}
buf.append("::").append(this.description);
if(this.type!=null)
{
buf.append("::").append(this.type);
}
buf.append("]");
returnbuf.toString();
}
//一个Option是否可以是任意值
privatebooleanhasNoValues()
{
returnthis.values.size()==0;
}
}
importjava.util.ArrayList;
importjava.util.regex.Pattern;
publicclassOption{
//参数值没有被指定时,用-1表示
publicstaticfinalintUNINITIALIZED=-1;
//参数值为无穷时使用-2表示
publicstaticfinalintUNLIMITED_VALUES=-2;
//标识一个Option的字符串名称
privateStringopt;
//Option使用长名称表示
privateStringlongOpt;
//表明一个Option是否有一个相关的参数
privatebooleanhasArg;
//表明一个Option的参数的名称
privateStringargName="arg";
//一个Option的描述信息
privateStringdescription;
//一个Option是否是必须指定的
privatebooleanrequired;
//是否一个Option的参数值是可选的
privatebooleanoptionalArg;
//一个Option可以具有参数值的个数
privateintnumberOfArgs=UNINITIALIZED;
//一个Option的类型
privateObjecttype;
//参数值列表
privateArrayListvalues=newArrayList();
//指定用作分隔符的字符
privatecharvaluesep;
//参数样式及其它出现的次数
privatePatternargPattern;
privateintlimit;
/**
*构造一个Option.
*
*@paramopt标识一个Option的名称
*@paramdescription一个Option的描述信息
*/
publicOption(Stringopt,Stringdescription)
throwsIllegalArgumentException
{
this(opt,null,false,description);//调用其他构造方法
}
//另一种构造方法
publicOption(Stringopt,booleanhasArg,Stringdescription)
throwsIllegalArgumentException
{
this(opt,null,hasArg,description);
}
//还是构造一个Option
publicOption(Stringopt,StringlongOpt,booleanhasArg,
Stringdescription)
throwsIllegalArgumentException
{
//验证一个Option是合法的
OptionValidator.validateOption(opt);
this.opt=opt;
this.longOpt=longOpt;
//ifhasArgissetthenthenumberofargumentsis1
if(hasArg)
{
this.numberOfArgs=1;
}
this.hasArg=hasArg;
this.description=description;
}
//返回Option的ID
publicintgetId()
{
returngetKey().charAt(0);
}
/**
*Returnsthe'unique'Optionidentifier.
*
*@returnthe'unique'Optionidentifier
*/
StringgetKey()
{
//if'opt'isnull,thenitisa'long'option
if(opt==null)
{
returnthis.longOpt;
}
returnthis.opt;
}
/**
*返回一个Option的name
*/
publicStringgetOpt()
{
returnthis.opt;
}
/**
*返回一个Option的类型
*/
publicObjectgetType()
{
returnthis.type;
}
/**
*设置一个Option的类型
*/
publicvoidsetType(Objecttype)
{
this.type=type;
}
/**
*返回一个Option的长名称
*/
publicStringgetLongOpt()
{
returnthis.longOpt;
}
/**
*设置一个Option的长名称
*/
publicvoidsetLongOpt(StringlongOpt)
{
this.longOpt=longOpt;
}
/**
*设置一个Option是否具有一个可选的参数
*/
publicvoidsetOptionalArg(booleanoptionalArg)
{
this.optionalArg=optionalArg;
}
/**
*返回一个Option的是否具有可选的参数
*/
publicbooleanhasOptionalArg()
{
returnthis.optionalArg;
}
/**
*是否Option具有一个长名称
*/
publicbooleanhasLongOpt()
{
return(this.longOpt!=null);
}
/**
*是否一个Option有一个必需的参数
*/
publicbooleanhasArg()
{
return(this.numberOfArgs>0)||(numberOfArgs==UNLIMITED_VALUES);
}
//返回一个Option的描述信息
publicStringgetDescription()
{
returnthis.description;
}
//设置一个Option的描述信息
publicvoidsetDescription(Stringdescription)
{
this.description=description;
}
//是否一个Option需要指定一个参数
publicbooleanisRequired()
{
returnthis.required;
}
//设置一个Option的参数是否必需
publicvoidsetRequired(booleanrequired)
{
this.required=required;
}
//设置这个参数值的显示名称
publicvoidsetArgName(StringargName)
{
this.argName=argName;
}
//返回这个参数值的显示名称
publicStringgetArgName()
{
returnthis.argName;
}
//是否这个参数值的显示名称已经被设置了
publicbooleanhasArgName()
{
return(this.argName!=null&&this.argName.length()>0);
}
//是否一个Option可以具有多个参数值
publicbooleanhasArgs()
{
return(this.numberOfArgs>1)
||(this.numberOfArgs==UNLIMITED_VALUES);
}
//设置一个Option具有的参数值的个数
publicvoidsetArgs(intnum)
{
this.numberOfArgs=num;
}
//设置值的分隔符字符
publicvoidsetValueSeparator(charsep)
{
this.valuesep=sep;
}
//返回值的分隔符字符
publicchargetValueSeparator()
{
returnthis.valuesep;
}
//是否一个Option指定了值的分隔符字符
publicbooleanhasValueSeparator()
{
return(this.valuesep>0);
}
//一个Option是否指定多了参数的样式
publicbooleanhasArgPattern()
{
return(limit!=0&&argPattern!=null);
}
publicvoidsetArgPattern(StringargPattern,intlimit)
{
if(argPattern==null||argPattern.length()==0||limit==0)
return;
this.argPattern=Pattern.compile(argPattern);
this.limit=limit;
}
//返回一个Option具有参数的个数
publicintgetArgs()
{
returnthis.numberOfArgs;
}
//设置一个Option的值
voidaddValue(Stringvalue)
{
switch(numberOfArgs)
{
caseUNINITIALIZED:
thrownewRuntimeException("NO_ARGS_ALLOWED");
default:
processValue(value);
}
}
//检查参数样式
privatevoidcheckArgPattern(Stringarg){
if(!hasArgPattern()){
add(arg);
}else{
String[]tokens=argPattern.split(arg,-1);
if(tokens.length!=limit+1)
thrownewRuntimeException("ARG_PATTERN_NOT_MATCH");
for(inti=0;i<=limit;i++){
add(tokens[i]);
}
}
}
//处理一个Option的值
privatevoidprocessValue(Stringvalue)
{
//thisOptionhasaseparatorcharacter
if(hasValueSeparator())
{
//gettheseparatorcharacter
charsep=getValueSeparator();
//storetheindexforthevalueseparator
intindex=value.indexOf(sep);
//whiletherearemorevalueseparators
while(index!=-1)
{
//nextvaluetobeadded
if(values.size()/(limit+1)==(numberOfArgs-1))
{
break;
}
//store
checkArgPattern(value.substring(0,index));
//parse
value=value.substring(index+1);
//getnewindex
index=value.indexOf(sep);
}
}
//checkiftheargmentmatchesspecifiedpattern;ifyes,
//storetheactualvalueorthelastvaluethathasbeenparsed
checkArgPattern(value);
}
//向一个Option添加值,如果参数的个数大于0并且有足够的列表的时候才可以添加
privatevoidadd(Stringvalue)
{
if((numberOfArgs>0)&&(values.size()>(numberOfArgs-1)))
{
thrownewRuntimeException("Cannotaddvalue,listfull.");
}
this.values.add(value);
}
//返回Option的值
publicStringgetValue()
{
returnhasNoValues()?null:(String)this.values.get(0);
}
//返回指定的Option的值
publicStringgetValue(intindex)
throwsIndexOutOfBoundsException
{
returnhasNoValues()?null:(String)this.values.get(index);
}
//返回一个Option的值,或者第一个值,如果它没有值就返回一个默认值
publicStringgetValue(StringdefaultValue)
{
Stringvalue=getValue();
return(value!=null)?value:defaultValue;
}
//以一个字符串数组的形式返回一个Option的所有值
publicString[]getValues()
{
returnhasNoValues()
?null:(String[])this.values.toArray(newString[]{});
}
//以列表的形式返回一个Option的所有值
publicjava.util.ListgetValuesList()
{
returnthis.values;
}
//用于调试使用的
publicStringtoString()
{
StringBufferbuf=newStringBuffer().append("[option:");
buf.append(this.opt);
if(this.longOpt!=null)
{
buf.append("").append(this.longOpt);
}
buf.append("");
if(hasArg)
{
buf.append("+ARG");
}
buf.append("::").append(this.description);
if(this.type!=null)
{
buf.append("::").append(this.type);
}
buf.append("]");
returnbuf.toString();
}
//一个Option是否可以是任意值
privatebooleanhasNoValues()
{
returnthis.values.size()==0;
}
}
可以看出,一个Option所具有的信息很多:长名称(longOpt)、短名称(name)、类型(type)、样式(pattern)、参数个数(numberOfArgs)、参数值的字符分隔符、ID,描述等等。
只要设置好了这些Option的信息,调用private Options buildGeneralOptions(Options opts) 方法时候返回的Options可以被后面进行解析使用。