Java tutorial
package org.apache.flex.forks.velocity.runtime.configuration; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Reader; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; import org.apache.commons.collections.ExtendedProperties; /** * This class extends normal Java properties by adding the possibility * to use the same key many times concatenating the value strings * instead of overwriting them. * * <p>The Extended Properties syntax is explained here: * * <ul> * <li> * Each property has the syntax <code>key = value</code> * </li> * <li> * The <i>key</i> may use any character but the equal sign '='. * </li> * <li> * <i>value</i> may be separated on different lines if a backslash * is placed at the end of the line that continues below. * </li> * <li> * If <i>value</i> is a list of strings, each token is separated * by a comma ','. * </li> * <li> * Commas in each token are escaped placing a backslash right before * the comma. * </li> * <li> * If a <i>key</i> is used more than once, the values are appended * like if they were on the same line separated with commas. * </li> * <li> * Blank lines and lines starting with character '#' are skipped. * </li> * <li> * If a property is named "include" (or whatever is defined by * setInclude() and getInclude() and the value of that property is * the full path to a file on disk, that file will be included into * the ConfigurationsRepository. You can also pull in files relative * to the parent configuration file. So if you have something * like the following: * * include = additional.properties * * Then "additional.properties" is expected to be in the same * directory as the parent configuration file. * * Duplicate name values will be replaced, so be careful. * * </li> * </ul> * * <p>Here is an example of a valid extended properties file: * * <p><pre> * # lines starting with # are comments * * # This is the simplest property * key = value * * # A long property may be separated on multiple lines * longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa * * # This is a property with many tokens * tokens_on_a_line = first token, second token * * # This sequence generates exactly the same result * tokens_on_multiple_lines = first token * tokens_on_multiple_lines = second token * * # commas may be escaped in tokens * commas.excaped = Hi\, what'up? * </pre> * * <p><b>NOTE</b>: this class has <b>not</b> been written for * performance nor low memory usage. In fact, it's way slower than it * could be and generates too much memory garbage. But since * performance is not an issue during intialization (and there is not * much time to improve it), I wrote it this way. If you don't like * it, go ahead and tune it up! * * * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> * @author <a href="mailto:daveb@miceda-data">Dave Bryson</a> * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> * @author <a href="mailto:kjohnson@transparent.com>Kent Johnson</a> * @version $Id: Configuration.java,v 1.34 2003/05/04 17:14:37 geirm Exp $ * * @deprecated As of version 1.1, please use ExtendedProperties from * the Jakarta Commons Collections component. */ public class Configuration extends Hashtable { // $$$ GMJ : remove post version 1.1 // intended to help deprecate this class w/o having to modify // the jakarta commons collections class which contains // extended properties. We need this when someone wants to // configure velocity w/ a Configuration : the strategy is simply // to shadow the Configuration with the EP private ExtendedProperties deprecationCrutch = new ExtendedProperties(); /** * Default configurations repository. */ private Configuration defaults; /** * The file connected to this repository (holding comments and * such). * * @serial */ protected String file; /** * Base path of the configuration file used to create * this Configuration object. */ protected String basePath; /** * File separator. */ protected String fileSeparator = System.getProperty("file.separator"); /** * Has this configuration been intialized. */ protected boolean isInitialized = false; /** * This is the name of the property that can point to other * properties file for including other properties files. */ protected static String include = "include"; /** * These are the keys in the order they listed * in the configuration file. This is useful when * you wish to perform operations with configuration * information in a particular order. */ protected ArrayList keysAsListed = new ArrayList(); /** * This class is used to read properties lines. These lines do * not terminate with new-line chars but rather when there is no * backslash sign a the end of the line. This is used to * concatenate multiple lines for readability. */ class PropertiesReader extends LineNumberReader { /** * Constructor. * * @param reader A Reader. */ public PropertiesReader(Reader reader) { super(reader); } /** * Read a property. * * @return A String. * @exception IOException. */ public String readProperty() throws IOException { StringBuffer buffer = new StringBuffer(); try { while (true) { String line = readLine().trim(); if ((line.length() != 0) && (line.charAt(0) != '#')) { if (line.endsWith("\\")) { line = line.substring(0, line.length() - 1); buffer.append(line); } else { buffer.append(line); break; } } } } catch (NullPointerException e) { return null; } return buffer.toString(); } } /** * This class divides into tokens a property value. Token * separator is "," but commas into the property value are escaped * using the backslash in front. */ class PropertiesTokenizer extends StringTokenizer { /** * The property delimiter used while parsing (a comma). */ static final String DELIMITER = ","; /** * Constructor. * * @param string A String. */ public PropertiesTokenizer(String string) { super(string, DELIMITER); } /** * Check whether the object has more tokens. * * @return True if the object has more tokens. */ public boolean hasMoreTokens() { return super.hasMoreTokens(); } /** * Get next token. * * @return A String. */ public String nextToken() { StringBuffer buffer = new StringBuffer(); while (hasMoreTokens()) { String token = super.nextToken(); if (token.endsWith("\\")) { buffer.append(token.substring(0, token.length() - 1)); buffer.append(DELIMITER); } else { buffer.append(token); break; } } return buffer.toString().trim(); } } /** * Creates an empty extended properties object. */ public Configuration() { super(); } /** * Creates and loads the extended properties from the specified * file. * * @param file A String. * @exception IOException. */ public Configuration(String file) throws IOException { this(file, null); } /** * Creates and loads the extended properties from the specified * file. * * @param file A String. * @exception IOException. */ public Configuration(String file, String defaultFile) throws IOException { this.file = file; basePath = new File(file).getAbsolutePath(); basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1); this.load(new FileInputStream(file)); if (defaultFile != null) { defaults = new Configuration(defaultFile); } } /** * Private initializer method that sets up the generic * resources. * * @exception IOException, if there was an I/O problem. */ private void init(Configuration exp) throws IOException { isInitialized = true; } /** * Indicate to client code whether property * resources have been initialized or not. */ public boolean isInitialized() { return isInitialized; } /** * Gets the property value for including other properties files. * By default it is "include". * * @return A String. */ public String getInclude() { return Configuration.include; } /** * Sets the property value for including other properties files. * By default it is "include". * * @param inc A String. */ public void setInclude(String inc) { Configuration.include = inc; } /** * Load the properties from the given input stream. * * @param input An InputStream. * @exception IOException. */ public synchronized void load(InputStream input) throws IOException { PropertiesReader reader = new PropertiesReader(new InputStreamReader(input)); try { while (true) { String line = reader.readProperty(); int equalSign = line.indexOf('='); if (equalSign > 0) { String key = line.substring(0, equalSign).trim(); String value = line.substring(equalSign + 1).trim(); /* * Configure produces lines like this ... just * ignore them. */ if ("".equals(value)) continue; if (getInclude() != null && key.equalsIgnoreCase(getInclude())) { /* * Recursively load properties files. */ File file = null; if (value.startsWith(fileSeparator)) { /* * We have an absolute path so we'll * use this. */ file = new File(value); } else { /* * We have a relative path, and we have * two possible forms here. If we have the * "./" form then just strip that off first * before continuing. */ if (value.startsWith("." + fileSeparator)) { value = value.substring(2); } file = new File(basePath + value); } if (file != null && file.exists() && file.canRead()) { load(new FileInputStream(file)); } } else { addProperty(key, value); //setProperty(key,value); } } } } catch (NullPointerException e) { /* * Should happen only when EOF is reached. */ return; } } /** * Gets a property from the configuration. * * @param key property to retrieve * @return value as object. Will return user value if exists, * if not then default value if exists, otherwise null */ public Object getProperty(String key) { /* * first, try to get from the 'user value' store */ Object o = this.get(key); if (o == null) { /* * if there isn't a value there, get it from the * defaults if we have them */ if (defaults != null) { o = defaults.get(key); } } return o; } /** * Add a property to the configuration. If it already * exists then the value stated here will be added * to the configuration entry. For example, if * * resource.loader = file * * is already present in the configuration and you * * addProperty("resource.loader", "classpath") * * Then you will end up with a Vector like the * following: * * ["file", "classpath"] * * @param String key * @param String value */ //public void setProperty(String key, Object token) public void addProperty(String key, Object token) { // $$$ GMJ : remove after 1.1 release // for deprecation help deprecationCrutch.addProperty(key, token); Object o = this.get(key); /* * $$$ GMJ * FIXME : post 1.0 release, we need to not assume * that a scalar is a String - it can be an Object * so we should make a little vector-like class * say, Foo that wraps (not extends Vector), * so we can do things like * if ( !( o instanceof Foo) ) * so we know it's our 'vector' container * * This applies throughout */ if (o instanceof String) { Vector v = new Vector(2); v.addElement(o); v.addElement(token); put(key, v); } else if (o instanceof Vector) { ((Vector) o).addElement(token); } else { /* * This is the first time that we have seen * request to place an object in the * configuration with the key 'key'. So * we just want to place it directly into * the configuration ... but we are going to * make a special exception for String objects * that contain "," characters. We will take * CSV lists and turn the list into a vector of * Strings before placing it in the configuration. * This is a concession for Properties and the * like that cannot parse multiple same key * values. */ if (token instanceof String && ((String) token).indexOf(PropertiesTokenizer.DELIMITER) > 0) { PropertiesTokenizer tokenizer = new PropertiesTokenizer((String) token); while (tokenizer.hasMoreTokens()) { String value = tokenizer.nextToken(); /* * we know this is a string, so make sure it * just goes in rather than risking vectorization * if it contains an escaped comma */ addStringProperty(key, value); } } else { /* * We want to keep track of the order the keys * are parsed, or dynamically entered into * the configuration. So when we see a key * for the first time we will place it in * an ArrayList so that if a client class needs * to perform operations with configuration * in a definite order it will be possible. */ /* * safety check */ if (!containsKey(key)) { keysAsListed.add(key); } /* * and the value */ put(key, token); } } } /** * Sets a string property w/o checking for commas - used * internally when a property has been broken up into * strings that could contain escaped commas to prevent * the inadvertant vectorization. * * Thanks to Leon Messerschmidt for this one. * */ private void addStringProperty(String key, String token) { Object o = this.get(key); /* * $$$ GMJ * FIXME : post 1.0 release, we need to not assume * that a scalar is a String - it can be an Object * so we should make a little vector-like class * say, Foo that wraps (not extends Vector), * so we can do things like * if ( !( o instanceof Foo) ) * so we know it's our 'vector' container * * This applies throughout */ /* * do the usual thing - if we have a value and * it's scalar, make a vector, otherwise add * to the vector */ if (o instanceof String) { Vector v = new Vector(2); v.addElement(o); v.addElement(token); put(key, v); } else if (o instanceof Vector) { ((Vector) o).addElement(token); } else { if (!containsKey(key)) { keysAsListed.add(key); } put(key, token); } } /** * Set a property, this will replace any previously * set values. Set values is implicitly a call * to clearProperty(key), addProperty(key,value). * * @param String key * @param String value */ public void setProperty(String key, Object value) { clearProperty(key); addProperty(key, value); } /** * Save the properties to the given outputstream. * * @param output An OutputStream. * @param header A String. * @exception IOException. */ public synchronized void save(OutputStream output, String Header) throws IOException { if (output != null) { PrintWriter theWrtr = new PrintWriter(output); if (Header != null) { theWrtr.println(Header); } Enumeration theKeys = keys(); while (theKeys.hasMoreElements()) { String key = (String) theKeys.nextElement(); Object value = get((Object) key); if (value != null) { if (value instanceof String) { StringBuffer currentOutput = new StringBuffer(); currentOutput.append(key); currentOutput.append("="); currentOutput.append((String) value); theWrtr.println(currentOutput.toString()); } else if (value instanceof Vector) { Vector values = (Vector) value; Enumeration valuesEnum = values.elements(); while (valuesEnum.hasMoreElements()) { String currentElement = (String) valuesEnum.nextElement(); StringBuffer currentOutput = new StringBuffer(); currentOutput.append(key); currentOutput.append("="); currentOutput.append(currentElement); theWrtr.println(currentOutput.toString()); } } } theWrtr.println(); theWrtr.flush(); } } } /** * Combines an existing Hashtable with this Hashtable. * * Warning: It will overwrite previous entries without warning. * * @param Configuration */ public void combine(Configuration c) { for (Iterator i = c.getKeys(); i.hasNext();) { String key = (String) i.next(); //clearProperty(key); setProperty(key, c.get(key)); } } /** * Clear a property in the configuration. * * @param String key to remove along with corresponding value. */ public void clearProperty(String key) { // $$$ GMJ : remove after 1.1 release // for deprecation help deprecationCrutch.clearProperty(key); if (containsKey(key)) { /* * we also need to rebuild the keysAsListed or else * things get *very* confusing */ for (int i = 0; i < keysAsListed.size(); i++) { if (((String) keysAsListed.get(i)).equals(key)) { keysAsListed.remove(i); break; } } remove(key); } } /** * Get the list of the keys contained in the configuration * repository. * * @return An Iterator. */ public Iterator getKeys() { return keysAsListed.iterator(); } /** * Get the list of the keys contained in the configuration * repository that match the specified prefix. * * @param prefix The prefix to test against. * @return An Iterator of keys that match the prefix. */ public Iterator getKeys(String prefix) { Iterator keys = getKeys(); ArrayList matchingKeys = new ArrayList(); while (keys.hasNext()) { Object key = keys.next(); if (key instanceof String && ((String) key).startsWith(prefix)) { matchingKeys.add(key); } } return matchingKeys.iterator(); } /** * Create a Configurations object that is a subset * of this one. Take into account duplicate keys * by using the setProperty() in Configuration. * * @param String prefix */ public Configuration subset(String prefix) { Configuration c = new Configuration(); Iterator keys = getKeys(); boolean validSubset = false; while (keys.hasNext()) { Object key = keys.next(); if (key instanceof String && ((String) key).startsWith(prefix)) { if (!validSubset) { validSubset = true; } String newKey = null; /* * Check to make sure that c.subset(prefix) doesn't * blow up when there is only a single property * with the key prefix. This is not a useful * subset but it is a valid subset. */ if (((String) key).length() == prefix.length()) { newKey = prefix; } else { newKey = ((String) key).substring(prefix.length() + 1); } /* * Make sure to use the setProperty() method and not * just put(). setProperty() takes care of catching * all the keys in the order they appear in a * properties files or the order they are set * dynamically. */ c.setProperty(newKey, get(key)); } } if (validSubset) { return c; } else { return null; } } /** * Display the configuration for debugging * purposes. */ public void display() { Iterator i = getKeys(); while (i.hasNext()) { String key = (String) i.next(); Object value = get(key); System.out.println(key + " => " + value); } } /** * Get a string associated with the given configuration key. * * @param key The configuration key. * @return The associated string. * @exception ClassCastException is thrown if the key maps to an * object that is not a String. */ public String getString(String key) { return getString(key, null); } /** * Get a string associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated string if key is found, * default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a String. */ public String getString(String key, String defaultValue) { Object value = get(key); if (value instanceof String) { return (String) value; } else if (value == null) { if (defaults != null) { return defaults.getString(key, defaultValue); } else { return defaultValue; } } else if (value instanceof Vector) { return (String) ((Vector) value).get(0); } else { throw new ClassCastException('\'' + key + "' doesn't map to a String object"); } } /** * Get a list of properties associated with the given * configuration key. * * @param key The configuration key. * @return The associated properties if key is found. * @exception ClassCastException is thrown if the key maps to an * object that is not a String/Vector. * @exception IllegalArgumentException if one of the tokens is * malformed (does not contain an equals sign). */ public Properties getProperties(String key) { return getProperties(key, new Properties()); } /** * Get a list of properties associated with the given * configuration key. * * @param key The configuration key. * @return The associated properties if key is found. * @exception ClassCastException is thrown if the key maps to an * object that is not a String/Vector. * @exception IllegalArgumentException if one of the tokens is * malformed (does not contain an equals sign). */ public Properties getProperties(String key, Properties defaults) { /* * Grab an array of the tokens for this key. */ String[] tokens = getStringArray(key); /* * Each token is of the form 'key=value'. */ Properties props = new Properties(defaults); for (int i = 0; i < tokens.length; i++) { String token = tokens[i]; int equalSign = token.indexOf('='); if (equalSign > 0) { String pkey = token.substring(0, equalSign).trim(); String pvalue = token.substring(equalSign + 1).trim(); props.put(pkey, pvalue); } else { throw new IllegalArgumentException('\'' + token + "' does not contain " + "an equals sign"); } } return props; } /** * Get an array of strings associated with the given configuration * key. * * @param key The configuration key. * @return The associated string array if key is found. * @exception ClassCastException is thrown if the key maps to an * object that is not a String/Vector. */ public String[] getStringArray(String key) { Object value = get(key); // What's your vector, Victor? Vector vector; if (value instanceof String) { vector = new Vector(1); vector.addElement(value); } else if (value instanceof Vector) { vector = (Vector) value; } else if (value == null) { if (defaults != null) { return defaults.getStringArray(key); } else { return new String[0]; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a String/Vector object"); } String[] tokens = new String[vector.size()]; for (int i = 0; i < tokens.length; i++) { tokens[i] = (String) vector.elementAt(i); } return tokens; } /** * Get a Vector of strings associated with the given configuration * key. * * @param key The configuration key. * @return The associated Vector. * @exception ClassCastException is thrown if the key maps to an * object that is not a Vector. */ public Vector getVector(String key) { return getVector(key, null); } /** * Get a Vector of strings associated with the given configuration * key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated Vector. * @exception ClassCastException is thrown if the key maps to an * object that is not a Vector. */ public Vector getVector(String key, Vector defaultValue) { Object value = get(key); if (value instanceof Vector) { return (Vector) value; } else if (value instanceof String) { Vector v = new Vector(1); v.addElement((String) value); put(key, v); return v; } else if (value == null) { if (defaults != null) { return defaults.getVector(key, defaultValue); } else { return ((defaultValue == null) ? new Vector() : defaultValue); } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Vector object"); } } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @return The associated boolean. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public boolean getBoolean(String key) { Boolean b = getBoolean(key, (Boolean) null); if (b != null) { return b.booleanValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated boolean. * @exception ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public boolean getBoolean(String key, boolean defaultValue) { return getBoolean(key, new Boolean(defaultValue)).booleanValue(); } /** * Get a boolean associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated boolean if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Boolean. */ public Boolean getBoolean(String key, Boolean defaultValue) { Object value = get(key); if (value instanceof Boolean) { return (Boolean) value; } else if (value instanceof String) { String s = testBoolean((String) value); Boolean b = new Boolean(s); put(key, b); return b; } else if (value == null) { if (defaults != null) { return defaults.getBoolean(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Boolean object"); } } /** * Test whether the string represent by value maps to a boolean * value or not. We will allow <code>true</code>, <code>on</code>, * and <code>yes</code> for a <code>true</code> boolean value, and * <code>false</code>, <code>off</code>, and <code>no</code> for * <code>false</code> boolean values. Case of value to test for * boolean status is ignored. * * @param String The value to test for boolean state. * @return <code>true</code> or <code>false</code> if the supplied * text maps to a boolean value, or <code>null</code> otherwise. */ public String testBoolean(String value) { String s = ((String) value).toLowerCase(); if (s.equals("true") || s.equals("on") || s.equals("yes")) { return "true"; } else if (s.equals("false") || s.equals("off") || s.equals("no")) { return "false"; } else { return null; } } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @return The associated byte. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Byte. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public byte getByte(String key) { Byte b = getByte(key, null); if (b != null) { return b.byteValue(); } else { throw new NoSuchElementException('\'' + key + " doesn't map to an existing object"); } } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated byte. * @exception ClassCastException is thrown if the key maps to an * object that is not a Byte. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public byte getByte(String key, byte defaultValue) { return getByte(key, new Byte(defaultValue)).byteValue(); } /** * Get a byte associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated byte if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Byte. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Byte getByte(String key, Byte defaultValue) { Object value = get(key); if (value instanceof Byte) { return (Byte) value; } else if (value instanceof String) { Byte b = new Byte((String) value); put(key, b); return b; } else if (value == null) { if (defaults != null) { return defaults.getByte(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Byte object"); } } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @return The associated short. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Short. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public short getShort(String key) { Short s = getShort(key, null); if (s != null) { return s.shortValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated short. * @exception ClassCastException is thrown if the key maps to an * object that is not a Short. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public short getShort(String key, short defaultValue) { return getShort(key, new Short(defaultValue)).shortValue(); } /** * Get a short associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated short if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Short. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Short getShort(String key, Short defaultValue) { Object value = get(key); if (value instanceof Short) { return (Short) value; } else if (value instanceof String) { Short s = new Short((String) value); put(key, s); return s; } else if (value == null) { if (defaults != null) { return defaults.getShort(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Short object"); } } /** * The purpose of this method is to get the configuration resource * with the given name as an integer. * * @param name The resource name. * @return The value of the resource as an integer. */ public int getInt(String name) { return getInteger(name); } /** * The purpose of this method is to get the configuration resource * with the given name as an integer, or a default value. * * @param name The resource name * @param def The default value of the resource. * @return The value of the resource as an integer. */ public int getInt(String name, int def) { return getInteger(name, def); } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @return The associated int. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Integer. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public int getInteger(String key) { Integer i = getInteger(key, null); if (i != null) { return i.intValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated int. * @exception ClassCastException is thrown if the key maps to an * object that is not a Integer. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public int getInteger(String key, int defaultValue) { Integer i = getInteger(key, null); if (i == null) { return defaultValue; } return i.intValue(); } /** * Get a int associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated int if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Integer. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Integer getInteger(String key, Integer defaultValue) { Object value = get(key); if (value instanceof Integer) { return (Integer) value; } else if (value instanceof String) { Integer i = new Integer((String) value); put(key, i); return i; } else if (value == null) { if (defaults != null) { return defaults.getInteger(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Integer object"); } } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @return The associated long. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Long. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public long getLong(String key) { Long l = getLong(key, null); if (l != null) { return l.longValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated long. * @exception ClassCastException is thrown if the key maps to an * object that is not a Long. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public long getLong(String key, long defaultValue) { return getLong(key, new Long(defaultValue)).longValue(); } /** * Get a long associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated long if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Long. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Long getLong(String key, Long defaultValue) { Object value = get(key); if (value instanceof Long) { return (Long) value; } else if (value instanceof String) { Long l = new Long((String) value); put(key, l); return l; } else if (value == null) { if (defaults != null) { return defaults.getLong(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Long object"); } } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @return The associated float. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Float. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public float getFloat(String key) { Float f = getFloat(key, null); if (f != null) { return f.floatValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated float. * @exception ClassCastException is thrown if the key maps to an * object that is not a Float. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public float getFloat(String key, float defaultValue) { return getFloat(key, new Float(defaultValue)).floatValue(); } /** * Get a float associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated float if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Float. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Float getFloat(String key, Float defaultValue) { Object value = get(key); if (value instanceof Float) { return (Float) value; } else if (value instanceof String) { Float f = new Float((String) value); put(key, f); return f; } else if (value == null) { if (defaults != null) { return defaults.getFloat(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Float object"); } } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @return The associated double. * @exception NoSuchElementException is thrown if the key doesn't * map to an existing object. * @exception ClassCastException is thrown if the key maps to an * object that is not a Double. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public double getDouble(String key) { Double d = getDouble(key, null); if (d != null) { return d.doubleValue(); } else { throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); } } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated double. * @exception ClassCastException is thrown if the key maps to an * object that is not a Double. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public double getDouble(String key, double defaultValue) { return getDouble(key, new Double(defaultValue)).doubleValue(); } /** * Get a double associated with the given configuration key. * * @param key The configuration key. * @param defaultValue The default value. * @return The associated double if key is found and has valid * format, default value otherwise. * @exception ClassCastException is thrown if the key maps to an * object that is not a Double. * @exception NumberFormatException is thrown if the value mapped * by the key has not a valid number format. */ public Double getDouble(String key, Double defaultValue) { Object value = get(key); if (value instanceof Double) { return (Double) value; } else if (value instanceof String) { Double d = new Double((String) value); put(key, d); return d; } else if (value == null) { if (defaults != null) { return defaults.getDouble(key, defaultValue); } else { return defaultValue; } } else { throw new ClassCastException('\'' + key + "' doesn't map to a Double object"); } } /** * Convert a standard properties class into a configuration * class. * * @param Properties properties object to convert into * a Configuration object. * * @return Configuration configuration created from the * properties object. */ public static Configuration convertProperties(Properties p) { Configuration c = new Configuration(); for (Enumeration e = p.keys(); e.hasMoreElements();) { String s = (String) e.nextElement(); c.setProperty(s, p.getProperty(s)); } return c; } /** * <p> * Routine intended for deprecation period only * as we switch from using the Configuration * class in Velocity to the Jakarta Commons * ExtendedProperties * </p> * <p> * Do not use this for general use. It will disappear * </p> * @return ExtendedProperties containing data of Configuration * * @deprecated Do not use. For deprecation assistance only. */ public ExtendedProperties getExtendedProperties() { return deprecationCrutch; } }