Log Message
Merge new NamedArrayConverter from trunk.
Modified Paths
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java
- branches/v-1.4.x/xstream-distribution/src/content/changes.html
- branches/v-1.4.x/xstream-distribution/src/content/converters.html
Added Paths
Diff
Copied: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java (from rev 2175, trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java) (0 => 2176)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java (rev 0)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java 2013-12-03 23:49:41 UTC (rev 2176)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 XStream Committers.
+ * All rights reserved.
+ *
+ * The software in this package is published under the terms of the BSD
+ * style license a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ *
+ * Created on 03. December 2013 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.converters.extended;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.core.util.HierarchicalStreams;
+import com.thoughtworks.xstream.core.util.Primitives;
+import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.Mapper;
+
+/**
+ * @author Jörg Schaible
+ *
+ * @since upcoming
+ */
+public class NamedArrayConverter implements Converter {
+
+ private final Class arrayType;
+ private final String itemName;
+ private final Mapper mapper;
+
+ /**
+ * Construct a NamedArrayConverter.
+ * @param arrayType
+ * @param mapper
+ * @param itemName
+ * @since upcoming
+ */
+ public NamedArrayConverter(final Class arrayType, final Mapper mapper, final String itemName) {
+ if (!arrayType.isArray()) {
+ throw new IllegalArgumentException(arrayType.getName() + " is not an array");
+ }
+ this.arrayType = arrayType;
+ this.mapper = mapper;
+ this.itemName = itemName;
+ }
+
+ public boolean canConvert(final Class type) {
+ return type == arrayType;
+ }
+
+ public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) {
+ final int length = Array.getLength(source);
+ for (int i = 0; i < length; ++i) {
+ final Object item = Array.get(source, i);
+ final Class itemType = item == null
+ ? Mapper.Null.class
+ : arrayType.getComponentType().isPrimitive()
+ ? Primitives.unbox(item.getClass())
+ : item.getClass();
+ ExtendedHierarchicalStreamWriterHelper.startNode(writer, itemName, itemType);
+ if (!itemType.equals(arrayType.getComponentType())) {
+ final String attributeName = mapper.aliasForSystemAttribute("class");
+ if (attributeName != null) {
+ writer.addAttribute(attributeName, mapper.serializedClass(itemType));
+ }
+ }
+ if (item != null) {
+ context.convertAnother(item);
+ }
+ writer.endNode();
+ }
+ }
+
+ public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
+ final List list = new ArrayList();
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ final Object item;
+ final String className = HierarchicalStreams.readClassAttribute(reader, mapper);
+ final Class itemType = className == null ? arrayType.getComponentType() : mapper.realClass(className);
+ if (Mapper.Null.class.equals(itemType)) {
+ item = null;
+ } else {
+ item = context.convertAnother(null, itemType);
+ }
+ list.add(item);
+ reader.moveUp();
+ }
+ final Object array = Array.newInstance(arrayType.getComponentType(), list.size());
+ for (int i = 0; i < list.size(); ++i) {
+ Array.set(array, i, list.get(i));
+ }
+ return array;
+ }
+
+}
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java (2175 => 2176)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java 2013-12-03 23:46:40 UTC (rev 2175)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java 2013-12-03 23:49:41 UTC (rev 2176)
@@ -6,7 +6,7 @@
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
- * Created on 20.09.2013 by Joerg Schaible
+ * Created on 20. September 2013 by Joerg Schaible
*/
package com.thoughtworks.acceptance;
@@ -17,6 +17,7 @@
import com.thoughtworks.acceptance.objects.Category;
import com.thoughtworks.acceptance.objects.SampleMaps;
+import com.thoughtworks.xstream.converters.extended.NamedArrayConverter;
import com.thoughtworks.xstream.converters.extended.NamedCollectionConverter;
import com.thoughtworks.xstream.converters.extended.NamedMapConverter;
@@ -31,6 +32,7 @@
super.setUp();
xstream.alias("category", Category.class);
xstream.alias("maps", SampleMaps.class);
+ xstream.alias("arrays", Arrays.class);
xstream.aliasField("products", SampleMaps.class, "good");
xstream.addDefaultImplementation(LinkedHashMap.class, Map.class);
}
@@ -478,4 +480,124 @@
// OK
}
}
+
+ public static class Arrays {
+ String[] strings;
+ Object[] objects;
+ int[] ints;
+ short[][] shortArrays;
+ }
+
+ public void testArrayWithFinalType() {
+ xstream.registerLocalConverter(Arrays.class, "strings",
+ new NamedArrayConverter(String[].class, xstream.getMapper(), "name"));
+
+ Arrays arrays = new Arrays();
+ arrays.strings = new String[] {
+ "joe", "mauro"
+ };
+
+ String expected = ""
+ + "<arrays>\n"
+ + " <strings>\n"
+ + " <name>joe</name>\n"
+ + " <name>mauro</name>\n"
+ + " </strings>\n"
+ + "</arrays>";
+
+ assertBothWays(arrays, expected);
+ }
+
+ public void testArrayWithSuperTypes() {
+ xstream.registerLocalConverter(Arrays.class, "objects",
+ new NamedArrayConverter(Object[].class, xstream.getMapper(), "item"));
+
+ Arrays arrays = new Arrays();
+ arrays.objects = new Object[] {
+ "joe", Boolean.TRUE, new Integer(47)
+ };
+
+ String expected = (""
+ + "<arrays>\n"
+ + " <objects>\n"
+ + " <item class='string'>joe</item>\n"
+ + " <item class='boolean'>true</item>\n"
+ + " <item class='int'>47</item>\n"
+ + " </objects>\n"
+ + "</arrays>").replace('\'', '"');
+
+ assertBothWays(arrays, expected);
+ }
+
+ public void testArrayWithNullElement() {
+ xstream.registerLocalConverter(Arrays.class, "strings",
+ new NamedArrayConverter(String[].class, xstream.getMapper(), "name"));
+
+ Arrays arrays = new Arrays();
+ arrays.strings = new String[] {
+ "joe", null, "mauro"
+ };
+
+ String expected = ""
+ + "<arrays>\n"
+ + " <strings>\n"
+ + " <name>joe</name>\n"
+ + " <name class=\"null\"/>\n"
+ + " <name>mauro</name>\n"
+ + " </strings>\n"
+ + "</arrays>";
+
+ assertBothWays(arrays, expected);
+ }
+
+ public void testArrayWithPrimitives() {
+ xstream.registerLocalConverter(Arrays.class, "ints",
+ new NamedArrayConverter(int[].class, xstream.getMapper(), "value"));
+
+ Arrays arrays = new Arrays();
+ arrays.ints = new int[] {
+ 47, 0, -3
+ };
+
+ String expected = ""
+ + "<arrays>\n"
+ + " <ints>\n"
+ + " <value>47</value>\n"
+ + " <value>0</value>\n"
+ + " <value>-3</value>\n"
+ + " </ints>\n"
+ + "</arrays>";
+
+ assertBothWays(arrays, expected);
+ }
+
+ public void testArrayWithPrimitiveArrays() {
+ xstream.registerLocalConverter(Arrays.class, "shortArrays",
+ new NamedArrayConverter(short[][].class, xstream.getMapper(), "values"));
+
+ Arrays arrays = new Arrays();
+ arrays.shortArrays = new short[][] {
+ {47, 0, -3},
+ null,
+ {13, 7}
+ };
+
+ String expected = ""
+ + "<arrays>\n"
+ + " <shortArrays>\n"
+ + " <values>\n"
+ + " <short>47</short>\n"
+ + " <short>0</short>\n"
+ + " <short>-3</short>\n"
+ + " </values>\n"
+ + " <values class=\"null\"/>\n"
+ + " <values>\n"
+ + " <short>13</short>\n"
+ + " <short>7</short>\n"
+ + " </values>\n"
+ + " </shortArrays>\n"
+ + "</arrays>";
+
+ assertBothWays(arrays, expected);
+ }
}
Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2175 => 2176)
--- branches/v-1.4.x/xstream-distribution/src/content/changes.html 2013-12-03 23:46:40 UTC (rev 2175)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html 2013-12-03 23:49:41 UTC (rev 2176)
@@ -63,6 +63,7 @@
</li>
<li>JIRA:XSTR-739 and JIRA:XSTR-746: OrderRetainingMap fails if HashMap.putAll(Map) of Java Runtime is not
implemented calling put for every element within the map.</li>
+ <li>New NamedArrayConverter to define names of inner elements.</li>
</ul>
<h2>Minor changes</h2>
@@ -75,6 +76,7 @@
<h2>API changes</h2>
<ul>
+ <li>Added c.t.x.converters.extended.NamedArrayConverter for free element names in arrays.</li>
<li>Added constructors to c.t.x.io.xml.StandardStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li>
<li>Deprecated constructors of c.t.x.io.xml.StandardStaxDriver taking a XmlFriendlyNameCoder.</li>
<li>Added constructors to c.t.x.io.xml.BEAStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li>
Modified: branches/v-1.4.x/xstream-distribution/src/content/converters.html (2175 => 2176)
--- branches/v-1.4.x/xstream-distribution/src/content/converters.html 2013-12-03 23:46:40 UTC (rev 2175)
+++ branches/v-1.4.x/xstream-distribution/src/content/converters.html 2013-12-03 23:49:41 UTC (rev 2176)
@@ -52,7 +52,7 @@
</tr>
<tr>
<td><a href=""
- <td>Any kind of array</td>
+ <td>any kind of array</td>
<td class="example">
<<i>string</i>-array><br/>
<<i>string</i>>apple</<i>string</i>><br/>
@@ -83,12 +83,12 @@
<td>byte[]</td>
<td class="example"><byte-array>AHiEFiEABQ==</byte-array></td>
<td>Uses Base64 encoding to store binary data in XML. Converter can be registered globally or locally.</td>
- <td> </td>
+ <td>normal</td>
</tr>
<tr>
<td><a href=""
<td>char<br/>java.lang.Character</td>
- <td class="example"><char>X</char></br><char null="true"/></td>
+ <td class="example"><char>X</char><br/><char null="true"/></td>
<td>The '\0' character is invalid in XML.</td>
<td>normal</td>
</tr>
@@ -128,6 +128,20 @@
<td>normal</td>
</tr>
<tr>
+ <td><a href=""
+ <td>any kind of array</td>
+ <td class="example">
+ <<i>string</i>-array><br/>
+ <<i>product</i>>apple</<i>product</i>><br/>
+ <<i>product</i>>banana</<i>product</i>><br/>
+ <<i>product</i>>cabbage</<i>product</i>><br/>
+ <<i>string</i>-array>
+ </td>
+ <td>This supports arrays of primitives as well as objects. It also supports multi-dimensional arrays, even if
+ they are non-rectangular. Should be registered locally or for an individual array type.</td>
+ <td> </td>
+ </tr>
+ <tr>
<td><a href=""
<td>short<br/>java.lang.Short</td>
<td class="example"><short>1445</short></td>
To unsubscribe from this list please visit:
