Commits

unkyaku  committed 3502f85

Fix for XW-193, based on patch submitted by Wolfgang Jung.

Type conversion is now performed for collections.

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@302e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits 00caf8e

Comments (0)

Files changed (3)

File src/java/com/opensymphony/xwork/util/XWorkBasicConverter.java

         if (toType == String.class) {
             result = doConvertToString(context, value);
         } else if (toType == boolean.class) {
-            result = doConvertToBoolean(context, value);
+            result = doConvertToBoolean(value);
         } else if (toType == Boolean.class) {
-            result = doConvertToBoolean(context, value);
+            result = doConvertToBoolean(value);
         } else if (toType.isArray()) {
             result = doConvertToArray(context, o, member, s, value, toType);
         } else if (toType == Date.class) {
             result = doConvertToDate(context, value);
-        } else if (toType == List.class) {
-            result = doConvertToList(context, value);
-        } else if (toType == Set.class) {
-            result = doConvertToSet(context, value);
-        } else if (toType == Collection.class) {
-            result = doConvertToList(context, value);
+        } else if (Collection.class.isAssignableFrom(toType)) {
+            result = doConvertToCollection(context, o, member, s, value, toType);
         } else if (toType == Class.class) {
-            result = doConvertToClass(context, value);
+            result = doConvertToClass(value);
         }
 
         if (result == null) {
         return result;
     }
 
-    private Object doConvertToBoolean(Map context, Object value) {
+    private Object doConvertToBoolean(Object value) {
         if (value instanceof String) {
             String bStr = (String) value;
 
         return null;
     }
 
-    private Class doConvertToClass(Map context, Object value) {
+    private Class doConvertToClass(Object value) {
         Class clazz = null;
 
         if (value instanceof String) {
         return clazz;
     }
 
-    private Object doConvertToDate(Map context, Object value) {
-        Date result = null;
+    private Collection doConvertToCollection(Map context, Object o, Member member, String prop, Object value, Class toType) {
+        Collection result = null;
+        Class memberType = String.class;
 
-        if (value instanceof String) {
-            String sa = (String) value;
-            Locale locale = getLocale(context);
+        if (o != null) {
+            memberType = (Class) XWorkConverter.getInstance().getConverter(o.getClass(), "Collection_" + prop);
 
-            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
-
-            try {
-                result = df.parse(sa);
-            } catch (ParseException e) {
-                throw new XworkException("Could not parse date", e);
+            if (memberType == null) {
+                memberType = String.class;
             }
-        } else if (Date.class.isAssignableFrom(value.getClass())) {
-            result = (Date) value;
         }
 
-        return result;
-    }
-
-    private List doConvertToList(Map context, Object value) {
-        List result = null;
-
         if (value instanceof String[]) {
             String[] sa = (String[]) value;
-            result = new ArrayList(sa.length);
+
+            if (toType == Set.class) {
+                result = new HashSet(sa.length);
+            } else if (toType == SortedSet.class) {
+                result = new TreeSet();
+            } else {
+                result = new XWorkList(memberType, sa.length);
+            }
+
+            TypeConverter converter = Ognl.getTypeConverter(context);
 
             for (int i = 0; i < sa.length; i++) {
-                String s = sa[i];
-                result.add(s);
+                result.add(converter.convertValue(context, o, member, prop, sa[i], memberType));
+            }
+        } else if (toType.isAssignableFrom(value.getClass())) {
+            result = (Collection) value;
+        } else if (Collection.class.isAssignableFrom(value.getClass())) {
+            Collection col = (Collection) value;
+
+            if (toType == Set.class) {
+                result = new HashSet(col.size());
+            } else if (toType == SortedSet.class) {
+                result = new TreeSet();
+            } else {
+                result = new XWorkList(memberType, col.size());
+            }
+
+            TypeConverter converter = Ognl.getTypeConverter(context);
+
+            for (Iterator it = col.iterator(); it.hasNext();) {
+                result.add(converter.convertValue(context, o, member, prop, it.next(), memberType));
             }
-        } else if (List.class.isAssignableFrom(value.getClass())) {
-            result = (List) value;
         }
 
         return result;
     }
 
-    private Object doConvertToSet(Map context, Object value) {
-        Set result = null;
+    private Object doConvertToDate(Map context, Object value) {
+        Date result = null;
 
-        if (value instanceof String[]) {
-            String[] sa = (String[]) value;
-            result = new HashSet(sa.length);
+        if (value instanceof String) {
+            String sa = (String) value;
+            Locale locale = getLocale(context);
 
-            for (int i = 0; i < sa.length; i++) {
-                String s = sa[i];
-                result.add(s);
+            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+
+            try {
+                result = df.parse(sa);
+            } catch (ParseException e) {
+                throw new XworkException("Could not parse date", e);
             }
-        } else if (Set.class.isAssignableFrom(value.getClass())) {
-            result = (Set) value;
+        } else if (Date.class.isAssignableFrom(value.getClass())) {
+            result = (Date) value;
         }
 
         return result;

File src/test/com/opensymphony/xwork/util/FooBarConverter.java

             bar.setSomethingElse(Integer.parseInt(rest));
 
             return bar;
+        } else if (toType == Cat.class) {
+            Cat cat = new Cat();
+            cat.setName((String) value);
+
+            return cat;
         }
 
         return null;

File src/test/com/opensymphony/xwork/util/SetPropertiesTest.java

 
 import ognl.Ognl;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 
 
         assertEquals(0, bar.getFieldErrors().size());
     }
 
+    public void testSetCollectionByConverterFromArray() {
+        Foo foo = new Foo();
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        XWorkConverter c = (XWorkConverter) Ognl.getTypeConverter(vs.getContext());
+        c.registerConverter(Cat.class.getName(), new FooBarConverter());
+        vs.push(foo);
+
+        vs.setValue("cats", new String[] {"1", "2"});
+        assertNotNull(foo.getCats());
+        assertEquals(2, foo.getCats().size());
+        assertEquals(Cat.class, foo.getCats().get(0).getClass());
+        assertEquals(Cat.class, foo.getCats().get(1).getClass());
+    }
+
+    public void testSetCollectionByConverterFromCollection() {
+        Foo foo = new Foo();
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        XWorkConverter c = (XWorkConverter) Ognl.getTypeConverter(vs.getContext());
+        c.registerConverter(Cat.class.getName(), new FooBarConverter());
+        vs.push(foo);
+
+        HashSet s = new HashSet();
+        s.add("1");
+        s.add("2");
+        vs.setValue("cats", s);
+        assertNotNull(foo.getCats());
+        assertEquals(2, foo.getCats().size());
+        assertEquals(Cat.class, foo.getCats().get(0).getClass());
+        assertEquals(Cat.class, foo.getCats().get(1).getClass());
+    }
+
     public void testValueStackSetValueEmptyStringAsLong() {
         Bar bar = new Bar();
         OgnlValueStack vs = new OgnlValueStack();