Log Message
Fix: ToAttributedValueConverter silently appends fields without attribute support to the value. Avoid usage of deprecated API.
Modified Paths
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java (2078 => 2079)
--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java 2013-06-29 22:02:05 UTC (rev 2078)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java 2013-07-01 22:43:10 UTC (rev 2079)
@@ -47,6 +47,7 @@
* @since 1.4
*/
public class ToAttributedValueConverter implements Converter {
+ private static final String STRUCTURE_MARKER = "";
private final Class type;
private final Mapper mapper;
private final ReflectionProvider reflectionProvider;
@@ -140,13 +141,17 @@
}
if (value != null) {
+ boolean isValueField = valueField != null && fieldIsEqual(field);
+ if (isValueField) {
+ definingType[0] = definedIn;
+ fieldType[0] = type;
+ realValue[0] = value;
+ tagValue[0] = STRUCTURE_MARKER;
+ }
if (converter instanceof SingleValueConverter) {
final String str = ((SingleValueConverter)converter).toString(value);
- if (valueField != null && fieldIsEqual(field)) {
- definingType[0] = definedIn;
- fieldType[0] = type;
- realValue[0] = value;
+ if (isValueField) {
tagValue[0] = str;
} else {
if (str != null) {
@@ -154,7 +159,13 @@
}
}
} else {
- context.convertAnother(value);
+ if (!isValueField) {
+ final ConversionException exception = new ConversionException(
+ "Cannot write element as attribute");
+ exception.add("alias", alias);
+ exception.add("type", sourceType.getName());
+ throw exception;
+ }
}
}
}
@@ -173,7 +184,11 @@
}
}
- writer.setValue(tagValue[0]);
+ if (tagValue[0] == STRUCTURE_MARKER) {
+ context.convertAnother(realValue[0]);
+ } else {
+ writer.setValue(tagValue[0]);
+ }
}
}
Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java (2078 => 2079)
--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java 2013-06-29 22:02:05 UTC (rev 2078)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java 2013-07-01 22:43:10 UTC (rev 2079)
@@ -18,6 +18,7 @@
import com.thoughtworks.acceptance.objects.Software;
import com.thoughtworks.acceptance.someobjects.X;
import com.thoughtworks.acceptance.someobjects.Y;
+import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.SingleValueConverterWrapper;
import com.thoughtworks.xstream.converters.basic.IntConverter;
import com.thoughtworks.xstream.converters.basic.StringConverter;
@@ -29,9 +30,11 @@
import com.thoughtworks.xstream.core.DefaultConverterLookup;
import com.thoughtworks.xstream.core.TreeMarshaller;
import com.thoughtworks.xstream.core.TreeUnmarshaller;
+import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
+import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.io.xml.XppReader;
import com.thoughtworks.xstream.mapper.ArrayMapper;
import com.thoughtworks.xstream.mapper.ClassAliasingMapper;
@@ -48,6 +51,7 @@
* @author jos / last modified by $Author$
*/
public class ToAttributedValueConverterTest extends TestCase {
+ private HierarchicalStreamDriver driver;
private DefaultConverterLookup converterLookup;
private ReflectionProvider reflectionProvider;
private Mapper mapper;
@@ -63,6 +67,7 @@
mapper = new DefaultImplementationsMapper(new ArrayMapper(classAliasingMapper));
reflectionProvider = new Sun14ReflectionProvider();
+ driver = new XppDriver();
converterLookup = new DefaultConverterLookup();
converterLookup.registerConverter(
@@ -88,7 +93,7 @@
compactWriter.flush();
assertEquals("<software>XStream</software>", writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
assertEquals(
name, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null));
@@ -111,7 +116,7 @@
"<open-source vendor=\"Codehaus\" license=\"BSD\">XStream</open-source>",
writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
assertEquals(
software, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null));
@@ -141,7 +146,7 @@
+ " <open-source vendor=\"Codehaus\" name=\"XStream\">BSD</open-source>\n"
+ "</software-array>", writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
Software[] array = (Software[])new TreeUnmarshaller(
null, reader, converterLookup, mapper).start(null);
@@ -163,7 +168,7 @@
compactWriter.flush();
assertEquals("<software/>", writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
assertEquals(
"",
@@ -184,7 +189,7 @@
compactWriter.flush();
assertEquals("<software vendor=\"Codehaus\" name=\"XStream\"/>", writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
assertEquals(
software, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null));
@@ -208,8 +213,26 @@
assertEquals(
"<x aStr=\"xXx\" anInt=\"42\"><yField>inner</yField></x>", writer.toString());
- final HierarchicalStreamReader reader = new XppReader(new StringReader(
+ final HierarchicalStreamReader reader = driver.createReader(new StringReader(
writer.toString()));
assertEquals(x, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null));
}
+
+ public void testFailsWhenFieldCannotBeWrittenAsAttribute() {
+ converterLookup.registerConverter(new ToAttributedValueConverter(
+ X.class, mapper, reflectionProvider, converterLookup, "aStr"), 0);
+
+ final X x = new X(42);
+ x.aStr = "xXx";
+ x.innerObj = new Y();
+ x.innerObj.yField = "inner";
+ final StringWriter writer = new StringWriter();
+ final CompactWriter compactWriter = new CompactWriter(writer);
+ try {
+ new TreeMarshaller(compactWriter, converterLookup, mapper).start(x, null);
+ fail("Thrown " + ConversionException.class.getName() + " expected");
+ } catch (final ConversionException e) {
+ assertTrue(e.getMessage().contains("innerObj"));
+ }
+ }
}
Modified: trunk/xstream-distribution/src/content/changes.html (2078 => 2079)
--- trunk/xstream-distribution/src/content/changes.html 2013-06-29 22:02:05 UTC (rev 2078)
+++ trunk/xstream-distribution/src/content/changes.html 2013-07-01 22:43:10 UTC (rev 2079)
@@ -55,6 +55,7 @@
XStream 1.4.</li>
<li>JIRA:XSTR-300: New EnumToStringConverter to support custom string representations of Enum values.</li>
<li>JIRA:XSTR-735: Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.</li>
+ <li>Fix: ToAttributedValueConverter silently appends fields without attribute support to the value.</li>
</ul>
<h2>Minor changes</h2>
To unsubscribe from this list please visit:
