/** * Consume all command line options and turn them into properties.<br> * * <p> * * <p>The arguments are processed as follows: If an argument is of the form "-option" or * "--option", it is considered to be an option. If an argument is an option, the next argument is * considered to be the parameter, unless the option is boolean and the next argument is missing * or an option as well. We add the pair to our properties, consuming both arguments. * * <p>If an argument starts with @, the rest of it is considered as a property file name, which is * then loaded and added to the configuration. The first non-option or the argument string {@code * --} terminates the option list. * * @param args The argument list * @return An array of unconsumed arguments * @throws Config.BadConfigurationException if an argument is malformed. */ public String[] consumeOptions(String[] args) throws Config.BadConfigurationException { int i = 0; while (i < args.length) { if (commands.contains(args[i])) { config.setProperty(getConfigKey(CMD_KEY), args[i]); OptionGroup cmdGroup = subGroups.get(args[i]); return cmdGroup.consumeOptions(Arrays.copyOfRange(args, i + 1, args.length)); } // handle custom config files if (args[i].startsWith("@")) { String filename = args[i].substring(1); try { InputStream is = new BufferedInputStream(new FileInputStream(filename)); config.addProperties(is, prefix); is.close(); } catch (FileNotFoundException e) { throw new Config.BadConfigurationException( "Configuration file '" + filename + "' not found!", e); } catch (IOException e) { throw new Config.BadConfigurationException( "Error reading file '" + filename + "': " + e.getMessage(), e); } i++; continue; } // break if this is not an option argument, return rest if (!args[i].startsWith("-")) break; if ("-".equals(args[i]) || "--".equals(args[i])) { i++; break; } String key = null; if (args[i].charAt(1) == '-') key = args[i].substring(2); else { // for something of form '-<char>', try short option, if (args[i].length() == 2) { Option shortOption = getShortOptionKey(args[i].charAt(1)); if (shortOption != null) { key = shortOption.getKey(); } // for something of form '-<longtext>' try normal key for compatibility } else { key = args[i].substring(1); } } i = parseOption(args, key, i); i++; } return Arrays.copyOfRange(args, i, args.length); }
public Option findOption(String subKey) { int pos = subKey.indexOf('.'); if (pos == -1) { return getOptionSpec(subKey); } OptionGroup group = subGroups.get(subKey.substring(0, pos)); if (group == null) { return getOptionSpec(subKey); } return group.findOption(subKey.substring(pos + 1)); }
/** * Dump configuration of all options for debugging purposes * * @param p a writer to print the options to * @param indent indent used for keys * @return a set of all printed keys */ public Collection<String> printOptions(PrintStream p, int indent) { Set<String> keys = new HashSet<String>(); for (Option<?> o : availableOptions()) { String key = getConfigKey(o); Object val = tryGetOption(o); keys.add(key); Config.printOption(p, indent, key, val); } for (OptionGroup group : subGroups.values()) { keys.addAll(group.printOptions(p, indent)); } return keys; }
public OptionGroup findOptionGroup(String subKey) { int pos = subKey.indexOf('.'); if (pos == -1) { // check if the key specifies a group or a key: if the group is not known, assume its an // option key if (subGroups.containsKey(subKey)) { return subGroups.get(subKey); } else { return this; } } OptionGroup group = subGroups.get(subKey.substring(0, pos)); if (group == null) { // no subgroup by that key, return this group return this; } return group.findOptionGroup(subKey.substring(pos + 1)); }
protected int parseOption(String[] args, String key, int pos) throws BadConfigurationException { Option<?> spec = getOptionSpec(key); if (spec != null) { if (isHidden(spec)) { throw new BadConfigurationException("Invalid option: " + spec); } String val = null; if (pos + 1 < args.length) { String newVal = args[pos + 1]; // allow to set to empty string if ("''".equals(newVal) || "\"\"".equals(newVal)) { newVal = ""; } // TODO handle quoted arguments if (spec.isValue(newVal)) { val = newVal; } } int i = pos; if (spec instanceof BooleanOption && val == null) { val = "true"; } else if (val == null) { throw new BadConfigurationException("Missing argument for option: " + spec); } else { i++; } config.setProperty(getConfigKey(spec), val); return i; } // maybe a boolean option, check for --no-<key> if (key.startsWith("no-")) { spec = getOptionSpec(key.substring(3)); if (isHidden(spec)) { throw new BadConfigurationException("Invalid option: " + spec); } if (spec != null && spec instanceof BooleanOption) { config.setProperty(getConfigKey(spec), "false"); } else if (spec != null) { // unset it config.setProperty(getConfigKey(spec), null); } // else spec == null; } else if (key.contains(".")) { // or maybe a sub-option int j = key.indexOf('.'); OptionGroup group = subGroups.get(key.substring(0, j)); if (group != null) { return group.parseOption(args, key.substring(j + 1), pos); } } if (spec == null) { throw new BadConfigurationException("Unknown option: " + key); } return pos; }