Title: [2081] trunk: ToAttributedValueConverter fails to write enums as attributes (XSTR-741).
Revision
2081
Author
joehni
Date
2013-07-02 17:52:03 -0500 (Tue, 02 Jul 2013)

Log Message

ToAttributedValueConverter fails to write enums as attributes (XSTR-741).

Modified Paths

Diff

Modified: trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java (2080 => 2081)


--- trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java	2013-07-01 23:32:45 UTC (rev 2080)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java	2013-07-02 22:52:03 UTC (rev 2081)
@@ -22,16 +22,21 @@
 import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.ConverterLookup;
+import com.thoughtworks.xstream.converters.ConverterMatcher;
 import com.thoughtworks.xstream.converters.MarshallingContext;
 import com.thoughtworks.xstream.converters.SingleValueConverter;
 import com.thoughtworks.xstream.converters.UnmarshallingContext;
 import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.DuplicateFieldException;
 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
+import com.thoughtworks.xstream.core.JVM;
+import com.thoughtworks.xstream.core.util.DependencyInjectionFactory;
 import com.thoughtworks.xstream.core.util.FastField;
 import com.thoughtworks.xstream.core.util.HierarchicalStreams;
 import com.thoughtworks.xstream.core.util.Primitives;
 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.mapper.AttributeMapper;
+import com.thoughtworks.xstream.mapper.DefaultMapper;
 import com.thoughtworks.xstream.mapper.Mapper;
 
 
@@ -50,6 +55,7 @@
     private static final String STRUCTURE_MARKER = "";
     private final Class type;
     private final Mapper mapper;
+    private final Mapper enumMapper;
     private final ReflectionProvider reflectionProvider;
     private final ConverterLookup lookup;
     private final Field valueField;
@@ -100,8 +106,23 @@
             }
             this.valueField = field;
         }
+        enumMapper = JVM.is15() ? createEnumMapper(mapper) : null;
     }
 
+    private Mapper createEnumMapper(final Mapper mapper) {
+        try {
+            Class enumMapperClass = Class.forName(
+                "com.thoughtworks.xstream.mapper.EnumMapper", true,
+                Mapper.class.getClassLoader());
+            return (Mapper)DependencyInjectionFactory.newInstance(
+                enumMapperClass,
+                new Object[]{new UseAttributeForEnumMapper(mapper
+                    .lookupMapperOfType(DefaultMapper.class))});
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     public boolean canConvert(final Class type) {
         return this.type == type;
     }
@@ -135,7 +156,9 @@
                     throw exception;
                 }
 
-                Converter converter = mapper.getLocalConverter(definedIn, fieldName);
+                ConverterMatcher converter = isEnum(type)
+                    ? enumMapper.getConverterFromItemType(null, type, null)
+                    : mapper.getLocalConverter(definedIn, fieldName);
                 if (converter == null) {
                     converter = lookup.lookupConverterForType(type);
                 }
@@ -219,7 +242,9 @@
 
                 Class type = field.getType();
                 final Class declaringClass = field.getDeclaringClass();
-                Converter converter = mapper.getLocalConverter(declaringClass, fieldName);
+                ConverterMatcher converter = isEnum(type)
+                        ? enumMapper.getConverterFromItemType(null, type, null)
+                        : mapper.getLocalConverter(declaringClass, fieldName);
                 if (converter == null) {
                     converter = lookup.lookupConverterForType(type);
                 }
@@ -315,4 +340,39 @@
         return valueField.getName().equals(field.getName())
             && valueField.getDeclaringClass().getName().equals(field.getDeclaringClass());
     }
+    
+    private static boolean isEnum(Class type) {
+        while(type != Object.class) {
+            if (type.getName().equals("java.lang.Enum")) {
+                return true;
+            }
+            type = type.getSuperclass();
+        }
+        return false;
+    }
+    
+    private static class UseAttributeForEnumMapper extends AttributeMapper {
+
+        public UseAttributeForEnumMapper(Mapper wrapped) {
+            super(wrapped, null, null);
+        }
+
+        @Override
+        public boolean shouldLookForSingleValueConverter(String fieldName, Class type,
+            Class definedIn) {
+            return isEnum(type);
+        }
+
+        @Override
+        public SingleValueConverter getConverterFromItemType(String fieldName, Class type,
+            Class definedIn) {
+            return null;
+        }
+
+        @Override
+        public SingleValueConverter getConverterFromAttribute(Class definedIn,
+            String attribute, Class type) {
+            return null;
+        }
+    }
 }

Modified: trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java (2080 => 2081)


--- trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java	2013-07-01 23:32:45 UTC (rev 2080)
+++ trunk/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java	2013-07-02 22:52:03 UTC (rev 2081)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2011, 2012 XStream Committers.
+ * Copyright (C) 2008, 2009, 2011, 2012, 2013 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -21,6 +21,7 @@
 import com.thoughtworks.xstream.annotations.XStreamConverters;
 import com.thoughtworks.xstream.converters.basic.BooleanConverter;
 import com.thoughtworks.xstream.converters.collections.MapConverter;
+import com.thoughtworks.xstream.converters.enums.SimpleEnum;
 import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;
 import com.thoughtworks.xstream.converters.extended.ToStringConverter;
 import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter;
@@ -106,7 +107,7 @@
         String expected = ""
             + "<type>\n"
             + "  <decimal>1.5</decimal>\n"
-            + "  <bool>true</bool>\n"
+            + "  <boolean>true</boolean>\n"
             + "  <agreement>yes</agreement>\n"
             + "</type>";
 
@@ -124,6 +125,7 @@
         @XStreamConverter(ToStringConverter.class)
         private Decimal decimal = null;
         @XStreamConverter(ToStringConverter.class)
+        @XStreamAlias("boolean")
         private Boolean bool = null;
         @XStreamConverter(value=BooleanConverter.class, booleans={true}, strings={"yes", "no"})
         private Boolean agreement = null;
@@ -136,19 +138,22 @@
     }
 
     public void testConverterWithSecondTypeParameter() {
-        final Type value = new DerivedType(new Decimal("1.5"), new Boolean(true));
-        String expected = "<dtype bool='true' agreement='yes'>1.5</dtype>".replace('\'', '"');
+        final Type value = new DerivedType(new Decimal("1.5"), new Boolean(true), DerivedType.E.FOO);
+        String expected = "<dtype boolean='true' agreement='yes' enum='FOO'>1.5</dtype>".replace('\'', '"');
         assertBothWays(value, expected);
     }
     
     @XStreamAlias("dtype")
     @XStreamConverter(value=ToAttributedValueConverter.class, types={Type.class}, strings={"decimal"})
     public static class DerivedType extends Type {
+        public enum E { FOO, BAR };
+        @XStreamAlias("enum")
+        private E e;
 
-        public DerivedType(Decimal decimal, Boolean bool) {
+        public DerivedType(Decimal decimal, Boolean bool, E e) {
             super(decimal, bool);
+            this.e = e;
         }
-        
     }
 
     public void testAnnotatedJavaBeanConverter() {

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


--- trunk/xstream-distribution/src/content/changes.html	2013-07-01 23:32:45 UTC (rev 2080)
+++ trunk/xstream-distribution/src/content/changes.html	2013-07-02 22:52:03 UTC (rev 2081)
@@ -119,6 +119,7 @@
     <ul>
     	<li>JIRA:XSTR-709: Locks up on Mac with Apple JVM due to unwanted initialization of AWT.</li>
     	<li>JIRA:XSTR-711: DateConverter cannot handle dates in different era.</li>
+    	<li>JIRA:XSTR-741: ToAttributedValueConverter fails to write enums as attributes.</li>
     	<li>JIRA:XSTR-712: HibernateMapper throws NPE if a collection contains null.</li>
     	<li>DateConverter supports now localized formats.</li>
     	<li>JIRA:XSTR-710: JsonWriter does not write BigInteger and BigDecimal as number values.</li>

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to