Make ExtendedProperties support List rather than just Vector

bug 36812, from Henning P. Schmiedehausen

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/collections/trunk@333060 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2005-11-13 16:59:51 +00:00
parent e6c681f115
commit d29ce53657
3 changed files with 135 additions and 36 deletions

View File

@ -67,6 +67,8 @@ If this causes major headaches to anyone please contact commons-dev at jakarta.a
<li>CollectionUtils/MapUtils.isEmpty/isNotEmpty - Null-safe checks of collection emptyness [35890]</li>
<li>CollectionUtils.sizeIsEmpty - Checks if a collection, array, map, iterator or enumeration is empty</li>
<li>CollectionUtils/ListUtils - retainAll/removeAll that don't change original colllection</li>
<li>ExtendedProperties - Accepts List elements (does not enforce Vector) as values [36812]</li>
<li>ExtendedProperties - new Methods getList(String key) and getList(String key, List defaults) [36812]</li>
<li>ExtendedProperties - No longer uses an exception in normal processing [30497]</li>
<li>BlockingBuffer - now includes stack trace if InterupttedException occurs [33700]</li>
<li>BlockingBuffer - new methods that allow get and remove with a timeout [27691]</li>

View File

@ -138,6 +138,7 @@ import java.util.Vector;
* @author Mohan Kishore
* @author Stephen Colebourne
* @author Shinobu Kawai
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
*/
public class ExtendedProperties extends Hashtable {
@ -691,14 +692,14 @@ public class ExtendedProperties extends Hashtable {
if (current instanceof String) {
// one object already in map - convert it to a vector
Vector v = new Vector(2);
v.addElement(current);
v.addElement(value);
put(key, v);
List values = new Vector(2);
values.add(current);
values.add(value);
put(key, values);
} else if (current instanceof Vector) {
// already a vector - just add the new token
((Vector) current).addElement(value);
} else if (current instanceof List) {
// already a list - just add the new token
((List) current).add(value);
} else {
// brand new key - store in keysAsListed to retain order
@ -752,11 +753,10 @@ public class ExtendedProperties extends Hashtable {
currentOutput.append(escape((String) value));
theWrtr.println(currentOutput.toString());
} else if (value instanceof Vector) {
Vector values = (Vector) value;
Enumeration valuesEnum = values.elements();
while (valuesEnum.hasMoreElements()) {
String currentElement = (String) valuesEnum.nextElement();
} else if (value instanceof List) {
List values = (List) value;
for (Iterator it = values.iterator(); it.hasNext(); ) {
String currentElement = (String) it.next();
StringBuffer currentOutput = new StringBuffer();
currentOutput.append(key);
currentOutput.append("=");
@ -931,8 +931,8 @@ public class ExtendedProperties extends Hashtable {
} else {
return interpolate(defaultValue);
}
} else if (value instanceof Vector) {
return interpolate((String) ((Vector) value).get(0));
} else if (value instanceof List) {
return interpolate((String) ((List) value).get(0));
} else {
throw new ClassCastException('\'' + key + "' doesn't map to a String object");
}
@ -945,7 +945,7 @@ public class ExtendedProperties extends Hashtable {
* @param key The configuration key.
* @return The associated properties if key is found.
* @throws ClassCastException is thrown if the key maps to an
* object that is not a String/Vector.
* object that is not a String/List.
* @throws IllegalArgumentException if one of the tokens is
* malformed (does not contain an equals sign).
*/
@ -960,7 +960,7 @@ public class ExtendedProperties extends Hashtable {
* @param key The configuration key.
* @return The associated properties if key is found.
* @throws ClassCastException is thrown if the key maps to an
* object that is not a String/Vector.
* object that is not a String/List.
* @throws IllegalArgumentException if one of the tokens is
* malformed (does not contain an equals sign).
*/
@ -993,19 +993,18 @@ public class ExtendedProperties extends Hashtable {
* @param key The configuration key.
* @return The associated string array if key is found.
* @throws ClassCastException is thrown if the key maps to an
* object that is not a String/Vector.
* object that is not a String/List.
*/
public String[] getStringArray(String key) {
Object value = get(key);
// What's your vector, Victor?
Vector vector;
List values;
if (value instanceof String) {
vector = new Vector(1);
vector.addElement(value);
values = new Vector(1);
values.add(value);
} else if (value instanceof Vector) {
vector = (Vector) value;
} else if (value instanceof List) {
values = (List) value;
} else if (value == null) {
if (defaults != null) {
@ -1014,12 +1013,12 @@ public class ExtendedProperties extends Hashtable {
return new String[0];
}
} else {
throw new ClassCastException('\'' + key + "' doesn't map to a String/Vector object");
throw new ClassCastException('\'' + key + "' doesn't map to a String/List object");
}
String[] tokens = new String[vector.size()];
String[] tokens = new String[values.size()];
for (int i = 0; i < tokens.length; i++) {
tokens[i] = (String) vector.elementAt(i);
tokens[i] = (String) values.get(i);
}
return tokens;
@ -1039,8 +1038,10 @@ public class ExtendedProperties extends Hashtable {
}
/**
* Get a Vector of strings associated with the given configuration
* key.
* Get a Vector of strings associated with the given configuration key.
* <p>
* The list is a copy of the internal data of this object, and as
* such you may alter it freely.
*
* @param key The configuration key.
* @param defaultValue The default value.
@ -1051,14 +1052,14 @@ public class ExtendedProperties extends Hashtable {
public Vector getVector(String key, Vector defaultValue) {
Object value = get(key);
if (value instanceof Vector) {
return (Vector) value;
if (value instanceof List) {
return new Vector((List) value);
} else if (value instanceof String) {
Vector v = new Vector(1);
v.addElement(value);
put(key, v);
return v;
Vector values = new Vector(1);
values.add(value);
put(key, values);
return values;
} else if (value == null) {
if (defaults != null) {
@ -1071,6 +1072,56 @@ public class ExtendedProperties extends Hashtable {
}
}
/**
* Get a List of strings associated with the given configuration key.
* <p>
* The list is a copy of the internal data of this object, and as
* such you may alter it freely.
*
* @param key The configuration key.
* @return The associated List object.
* @throws ClassCastException is thrown if the key maps to an
* object that is not a List.
*/
public List getList(String key) {
return getList(key, null);
}
/**
* Get a List of strings associated with the given configuration key.
* <p>
* The list is a copy of the internal data of this object, and as
* such you may alter it freely.
*
* @param key The configuration key.
* @param defaultValue The default value.
* @return The associated List.
* @throws ClassCastException is thrown if the key maps to an
* object that is not a List.
*/
public List getList(String key, List defaultValue) {
Object value = get(key);
if (value instanceof List) {
return new ArrayList((List) value);
} else if (value instanceof String) {
List values = new ArrayList(1);
values.add(value);
put(key, values);
return values;
} else if (value == null) {
if (defaults != null) {
return defaults.getList(key, defaultValue);
} else {
return ((defaultValue == null) ? new ArrayList() : defaultValue);
}
} else {
throw new ClassCastException('\'' + key + "' doesn't map to a List object");
}
}
/**
* Get a boolean associated with the given configuration key.
*

View File

@ -33,6 +33,7 @@ import junit.framework.TestSuite;
* @author Mohan Kishore
* @author Stephen Colebourne
* @author Shinobu Kawai
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
*/
public class TestExtendedProperties extends TestCase {
@ -65,14 +66,15 @@ public class TestExtendedProperties extends TestCase {
assertEquals("This returns '1'", eprop.getString("number"), "1");
/*
* now add another and get a Vector
* now add another and get a Vector/list
*/
eprop.addProperty("number", "2");
assertTrue("This returns array", (eprop.getVector("number") instanceof java.util.Vector));
assertTrue("This returns array", (eprop.getList("number") instanceof java.util.List));
/*
* now test dan's new fix where we get the first scalar
* when we access a vector valued
* when we access a vector/list valued
* property
*/
assertTrue("This returns scalar", (eprop.getString("number") instanceof String));
@ -83,6 +85,7 @@ public class TestExtendedProperties extends TestCase {
String prop = "hey, that's a test";
eprop.setProperty("prop.string", prop);
assertTrue("This returns vector", (eprop.getVector("prop.string") instanceof java.util.Vector));
assertTrue("This returns list", (eprop.getList("prop.string") instanceof java.util.List));
String prop2 = "hey\\, that's a test";
eprop.remove("prop.string");
@ -99,6 +102,7 @@ public class TestExtendedProperties extends TestCase {
assertTrue("Returns the full string", subEprop.getString("string").equals(prop));
assertTrue("This returns string for subset", (subEprop.getString("string") instanceof java.lang.String));
assertTrue("This returns array for subset", (subEprop.getVector("string") instanceof java.util.Vector));
assertTrue("This returns array for subset", (subEprop.getList("string") instanceof java.util.List));
}
@ -134,6 +138,13 @@ public class TestExtendedProperties extends TestCase {
assertEquals("Commas not interpreted properly",
"World", ep1.getVector("three").get(1));
assertEquals("Commas not interpreted properly",
2, ep1.getList("three").size());
assertEquals("Commas not interpreted properly",
"Hello", ep1.getList("three").get(0));
assertEquals("Commas not interpreted properly",
"World", ep1.getList("three").get(1));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ep1.save(baos, null);
bytes = baos.toByteArray();
@ -186,10 +197,16 @@ public class TestExtendedProperties extends TestCase {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ep1.load(bais);
assertEquals(1, ep1.size());
assertEquals(3, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals("b", ep1.getVector("one").get(1));
assertEquals("c", ep1.getVector("one").get(2));
assertEquals(3, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
assertEquals("b", ep1.getList("one").get(1));
assertEquals("c", ep1.getList("one").get(2));
}
public void testMultipleSameKey2() throws Exception {
@ -205,11 +222,18 @@ public class TestExtendedProperties extends TestCase {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ep1.load(bais);
assertEquals(1, ep1.size());
assertEquals(4, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals("b", ep1.getVector("one").get(1));
assertEquals("c", ep1.getVector("one").get(2));
assertEquals("d", ep1.getVector("one").get(3));
assertEquals(4, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
assertEquals("b", ep1.getList("one").get(1));
assertEquals("c", ep1.getList("one").get(2));
assertEquals("d", ep1.getList("one").get(3));
}
public void testMultipleSameKey3() throws Exception {
@ -225,10 +249,16 @@ public class TestExtendedProperties extends TestCase {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ep1.load(bais);
assertEquals(1, ep1.size());
assertEquals(3, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals("b", ep1.getVector("one").get(1));
assertEquals("c", ep1.getVector("one").get(2));
assertEquals(3, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
assertEquals("b", ep1.getList("one").get(1));
assertEquals("c", ep1.getList("one").get(2));
}
public void testMultipleSameKeyByCode() throws Exception {
@ -236,22 +266,38 @@ public class TestExtendedProperties extends TestCase {
ep1.addProperty("one", "a");
assertEquals(1, ep1.size());
assertEquals(1, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals(1, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
ep1.addProperty("one", Boolean.TRUE);
assertEquals(1, ep1.size());
assertEquals(2, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals(Boolean.TRUE, ep1.getVector("one").get(1));
assertEquals(2, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
assertEquals(Boolean.TRUE, ep1.getList("one").get(1));
ep1.addProperty("one", "c,d");
assertEquals(1, ep1.size());
assertEquals(4, ep1.getVector("one").size());
assertEquals("a", ep1.getVector("one").get(0));
assertEquals(Boolean.TRUE, ep1.getVector("one").get(1));
assertEquals("c", ep1.getVector("one").get(2));
assertEquals("d", ep1.getVector("one").get(3));
assertEquals(4, ep1.getList("one").size());
assertEquals("a", ep1.getList("one").get(0));
assertEquals(Boolean.TRUE, ep1.getList("one").get(1));
assertEquals("c", ep1.getList("one").get(2));
assertEquals("d", ep1.getList("one").get(3));
}
public void testInheritDefaultProperties() {