Changeset 2607

Show
Ignore:
Timestamp:
10/29/08 16:51:15 (2 months ago)
Author:
leo
Message:

OptionParser?: help message done.

Location:
XerialJ/trunk/xerial-core/src
Files:
2 added
14 modified

Legend:

Unmodified
Added
Removed
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/core/XerialErrorCode.java

    r2606 r2607  
    3939    // option parser error 
    4040    DUPLICATE_OPTION, 
    41      
     41    NO_OPTION, 
     42    NO_USAGE_ANNOTATION, 
    4243    // type  
    43     MISSING_TYPE_PARAMETER 
     44    MISSING_TYPE_PARAMETER, 
    4445 
    4546    ; 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/Algorithm.java

    r2605 r2607  
    144144        } 
    145145 
    146         return null; 
     146        return result; 
    147147    } 
    148148 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/Range.java

    r2605 r2607  
    3030 * @author leo 
    3131 */ 
    32 public class Range 
     32public class Range implements Comparable<Range> 
    3333{ 
    3434    public final int start; 
     
    5252    } 
    5353 
     54    public int compareTo(Range o) 
     55    { 
     56        int diff = this.start - o.start; 
     57        return diff == 0 ? this.end - o.end : diff; 
     58    } 
     59 
    5460} 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/log/Logger.java

    r2073 r2607  
    3939public class Logger 
    4040{ 
    41     private static String[] logPrefix = { "", // ALL 
     41    private static String[]                logPrefix          = { "", // ALL 
    4242            "\033[0;32m", // TRACE 
    4343            "", // DEBUG 
     
    4747            "\033[1;31m", // FATAL 
    4848            "", // OFF 
    49             "", }; 
    50  
    51     private Writer _out = null; 
    52     private LogLevel _threshold = LogLevel.UNSPECIFIED; 
    53     private String _loggerFullName = ""; 
    54     private String _loggerShortName = ""; 
    55     private Logger _parentLogger = null; 
    56     private boolean _emitEscapeSequence = false; 
    57  
    58     private static TreeMap<String, Logger> _loggerHolder = new TreeMap<String, Logger>(); 
    59     private static Logger _rootLogger = new Logger(); 
     49            "",                                               }; 
     50 
     51    private Writer                         _out                = null; 
     52    private LogLevel                       _threshold          = LogLevel.UNSPECIFIED; 
     53    private String                         _loggerFullName    = ""; 
     54    private String                         _loggerShortName    = ""; 
     55    private Logger                         _parentLogger      = null; 
     56    private boolean                        _emitEscapeSequence = false; 
     57 
     58    private static TreeMap<String, Logger> _loggerHolder       = new TreeMap<String, Logger>(); 
     59    private static Logger                  _rootLogger        = new Logger(); 
    6060 
    6161    static 
     
    6767 
    6868        String logLevel = System.getProperty("xerial.loglevel"); 
    69         if(logLevel != null) 
     69        if (logLevel != null) 
    7070        { 
    7171            _rootLogger.setLogLevel(logLevel); 
     
    7474        { 
    7575            logLevel = System.getProperty("loglevel"); 
    76             if(logLevel != null) 
     76            if (logLevel != null) 
    7777            { 
    7878                _rootLogger.setLogLevel(logLevel); 
    7979            } 
    8080        } 
    81          
    82          
     81 
     82        String useColor = System.getProperty("color"); 
     83        if (useColor != null) 
     84            _rootLogger._emitEscapeSequence = Boolean.parseBoolean(useColor); 
     85 
    8386        String loggerConfigFile = System.getProperty("log.config"); 
    8487        if (loggerConfigFile != null) 
     
    152155            Logger newLogger = new Logger(fullTypeName); 
    153156            _loggerHolder.put(fullTypeName, newLogger); 
     157            newLogger._emitEscapeSequence = _rootLogger._emitEscapeSequence; 
    154158            return newLogger; 
    155159        } 
     
    168172    public static void configure(Reader configurationFileReader) throws IOException 
    169173    { 
    170         Properties configProperties = new Properties(); 
    171          
    172         StringBuilder sb = new StringBuilder(); 
    173         int ch; 
    174         while((ch = configurationFileReader.read()) > 0) 
    175         {   
    176             sb.append((char) ch); 
    177         } 
    178         ByteArrayInputStream bs = new ByteArrayInputStream(sb.toString().getBytes()); 
    179         configProperties.load(bs); 
    180          
    181         for(Object key : configProperties.keySet()) 
    182         { 
    183             String[] lhs = ((String) key).split("#"); 
    184                 String loggerName = lhs[0]; 
    185                 String value = configProperties.getProperty(key.toString()); 
    186                 Logger logger = getLogger(loggerName); 
    187                 if(lhs.length <= 1) 
    188                 { 
    189                     logger.setLogLevel(value); 
    190                 } 
    191                 else if(lhs.length > 1) 
    192                 { 
    193                     // packageName:parameter = value configuration 
    194                     String parameter = lhs[1]; 
    195                     if(parameter.equals("color")) 
    196                     { 
    197                         logger.setColor(Boolean.parseBoolean(value)); 
    198                     } 
    199                     else 
    200                     { 
    201                         System.err.println("unknown configuration parameter: " + parameter); 
    202                     } 
    203                 } 
    204                 else 
    205                 { 
    206                     System.err.println("Error in the logger configuration file: " + key); 
    207                 } 
    208         } 
     174        Properties configProperties = new Properties(); 
     175 
     176        StringBuilder sb = new StringBuilder(); 
     177        int ch; 
     178        while ((ch = configurationFileReader.read()) > 0) 
     179        { 
     180            sb.append((char) ch); 
     181        } 
     182        ByteArrayInputStream bs = new ByteArrayInputStream(sb.toString().getBytes()); 
     183        configProperties.load(bs); 
     184 
     185        for (Object key : configProperties.keySet()) 
     186        { 
     187            String[] lhs = ((String) key).split("#"); 
     188            String loggerName = lhs[0]; 
     189            String value = configProperties.getProperty(key.toString()); 
     190            Logger logger = getLogger(loggerName); 
     191            if (lhs.length <= 1) 
     192            { 
     193                logger.setLogLevel(value); 
     194            } 
     195            else if (lhs.length > 1) 
     196            { 
     197                // packageName:parameter = value configuration 
     198                String parameter = lhs[1]; 
     199                if (parameter.equals("color")) 
     200                { 
     201                    logger.setColor(Boolean.parseBoolean(value)); 
     202                } 
     203                else 
     204                { 
     205                    System.err.println("unknown configuration parameter: " + parameter); 
     206                } 
     207            } 
     208            else 
     209            { 
     210                System.err.println("Error in the logger configuration file: " + key); 
     211            } 
     212        } 
    209213    } 
    210214 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/Argument.java

    r2605 r2607  
    4141 
    4242    /** 
    43      * description of the argument 
     43     * name of the argument 
    4444     */ 
    45     String description() default ""; 
     45    String name() default ""; 
    4646 
    4747    /** 
    48      * This argument is required 
     48     * This argument is required or not 
    4949     */ 
    50     boolean required() default false; 
     50    boolean required() default true; 
    5151 
    5252    /** 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/ArgumentItem.java

    r2605 r2607  
    2828import java.lang.reflect.Method; 
    2929 
     30import org.xerial.util.Range; 
    3031import org.xerial.util.bean.TypeInformation; 
    3132import org.xerial.util.cui.OptionParserException; 
     
    8384    } 
    8485 
     86    public static Range getRangeOf(ArgumentItem arg) 
     87    { 
     88        int start = arg.getArgumentDescriptor().index(); 
     89        int end = arg.takesMultipleArguments() ? Integer.MAX_VALUE : start; 
     90        return new Range(start, end); 
     91    } 
     92 
     93    public Range getRange() 
     94    { 
     95        return getRangeOf(this); 
     96    } 
     97 
    8598    public void set(Object bean, Object value) throws OptionParserException 
    8699    { 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/Option.java

    r2603 r2607  
    4343 
    4444    /** 
    45      * Name of the option. If the name is "h", it handles option "-h" 
     45     * symbol of the option. If the symbol is "h", it handles option "-h" 
    4646     *  
    4747     */ 
    48     String name(); 
     48    String symbol() default ""; 
    4949 
    5050    /** 
     
    5656 
    5757    /** 
     58     * Variable name used to describe option argument (e.g. --file=VALUE). The 
     59     * default value is capitalized name(). 
     60     */ 
     61    String varName() default "VAR"; 
     62 
     63    /** 
    5864     * Description of the option, used to generate a help message of the 
    5965     * command-line options 
    6066     */ 
    6167    String description() default ""; 
    62      
     68 
    6369} 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionItem.java

    r2603 r2607  
    4040public class OptionItem 
    4141{ 
    42     private final Option optionDescriptor; 
     42    private final Option       optionDescriptor; 
    4343    private final OptionSetter optionSetter; 
    44      
     44 
    4545    public OptionItem(Method method) 
    4646    { 
    4747        Option option = method.getAnnotation(Option.class); 
    48         if(option == null) 
     48        if (option == null) 
    4949            throw new IllegalArgumentException(method + " is not an option item"); 
    5050 
     
    5252        this.optionSetter = new OptionSetterViaMethod(method); 
    5353    } 
    54      
     54 
    5555    public OptionItem(Field field) 
    5656    { 
    5757        Option option = field.getAnnotation(Option.class); 
    58         if(option == null) 
     58        if (option == null) 
    5959            throw new IllegalArgumentException(field + " is not an option item"); 
    6060 
     
    6262        this.optionSetter = new OptionSetterViaField(field); 
    6363    } 
    64      
    6564 
    6665    @Override 
     
    8180        return optionDescriptor.hashCode(); 
    8281    } 
    83      
     82 
    8483    public boolean needsArgument() 
    8584    { 
    8685        return optionSetter.takesArgument(); 
    8786    } 
    88      
     87 
     88    public boolean hasSymbol() 
     89    { 
     90        return optionDescriptor.symbol() != null && optionDescriptor.symbol().length() > 0; 
     91    } 
     92 
     93    public boolean hasLongName() 
     94    { 
     95        return optionDescriptor.longName() != null && optionDescriptor.longName().length() > 0; 
     96    } 
     97 
    8998    public Option getOption() 
    9099    { 
    91         return optionDescriptor;  
     100        return optionDescriptor; 
    92101    } 
    93      
     102 
    94103    public void setOption(Object bean, String value) throws OptionParserException 
    95104    { 
    96         Class<?> optionType = optionSetter.getOptionDataType(); 
     105        Class< ? > optionType = optionSetter.getOptionDataType(); 
    97106        try 
    98107        { 
     
    104113            throw new OptionParserException(ShellError.WRONG_DATA_TYPE, e); 
    105114        } 
    106          
     115 
    107116    } 
    108       
    109117 
    110118} 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionParser.java

    r2606 r2607  
    2626 
    2727import java.io.OutputStream; 
    28 import java.lang.reflect.Field; 
    29 import java.lang.reflect.Method; 
    3028import java.util.HashSet; 
    3129 
     
    3836 * @author leo 
    3937 *  
    40  */  
     38 */ 
    4139public class OptionParser 
    4240{ 
    4341    private boolean            ignoreUnknownOption = false; 
    4442    private final OptionSchema schema; 
    45     private final Object optionHolder; 
     43    private final Object       optionHolder; 
    4644 
    4745    public <T> OptionParser(T optionHolder) 
    4846    { 
    4947        this.optionHolder = optionHolder; 
    50         schema = newOptionSchema(optionHolder); 
     48        schema = OptionSchema.newOptionSchema(optionHolder); 
    5149    } 
    5250 
     
    160158                argItem.set(optionHolder, currentArg); 
    161159                activatedArgument.add(argItem.getArgumentDescriptor()); 
     160                argIndex++; 
    162161            } 
    163162 
     
    165164    } 
    166165 
    167     public static <OptionBean> OptionSchema newOptionSchema(Class<OptionBean> optionHolderType) 
    168     { 
    169         OptionSchema optionSchema = new OptionSchema(); 
    170  
    171         // traverses through super classes 
    172         for (Class< ? > optionHolderClass = optionHolderType; optionHolderClass != null; optionHolderClass = optionHolderClass 
    173                 .getSuperclass()) 
    174         { 
    175             // looks for bean methods annotated with Option or Argument  
    176             for (Method eachMethod : optionHolderClass.getDeclaredMethods()) 
    177             { 
    178                 if (eachMethod.getAnnotation(Option.class) != null) 
    179                     optionSchema.addOptionItem(eachMethod); 
    180  
    181                 if (eachMethod.getAnnotation(Argument.class) != null) 
    182                     optionSchema.addArgumentItem(eachMethod); 
    183             } 
    184  
    185             // looks for bean fields annotated with Option or Argument  
    186             for (Field f : optionHolderClass.getFields()) 
    187             { 
    188                 if (f.getAnnotation(Option.class) != null) 
    189                     optionSchema.addOptionItem(f); 
    190  
    191                 if (f.getAnnotation(Argument.class) != null) 
    192                     optionSchema.addArgumentItem(f); 
    193             } 
    194         } 
    195  
    196         return optionSchema; 
    197     } 
    198  
    199     public static <OptionHolder> OptionSchema newOptionSchema(OptionHolder optionHolder) 
    200     { 
    201         return newOptionSchema(optionHolder.getClass()); 
    202     } 
    203166} 
  • XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionSchema.java

    r2606 r2607  
    2525package org.xerial.util.shell; 
    2626 
     27import java.io.IOException; 
    2728import java.io.OutputStream; 
     29import java.io.OutputStreamWriter; 
    2830import java.io.PrintWriter; 
     31import java.io.Writer; 
    2932import java.lang.reflect.Field; 
    3033import java.lang.reflect.Method; 
    3134import java.util.ArrayList; 
     35import java.util.Collections; 
     36import java.util.Comparator; 
     37import java.util.List; 
    3238 
    3339import org.xerial.core.XerialError; 
     
    3642import org.xerial.util.Mapper; 
    3743import org.xerial.util.Range; 
    38 import org.xerial.util.Reducer; 
     44import org.xerial.util.StringUtil; 
    3945 
    4046/** 
     
    4854    private final ArrayList<OptionItem>   optionItemList   = new ArrayList<OptionItem>(); 
    4955    private final ArrayList<ArgumentItem> argumentItemList = new ArrayList<ArgumentItem>(); 
    50  
    51     public void printUsage(OutputStream out) 
     56    private Usage                         usage            = null; 
     57 
     58    List<OptionItem> getOptionItemList() 
     59    { 
     60        return optionItemList; 
     61    } 
     62 
     63    List<ArgumentItem> getArgumentItemList() 
     64    { 
     65        return argumentItemList; 
     66    } 
     67 
     68    Usage getUsage() 
     69    { 
     70        return usage; 
     71    } 
     72 
     73    protected static String optionDescription(OptionItem optionItem) 
     74    { 
     75        StringBuilder line = new StringBuilder(); 
     76        Option opt = optionItem.getOption(); 
     77        if (optionItem.hasSymbol()) 
     78        { 
     79            line.append(String.format("-%s", opt.symbol())); 
     80            if (optionItem.hasLongName()) 
     81            { 
     82                line.append(String.format(", --%s", opt.longName())); 
     83 
     84                if (optionItem.needsArgument()) 
     85                    line.append(String.format("=%s", opt.varName())); 
     86            } 
     87            else 
     88            { 
     89                if (optionItem.needsArgument()) 
     90                    line.append(String.format(" ", opt.varName())); 
     91            } 
     92        } 
     93        else if (optionItem.hasLongName()) 
     94        { 
     95            line.append(String.format("    --%s", opt.longName())); 
     96            if (optionItem.needsArgument()) 
     97                line.append(String.format("=%s", opt.varName())); 
     98        } 
     99        else 
     100        { 
     101            throw new XerialError(XerialErrorCode.NO_OPTION, optionItem.toString()); 
     102        } 
     103 
     104        return line.toString(); 
     105 
     106    } 
     107 
     108    protected static String argumentExpression(ArgumentItem argItem) 
     109    { 
     110        StringBuilder line = new StringBuilder(); 
     111 
     112        Argument arg = argItem.getArgumentDescriptor(); 
     113        String format; 
     114 
     115        if (arg.required()) 
     116            format = argItem.takesMultipleArguments() ? "%s ..." : "%s"; 
     117        else 
     118            format = argItem.takesMultipleArguments() ? "[%s ...]" : "[%s]"; 
     119 
     120        String name = arg.name(); 
     121        if (name == null || name.length() <= 0) 
     122            name = "ARG"; 
     123 
     124        line.append(String.format(format, name)); 
     125 
     126        return line.toString(); 
     127    } 
     128 
     129    public void printUsage(OutputStream out) throws IOException 
     130    { 
     131        printUsage(new OutputStreamWriter(out)); 
     132    } 
     133 
     134    public void printUsage(Writer out) throws IOException 
    52135    { 
    53136        PrintWriter writer = new PrintWriter(out); 
    54          
    55         int longestLongOptionNameSize =  
    56             Algorithm.mapReduce(optionItemList,  
    57                     new Mapper<OptionItem, Integer>(){ 
    58                 public Integer map(OptionItem input) 
     137 
     138        // argument list 
     139        Collections.sort(argumentItemList, new Comparator<ArgumentItem>() { 
     140            public int compare(ArgumentItem o1, ArgumentItem o2) 
     141            { 
     142                return o1.getRange().compareTo(o2.getRange()); 
     143            } 
     144        }); 
     145 
     146        List<String> argExpressionList = Algorithm.map(argumentItemList, new Mapper<ArgumentItem, String>() { 
     147            public String map(ArgumentItem input) 
     148            { 
     149                return argumentExpression(input); 
     150            } 
     151        }); 
     152 
     153        // usage information 
     154        if (usage != null) 
     155        { 
     156            writer.print("usage: "); 
     157            writer.print(usage.command()); 
     158            writer.print(" "); 
     159        } 
     160        writer.println(StringUtil.join(argExpressionList, " ")); 
     161 
     162        if (usage != null) 
     163        { 
     164            if (usage.description().length() > 0) 
     165                writer.println("\t" + usage.description()); 
     166        } 
     167 
     168        // option list 
     169        Collections.sort(optionItemList, new Comparator<OptionItem>() { 
     170            public int compare(OptionItem o1, OptionItem o2) 
     171            { 
     172                Option opt1 = o1.getOption(); 
     173                Option opt2 = o2.getOption(); 
     174 
     175                // prefer options that have a short name  
     176                if (o1.hasSymbol()) 
    59177                { 
    60                     Option opt = input.getOption(); 
    61