Title: [2040] trunk: New EnumToStringConverter to support custom string representations of Enum values (XSTR-300).

Diff

Added: trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java (0 => 2040)


--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java	                        (rev 0)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java	2013-03-14 01:22:08 UTC (rev 2040)
@@ -0,0 +1,100 @@
+/*
+ * 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 14. March 2013 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.converters.enums;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
+
+
+/**
+ * A single value converter for a special enum type using its string representation.
+ * 
+ * @author Jörg Schaible
+ * @since upcoming
+ */
+public class EnumToStringConverter<T extends Enum<T>> extends AbstractSingleValueConverter {
+
+    private final Class<T> enumType;
+    private final Map<String, T> strings;
+    private final EnumMap<T, String> values;
+
+    public EnumToStringConverter(Class<T> type) {
+        this(type, extractStringMap(type), null);
+    }
+
+    public EnumToStringConverter(Class<T> type, Map<String, T> strings) {
+        this(type, strings, buildValueMap(type, strings));
+    }
+
+    private EnumToStringConverter(
+        Class<T> type, Map<String, T> strings, EnumMap<T, String> values) {
+        enumType = type;
+        this.strings = strings;
+        this.values = values;
+    }
+
+    private static <T extends Enum<T>> Map<String, T> extractStringMap(Class<T> type) {
+        if (!Enum.class.isAssignableFrom(type) && type != Enum.class) {
+            throw new IllegalArgumentException("Converter can only handle enum types");
+        }
+        EnumSet<T> values = EnumSet.allOf(type);
+        Map<String, T> strings = new HashMap<String, T>(values.size());
+        for (T value : values) {
+            if (strings.put(value.toString(), value) != null) {
+                throw new IllegalArgumentException("Enum type "
+                    + type.getName()
+                    + " does not have unique string representations for its values");
+            }
+        }
+        return strings;
+    }
+
+    private static <T extends Enum<T>> EnumMap<T, String> buildValueMap(Class<T> type,
+        Map<String, T> strings) {
+        EnumMap<T, String> values = new EnumMap<T, String>(type);
+        for (Map.Entry<String, T> entry : strings.entrySet()) {
+            values.put(entry.getValue(), entry.getKey());
+        }
+        return values;
+    }
+
+    @Override
+    public boolean canConvert(Class type) {
+        return enumType.isAssignableFrom(type);
+    }
+
+    @Override
+    public String toString(Object obj) {
+        Enum value = Enum.class.cast(obj);
+        return values == null ? value.toString() : values.get(value);
+    }
+
+    @Override
+    public Object fromString(String str) {
+        if (str == null) {
+            return null;
+        }
+        T result = strings.get(str);
+        if (result == null) {
+            throw new ConversionException("Invalid string representation for enum type "
+                + enumType.getName()
+                + ": <"
+                + str
+                + ">");
+        }
+        return result;
+    }
+}
Property changes on: trunk/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java
___________________________________________________________________

Added: svn:keywords

Added: svn:eol-style

Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java (2039 => 2040)


--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java	2013-03-13 23:47:35 UTC (rev 2039)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java	2013-03-14 01:22:08 UTC (rev 2040)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -53,7 +53,7 @@
         xstream.alias("poly", PolymorphicEnum.class);
         EnumSet<PolymorphicEnum> set = EnumSet.allOf(PolymorphicEnum.class);
 
-        String expectedXml = "<enum-set enum-type=\"poly\">A,B</enum-set>";
+        String expectedXml = "<enum-set enum-type=\"poly\">A,B,C</enum-set>";
 
         assertEquals(expectedXml, xstream.toXML(set));
         assertEquals(set, xstream.fromXML(expectedXml));

Added: trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java (0 => 2040)


