Changeset 2607
- Timestamp:
- 10/29/08 16:51:15 (2 months ago)
- Location:
- XerialJ/trunk/xerial-core/src
- Files:
-
- 2 added
- 14 modified
-
main/java/org/xerial/core/XerialErrorCode.java (modified) (1 diff)
-
main/java/org/xerial/util/Algorithm.java (modified) (1 diff)
-
main/java/org/xerial/util/Range.java (modified) (2 diffs)
-
main/java/org/xerial/util/log/Logger.java (modified) (6 diffs)
-
main/java/org/xerial/util/shell/Argument.java (modified) (1 diff)
-
main/java/org/xerial/util/shell/ArgumentItem.java (modified) (2 diffs)
-
main/java/org/xerial/util/shell/Option.java (modified) (2 diffs)
-
main/java/org/xerial/util/shell/OptionItem.java (modified) (5 diffs)
-
main/java/org/xerial/util/shell/OptionParser.java (modified) (4 diffs)
-
main/java/org/xerial/util/shell/OptionSchema.java (modified) (6 diffs)
-
main/java/org/xerial/util/shell/OptionSetterViaField.java (modified) (2 diffs)
-
main/java/org/xerial/util/shell/OptionSetterViaMethod.java (modified) (4 diffs)
-
main/java/org/xerial/util/shell/Usage.java (added)
-
test/java/org/xerial/util/shell/OptionParserTest.java (modified) (3 diffs)
-
test/java/org/xerial/util/shell/OptionSchemaTest.java (added)
-
test/java/org/xerial/util/shell/OptionTest.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
XerialJ/trunk/xerial-core/src/main/java/org/xerial/core/XerialErrorCode.java
r2606 r2607 39 39 // option parser error 40 40 DUPLICATE_OPTION, 41 41 NO_OPTION, 42 NO_USAGE_ANNOTATION, 42 43 // type 43 MISSING_TYPE_PARAMETER 44 MISSING_TYPE_PARAMETER, 44 45 45 46 ; -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/Algorithm.java
r2605 r2607 144 144 } 145 145 146 return null;146 return result; 147 147 } 148 148 -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/Range.java
r2605 r2607 30 30 * @author leo 31 31 */ 32 public class Range 32 public class Range implements Comparable<Range> 33 33 { 34 34 public final int start; … … 52 52 } 53 53 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 54 60 } -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/log/Logger.java
r2073 r2607 39 39 public class Logger 40 40 { 41 private static String[] logPrefix= { "", // ALL41 private static String[] logPrefix = { "", // ALL 42 42 "\033[0;32m", // TRACE 43 43 "", // DEBUG … … 47 47 "\033[1;31m", // FATAL 48 48 "", // 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(); 60 60 61 61 static … … 67 67 68 68 String logLevel = System.getProperty("xerial.loglevel"); 69 if (logLevel != null)69 if (logLevel != null) 70 70 { 71 71 _rootLogger.setLogLevel(logLevel); … … 74 74 { 75 75 logLevel = System.getProperty("loglevel"); 76 if (logLevel != null)76 if (logLevel != null) 77 77 { 78 78 _rootLogger.setLogLevel(logLevel); 79 79 } 80 80 } 81 82 81 82 String useColor = System.getProperty("color"); 83 if (useColor != null) 84 _rootLogger._emitEscapeSequence = Boolean.parseBoolean(useColor); 85 83 86 String loggerConfigFile = System.getProperty("log.config"); 84 87 if (loggerConfigFile != null) … … 152 155 Logger newLogger = new Logger(fullTypeName); 153 156 _loggerHolder.put(fullTypeName, newLogger); 157 newLogger._emitEscapeSequence = _rootLogger._emitEscapeSequence; 154 158 return newLogger; 155 159 } … … 168 172 public static void configure(Reader configurationFileReader) throws IOException 169 173 { 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 configuration194 String parameter = lhs[1];195 if(parameter.equals("color"))196 {197 logger.setColor(Boolean.parseBoolean(value));198 }199 else200 {201 System.err.println("unknown configuration parameter: " + parameter);202 }203 }204 else205 {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 } 209 213 } 210 214 -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/Argument.java
r2605 r2607 41 41 42 42 /** 43 * descriptionof the argument43 * name of the argument 44 44 */ 45 String description() default "";45 String name() default ""; 46 46 47 47 /** 48 * This argument is required 48 * This argument is required or not 49 49 */ 50 boolean required() default false;50 boolean required() default true; 51 51 52 52 /** -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/ArgumentItem.java
r2605 r2607 28 28 import java.lang.reflect.Method; 29 29 30 import org.xerial.util.Range; 30 31 import org.xerial.util.bean.TypeInformation; 31 32 import org.xerial.util.cui.OptionParserException; … … 83 84 } 84 85 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 85 98 public void set(Object bean, Object value) throws OptionParserException 86 99 { -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/Option.java
r2603 r2607 43 43 44 44 /** 45 * Name of the option. If the nameis "h", it handles option "-h"45 * symbol of the option. If the symbol is "h", it handles option "-h" 46 46 * 47 47 */ 48 String name();48 String symbol() default ""; 49 49 50 50 /** … … 56 56 57 57 /** 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 /** 58 64 * Description of the option, used to generate a help message of the 59 65 * command-line options 60 66 */ 61 67 String description() default ""; 62 68 63 69 } -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionItem.java
r2603 r2607 40 40 public class OptionItem 41 41 { 42 private final Option optionDescriptor;42 private final Option optionDescriptor; 43 43 private final OptionSetter optionSetter; 44 44 45 45 public OptionItem(Method method) 46 46 { 47 47 Option option = method.getAnnotation(Option.class); 48 if (option == null)48 if (option == null) 49 49 throw new IllegalArgumentException(method + " is not an option item"); 50 50 … … 52 52 this.optionSetter = new OptionSetterViaMethod(method); 53 53 } 54 54 55 55 public OptionItem(Field field) 56 56 { 57 57 Option option = field.getAnnotation(Option.class); 58 if (option == null)58 if (option == null) 59 59 throw new IllegalArgumentException(field + " is not an option item"); 60 60 … … 62 62 this.optionSetter = new OptionSetterViaField(field); 63 63 } 64 65 64 66 65 @Override … … 81 80 return optionDescriptor.hashCode(); 82 81 } 83 82 84 83 public boolean needsArgument() 85 84 { 86 85 return optionSetter.takesArgument(); 87 86 } 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 89 98 public Option getOption() 90 99 { 91 return optionDescriptor; 100 return optionDescriptor; 92 101 } 93 102 94 103 public void setOption(Object bean, String value) throws OptionParserException 95 104 { 96 Class< ?> optionType = optionSetter.getOptionDataType();105 Class< ? > optionType = optionSetter.getOptionDataType(); 97 106 try 98 107 { … … 104 113 throw new OptionParserException(ShellError.WRONG_DATA_TYPE, e); 105 114 } 106 115 107 116 } 108 109 117 110 118 } -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionParser.java
r2606 r2607 26 26 27 27 import java.io.OutputStream; 28 import java.lang.reflect.Field;29 import java.lang.reflect.Method;30 28 import java.util.HashSet; 31 29 … … 38 36 * @author leo 39 37 * 40 */ 38 */ 41 39 public class OptionParser 42 40 { 43 41 private boolean ignoreUnknownOption = false; 44 42 private final OptionSchema schema; 45 private final Object optionHolder;43 private final Object optionHolder; 46 44 47 45 public <T> OptionParser(T optionHolder) 48 46 { 49 47 this.optionHolder = optionHolder; 50 schema = newOptionSchema(optionHolder);48 schema = OptionSchema.newOptionSchema(optionHolder); 51 49 } 52 50 … … 160 158 argItem.set(optionHolder, currentArg); 161 159 activatedArgument.add(argItem.getArgumentDescriptor()); 160 argIndex++; 162 161 } 163 162 … … 165 164 } 166 165 167 public static <OptionBean> OptionSchema newOptionSchema(Class<OptionBean> optionHolderType)168 {169 OptionSchema optionSchema = new OptionSchema();170 171 // traverses through super classes172 for (Class< ? > optionHolderClass = optionHolderType; optionHolderClass != null; optionHolderClass = optionHolderClass173 .getSuperclass())174 {175 // looks for bean methods annotated with Option or Argument176 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 Argument186 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 }203 166 } -
XerialJ/trunk/xerial-core/src/main/java/org/xerial/util/shell/OptionSchema.java
r2606 r2607 25 25 package org.xerial.util.shell; 26 26 27 import java.io.IOException; 27 28 import java.io.OutputStream; 29 import java.io.OutputStreamWriter; 28 30 import java.io.PrintWriter; 31 import java.io.Writer; 29 32 import java.lang.reflect.Field; 30 33 import java.lang.reflect.Method; 31 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import java.util.Comparator; 37 import java.util.List; 32 38 33 39 import org.xerial.core.XerialError; … … 36 42 import org.xerial.util.Mapper; 37 43 import org.xerial.util.Range; 38 import org.xerial.util. Reducer;44 import org.xerial.util.StringUtil; 39 45 40 46 /** … … 48 54 private final ArrayList<OptionItem> optionItemList = new ArrayList<OptionItem>(); 49 55 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 52 135 { 53 136 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()) 59 177 { 60 Option opt = input.getOption(); 61  
