【转】分析Hadoop自带WordCount例子的执行过程(2)

这里说明一下Option类及其如何设置一个Option类的实例。buildGeneralOptions()方法接收Options opts然后又返回了opts,在这个过程中已经改变了opts的值。如下所示:

  /**
   * Specify properties of each generic option
   
*/
@SuppressWarnings(
" static-access " )
private  Options buildGeneralOptions(Options opts) {
    Option fs 
=  OptionBuilder.withArgName( " local|namenode:port " )
    .hasArg()
    .withDescription(
" specify a namenode " )
    .create(
" fs " );
    Option jt 
=  OptionBuilder.withArgName( " local|jobtracker:port " )
    .hasArg()
    .withDescription(
" specify a job tracker " )
    .create(
" jt " );
    Option oconf 
=  OptionBuilder.withArgName( " configuration file " )
    .hasArg()
    .withDescription(
" specify an application configuration file " )
    .create(
" conf " );
    Option property 
=  OptionBuilder.withArgName( " property=value " )
    .hasArgs()
    .withArgPattern(
" = " 1 )
    .withDescription(
" use value for given property " )
    .create(
' D ' );
    opts.addOption(fs);
    opts.addOption(jt);
    opts.addOption(oconf);
    opts.addOption(property);
    
    
return  opts;
}

     开始传进来一个opts,它并没有任何内容(是指Option类的对象,即一个选项),因为从开始实例化就没有配置过Options opts。但是,在上面代码的后面部分,已经为opts设置内容了,其实就是设置添加Option类的对象到Options中去。

看看具体都添加了一些什么信息。拿出一项来看看:

 Option fs  =  OptionBuilder.withArgName( " local|namenode:port " )
    .hasArg()
    .withDescription(
" specify a namenode " )
    .create(
" fs " );
     opts.addOption(fs);

Option代表了一个命令行,我们看一下Option类的定义:

