Log Message
New constructors for CollectionConverter and MapConverter to allow registration for an individual type.
Modified Paths
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java
- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java
- trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java
- trunk/xstream-distribution/src/content/changes.html
- trunk/xstream-distribution/src/content/converters.html
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003, 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -36,16 +36,35 @@
*/
public class CollectionConverter extends AbstractCollectionConverter {
+ private final Class type;
+
public CollectionConverter(Mapper mapper) {
+ this(mapper, null);
+ }
+
+ /**
+ * Construct a CollectionConverter for a special Collection type.
+ * @param mapper the mapper
+ * @param type the Collection type to handle
+ * @since upcoming
+ */
+ public CollectionConverter(Mapper mapper, Class type) {
super(mapper);
+ this.type = type;
+ if (type != null && !Collection.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(type + " not of type " + Collection.class);
+ }
}
public boolean canConvert(Class type) {
+ if (this.type != null) {
+ return type.equals(this.type);
+ }
return type.equals(ArrayList.class)
- || type.equals(HashSet.class)
- || type.equals(LinkedList.class)
- || type.equals(Vector.class)
- || (JVM.is14() && type.getName().equals("java.util.LinkedHashSet"));
+ || type.equals(HashSet.class)
+ || type.equals(LinkedList.class)
+ || type.equals(Vector.class)
+ || (JVM.is14() && type.getName().equals("java.util.LinkedHashSet"));
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
@@ -79,4 +98,8 @@
Object item = readItem(reader, context, collection);
target.add(item);
}
+
+ protected Object createCollection(Class type) {
+ return super.createCollection(this.type != null ? this.type : type);
+ }
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -36,17 +36,36 @@
*/
public class MapConverter extends AbstractCollectionConverter {
+ private final Class type;
+
public MapConverter(Mapper mapper) {
+ this(mapper, null);
+ }
+
+ /**
+ * Construct a MapConverter for a special Map type.
+ * @param mapper the mapper
+ * @param type the type to handle
+ * @since upcoming
+ */
+ public MapConverter(Mapper mapper, Class type) {
super(mapper);
+ this.type = type;
+ if (type != null && !Map.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException(type + " not of type " + Map.class);
+ }
}
public boolean canConvert(Class type) {
+ if (this.type != null) {
+ return type.equals(this.type);
+ }
return type.equals(HashMap.class)
- || type.equals(Hashtable.class)
- || type.getName().equals("java.util.LinkedHashMap")
- || type.getName().equals("java.util.concurrent.ConcurrentHashMap")
- || type.getName().equals("sun.font.AttributeMap") // Used by java.awt.Font in JDK 6
- ;
+ || type.equals(Hashtable.class)
+ || type.getName().equals("java.util.LinkedHashMap")
+ || type.getName().equals("java.util.concurrent.ConcurrentHashMap")
+ || type.getName().equals("sun.font.AttributeMap") // Used by java.awt.Font in JDK 6
+ ;
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
@@ -94,4 +113,7 @@
target.put(key, value);
}
+ protected Object createCollection(Class type) {
+ return super.createCollection(this.type != null ? this.type : type);
+ }
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -50,13 +50,9 @@
private final static Field comparatorField = Fields.locate(TreeMap.class, Comparator.class, false);
public TreeMapConverter(Mapper mapper) {
- super(mapper);
+ super(mapper, TreeMap.class);
}
- public boolean canConvert(Class type) {
- return type.equals(TreeMap.class);
- }
-
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
SortedMap sortedMap = (SortedMap) source;
marshalComparator(sortedMap.comparator(), writer, context);
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -45,14 +45,10 @@
JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, SortedMap.class, false) : null;
public TreeSetConverter(Mapper mapper) {
- super(mapper);
+ super(mapper, TreeSet.class);
readResolve();
}
- public boolean canConvert(Class type) {
- return type.equals(TreeSet.class);
- }
-
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
SortedSet sortedSet = (SortedSet) source;
treeMapConverter.marshalComparator(sortedSet.comparator(), writer, context);
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -44,7 +44,20 @@
* @since upcoming
*/
public NamedCollectionConverter(Mapper mapper, String itemName, Class itemType) {
- super(mapper);
+ this(null, mapper, itemName, itemType);
+ }
+
+ /**
+ * Constructs a NamedCollectionConverter handling an explicit Collection type.
+ *
+ * @param type the Collection type to handle
+ * @param mapper the mapper
+ * @param itemName the name of the items
+ * @param itemType the base type of the items
+ * @since upcoming
+ */
+ public NamedCollectionConverter(Class type, Mapper mapper, String itemName, Class itemType) {
+ super(mapper, type);
this.name = itemName;
this.type = itemType;
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java (2130 => 2131)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -139,14 +139,33 @@
}
/**
- * Constructs a NamedMapConverter.
+ * Constructs a NamedMapConverter handling an explicit Map type.
*
+ * @param type the Map type this instance will handle
* @param mapper the mapper
* @param entryName the name of the entry elements
* @param keyName the name of the key elements
* @param keyType the base type of key elements
* @param valueName the name of the value elements
* @param valueType the base type of value elements
+ * @since upcoming
+ */
+ public NamedMapConverter(
+ Class type, Mapper mapper, String entryName, String keyName, Class keyType,
+ String valueName, Class valueType) {
+ this(
+ type, mapper, entryName, keyName, keyType, valueName, valueType, false, false, null);
+ }
+
+ /**
+ * Constructs a NamedMapConverter with attribute support.
+ *
+ * @param mapper the mapper
+ * @param entryName the name of the entry elements
+ * @param keyName the name of the key elements
+ * @param keyType the base type of key elements
+ * @param valueName the name of the value elements
+ * @param valueType the base type of value elements
* @param keyAsAttribute flag to write key as attribute of entry element
* @param valueAsAttribute flag to write value as attribute of entry element
* @param lookup used to lookup SingleValueConverter for attributes
@@ -156,7 +175,31 @@
Mapper mapper, String entryName, String keyName, Class keyType, String valueName,
Class valueType, boolean keyAsAttribute, boolean valueAsAttribute,
ConverterLookup lookup) {
- super(mapper);
+ this(
+ null, mapper, entryName, keyName, keyType, valueName, valueType, keyAsAttribute,
+ valueAsAttribute, lookup);
+ }
+
+ /**
+ * Constructs a NamedMapConverter with attribute support handling an explicit Map type.
+ *
+ * @param type the Map type this instance will handle
+ * @param mapper the mapper
+ * @param entryName the name of the entry elements
+ * @param keyName the name of the key elements
+ * @param keyType the base type of key elements
+ * @param valueName the name of the value elements
+ * @param valueType the base type of value elements
+ * @param keyAsAttribute flag to write key as attribute of entry element
+ * @param valueAsAttribute flag to write value as attribute of entry element
+ * @param lookup used to lookup SingleValueConverter for attributes
+ * @since upcoming
+ */
+ public NamedMapConverter(
+ Class type, Mapper mapper, String entryName, String keyName, Class keyType,
+ String valueName, Class valueType, boolean keyAsAttribute, boolean valueAsAttribute,
+ ConverterLookup lookup) {
+ super(mapper, type);
this.entryName = entryName != null && entryName.length() == 0 ? null : entryName;
this.keyName = keyName != null && keyName.length() == 0 ? null : keyName;
this.keyType = keyType;
Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java (2130 => 2131)
--- trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java 2013-09-25 22:35:07 UTC (rev 2131)
@@ -21,6 +21,7 @@
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamConverters;
+import com.thoughtworks.xstream.annotations.XStreamInclude;
import com.thoughtworks.xstream.converters.basic.BooleanConverter;
import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.converters.extended.NamedMapConverter;
@@ -184,13 +185,13 @@
}
public void testAnnotatedNamedMapConverter() {
- Map<ContainsMap.E, String> map = new LinkedHashMap<ContainsMap.E, String>();
+ Map<ContainsMap.E, String> map = new MyEnumMap();
map.put(ContainsMap.E.FOO, "foo");
map.put(ContainsMap.E.BAR, "bar");
final ContainsMap value = new ContainsMap(map);
String expected = (""
+ "<container>\n"
- + " <map class='linked-hash-map'>\n"
+ + " <map class='my-enums'>\n"
+ " <issue key='FOO'>foo</issue>\n"
+ " <issue key='BAR'>bar</issue>\n"
+ " </map>\n"
@@ -198,6 +199,7 @@
assertBothWays(value, expected);
}
+ @XStreamInclude({MyEnumMap.class})
@XStreamAlias("container")
public static class ContainsMap extends StandardObject {
public enum E {
@@ -205,11 +207,15 @@
};
@XStreamConverter(value = NamedMapConverter.class, strings = {"issue", "key", ""}, types = {
- E.class, String.class}, booleans = {true, false}, useImplicitType = false)
+ MyEnumMap.class, E.class, String.class}, booleans = {true, false}, useImplicitType = false)
private Map<E, String> map;
public ContainsMap(Map<E, String> map) {
this.map = map;
}
}
+
+ @XStreamAlias("my-enums")
+ public static class MyEnumMap extends LinkedHashMap<ContainsMap.E, String> {
+ }
}
Modified: trunk/xstream-distribution/src/content/changes.html (2130 => 2131)
--- trunk/xstream-distribution/src/content/changes.html 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream-distribution/src/content/changes.html 2013-09-25 22:35:07 UTC (rev 2131)
@@ -71,6 +71,7 @@
<li>JIRA:XSTR-719: Support replacement of default converter in any case.</li>
<li>JIRA:XSTR-725: processAnnotation performance improvement in concurrent situation.</li>
<li>JIRA:XSTR-721: EnumConverter is more lenient while parsing constants.</li>
+ <li>New constructors for CollectionConverter and MapConverter to allow registration for an individual type.</li>
<li>JIRA:XSTR-724: Cache class name lookup failures.</li>
<li>Current IBM JDK for Java 1.4.2 no longer has a reverse field ordering.</li>
<li>JIRA:XSTR-457: Do not write 'defined-in' attribute it not needed.</li>
@@ -102,6 +103,8 @@
implementations of javax.xml.stream.XMLInputFactory (resp. javax.xml.stream.XMLOutputFactory) delivered with
the Java Runtime since Java 6.</li>
<li>Added c.t.x.core.ClassLoaderReference.</li>
+ <li>Added constructors taking an additional type argument for c.t.x.converter.collections.CollectionConverter
+ and c.t.x.converter.collections.MapConverter.</li>
<li>Added constructors taking a ClassLoaderReference instead of a ClassLoader and deprecated the ones taking the ClassLoader:
<ul>
<li>c.t.x.XStream</li>
Modified: trunk/xstream-distribution/src/content/converters.html (2130 => 2131)
--- trunk/xstream-distribution/src/content/converters.html 2013-09-25 01:33:00 UTC (rev 2130)
+++ trunk/xstream-distribution/src/content/converters.html 2013-09-25 22:35:07 UTC (rev 2131)
@@ -211,7 +211,9 @@
<big-decimal>12345.4555</big-decimal><br/>
</linked-list>
</td>
- <td>The objects inside the collection can be any type of objects, including nested collections.</td>
+ <td>The objects inside the collection can be any type of objects, including nested collections. Can be
+ registered for an individual Collection type or locally, suppression of implicit type might be
+ necessary.</td>
<td>normal</td>
</tr>
<tr>
@@ -229,23 +231,11 @@
</entry><br/>
</map>
</td>
- <td>Both key and values can be any type of objects.</td>
+ <td>Both key and values can be any type of objects. Can be registered for an individual Map type or
+ locally, suppression of implicit type might be necessary.</td>
<td>normal</td>
</tr>
<tr>
- <td><a href=""
- <td>java.util.ArrayList<br/>java.util.LinkedList<br/>java.util.HashSet<br/>java.util.Vector<br/>java.util.LinkedHashSet</td>
- <td class="example">
- <linked-list><br/>
- <string>apple</string><br/>
- <string>banana</string><br/>
- <big-decimal>12345.4555</big-decimal><br/>
- </linked-list>
- </td>
- <td>The objects inside the collection can be any type of objects, including nested collections.</td>
- <td>normal</td>
- </tr>
- <tr>
<td><a href=""
<td>java.util.ArrayList<br/>java.util.LinkedList<br/>java.util.HashSet<br/>java.util.Vector<br/>java.util.LinkedHashSet</td>
<td class="example">
@@ -256,7 +246,7 @@
</linked-list>
</td>
<td>The objects inside the collection can be any type of objects, including nested collections. Should
- be registered locally.</td>
+ be registered locally or for an individual Collection type.</td>
<td> </td>
</tr>
<tr>
@@ -275,8 +265,8 @@
</map>
</td>
<td>Both key and values can be any type of objects. If key or value are written as attributes or if
- the value is written as text of the entry element, those types must be hjandled by a
- SingleValueConverter. Should be registered locally.</td>
+ the value is written as text of the entry element, those types must be handled by a
+ SingleValueConverter. Should be registered locally or for an individual Map type.</td>
<td> </td>
</tr>
<tr>
To unsubscribe from this list please visit:
