You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by mp...@apache.org on 2002/02/04 12:31:34 UTC
cvs commit: jakarta-turbine-stratum/src/java/org/apache/stratum/configuration BaseConfiguration.java package.html Configuration.java PropertiesConfiguration.java XmlConfiguration.java AbstractConfiguration.java
mpoeschl 02/02/04 03:31:34
Modified: src/java/org/apache/stratum/configuration Configuration.java
PropertiesConfiguration.java XmlConfiguration.java
Added: src/java/org/apache/stratum/configuration
BaseConfiguration.java package.html
Removed: src/java/org/apache/stratum/configuration
AbstractConfiguration.java
Log:
new configuration package based on ExtendedProperties
Revision Changes Path
1.2 +97 -19 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/Configuration.java
Index: Configuration.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/Configuration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Configuration.java 5 Jan 2002 03:22:59 -0000 1.1
+++ Configuration.java 4 Feb 2002 11:31:34 -0000 1.2
@@ -1,29 +1,107 @@
package org.apache.stratum.configuration;
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache Turbine" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache Turbine", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
import java.util.Iterator;
+import java.util.Properties;
import java.util.Vector;
-// The general idea here is to make something that will work like
-// our extended properties and be compatible with the preferences
-// API if at all possible.
-
+/**
+ * Configuration interface.
+ * The general idea here is to make something that will work like our
+ * extended properties and be compatible with the preferences API if at all
+ * possible.
+ *
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
+ * @version $Id: Configuration.java,v 1.2 2002/02/04 11:31:34 mpoeschl Exp $
+ */
public interface Configuration
-{
- Vector getVector(String key);
- String getString(String key);
+{
+ Configuration subset(String prefix);
+
+ boolean isEmpty();
+ boolean containsKey(String key);
+ void addProperty(String key, Object value);
+ void setProperty(String key, Object value);
+ void clearProperty(String key);
Iterator getKeys(String key);
- int getInt(String key, int defaultValue);
-
+ Iterator getKeys();
+ Properties getProperties();
+
// We probably want to at least try to be compatible with
// the new preferences API.
-
- // Iterator getKeys()
-
- // byte getByte(String key);
- // short getShort(String key);
- // long getLong(String key);
-
- // float getFloat(String key);
- // boolean getBoolean(String key);
- // double getDouble(String key);
+
+ boolean getBoolean(String key);
+ boolean getBoolean(String key, boolean defaultValue);
+// Boolean getBoolean(String key, Boolean defaultValue);
+ byte getByte(String key);
+ double getDouble(String key);
+ float getFloat(String key);
+ int getInt(String key, int defaultValue);
+ Integer getInteger(String key, Integer defaultValue);
+ long getLong(String key);
+ long getLong(String key, long defaultValue);
+// Long getLong(String key, Long defaultValue);
+ short getShort(String key);
+ String getString(String key);
+ String getString(String key, String defaultValue);
+ String[] getStringArray(String key);
+ Vector getVector(String key);
+ Vector getVector(String key, Vector defaultValue);
+
+
+
}
1.2 +402 -3 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/PropertiesConfiguration.java
Index: PropertiesConfiguration.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/PropertiesConfiguration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PropertiesConfiguration.java 18 Jan 2002 22:26:05 -0000 1.1
+++ PropertiesConfiguration.java 4 Feb 2002 11:31:34 -0000 1.2
@@ -1,9 +1,408 @@
package org.apache.stratum.configuration;
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache Turbine" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache Turbine", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
// Borrow a lot of the code from ExtendedProperties, but leave
// the resource handling to the resources package.
-public class PropertiesConfiguration
- extends AbstractConfiguration
-{
+/**
+ * loads the configuration from a properties file. <p>
+ *
+ * <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>
+ *
+ * @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: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>
+ * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ * @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a>
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
+ * @version $Id: PropertiesConfiguration.java,v 1.2 2002/02/04 11:31:34 mpoeschl Exp $
+ */
+public class PropertiesConfiguration extends BaseConfiguration
+{
+
+ /** File separator. */
+ protected String fileSeparator = System.getProperty("file.separator");
+
+ /**
+ * Base path of the configuration file used to create this Configuration
+ * object.
+ */
+ protected String basePath;
+
+ /**
+ * This is the name of the property that can point to other
+ * properties file for including other properties files.
+ */
+ protected static String include = "include";
+
+
+ /**
+ * Creates an empty Configuration
+ */
+ public PropertiesConfiguration()
+ {
+ }
+
+ /**
+ * Creates and loads the extended properties from the specified file.
+ *
+ * @param file A String.
+ * @exception IOException.
+ */
+ public PropertiesConfiguration(String file) throws IOException
+ {
+ this(file, null);
+ }
+
+ /**
+ * Creates and loads the extended properties from the specified file.
+ *
+ * @param file A String.
+ * @exception IOException.
+ */
+ public PropertiesConfiguration(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 = (BaseConfiguration)
+ new PropertiesConfiguration(defaultFile);
+ }
+ }
+
+ /**
+ * Load the properties from the given input stream.
+ *
+ * @param input An InputStream.
+ * @exception IOException.
+ */
+ public void load(InputStream input) throws IOException
+ {
+ load(input, null);
+ }
+
+ /**
+ * Load the properties from the given input stream and using the specified
+ * encoding.
+ *
+ * @param input An InputStream.
+ * @param enc An encoding.
+ * @exception IOException.
+ */
+ public synchronized void load(InputStream input, String enc)
+ throws IOException
+ {
+ PropertiesReader reader = null;
+ if (enc != null)
+ {
+ try
+ {
+ reader =
+ new PropertiesReader(new InputStreamReader(input, enc));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ // Get one with the default encoding...
+ }
+ }
+
+ if (reader == null)
+ {
+ 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);
+ }
+ }
+ }
+ }
+ catch (NullPointerException e)
+ {
+ /*
+ * Should happen only when EOF is reached.
+ */
+ return;
+ }
+ }
+
+ /**
+ * Gets the property value for including other properties files.
+ * By default it is "include".
+ *
+ * @return A String.
+ */
+ public String getInclude()
+ {
+ return this.include;
+ }
+
+ /**
+ * Sets the property value for including other properties files.
+ * By default it is "include".
+ *
+ * @param inc A String.
+ */
+ public void setInclude(String inc)
+ {
+ this.include = inc;
+ }
+
+
+ /**
+ * 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();
+ }
+ } // class PropertiesReader
+
+
}
1.2 +3 -3 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/XmlConfiguration.java
Index: XmlConfiguration.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/XmlConfiguration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XmlConfiguration.java 18 Jan 2002 22:26:05 -0000 1.1
+++ XmlConfiguration.java 4 Feb 2002 11:31:34 -0000 1.2
@@ -1,5 +1,6 @@
package org.apache.stratum.configuration;
+
/**
* <configuration>
* <entries>
@@ -11,7 +12,6 @@
* </configuration>
*
*/
-public class XmlConfiguration
- extends AbstractConfiguration
-{
+public class XmlConfiguration extends BaseConfiguration
+{
}
1.1 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/BaseConfiguration.java
Index: BaseConfiguration.java
===================================================================
package org.apache.stratum.configuration;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* Basic configuration classe. Stores the configuration data but does not
* provide any load or save functions. If you want to load your Configuration
* from a file use PropertiesConfiguration or XmlConfiguration.
*
* 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.
*
* @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: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>
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
* @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a>
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
* @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
* @version $Id: BaseConfiguration.java,v 1.1 2002/02/04 11:31:34 mpoeschl Exp $
*/
public class BaseConfiguration
{
/* stores the configuration key-value pairs */
private Hashtable store = new Hashtable();
/* stores the configuration key-value pairs */
protected BaseConfiguration defaults = null;
/**
* 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();
protected final static String START_TOKEN = "${";
protected final static String END_TOKEN = "}";
/**
* 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 addProperty(String key, Object token)
{
Object o = store.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);
store.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.
*/
addPropertyDirect(key, token);
}
}
}
/**
* Adds a key/value pair to the map. This routine does no magic morphing.
* It ensures the keylist is maintained
*
* @param key key to use for mapping
* @param obj object to store
*/
protected void addPropertyDirect(String key, Object obj)
{
// safety check
if(! store.containsKey(key))
{
keysAsListed.add(key);
}
// and the value
store.put(key, obj);
}
/**
* 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.
*/
private void addStringProperty(String key, String token)
{
Object o = store.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);
store.put(key, v);
}
else if (o instanceof Vector)
{
((Vector) o).addElement(token);
}
else
{
addPropertyDirect(key, token);
}
}
/**
* interpolate key names to handle ${key} stuff
*/
protected String interpolate(String base)
{
if (base == null)
{
return null;
}
int begin = -1;
int end = -1;
int prec = 0 - END_TOKEN.length();
String variable = null;
StringBuffer result = new StringBuffer();
// FIXME: we should probably allow the escaping of the start token
while ( ((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) >-1)
&& ((end = base.indexOf(END_TOKEN, begin)) > -1) )
{
result.append(base.substring(prec + END_TOKEN.length(), begin));
variable = base.substring(begin + START_TOKEN.length(), end);
if (store.get(variable) != null)
{
result.append(store.get(variable));
}
prec = end;
}
result.append(base.substring(prec + END_TOKEN.length(), base.length()));
return result.toString();
}
/**
* 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;
}
}
/**
* Create an ExtendedProperties object that is a subset
* of this one. Take into account duplicate keys
* by using the setProperty() in ExtendedProperties.
*
* @param String prefix
*/
public Configuration subset(String prefix)
{
PropertiesConfiguration c = new PropertiesConfiguration();
Iterator keys = this.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);
}
/*
* use addPropertyDirect() - this will plug the data as is into
* the Map, but will also do the right thing re key accounting
*/
c.addPropertyDirect(newKey, store.get(key));
}
}
if (validSubset)
{
return (Configuration) c;
}
else
{
return null;
}
}
/**
* check if the configuration is empty
*/
public boolean isEmpty()
{
return store.isEmpty();
}
/**
* check if the configuration contains the key
*/
public boolean containsKey(String key)
{
return store.containsKey(key);
}
/**
* 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);
}
/**
* Clear a property in the configuration.
*
* @param String key to remove along with corresponding value.
*/
public void clearProperty(String 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;
}
}
store.remove(key);
}
}
/**
* Get the list of the keys contained in the configuration
* repository.
*
* @return An Iterator.
*/
public Iterator getKeys()
{
return keysAsListed.iterator();
}
/**
* 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 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 = store.get(key);
if (value instanceof Boolean)
{
return (Boolean) value;
}
else if (value instanceof String)
{
String s = testBoolean((String)value);
Boolean b = new Boolean(s);
store.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");
}
}
/**
* 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 = store.get(key);
if (value instanceof Byte)
{
return (Byte) value;
}
else if (value instanceof String)
{
Byte b = new Byte((String) value);
store.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 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 = store.get(key);
if (value instanceof Double)
{
return (Double) value;
}
else if (value instanceof String)
{
Double d = new Double((String) value);
store.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");
}
}
/**
* 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 = store.get(key);
if (value instanceof Float)
{
return (Float) value;
}
else if (value instanceof String)
{
Float f = new Float((String) value);
store.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 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 getInt(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 getInt(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 = store.get(key);
if (value instanceof Integer)
{
return (Integer) value;
}
else if (value instanceof String)
{
Integer i = new Integer((String) value);
store.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 = store.get(key);
if (value instanceof Long)
{
return (Long) value;
}
else if (value instanceof String)
{
Long l = new Long((String) value);
store.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 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 = store.get(key);
if (value instanceof Short)
{
return (Short) value;
}
else if (value instanceof String)
{
Short s = new Short((String) value);
store.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");
}
}
/**
* 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 = store.get(key);
if (value instanceof String)
{
return (String) interpolate((String)value);
}
else if (value == null)
{
if (defaults != null)
{
return interpolate(defaults.getString(key, defaultValue));
}
else
{
return interpolate(defaultValue);
}
}
else if (value instanceof Vector)
{
return interpolate((String) ((Vector) value).get(0));
}
else
{
throw new ClassCastException(
'\'' + key + "' doesn't map to a String object");
}
}
/**
* 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 = store.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 = store.get(key);
if (value instanceof Vector)
{
return (Vector) value;
}
else if (value instanceof String)
{
Vector v = new Vector(1);
v.addElement((String) value);
store.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");
}
}
/**
* 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();
}
} // class PropertiesTokenizer
}
1.1 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/package.html
Index: package.html
===================================================================
<html>
<head>
</head>
<body>
Configuration package.
<p>
<br>
<font size="-2">$Id: package.html,v 1.1 2002/02/04 11:31:34 mpoeschl Exp $</font>
</body>
</html>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-turbine-stratum/src/java/org/apache/stratum/configuration BaseConfiguration.java package.html Configuration.java PropertiesConfiguration.java XmlConfiguration.java AbstractConfiguration.java (2/2)
Posted by Daniel Rall <dl...@finemaltcoding.com>.
> /**
> * check if the configuration is empty
> */
> public boolean isEmpty()
> {
> return store.isEmpty();
> }
>
> /**
> * check if the configuration contains the key
> */
> public boolean containsKey(String key)
> {
> return store.containsKey(key);
> }
>
> /**
> * 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);
> }
>
> /**
> * Clear a property in the configuration.
> *
> * @param String key to remove along with corresponding value.
> */
> public void clearProperty(String 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;
> }
> }
> store.remove(key);
> }
> }
>
> /**
> * Get the list of the keys contained in the configuration
> * repository.
> *
> * @return An Iterator.
> */
> public Iterator getKeys()
> {
> return keysAsListed.iterator();
> }
>
> /**
> * 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 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 = store.get(key);
>
> if (value instanceof Boolean)
> {
> return (Boolean) value;
> }
> else if (value instanceof String)
> {
> String s = testBoolean((String)value);
> Boolean b = new Boolean(s);
> store.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");
> }
> }
>
> /**
> * 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 = store.get(key);
>
> if (value instanceof Byte)
> {
> return (Byte) value;
> }
> else if (value instanceof String)
> {
> Byte b = new Byte((String) value);
> store.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 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 = store.get(key);
>
> if (value instanceof Double)
> {
> return (Double) value;
> }
> else if (value instanceof String)
> {
> Double d = new Double((String) value);
> store.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");
> }
> }
>
> /**
> * 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 = store.get(key);
>
> if (value instanceof Float)
> {
> return (Float) value;
> }
> else if (value instanceof String)
> {
> Float f = new Float((String) value);
> store.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 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 getInt(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 getInt(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 = store.get(key);
>
> if (value instanceof Integer)
> {
> return (Integer) value;
> }
> else if (value instanceof String)
> {
> Integer i = new Integer((String) value);
> store.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 = store.get(key);
>
> if (value instanceof Long)
> {
> return (Long) value;
> }
> else if (value instanceof String)
> {
> Long l = new Long((String) value);
> store.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 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 = store.get(key);
>
> if (value instanceof Short)
> {
> return (Short) value;
> }
> else if (value instanceof String)
> {
> Short s = new Short((String) value);
> store.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");
> }
> }
>
> /**
> * 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 = store.get(key);
>
> if (value instanceof String)
> {
> return (String) interpolate((String)value);
> }
> else if (value == null)
> {
> if (defaults != null)
> {
> return interpolate(defaults.getString(key, defaultValue));
> }
> else
> {
> return interpolate(defaultValue);
> }
> }
> else if (value instanceof Vector)
> {
> return interpolate((String) ((Vector) value).get(0));
> }
> else
> {
> throw new ClassCastException(
> '\'' + key + "' doesn't map to a String object");
> }
> }
>
> /**
> * 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 = store.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 = store.get(key);
>
> if (value instanceof Vector)
> {
> return (Vector) value;
> }
> else if (value instanceof String)
> {
> Vector v = new Vector(1);
> v.addElement((String) value);
> store.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");
> }
> }
>
>
> /**
> * 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();
> }
> } // class PropertiesTokenizer
>
> }
>
>
>
> 1.1 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/package.html
>
> Index: package.html
> ===================================================================
> <html>
> <head>
> </head>
>
> <body>
> Configuration package.
> <p>
> <br>
> <font size="-2">$Id: package.html,v 1.1 2002/02/04 11:31:34 mpoeschl Exp $</font>
> </body>
> </html>
>
>
>
>
> --
> To unsubscribe, e-mail: <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
Re: cvs commit: jakarta-turbine-stratum/src/java/org/apache/stratum/configuration BaseConfiguration.java package.html Configuration.java PropertiesConfiguration.java XmlConfiguration.java AbstractConfiguration.java (1/2)
Posted by Daniel Rall <dl...@finemaltcoding.com>.
What's the reasoning for not subclassing ExtendedProperties for the
default implementation?
mpoeschl@apache.org writes:
> mpoeschl 02/02/04 03:31:34
>
> Modified: src/java/org/apache/stratum/configuration Configuration.java
> PropertiesConfiguration.java XmlConfiguration.java
> Added: src/java/org/apache/stratum/configuration
> BaseConfiguration.java package.html
> Removed: src/java/org/apache/stratum/configuration
> AbstractConfiguration.java
> Log:
> new configuration package based on ExtendedProperties
>
> Revision Changes Path
> 1.2 +97 -19 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/Configuration.java
>
> Index: Configuration.java
> ===================================================================
> RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/Configuration.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- Configuration.java 5 Jan 2002 03:22:59 -0000 1.1
> +++ Configuration.java 4 Feb 2002 11:31:34 -0000 1.2
> @@ -1,29 +1,107 @@
> package org.apache.stratum.configuration;
>
> +/* ====================================================================
> + * The Apache Software License, Version 1.1
> + *
> + * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
> + * reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + *
> + * 3. The end-user documentation included with the redistribution,
> + * if any, must include the following acknowledgment:
> + * "This product includes software developed by the
> + * Apache Software Foundation (http://www.apache.org/)."
> + * Alternately, this acknowledgment may appear in the software itself,
> + * if and wherever such third-party acknowledgments normally appear.
> + *
> + * 4. The names "Apache" and "Apache Software Foundation" and
> + * "Apache Turbine" must not be used to endorse or promote products
> + * derived from this software without prior written permission. For
> + * written permission, please contact apache@apache.org.
> + *
> + * 5. Products derived from this software may not be called "Apache",
> + * "Apache Turbine", nor may "Apache" appear in their name, without
> + * prior written permission of the Apache Software Foundation.
> + *
> + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + * ====================================================================
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals on behalf of the Apache Software Foundation. For more
> + * information on the Apache Software Foundation, please see
> + * <http://www.apache.org/>.
> + */
> +
> import java.util.Iterator;
> +import java.util.Properties;
> import java.util.Vector;
>
> -// The general idea here is to make something that will work like
> -// our extended properties and be compatible with the preferences
> -// API if at all possible.
> -
> +/**
> + * Configuration interface.
> + * The general idea here is to make something that will work like our
> + * extended properties and be compatible with the preferences API if at all
> + * possible.
> + *
> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
> + * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
> + * @version $Id: Configuration.java,v 1.2 2002/02/04 11:31:34 mpoeschl Exp $
> + */
> public interface Configuration
> -{
> - Vector getVector(String key);
> - String getString(String key);
> +{
> + Configuration subset(String prefix);
> +
> + boolean isEmpty();
> + boolean containsKey(String key);
> + void addProperty(String key, Object value);
> + void setProperty(String key, Object value);
> + void clearProperty(String key);
> Iterator getKeys(String key);
> - int getInt(String key, int defaultValue);
> -
> + Iterator getKeys();
> + Properties getProperties();
> +
> // We probably want to at least try to be compatible with
> // the new preferences API.
> -
> - // Iterator getKeys()
> -
> - // byte getByte(String key);
> - // short getShort(String key);
> - // long getLong(String key);
> -
> - // float getFloat(String key);
> - // boolean getBoolean(String key);
> - // double getDouble(String key);
> +
> + boolean getBoolean(String key);
> + boolean getBoolean(String key, boolean defaultValue);
> +// Boolean getBoolean(String key, Boolean defaultValue);
> + byte getByte(String key);
> + double getDouble(String key);
> + float getFloat(String key);
> + int getInt(String key, int defaultValue);
> + Integer getInteger(String key, Integer defaultValue);
> + long getLong(String key);
> + long getLong(String key, long defaultValue);
> +// Long getLong(String key, Long defaultValue);
> + short getShort(String key);
> + String getString(String key);
> + String getString(String key, String defaultValue);
> + String[] getStringArray(String key);
> + Vector getVector(String key);
> + Vector getVector(String key, Vector defaultValue);
> +
> +
> +
> }
>
>
>
> 1.2 +402 -3 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/PropertiesConfiguration.java
>
> Index: PropertiesConfiguration.java
> ===================================================================
> RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/PropertiesConfiguration.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- PropertiesConfiguration.java 18 Jan 2002 22:26:05 -0000 1.1
> +++ PropertiesConfiguration.java 4 Feb 2002 11:31:34 -0000 1.2
> @@ -1,9 +1,408 @@
> package org.apache.stratum.configuration;
>
> +/* ====================================================================
> + * The Apache Software License, Version 1.1
> + *
> + * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
> + * reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + *
> + * 3. The end-user documentation included with the redistribution,
> + * if any, must include the following acknowledgment:
> + * "This product includes software developed by the
> + * Apache Software Foundation (http://www.apache.org/)."
> + * Alternately, this acknowledgment may appear in the software itself,
> + * if and wherever such third-party acknowledgments normally appear.
> + *
> + * 4. The names "Apache" and "Apache Software Foundation" and
> + * "Apache Turbine" must not be used to endorse or promote products
> + * derived from this software without prior written permission. For
> + * written permission, please contact apache@apache.org.
> + *
> + * 5. Products derived from this software may not be called "Apache",
> + * "Apache Turbine", nor may "Apache" appear in their name, without
> + * prior written permission of the Apache Software Foundation.
> + *
> + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + * ====================================================================
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals on behalf of the Apache Software Foundation. For more
> + * information on the Apache Software Foundation, please see
> + * <http://www.apache.org/>.
> + */
> +
> +import java.io.File;
> +import java.io.FileInputStream;
> +import java.io.InputStream;
> +import java.io.InputStreamReader;
> +import java.io.IOException;
> +import java.io.LineNumberReader;
> +import java.io.Reader;
> +import java.io.UnsupportedEncodingException;
> +
> // Borrow a lot of the code from ExtendedProperties, but leave
> // the resource handling to the resources package.
>
> -public class PropertiesConfiguration
> - extends AbstractConfiguration
> -{
> +/**
> + * loads the configuration from a properties file. <p>
> + *
> + * <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>
> + *
> + * @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: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>
> + * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
> + * @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a>
> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
> + * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
> + * @version $Id: PropertiesConfiguration.java,v 1.2 2002/02/04 11:31:34 mpoeschl Exp $
> + */
> +public class PropertiesConfiguration extends BaseConfiguration
> +{
> +
> + /** File separator. */
> + protected String fileSeparator = System.getProperty("file.separator");
> +
> + /**
> + * Base path of the configuration file used to create this Configuration
> + * object.
> + */
> + protected String basePath;
> +
> + /**
> + * This is the name of the property that can point to other
> + * properties file for including other properties files.
> + */
> + protected static String include = "include";
> +
> +
> + /**
> + * Creates an empty Configuration
> + */
> + public PropertiesConfiguration()
> + {
> + }
> +
> + /**
> + * Creates and loads the extended properties from the specified file.
> + *
> + * @param file A String.
> + * @exception IOException.
> + */
> + public PropertiesConfiguration(String file) throws IOException
> + {
> + this(file, null);
> + }
> +
> + /**
> + * Creates and loads the extended properties from the specified file.
> + *
> + * @param file A String.
> + * @exception IOException.
> + */
> + public PropertiesConfiguration(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 = (BaseConfiguration)
> + new PropertiesConfiguration(defaultFile);
> + }
> + }
> +
> + /**
> + * Load the properties from the given input stream.
> + *
> + * @param input An InputStream.
> + * @exception IOException.
> + */
> + public void load(InputStream input) throws IOException
> + {
> + load(input, null);
> + }
> +
> + /**
> + * Load the properties from the given input stream and using the specified
> + * encoding.
> + *
> + * @param input An InputStream.
> + * @param enc An encoding.
> + * @exception IOException.
> + */
> + public synchronized void load(InputStream input, String enc)
> + throws IOException
> + {
> + PropertiesReader reader = null;
> + if (enc != null)
> + {
> + try
> + {
> + reader =
> + new PropertiesReader(new InputStreamReader(input, enc));
> + }
> + catch (UnsupportedEncodingException e)
> + {
> + // Get one with the default encoding...
> + }
> + }
> +
> + if (reader == null)
> + {
> + 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);
> + }
> + }
> + }
> + }
> + catch (NullPointerException e)
> + {
> + /*
> + * Should happen only when EOF is reached.
> + */
> + return;
> + }
> + }
> +
> + /**
> + * Gets the property value for including other properties files.
> + * By default it is "include".
> + *
> + * @return A String.
> + */
> + public String getInclude()
> + {
> + return this.include;
> + }
> +
> + /**
> + * Sets the property value for including other properties files.
> + * By default it is "include".
> + *
> + * @param inc A String.
> + */
> + public void setInclude(String inc)
> + {
> + this.include = inc;
> + }
> +
> +
> + /**
> + * 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();
> + }
> + } // class PropertiesReader
> +
> +
> }
>
>
>
> 1.2 +3 -3 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/XmlConfiguration.java
>
> Index: XmlConfiguration.java
> ===================================================================
> RCS file: /home/cvs/jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/XmlConfiguration.java,v
> retrieving revision 1.1
> retrieving revision 1.2
> diff -u -r1.1 -r1.2
> --- XmlConfiguration.java 18 Jan 2002 22:26:05 -0000 1.1
> +++ XmlConfiguration.java 4 Feb 2002 11:31:34 -0000 1.2
> @@ -1,5 +1,6 @@
> package org.apache.stratum.configuration;
>
> +
> /**
> * <configuration>
> * <entries>
> @@ -11,7 +12,6 @@
> * </configuration>
> *
> */
> -public class XmlConfiguration
> - extends AbstractConfiguration
> -{
> +public class XmlConfiguration extends BaseConfiguration
> +{
> }
>
>
>
> 1.1 jakarta-turbine-stratum/src/java/org/apache/stratum/configuration/BaseConfiguration.java
>
> Index: BaseConfiguration.java
> ===================================================================
> package org.apache.stratum.configuration;
>
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> * modification, are permitted provided that the following conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the above copyright
> * notice, this list of conditions and the following disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the redistribution,
> * if any, must include the following acknowledgment:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowledgment may appear in the software itself,
> * if and wherever such third-party acknowledgments normally appear.
> *
> * 4. The names "Apache" and "Apache Software Foundation" and
> * "Apache Turbine" must not be used to endorse or promote products
> * derived from this software without prior written permission. For
> * written permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache",
> * "Apache Turbine", nor may "Apache" appear in their name, without
> * prior written permission of the Apache Software Foundation.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> * SUCH DAMAGE.
> * ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation. For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> */
>
> import java.util.ArrayList;
> import java.util.Hashtable;
> import java.util.Iterator;
> import java.util.NoSuchElementException;
> import java.util.Properties;
> import java.util.StringTokenizer;
> import java.util.Vector;
>
> /**
> * Basic configuration classe. Stores the configuration data but does not
> * provide any load or save functions. If you want to load your Configuration
> * from a file use PropertiesConfiguration or XmlConfiguration.
> *
> * 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.
> *
> * @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: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>
> * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
> * @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a>
> * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
> * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
> * @version $Id: BaseConfiguration.java,v 1.1 2002/02/04 11:31:34 mpoeschl Exp $
> */
> public class BaseConfiguration
> {
>
> /* stores the configuration key-value pairs */
> private Hashtable store = new Hashtable();
>
> /* stores the configuration key-value pairs */
> protected BaseConfiguration defaults = null;
>
> /**
> * 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();
>
> protected final static String START_TOKEN = "${";
> protected final static String END_TOKEN = "}";
>
> /**
> * 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 addProperty(String key, Object token)
> {
> Object o = store.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);
> store.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.
> */
> addPropertyDirect(key, token);
> }
> }
> }
>
> /**
> * Adds a key/value pair to the map. This routine does no magic morphing.
> * It ensures the keylist is maintained
> *
> * @param key key to use for mapping
> * @param obj object to store
> */
> protected void addPropertyDirect(String key, Object obj)
> {
> // safety check
> if(! store.containsKey(key))
> {
> keysAsListed.add(key);
> }
>
> // and the value
> store.put(key, obj);
> }
>
> /**
> * 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.
> */
> private void addStringProperty(String key, String token)
> {
> Object o = store.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);
> store.put(key, v);
> }
> else if (o instanceof Vector)
> {
> ((Vector) o).addElement(token);
> }
> else
> {
> addPropertyDirect(key, token);
> }
> }
>
> /**
> * interpolate key names to handle ${key} stuff
> */
> protected String interpolate(String base)
> {
> if (base == null)
> {
> return null;
> }
>
> int begin = -1;
> int end = -1;
> int prec = 0 - END_TOKEN.length();
> String variable = null;
> StringBuffer result = new StringBuffer();
>
> // FIXME: we should probably allow the escaping of the start token
> while ( ((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) >-1)
> && ((end = base.indexOf(END_TOKEN, begin)) > -1) )
> {
> result.append(base.substring(prec + END_TOKEN.length(), begin));
> variable = base.substring(begin + START_TOKEN.length(), end);
> if (store.get(variable) != null)
> {
> result.append(store.get(variable));
> }
> prec = end;
> }
> result.append(base.substring(prec + END_TOKEN.length(), base.length()));
>
> return result.toString();
> }
>
> /**
> * 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;
> }
> }
>
> /**
> * Create an ExtendedProperties object that is a subset
> * of this one. Take into account duplicate keys
> * by using the setProperty() in ExtendedProperties.
> *
> * @param String prefix
> */
> public Configuration subset(String prefix)
> {
> PropertiesConfiguration c = new PropertiesConfiguration();
> Iterator keys = this.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);
> }
>
> /*
> * use addPropertyDirect() - this will plug the data as is into
> * the Map, but will also do the right thing re key accounting
> */
> c.addPropertyDirect(newKey, store.get(key));
> }
> }
>
> if (validSubset)
> {
> return (Configuration) c;
> }
> else
> {
> return null;
> }
> }
>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>