package  org.apache.commons.cli;
import  java.util.ArrayList;
import  java.util.regex.Pattern;
public   class  Option {
   
//  参数值没有被指定时,用-1表示 
     public   static   final   int  UNINITIALIZED  =   - 1 ;
    
//  参数值为无穷时使用-2表示
     public   static   final   int  UNLIMITED_VALUES  =   - 2 ;
    
//    标识一个Option的字符串名称
     private  String opt;
    
//  Option使用长名称表示
     private  String longOpt;
    
//  表明一个Option是否有一个相关的参数
     private   boolean  hasArg;
    
//  表明一个Option的参数的名称 
     private  String argName  =   " arg " ;
    
//  一个Option的描述信息
     private  String description;
    
//  一个Option是否是必须指定的
     private   boolean  required;
    
//  是否一个Option的参数值是可选的
     private   boolean  optionalArg;
    
//  一个Option可以具有参数值的个数 
      private   int  numberOfArgs  =  UNINITIALIZED;
    
//  一个Option的类型
     private  Object type;
    
//  参数值列表
     private  ArrayList values  =   new  ArrayList();
    
//  指定用作分隔符的字符
     private   char  valuesep;
    
//  参数样式及其它出现的次数 
     private  Pattern argPattern;
    
private   int  limit;
    
/**
     * 构造一个Option.
     *
     * 
@param  opt 标识一个Option的名称 
     * 
@param  description   一个Option的描述信息
     
*/
    
public  Option(String opt, String description)
           
throws  IllegalArgumentException
    {
        
this (opt,  null false , description);  //  调用其他构造方法
    }
    
//  另一种构造方法
     public  Option(String opt,  boolean  hasArg, String description)
           
throws  IllegalArgumentException
    {
        
this (opt,  null , hasArg, description);
    }
    
//  还是构造一个Option
     public  Option(String opt, String longOpt,  boolean  hasArg, 
                  String description)
           
throws  IllegalArgumentException
    {
        
//  验证一个Option是合法的
        OptionValidator.validateOption(opt);
        
this .opt  =  opt;
        
this .longOpt  =  longOpt;
       
//  if hasArg is set then the number of arguments is 1
         if  (hasArg)
        {
            
this .numberOfArgs  =   1 ;
        }
        
this .hasArg  =  hasArg;
        
this .description  =  description;
    }
    
//  返回Option的ID
     public   int  getId()
    {
        
return  getKey().charAt( 0 );
    }
   
/**
     * Returns the 'unique' Option identifier.
     * 
     * 
@return  the 'unique' Option identifier
     
*/
    String getKey()
    {
        
//  if 'opt' is null, then it is a 'long' option
         if  (opt  ==   null )
        {
            
return   this .longOpt;
        }
        
return   this .opt;
    }
    
/**  
     * 返回一个Option的name
     
*/
    
public  String getOpt()
    {
        
return   this .opt;
    }
    
/**  
     * 返回一个Option的类型
     
*/
    
public  Object getType()
    {
        
return   this .type;
    }
   
/**  
     * 设置一个Option的类型
     
*/
    
public   void  setType(Object type)
    {
        
this .type  =  type;
    }
    
/**  
     * 返回一个Option的长名称
     
*/
    
public  String getLongOpt()
    {
        
return   this .longOpt;
    }
    
/**  
     * 设置一个Option的长名称
     
*/
    
public   void  setLongOpt(String longOpt)
    {
        
this .longOpt  =  longOpt;
    }
    
/**  
     * 设置一个Option是否具有一个可选的参数
     
*/
    
public   void  setOptionalArg( boolean  optionalArg)
    {
        
this .optionalArg  =  optionalArg;
    }
    
/**  
     * 返回一个Option的是否具有可选的参数
     
*/
    
public   boolean  hasOptionalArg()
    {
        
return   this .optionalArg;
    }
    
/**  
     * 是否Option具有一个长名称
     
*/
    
public   boolean  hasLongOpt()
    {
        
return  ( this .longOpt  !=   null );
    }
    
/**  
     * 是否一个Option有一个必需的参数
     
*/
    
public   boolean  hasArg()
    {
        
return  ( this .numberOfArgs  >   0 ||  (numberOfArgs  ==  UNLIMITED_VALUES);
    }
      
//  返回一个Option的描述信息
     public  String getDescription()
    {
        
return   this .description;
    }
      
//  设置一个Option的描述信息
     public   void  setDescription(String description)
    {
        
this .description  =  description;
    }
    
//  是否一个Option需要指定一个参数
     public   boolean  isRequired()
    {
        
return   this .required;
    }
    
//  设置一个Option的参数是否必需
     public   void  setRequired( boolean  required)
    {
        
this .required  =  required;
    }
    
//  设置这个参数值的显示名称
     public   void  setArgName(String argName)
    {
        
this .argName  =  argName;
    }
     
//  返回这个参数值的显示名称
     public  String getArgName()
    {
        
return   this .argName;
    }
     
//    是否这个参数值的显示名称已经被设置了
       public   boolean  hasArgName()
    {
        
return  ( this .argName  !=   null   &&   this .argName.length()  >   0 );
    }
     
//    是否一个Option可以具有多个参数值
     public   boolean  hasArgs()
    {
        
return  ( this .numberOfArgs  >   1
                
||  ( this .numberOfArgs  ==  UNLIMITED_VALUES);
    }
     
//  设置一个Option具有的参数值的个数
     public   void  setArgs( int  num)
    {
        
this .numberOfArgs  =  num;
    }
     
//  设置值的分隔符字符
     public   void  setValueSeparator( char  sep)
    {
        
this .valuesep  =  sep;
    }
     
//  返回值的分隔符字符
     public   char  getValueSeparator()
    {
        
return   this .valuesep;
    }
     
//    是否一个Option指定了值的分隔符字符
     public   boolean  hasValueSeparator()
    {
        
return  ( this .valuesep  >   0 );
    }
     
//    一个Option是否指定多了参数的样式
     public   boolean  hasArgPattern()
    {
        
return  (limit != 0 && argPattern != null );
    }
    
public   void  setArgPattern( String argPattern,  int  limit )
    {
        
if (argPattern == null   ||  argPattern.length() == 0   ||  limit == 0  )
          
return ;
        
this .argPattern  =  Pattern.compile(argPattern);
        
this .limit  =  limit;
    }
     
//    返回一个Option具有参数的个数
     public   int  getArgs()
    {
        
return   this .numberOfArgs;
    }
     
//  设置一个Option的值
     void  addValue(String value)
    {
        
switch  (numberOfArgs)
        {
        
case  UNINITIALIZED:
            
throw   new  RuntimeException( " NO_ARGS_ALLOWED " );
        
default :
            processValue(value);
        }
    }
     
//    检查参数样式
     private   void  checkArgPattern( String arg ) {
      
if ( ! hasArgPattern()) {
        add(arg);
      } 
else  {
        String [] tokens 
=  argPattern.split(arg,  - 1 );
        
if (tokens.length  !=  limit + 1 )
          
throw   new  RuntimeException( " ARG_PATTERN_NOT_MATCH " );
        
for ( int  i = 0 ; i <=  limit; i ++ ) {
          add(tokens[i]);
        }
      }
    }
     
//  处理一个Option的值
     private   void  processValue(String value)
    {
        
//  this Option has a separator character
         if  (hasValueSeparator())
        {
            
//  get the separator character
             char  sep  =  getValueSeparator();
            
//  store the index for the value separator
             int  index  =  value.indexOf(sep);
            
//  while there are more value separators
             while  (index  !=   - 1 )
            {
                
//  next value to be added 
                 if  (values.size() / (limit + 1 ==  (numberOfArgs  -   1 ))
                {
                    
break ;
                }

                
//  store
                checkArgPattern(value.substring( 0 , index));

                
//  parse
                value  =  value.substring(index  +   1 );

                
//  get new index
                index  =  value.indexOf(sep);
            }
        }

        
//  check if the argment matches specified pattern; if yes,
        
//  store the actual value or the last value that has been parsed
        checkArgPattern(value);
    }
    
//    向一个Option添加值,如果参数的个数大于0并且有足够的列表的时候才可以添加
       private   void  add(String value)
    {
        
if  ((numberOfArgs  >   0 &&  (values.size()  >  (numberOfArgs  -   1 )))
        {
            
throw   new  RuntimeException( " Cannot add value, list full. " );
        }

        
this .values.add(value);
    }
     
//    返回Option的值
     public  String getValue()
    {
        
return  hasNoValues()  ?   null  : (String)  this .values.get( 0 );
    }
     
//  返回指定的Option的值
     public  String getValue( int  index)
        
throws  IndexOutOfBoundsException
    {
        
return  hasNoValues()  ?   null  : (String)  this .values.get(index);
    }
     
//  返回一个Option的值,或者第一个值,如果它没有值就返回一个默认值     
     public  String getValue(String defaultValue)
    {
        String value 
=  getValue();
        
return  (value  !=   null ?  value : defaultValue;
    }
     
//    以一个字符串数组的形式返回一个Option的所有值
     public  String[] getValues()
    {
        
return  hasNoValues()
               
?   null  : (String[])  this .values.toArray( new  String[] { });
    }
     
//    以列表的形式返回一个Option的所有值
     public  java.util.List getValuesList()
    {
        
return   this .values;
    }
     
//    用于调试使用的
     public  String toString()
    {
        StringBuffer buf 
=   new  StringBuffer().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(
"  ] " );
        
return  buf.toString();
    }
     
//    一个Option是否可以是任意值
     private   boolean  hasNoValues()
    {
        
return   this .values.size()  ==   0 ;
    }
}

     可以看出,一个Option所具有的信息很多:长名称(longOpt)、短名称(name)、类型(type)、样式(pattern)、参数个数(numberOfArgs)、参数值的字符分隔符、ID,描述等等。

     只要设置好了这些Option的信息,调用private Options buildGeneralOptions(Options opts) 方法时候返回的Options可以被后面进行解析使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值