public <T> void setOption(Option<T> option, T value) { if (!containsOption(option)) { throw new BadConfigurationError( "Option " + option.getKey() + " is not known in group " + prefix); } config.setProperty(getConfigKey(option), value.toString()); }
/** * 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); }
@Test public void settingNewPropertyMustNotAlterExistingSettings() { // Given Config config = new Config(stringMap("a", "1")); // When config.setProperty("b", "2"); // Then assertThat(config.getParams(), is(stringMap("a", "1", "b", "2"))); }
/* Parses a <properties entry="<url>"/> and then reads a property specified by <url> */ private static void setProperties(Config compConf, XmlPullParser parser, Bundle declaringBundle) throws IllegalXMLException, XmlPullParserException, IOException { String entry = null; for (int i = 0; i < parser.getAttributeCount(); i++) { if (parser.getAttributeName(i).equals("entry")) { entry = parser.getAttributeValue(i); } else { unrecognizedAttr(parser, i); // throws exception } } if (entry == null) { missingAttr(parser, "entry"); // throws exception } // read a property-file and adds it contents to conf's properties. Properties dict = new Properties(); String bundleLocation = declaringBundle.getLocation(); JarInputStream jis = new JarInputStream(new URL(bundleLocation).openStream()); ZipEntry zipEntry; while ((zipEntry = jis.getNextEntry()) != null && !zipEntry.getName().equals(entry)) /* skip */ ; if (zipEntry == null) { throw new IOException("Did not find requested entry " + entry); } dict.load(jis); for (Enumeration e = dict.keys(); e.hasMoreElements(); ) { Object key = e.nextElement(); compConf.setProperty((String) key, dict.get(key)); } // done reading file. skip(parser); }
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; }
private static void setProperty(Config compConf, XmlPullParser parser) throws IllegalXMLException, XmlPullParserException, IOException { String type = null; String name = null; Object retval = null; String[] values = null; boolean isArray = true; for (int i = 0; i < parser.getAttributeCount(); i++) { if (parser.getAttributeName(i).equals("name")) { name = parser.getAttributeValue(i); } else if (parser.getAttributeName(i).equals("value")) { values = new String[] {parser.getAttributeValue(i)}; isArray = false; } else if (parser.getAttributeName(i).equals("type")) { for (int j = 0; j < supportedTypes.length; j++) { if (supportedTypes[j].equals(parser.getAttributeValue(i))) { type = supportedTypes[j]; break; } } if (type == null) invalidValue(parser, supportedTypes, i); // throws exception } else { unrecognizedAttr(parser, i); // throws exception } } /* check if required attributes has been set */ if (name == null) { missingAttr(parser, name); // throws Exception } if (isArray) { /*I needed to add 'trim' order to make it pass the OSGi-test.. Isn't that a bit strange? */ String text = parser.nextText().trim(); values = splitwords(text, "\n\r"); for (int i = 0; i < values.length; i++) values[i] = values[i].trim(); } if (type == null || // defaults to string "String".equals(type)) { retval = isArray ? (Object) values : (Object) values[0]; } else if ("Boolean".equals(type)) { boolean[] array = new boolean[values.length]; for (int i = 0; i < array.length; i++) { if ("true".equals(values[i])) array[i] = true; else if ("false".equals(values[i])) array[i] = false; else throw new IllegalXMLException( "Unexpected value \"" + values[i] + "\" of boolean property."); } retval = isArray ? (Object) array : (Object) new Boolean(array[0]); } else if ("Byte".equals(type)) { byte[] array = new byte[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Byte.parseByte(values[i]); } retval = isArray ? (Object) array : (Object) new Byte(array[0]); } else if ("Char".equals(type) || "Character".equals(type)) { char[] array = new char[values.length]; for (int i = 0; i < array.length; i++) { array[i] = values[i].charAt(0); } retval = isArray ? (Object) array : (Object) new Character(array[0]); } else if ("Double".equals(type)) { double[] array = new double[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Double.parseDouble(values[i]); } retval = isArray ? (Object) array : (Object) new Double(array[0]); } else if ("Float".equals(type)) { float[] array = new float[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Float.parseFloat(values[i]); } retval = isArray ? (Object) array : (Object) new Float(array[0]); } else if ("Integer".equals(type)) { int[] array = new int[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Integer.parseInt(values[i]); } retval = isArray ? (Object) array : (Object) new Integer(array[0]); } else if ("Long".equals(type)) { long[] array = new long[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Long.parseLong(values[i]); } retval = isArray ? (Object) array : (Object) new Long(array[0]); } else if ("Short".equals(type)) { short[] array = new short[values.length]; for (int i = 0; i < array.length; i++) { array[i] = Short.parseShort(values[i]); } retval = isArray ? (Object) array : (Object) new Short(array[0]); } else { throw new IllegalXMLException("Did not recognize \"" + type + "\" in property-tag."); } if (isArray) { parser.next(); } else { skip(parser); } compConf.setProperty(name, retval); }