[Martin: Cc to commons-dev, that's why it is in english]
Hi,
I stumped over the following problem:
foo.bar = aaa
foo.bar = bbb, ccc
I expected a Configuration object to return for getVector("foo.bar") :
[ "aaa", "bbb", "ccc" ]
but I got
[ "aaa", "bbb, ccc" ]
Which basically sucks and is not the expected behaviour. Then I took
a look into BaseConfiguration (and recoiled in horror).
The attached patch(es) fix up the mess surrounding the internal store,
implement a Container wrapper for Vectors (as suggested in the comments)
and return the correct values for the scenario described above. These
are two patches, one is with additional commons-logging debugging
integrated but adds another jar to the dependencies.
As the comments suggest, that this container change should be post-1.0
(which IMHO would really be bad, the current code doesn't work correct
and is obfuscated) and the last changes are from August, I'd really like
to see this getting in _before_ 1.0 release.
As this seems to be Turbine spawned code, I hope, someone will check
this in (I'm using this with Turbine). Alternatively, someone might
simply give me karma on the repository (I'm a committer for Turbine so I
might be qualified for this. :-) )
Regards
Henning
--
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen -- Geschaeftsfuehrer
INTERMETA - Gesellschaft fuer Mehrwertdienste mbH [EMAIL PROTECTED]
Am Schwabachgrund 22 Fon.: 09131 / 50654-0 [EMAIL PROTECTED]
D-91054 Buckenhof Fax.: 09131 / 50654-20
? lib
Index: project.xml
===================================================================
RCS file: /home/cvspublic/jakarta-commons-sandbox/configuration/project.xml,v
retrieving revision 1.10
diff -u -b -r1.10 project.xml
--- project.xml 28 Aug 2002 20:01:05 -0000 1.10
+++ project.xml 3 Dec 2002 11:17:10 -0000
@@ -76,6 +76,13 @@
<organization>Multitask Consulting</organization>
</developer>
+ <developer>
+ <name>Henning P. Schmiedehausen</name>
+ <id>henning</id>
+ <email>[EMAIL PROTECTED]</email>
+ <organization>INTERMETA - Gesellschaft fuer Mehrwertdienste mbH</organization>
+ </developer>
+
</developers>
<dependencies>
Index: src/java/org/apache/commons/configuration/BaseConfiguration.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons-sandbox/configuration/src/java/org/apache/commons/configuration/BaseConfiguration.java,v
retrieving revision 1.3
diff -u -b -r1.3 BaseConfiguration.java
--- src/java/org/apache/commons/configuration/BaseConfiguration.java 28 Aug 2002
18:16:02 -0000 1.3
+++ src/java/org/apache/commons/configuration/BaseConfiguration.java 3 Dec 2002
+11:17:10 -0000
@@ -57,6 +57,7 @@
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
@@ -81,6 +82,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Ilkka Priha</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Martin Poeschl</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a>
* @version $Id: BaseConfiguration.java,v 1.3 2002/08/28 18:16:02 mpoeschl Exp $
*/
public class BaseConfiguration implements Configuration
@@ -115,50 +117,86 @@
*
* ["file", "classpath"]
*
- * @param key
- * @param token
+ * @param key The Key to add the property to.
+ * @param token The Value to add.
*/
public void addProperty(String key, Object token)
{
+ List tokenAdd = null;
+
+ if (token instanceof String)
+ {
+ tokenAdd = processString((String) token);
+ }
+ else
+ {
+ tokenAdd = new Vector(1);
+ tokenAdd.add(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);
+ if (o instanceof Container)
+ {
+ // There is already a container for our key in the config
+ // Simply add the new tokens
+ for (Iterator it = tokenAdd.iterator(); it.hasNext(); )
+ {
+ ((Container) o).add(it.next());
+ }
+ }
+ else
+ {
+ // No Key at all or the token key is not a container.
+ Container c = new Container();
+
+ if (o != null)
+ {
+ // There is an element. Put it into the container
+ // at the first position
+ c.add(o);
+ }
+
+ // Now gobble up the supplied objects
+ for (Iterator it = tokenAdd.iterator(); it.hasNext(); )
+ {
+ c.add(it.next());
}
- else if (o instanceof Vector)
+
+ // Do we have a key? If not, we simply add either the container
+ // (If the element was a CSV) or the first element of the
+ // Container (if its size is 1)
+
+ if (o == null && c.size() == 1)
{
- ((Vector) o).addElement(token);
+ // No Key existed and only one got put into the container. Then
+ // add the key direct. Do not mess with the container
+ addPropertyDirect(key, c.get(0));
}
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.
+ // Either a key already existed or there was a CSV supplied
+ // Add the Container to the Store
+ addPropertyDirect(key, c);
+ }
+ }
+ }
+
+ /**
+ * Returns a Vector of Strings built from the supplied
+ * String. Splits up CSV lists. If no commas are in the
+ * String, simply returns a Vector with the String as its
+ * first element
+ *
+ * @param token The String to tokenize
+ *
+ * @return A List of Strings
*/
- if (token instanceof String &&
- ((String) token).indexOf(PropertiesTokenizer.DELIMITER) > 0)
+ protected List processString(String token)
+ {
+ List retList = new ArrayList(2);
+
+ if (token.indexOf(PropertiesTokenizer.DELIMITER) > 0)
{
PropertiesTokenizer tokenizer =
new PropertiesTokenizer((String) token);
@@ -166,27 +204,20 @@
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);
+ retList.add(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);
- }
+ retList.add(token);
}
+
+ //
+ // We keep the sequence of the keys here and
+ // we also keep it in the Container. So the
+ // Keys are added to the store in the sequence that
+ // is given in the properties
+ return retList;
}
/**
@@ -209,49 +240,6 @@
}
/**
- * 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)
@@ -502,7 +490,7 @@
* @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.
+ * object that is not a String/Vector of Strings.
* @exception IllegalArgumentException if one of the tokens is
* malformed (does not contain an equals sign).
*/
@@ -557,6 +545,16 @@
o = defaults.getProperty(key);
}
}
+
+ //
+ // We must never give a Container Object out. So if the
+ // Return Value is a Container, we fix it up to be a
+ // Vector
+ //
+ if (o instanceof Container)
+ {
+ o = ((Container) o).asVector();
+ }
return o;
}
@@ -1207,9 +1205,9 @@
return interpolate(defaultValue);
}
}
- else if (value instanceof Vector)
+ else if (value instanceof Container)
{
- return interpolate((String) ((Vector) value).get(0));
+ return interpolate((String) ((Container) value).get(0));
}
else
{
@@ -1225,32 +1223,38 @@
* @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.
+ * object that is not a String/Vector of Strings.
*/
public String[] getStringArray(String key)
{
Object value = store.get(key);
- // What's your vector, Victor?
- Vector vector;
+ String [] tokens;
+
if (value instanceof String)
{
- vector = new Vector(1);
- vector.addElement(interpolate((String) value));
+ tokens = new String [1];
+
+ tokens[0] = interpolate((String) value);
}
- else if (value instanceof Vector)
+ else if (value instanceof Container)
+ {
+ tokens = new String [((Container) value).size()];
+
+ for (int i = 0; i < tokens.length; i++)
{
- vector = (Vector) value;
+ tokens[i] = interpolate((String) ((Container) value).get(i));
+ }
}
else if (value == null)
{
if (defaults != null)
{
- return defaults.getStringArray(key);
+ tokens = defaults.getStringArray(key);
}
else
{
- return new String[0];
+ tokens = new String[0];
}
}
else
@@ -1258,13 +1262,6 @@
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;
}
@@ -1293,35 +1290,35 @@
public Vector getVector(String key, Vector defaultValue)
{
Object value = store.get(key);
+ Vector v = null;
- if (value instanceof Vector)
+ if (value instanceof String)
{
- return (Vector) value;
+ v = new Vector(1);
+ v.addElement((String) value);
}
- else if (value instanceof String)
+ else if (value instanceof Container)
{
- Vector v = new Vector(1);
- v.addElement((String) value);
- store.put(key, v);
- return v;
+ v = ((Container) value).asVector();
}
else if (value == null)
{
if (defaults != null)
{
- return defaults.getVector(key, defaultValue);
+ v = defaults.getVector(key, defaultValue);
}
else
{
- return ((defaultValue == null) ?
+ v = ((defaultValue == null) ?
new Vector() : defaultValue);
}
}
else
{
throw new ClassCastException(
- '\'' + key + "' doesn't map to a Vector object");
+ '\'' + key + "' doesn't map to a Vector object: " + value + ", a " +
+value.getClass().getName());
}
+ return v;
}
/**
@@ -1383,4 +1380,88 @@
return buffer.toString().trim();
}
} // class PropertiesTokenizer
+
+
+ /**
+ * Private Wrapper class for Vector, so we can distinguish between
+ * Vector objects and our container
+ */
+ class Container
+ {
+ /** We're wrapping a List object (A vector) */
+ private List l = null;
+
+ /**
+ * C'tor
+ */
+ public Container()
+ {
+ l = new Vector(2);
+ }
+
+ /**
+ * Add an Object to the Container
+ *
+ * @param o The Object
+ */
+ public void add(Object o)
+ {
+ l.add(o);
+ }
+
+ /**
+ * Returns the current size of the Container
+ *
+ * @return The Number of elements in the container
+ */
+ public int size()
+ {
+ return l.size();
+ }
+
+ /**
+ * Returns the Element at an index
+ *
+ * @param index The Index
+ *
+ * @return The element at that index
+ */
+ public Object get(int index)
+ {
+ return l.get(index);
+ }
+
+ /**
+ * Returns an Iterator over the container
+ * objects
+ *
+ * @return An Iterator
+ */
+ public Iterator iterator()
+ {
+ return l.iterator();
+ }
+
+ /**
+ * Returns the Elements of the Container as
+ * a Vector. This is not the internal vector
+ * element but a shallow copy of the internal
+ * list. You may modify the returned list without
+ * modifying the container.
+ *
+ * @return A Vector containing the elements of
+ * the Container.
+ */
+
+ public Vector asVector()
+ {
+ Vector v = new Vector(l.size());
+
+ for (Iterator it = l.iterator(); it.hasNext(); )
+ {
+ v.add(it.next());
+ }
+ return v;
+ }
+ }
}
? lib
Index: project.xml
===================================================================
RCS file: /home/cvspublic/jakarta-commons-sandbox/configuration/project.xml,v
retrieving revision 1.10
diff -u -b -r1.10 project.xml
--- project.xml 28 Aug 2002 20:01:05 -0000 1.10
+++ project.xml 3 Dec 2002 11:17:10 -0000
@@ -76,6 +76,13 @@
<organization>Multitask Consulting</organization>
</developer>
+ <developer>
+ <name>Henning P. Schmiedehausen</name>
+ <id>henning</id>
+ <email>[EMAIL PROTECTED]</email>
+ <organization>INTERMETA - Gesellschaft fuer Mehrwertdienste mbH</organization>
+ </developer>
+
</developers>
<dependencies>
Index: build.xml
===================================================================
RCS file: /home/cvspublic/jakarta-commons-sandbox/configuration/build.xml,v
retrieving revision 1.3
diff -u -b -r1.3 build.xml
--- build.xml 28 Aug 2002 19:45:27 -0000 1.3
+++ build.xml 3 Dec 2002 11:13:20 -0000
@@ -130,6 +130,7 @@
<get dest="lib/commons-collections-2.0.jar" usetimestamp="true"
ignoreerrors="true"
src="http://www.ibiblio.org/maven/commons-collections/jars/commons-collections-2.0.jar"></get>
<get dest="lib/commons-lang-1.0-b1.jar" usetimestamp="true" ignoreerrors="true"
src="http://www.ibiblio.org/maven/commons-lang/jars/commons-lang-1.0-b1.jar"></get>
<get dest="lib/junit-3.7.jar" usetimestamp="true" ignoreerrors="true"
src="http://www.ibiblio.org/maven/junit/jars/junit-3.7.jar"></get>
+ <get dest="lib/commons-logging-1.0.2.jar" usetimestamp="true" ignoreerrors="true"
+src="http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.0.2.jar"></get>
</target>
Index: src/java/org/apache/commons/configuration/BaseConfiguration.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons-sandbox/configuration/src/java/org/apache/commons/configuration/BaseConfiguration.java,v
retrieving revision 1.3
diff -u -b -r1.3 BaseConfiguration.java
--- src/java/org/apache/commons/configuration/BaseConfiguration.java 28 Aug 2002
18:16:02 -0000 1.3
+++ src/java/org/apache/commons/configuration/BaseConfiguration.java 3 Dec 2002
+11:13:20 -0000
@@ -57,11 +57,15 @@
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
/**
* Basic configuration classe. Stores the configuration data but does not
* provide any load or save functions. If you want to load your Configuration
@@ -81,6 +85,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Ilkka Priha</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Martin Poeschl</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a>
* @version $Id: BaseConfiguration.java,v 1.3 2002/08/28 18:16:02 mpoeschl Exp $
*/
public class BaseConfiguration implements Configuration
@@ -91,6 +96,9 @@
/** stores the configuration key-value pairs */
protected Configuration defaults = null;
+ /** Logging */
+ private static Log log = LogFactory.getLog(BaseConfiguration.class);
+
/**
* These are the keys in the order they listed in the configuration file.
* This is useful when you wish to perform operations with configuration
@@ -115,50 +123,88 @@
*
* ["file", "classpath"]
*
- * @param key
- * @param token
+ * @param key The Key to add the property to.
+ * @param token The Value to add.
*/
public void addProperty(String key, Object token)
{
+ log.debug("doAddProperty(" + key + ", " + token + ")");
+
+ List tokenAdd = null;
+
+ if (token instanceof String)
+ {
+ tokenAdd = processString((String) token);
+ }
+ else
+ {
+ tokenAdd = new Vector(1);
+ tokenAdd.add(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);
+ if (o instanceof Container)
+ {
+ // There is already a container for our key in the config
+ // Simply add the new tokens
+ for (Iterator it = tokenAdd.iterator(); it.hasNext(); )
+ {
+ ((Container) o).add(it.next());
}
- else if (o instanceof Vector)
+ }
+ else
+ {
+ // No Key at all or the token key is not a container.
+ Container c = new Container();
+
+ if (o != null)
{
- ((Vector) o).addElement(token);
+ // There is an element. Put it into the container
+ // at the first position
+ c.add(o);
+ }
+
+ // Now gobble up the supplied objects
+ for (Iterator it = tokenAdd.iterator(); it.hasNext(); )
+ {
+ c.add(it.next());
+ }
+
+ // Do we have a key? If not, we simply add either the container
+ // (If the element was a CSV) or the first element of the
+ // Container (if its size is 1)
+
+ if (o == null && c.size() == 1)
+ {
+ // No Key existed and only one got put into the container. Then
+ // add the key direct. Do not mess with the container
+ addPropertyDirect(key, c.get(0));
}
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.
+ // Either a key already existed or there was a CSV supplied
+ // Add the Container to the Store
+ addPropertyDirect(key, c);
+ }
+ }
+ }
+
+ /**
+ * Returns a Vector of Strings built from the supplied
+ * String. Splits up CSV lists. If no commas are in the
+ * String, simply returns a Vector with the String as its
+ * first element
+ *
+ * @param token The String to tokenize
+ *
+ * @return A List of Strings
*/
- if (token instanceof String &&
- ((String) token).indexOf(PropertiesTokenizer.DELIMITER) > 0)
+ protected List processString(String token)
+ {
+ List retList = new ArrayList(2);
+
+ if (token.indexOf(PropertiesTokenizer.DELIMITER) > 0)
{
PropertiesTokenizer tokenizer =
new PropertiesTokenizer((String) token);
@@ -166,27 +212,20 @@
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);
+ retList.add(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);
- }
+ retList.add(token);
}
+
+ //
+ // We keep the sequence of the keys here and
+ // we also keep it in the Container. So the
+ // Keys are added to the store in the sequence that
+ // is given in the properties
+ return retList;
}
/**
@@ -209,49 +248,6 @@
}
/**
- * 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)
@@ -502,7 +498,7 @@
* @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.
+ * object that is not a String/Vector of Strings.
* @exception IllegalArgumentException if one of the tokens is
* malformed (does not contain an equals sign).
*/
@@ -557,6 +553,16 @@
o = defaults.getProperty(key);
}
}
+
+ //
+ // We must never give a Container Object out. So if the
+ // Return Value is a Container, we fix it up to be a
+ // Vector
+ //
+ if (o instanceof Container)
+ {
+ o = ((Container) o).asVector();
+ }
return o;
}
@@ -1207,9 +1213,9 @@
return interpolate(defaultValue);
}
}
- else if (value instanceof Vector)
+ else if (value instanceof Container)
{
- return interpolate((String) ((Vector) value).get(0));
+ return interpolate((String) ((Container) value).get(0));
}
else
{
@@ -1225,32 +1231,38 @@
* @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.
+ * object that is not a String/Vector of Strings.
*/
public String[] getStringArray(String key)
{
Object value = store.get(key);
- // What's your vector, Victor?
- Vector vector;
+ String [] tokens;
+
if (value instanceof String)
{
- vector = new Vector(1);
- vector.addElement(interpolate((String) value));
+ tokens = new String [1];
+
+ tokens[0] = interpolate((String) value);
}
- else if (value instanceof Vector)
+ else if (value instanceof Container)
{
- vector = (Vector) value;
+ tokens = new String [((Container) value).size()];
+
+ for (int i = 0; i < tokens.length; i++)
+ {
+ tokens[i] = interpolate((String) ((Container) value).get(i));
+ }
}
else if (value == null)
{
if (defaults != null)
{
- return defaults.getStringArray(key);
+ tokens = defaults.getStringArray(key);
}
else
{
- return new String[0];
+ tokens = new String[0];
}
}
else
@@ -1258,13 +1270,6 @@
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;
}
@@ -1293,35 +1298,51 @@
public Vector getVector(String key, Vector defaultValue)
{
Object value = store.get(key);
+ Vector v = null;
- if (value instanceof Vector)
+ if (log.isDebugEnabled())
{
- return (Vector) value;
+ if (value != null)
+ {
+ log.debug("Found a " + value.getClass().getName() + " for key " +
+key);
}
- else if (value instanceof String)
+ else
{
- Vector v = new Vector(1);
+ log.debug("Found null for key " + key);
+ }
+ }
+
+ if (value instanceof String)
+ {
+ log.debug("Value is a String");
+ v = new Vector(1);
v.addElement((String) value);
- store.put(key, v);
- return v;
+ }
+ else if (value instanceof Container)
+ {
+ log.debug("Value is a Container");
+ v = ((Container) value).asVector();
}
else if (value == null)
{
+ log.debug("Value is null");
+
if (defaults != null)
{
- return defaults.getVector(key, defaultValue);
+ v = defaults.getVector(key, defaultValue);
}
else
{
- return ((defaultValue == null) ?
+ v = ((defaultValue == null) ?
new Vector() : defaultValue);
}
}
else
{
throw new ClassCastException(
- '\'' + key + "' doesn't map to a Vector object");
+ '\'' + key + "' doesn't map to a Vector object: " + value + ", a " +
+value.getClass().getName());
}
+ return v;
}
/**
@@ -1383,4 +1404,88 @@
return buffer.toString().trim();
}
} // class PropertiesTokenizer
+
+
+ /**
+ * Private Wrapper class for Vector, so we can distinguish between
+ * Vector objects and our container
+ */
+ class Container
+ {
+ /** We're wrapping a List object (A vector) */
+ private List l = null;
+
+ /**
+ * C'tor
+ */
+ public Container()
+ {
+ l = new Vector(2);
+ }
+
+ /**
+ * Add an Object to the Container
+ *
+ * @param o The Object
+ */
+ public void add(Object o)
+ {
+ l.add(o);
+ }
+
+ /**
+ * Returns the current size of the Container
+ *
+ * @return The Number of elements in the container
+ */
+ public int size()
+ {
+ return l.size();
+ }
+
+ /**
+ * Returns the Element at an index
+ *
+ * @param index The Index
+ *
+ * @return The element at that index
+ */
+ public Object get(int index)
+ {
+ return l.get(index);
+ }
+
+ /**
+ * Returns an Iterator over the container
+ * objects
+ *
+ * @return An Iterator
+ */
+ public Iterator iterator()
+ {
+ return l.iterator();
+ }
+
+ /**
+ * Returns the Elements of the Container as
+ * a Vector. This is not the internal vector
+ * element but a shallow copy of the internal
+ * list. You may modify the returned list without
+ * modifying the container.
+ *
+ * @return A Vector containing the elements of
+ * the Container.
+ */
+
+ public Vector asVector()
+ {
+ Vector v = new Vector(l.size());
+
+ for (Iterator it = l.iterator(); it.hasNext(); )
+ {
+ v.add(it.next());
+ }
+ return v;
+ }
+ }
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>