--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java	                        (rev 0)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java	2013-03-14 01:22:08 UTC (rev 2040)
@@ -0,0 +1,69 @@
+/*
+ * 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 14. March 2013 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.converters.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.XStream;
+import junit.framework.TestCase;
+
+
+// ***** READ THIS *****
+// This class will only compile with JDK 1.5.0 or above as it test Java enums.
+// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it.
+
+/**
+ * @author J&ouml;rg Schaible
+ */
+public class EnumToStringConverterTest extends TestCase {
+
+    private XStream xstream;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        xstream = new XStream();
+        xstream.alias("simple", SimpleEnum.class);
+        xstream.alias("big", BigEnum.class);
+        xstream.alias("polymorphic", PolymorphicEnum.class);
+
+        Map<String, SimpleEnum> map = new HashMap<String, SimpleEnum>();
+        map.put("0xff0000", SimpleEnum.RED);
+        map.put("0x00ff00", SimpleEnum.GREEN);
+        map.put("0x0000ff", SimpleEnum.BLUE);
+        xstream.registerConverter(new EnumToStringConverter<SimpleEnum>(SimpleEnum.class, map));
+        xstream.registerConverter(new EnumToStringConverter<BigEnum>(BigEnum.class));
+        xstream.registerConverter(new EnumToStringConverter<PolymorphicEnum>(
+            PolymorphicEnum.class));
+    }
+
+    public void testMapsEnumToProvidedStringValue() {
+        String expectedXml = "<simple>0x00ff00</simple>";
+        SimpleEnum in = SimpleEnum.GREEN;
+        assertEquals(expectedXml, xstream.toXML(in));
+        assertEquals(in, xstream.fromXML(expectedXml));
+    }
+
+    public void testMapsEnumToStringDefaultValue() {
+        String expectedXml = "<big>C3</big>";
+        BigEnum in = BigEnum.C3;
+        assertEquals(expectedXml, xstream.toXML(in));
+        assertEquals(in, xstream.fromXML(expectedXml));
+    }
+
+    public void testMapsToPolymorphicStringValue() {
+        String expectedXml = "<polymorphic>banana</polymorphic>";
+        PolymorphicEnum in = PolymorphicEnum.B;
+        assertEquals(expectedXml, xstream.toXML(in));
+        assertEquals(in, xstream.fromXML(expectedXml));
+    }
+
+}
Property changes on: trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java
___________________________________________________________________

Added: svn:keywords

Added: svn:eol-style

Modified: trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java (2039 => 2040)


--- trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java	2013-03-13 23:47:35 UTC (rev 2039)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java	2013-03-14 01:22:08 UTC (rev 2040)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007, 2008 XStream Committers.
+ * Copyright (C) 2006, 2007, 2008, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -21,5 +21,15 @@
         public String fruit() {
             return "banana";
         }
-    };
+    },
+    C;
+    
+    public String fruit() {
+        return "unknown";
+    }
+    
+    @Override
+    public String toString() {
+        return fruit();
+    }
 }

Modified: trunk/xstream-distribution/src/content/changes.html (2039 => 2040)


--- trunk/xstream-distribution/src/content/changes.html	2013-03-13 23:47:35 UTC (rev 2039)
+++ trunk/xstream-distribution/src/content/changes.html	2013-03-14 01:22:08 UTC (rev 2040)
@@ -50,6 +50,7 @@
     	runtime based on GNU	Classpath (at least up to version 0.98).</li>
     	<li>JIRA:XSTR-728: XStream creates invalid JSON with JsonHierarchicalStreamDriver for custom converters since
     	XStream 1.4.</li>
+    	<li>JIRA:XSTR-300: New EnumToStringConverter to support custom string representations of Enum values.</li>
     </ul>
 
     <h2>Minor changes</h2>

Modified: trunk/xstream-distribution/src/content/converters.html (2039 => 2040)


--- trunk/xstream-distribution/src/content/converters.html	2013-03-13 23:47:35 UTC (rev 2039)
+++ trunk/xstream-distribution/src/content/converters.html	2013-03-14 01:22:08 UTC (rev 2040)
@@ -1,7 +1,7 @@
 <html>
 <!--
  Copyright (C) 2005, 2006 Joe Walnes.
- Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream committers.
+ Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream committers.
  All rights reserved.
  
  The software in this package is published under the terms of the BSD
@@ -163,6 +163,13 @@
                 <td class="example">&lt;java.lang.annotation.RetentionPolicy&gt;<br/>CLASS<br/>&lt;/java.lang.annotation.RetentionPolicy&gt;</td>
                 <td>Available under Java 1.5 or greater.</td>
             </tr>
+            <tr>
+                <td><a href=""
+                <td>java.lang.Enum</td>
+                <td>The Converter must be initialized with an Enum type and an optional mapping between strings and enum values. By default
+                it will use the Enum's string representation as value.</td>
+                <td>Available under Java 1.5 or greater. Must be registered explicitly for the Enum type.</td>
+            </tr>
 
             <!-- .................................................................................................. -->
             <tr>

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to