Log Message
Deserialized TreeSet does not honor remove(Object) return value contract (XSTR-757).
Modified Paths
Diff
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java (2286 => 2287)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2014-05-31 16:17:06 UTC (rev 2286)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 2014-06-16 21:18:00 UTC (rev 2287)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004, 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -41,9 +41,41 @@
*/
public class TreeSetConverter extends CollectionConverter {
private transient TreeMapConverter treeMapConverter;
- private final static Field sortedMapField =
- JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, SortedMap.class, false) : null;
+ private final static Field sortedMapField;
+ private final static Object constantValue;
+ static {
+ Object value = null;
+ sortedMapField = JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, SortedMap.class, false) : null;
+ if (sortedMapField != null) {
+ TreeSet set = new TreeSet();
+ set.add("1");
+ set.add("2");
+ Map<String, Object> backingMap = null;
+ try {
+ backingMap = (Map)sortedMapField.get(set);
+ } catch (final IllegalAccessException e) {
+ // give up;
+ }
+ if (backingMap != null) {
+ Object[] values = backingMap.values().toArray();
+ if (values[0] == values[1]) {
+ value = values[0];
+ }
+ }
+ } else {
+ Field valueField = Fields.locate(TreeSet.class, Object.class, true);
+ if (valueField != null) {
+ try {
+ value = valueField.get(null);
+ } catch (final IllegalAccessException e) {
+ // give up;
+ }
+ }
+ }
+ constantValue = value;
+ }
+
public TreeSetConverter(Mapper mapper) {
super(mapper, TreeSet.class);
readResolve();
@@ -103,7 +135,7 @@
UnmarshallingContext context, Map map, final Map target) {
populateCollection(reader, context, new AbstractList() {
public boolean add(Object object) {
- return target.put(object, object) != null;
+ return target.put(object, constantValue != null ? constantValue : object) != null;
}
public Object get(int location) {
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java (2286 => 2287)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java 2014-05-31 16:17:06 UTC (rev 2286)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java 2014-06-16 21:18:00 UTC (rev 2287)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers.
+ * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -200,4 +200,14 @@
assertEquals(new ArrayList(set), new ArrayList(result));
}
}
+
+ public void testTreeSetRemoveWorksProperlyAfterDeserialization() {
+ TreeSet set = new TreeSet();
+ set.add("guy");
+ set.add("hi");
+ set.add("bye");
+
+ TreeSet result = (TreeSet) xstream.fromXML(xstream.toXML(set));
+ assertTrue(result.remove("hi"));
+ }
}
Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2286 => 2287)
--- branches/v-1.4.x/xstream-distribution/src/content/changes.html 2014-05-31 16:17:06 UTC (rev 2286)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html 2014-06-16 21:18:00 UTC (rev 2287)
@@ -36,6 +36,7 @@
<ul>
<li>XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li>
+ <li>XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li>
<li>Fix: DateConverter ignores provided locale.</li>
<li>Fix: WeakCache.entrySet().iterator().next.setValue(value) returns the reference instead of the old value.</li>
<li>Fix: SqlTimestampConverter throws IllegalArgumentException instead of ConversionException on fromString().</li>
To unsubscribe from this list please visit:
