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

本文详细介绍了Option类的功能及其配置过程,包括如何创建Option实例并设置其属性,如长名称、短名称、参数个数等。

这里说明一下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, nullfalse, 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可以被后面进行解析使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值