You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC

svn commit: r1209569 [40/50] - in /struts/struts2/branches/STRUTS_3_X: apps/blank/src/main/java/example/ apps/blank/src/test/java/example/ apps/jboss-blank/src/main/java/example/ apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/AnnotationXWorkConverterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/AnnotationXWorkConverterTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/AnnotationXWorkConverterTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/AnnotationXWorkConverterTest.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.conversion.impl;
+
+import org.apache.struts2.xwork2.AnnotatedTestBean;
+import org.apache.struts2.xwork2.test.AnnotationUser;
+import org.apache.struts2.xwork2.test.ModelDrivenAnnotationAction2;
+import org.apache.struts2.xwork2.util.Bar;
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.reflection.ReflectionContextState;
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+import org.apache.struts2.xwork2.XWorkTestCase;
+import org.apache.struts2.xwork2.GenericsBean;
+import org.apache.struts2.xwork2.ModelDrivenAnnotationAction;
+import org.apache.struts2.xwork2.SimpleAnnotationAction;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * @author $Author: lukaszlenart $
+ * @author Rainer Hermanns
+ * @version $Revision: 1209415 $
+ */
+public class AnnotationXWorkConverterTest extends XWorkTestCase {
+
+    ActionContext ac;
+    Map<String, Object> context;
+    XWorkConverter converter;
+
+//    public void testConversionToSetKeepsOriginalSetAndReplacesContents() {
+//        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
+//
+//        Map stackContext = stack.getContext();
+//        stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
+//        stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE);
+//        stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+//
+//        String[] param = new String[] {"abc", "def", "ghi"};
+//        List paramList = Arrays.asList(param);
+//
+//        List originalList = new ArrayList();
+//        originalList.add("jkl");
+//        originalList.add("mno");
+//
+//        AnnotationUser user = new AnnotationUser();
+//        user.setList(originalList);
+//        stack.push(user);
+//
+//        stack.setValue("list", param);
+//
+//        List userList = user.getList();
+//        assertEquals(3,userList.size());
+//        assertEquals(paramList,userList);
+//        assertSame(originalList,userList);
+//    }
+
+    public void testArrayToNumberConversion() {
+        String[] value = new String[]{"12345"};
+        assertEquals(new Integer(12345), converter.convertValue(context, null, null, null, value, Integer.class));
+        assertEquals(new Long(12345), converter.convertValue(context, null, null, null, value, Long.class));
+        value[0] = "123.45";
+        assertEquals(new Float(123.45), converter.convertValue(context, null, null, null, value, Float.class));
+        assertEquals(new Double(123.45), converter.convertValue(context, null, null, null, value, Double.class));
+        value[0] = "1234567890123456789012345678901234567890";
+        assertEquals(new BigInteger(value[0]), converter.convertValue(context, null, null, null, value, BigInteger.class));
+        value[0] = "1234567890123456789.012345678901234567890";
+        assertEquals(new BigDecimal(value[0]), converter.convertValue(context, null, null, null, value, BigDecimal.class));
+    }
+
+    public void testDateConversion() throws ParseException {
+        java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
+        assertEquals(sqlDate, converter.convertValue(context, null, null, null, sqlDate, Date.class));
+
+        SimpleDateFormat format = new SimpleDateFormat("mm/dd/yyyy hh:mm:ss");
+        Date date = format.parse("01/10/2001 00:00:00");
+        String dateStr = (String) converter.convertValue(context, null, null, null, date, String.class);
+        Date date2 = (Date) converter.convertValue(context, null, null, null, dateStr, Date.class);
+        assertEquals(date, date2);
+    }
+
+    public void testFieldErrorMessageAddedForComplexProperty() {
+        SimpleAnnotationAction action = new SimpleAnnotationAction();
+        action.setBean(new AnnotatedTestBean());
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(action);
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+        ognlStackContext.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, "bean.birth");
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action.getBean(), null, "birth", value, Date.class));
+        stack.pop();
+
+        Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertTrue(conversionErrors.size() == 1);
+        assertEquals(value, conversionErrors.get("bean.birth"));
+    }
+
+    public void testFieldErrorMessageAddedWhenConversionFails() {
+        SimpleAnnotationAction action = new SimpleAnnotationAction();
+        action.setDate(null);
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(action);
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "date", value, Date.class));
+        stack.pop();
+
+        Map conversionErrors = (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("date"));
+        assertEquals(value, conversionErrors.get("date"));
+    }
+
+    public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven() {
+        ModelDrivenAnnotationAction action = new ModelDrivenAnnotationAction();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "birth", value, Date.class));
+        stack.pop();
+        stack.pop();
+
+        Map conversionErrors = (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("birth"));
+        assertEquals(value, conversionErrors.get("birth"));
+    }
+
+    public void testFindConversionErrorMessage() {
+        ModelDrivenAnnotationAction action = new ModelDrivenAnnotationAction();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        String message = XWorkConverter.getConversionErrorMessage("birth", stack);
+        assertNotNull(message);
+        assertEquals("Invalid date for birth.", message);
+
+        message = XWorkConverter.getConversionErrorMessage("foo", stack);
+        assertNotNull(message);
+        assertEquals("Invalid field value for field \"foo\".", message);
+    }
+
+    public void testFindConversionMappingForInterface() {
+        ModelDrivenAnnotationAction2 action = new ModelDrivenAnnotationAction2();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String value = "asdf:123";
+        Object o = converter.convertValue(ognlStackContext, action.getModel(), null, "barObj", value, Bar.class);
+        assertNotNull(o);
+        assertTrue("class is: " + o.getClass(), o instanceof Bar);
+
+        Bar b = (Bar) o;
+        assertEquals(value, b.getTitle() + ":" + b.getSomethingElse());
+    }
+
+    public void testLocalizedDateConversion() throws Exception {
+        Date date = new Date(System.currentTimeMillis());
+        Locale locale = Locale.GERMANY;
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        String dateString = df.format(date);
+        context.put(ActionContext.LOCALE, locale);
+        assertEquals(dateString, converter.convertValue(context, null, null, null, date, String.class));
+    }
+
+    public void testStringArrayToCollection() {
+        List<String> list = new ArrayList<String>();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "baz"
+        }, Collection.class));
+    }
+
+    public void testStringArrayToList() {
+        List<String> list = new ArrayList<String>();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "baz"
+        }, List.class));
+    }
+
+    public void testStringArrayToPrimitiveWrappers() {
+        Long[] longs = (Long[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Long[].class);
+        assertNotNull(longs);
+        assertTrue(Arrays.equals(new Long[]{new Long(123), new Long(456)}, longs));
+
+        Integer[] ints = (Integer[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Integer[].class);
+        assertNotNull(ints);
+        assertTrue(Arrays.equals(new Integer[]{
+                new Integer(123), new Integer(456)
+        }, ints));
+
+        Double[] doubles = (Double[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Double[].class);
+        assertNotNull(doubles);
+        assertTrue(Arrays.equals(new Double[]{new Double(123), new Double(456)}, doubles));
+
+        Float[] floats = (Float[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Float[].class);
+        assertNotNull(floats);
+        assertTrue(Arrays.equals(new Float[]{new Float(123), new Float(456)}, floats));
+
+        Boolean[] booleans = (Boolean[]) converter.convertValue(context, null, null, null, new String[]{
+                "true", "false"
+        }, Boolean[].class);
+        assertNotNull(booleans);
+        assertTrue(Arrays.equals(new Boolean[]{Boolean.TRUE, Boolean.FALSE}, booleans));
+    }
+
+    public void testStringArrayToPrimitives() throws OgnlException {
+        long[] longs = (long[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, long[].class);
+        assertNotNull(longs);
+        assertTrue(Arrays.equals(new long[]{123, 456}, longs));
+
+        int[] ints = (int[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, int[].class);
+        assertNotNull(ints);
+        assertTrue(Arrays.equals(new int[]{123, 456}, ints));
+
+        double[] doubles = (double[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, double[].class);
+        assertNotNull(doubles);
+        assertTrue(Arrays.equals(new double[]{123, 456}, doubles));
+
+        float[] floats = (float[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, float[].class);
+        assertNotNull(floats);
+        assertTrue(Arrays.equals(new float[]{123, 456}, floats));
+
+        boolean[] booleans = (boolean[]) converter.convertValue(context, null, null, null, new String[]{
+                "true", "false"
+        }, boolean[].class);
+        assertNotNull(booleans);
+        assertTrue(Arrays.equals(new boolean[]{true, false}, booleans));
+    }
+
+    public void testStringArrayToSet() {
+        Set<String> list = new HashSet<String>();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "bar", "baz"
+        }, Set.class));
+    }
+
+    // TODO: Fixme... This test does not work with GenericsObjectDeterminer!
+    public void testStringToCollectionConversion() {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        Map<String, Object> stackContext = stack.getContext();
+        stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE);
+        stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
+        stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        AnnotationUser user = new AnnotationUser();
+        stack.push(user);
+
+        stack.setValue("list", "asdf");
+        assertNotNull(user.getList());
+        assertEquals(1, user.getList().size());
+        assertEquals(String.class, user.getList().get(0).getClass());
+        assertEquals("asdf", user.getList().get(0));
+    }
+
+    public void testStringToCustomTypeUsingCustomConverter() {
+        // the converter needs to be registered as the Bar.class converter
+        // it won't be detected from the Foo-conversion.properties
+        // because the Foo-conversion.properties file is only used when converting a property of Foo
+        converter.registerConverter(Bar.class.getName(), new FooBarConverter());
+
+        Bar bar = (Bar) converter.convertValue(null, null, null, null, "blah:123", Bar.class);
+        assertNotNull("conversion failed", bar);
+        assertEquals(123, bar.getSomethingElse());
+        assertEquals("blah", bar.getTitle());
+    }
+
+    public void testStringToPrimitiveWrappers() {
+        assertEquals(new Long(123), converter.convertValue(context, null, null, null, "123", Long.class));
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "123", Integer.class));
+        assertEquals(new Double(123.5), converter.convertValue(context, null, null, null, "123.5", Double.class));
+        assertEquals(new Float(123.5), converter.convertValue(context, null, null, null, "123.5", float.class));
+        assertEquals(new Boolean(false), converter.convertValue(context, null, null, null, "false", Boolean.class));
+        assertEquals(new Boolean(true), converter.convertValue(context, null, null, null, "true", Boolean.class));
+    }
+
+    public void testStringToPrimitives() {
+        assertEquals(new Long(123), converter.convertValue(context, null, null, null, "123", long.class));
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "123", int.class));
+        assertEquals(new Double(123.5), converter.convertValue(context, null, null, null, "123.5", double.class));
+        assertEquals(new Float(123.5), converter.convertValue(context, null, null, null, "123.5", float.class));
+        assertEquals(new Boolean(false), converter.convertValue(context, null, null, null, "false", boolean.class));
+        assertEquals(new Boolean(true), converter.convertValue(context, null, null, null, "true", boolean.class));
+        assertEquals(new BigDecimal(123.5), converter.convertValue(context, null, null, null, "123.5", BigDecimal.class));
+        assertEquals(new BigInteger("123"), converter.convertValue(context, null, null, null, "123", BigInteger.class));
+    }
+
+    public void testValueStackWithTypeParameter() {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(new Foo1());
+        Bar1 bar = (Bar1) stack.findValue("bar", Bar1.class);
+        assertNotNull(bar);
+    }
+
+    public void testGenericProperties() {
+        GenericsBean gb = new GenericsBean();
+        ValueStack stack = ac.getValueStack();
+        stack.push(gb);
+
+        String[] value = new String[] {"123.12", "123.45"};
+        stack.setValue("doubles", value);
+        assertEquals(2, gb.getDoubles().size());
+        assertEquals(Double.class, gb.getDoubles().get(0).getClass());
+        assertEquals(new Double(123.12), gb.getDoubles().get(0));
+        assertEquals(new Double(123.45), gb.getDoubles().get(1));
+    }
+
+    public void testGenericPropertiesFromField() {
+        GenericsBean gb = new GenericsBean();
+        ValueStack stack = ac.getValueStack();
+        stack.push(gb);
+
+        stack.setValue("genericMap[123.12]", "66");
+        stack.setValue("genericMap[456.12]", "42");
+
+        assertEquals(2, gb.getGenericMap().size());
+        assertEquals(Integer.class, stack.findValue("genericMap.get(123.12).class"));
+        assertEquals(Integer.class, stack.findValue("genericMap.get(456.12).class"));
+        assertEquals(66, stack.findValue("genericMap.get(123.12)"));
+        assertEquals(42, stack.findValue("genericMap.get(456.12)"));
+        assertEquals(true, stack.findValue("genericMap.containsValue(66)"));
+        assertEquals(true, stack.findValue("genericMap.containsValue(42)"));
+        assertEquals(true, stack.findValue("genericMap.containsKey(123.12)"));
+        assertEquals(true, stack.findValue("genericMap.containsKey(456.12)"));
+    }
+
+    public void testGenericPropertiesFromSetter() {
+        GenericsBean gb = new GenericsBean();
+        ValueStack stack = ac.getValueStack();
+        stack.push(gb);
+
+        stack.setValue("genericMap[123.12]", "66");
+        stack.setValue("genericMap[456.12]", "42");
+
+        assertEquals(2, gb.getGenericMap().size());
+        assertEquals(Integer.class, stack.findValue("genericMap.get(123.12).class"));
+        assertEquals(Integer.class, stack.findValue("genericMap.get(456.12).class"));
+        assertEquals(66, stack.findValue("genericMap.get(123.12)"));
+        assertEquals(42, stack.findValue("genericMap.get(456.12)"));
+        assertEquals(true, stack.findValue("genericMap.containsValue(66)"));
+        assertEquals(true, stack.findValue("genericMap.containsValue(42)"));
+        assertEquals(true, stack.findValue("genericMap.containsKey(123.12)"));
+        assertEquals(true, stack.findValue("genericMap.containsKey(456.12)"));
+    }
+
+    public void testGenericPropertiesFromGetter() {
+        GenericsBean gb = new GenericsBean();
+        ValueStack stack = ac.getValueStack();
+        stack.push(gb);
+
+        assertEquals(1, gb.getGetterList().size());
+        assertEquals(Double.class, stack.findValue("getterList.get(0).class"));
+        assertEquals(new Double(42.42), stack.findValue("getterList.get(0)"));
+        assertEquals(new Double(42.42), gb.getGetterList().get(0));
+
+    }
+
+
+    // FIXME: Implement nested Generics such as: List of Generics List, Map of Generic keys/values, etc...
+    public void no_testGenericPropertiesWithNestedGenerics() {
+        GenericsBean gb = new GenericsBean();
+        ValueStack stack = ac.getValueStack();
+        stack.push(gb);
+
+        stack.setValue("extendedMap[123.12]", new String[] {"1", "2", "3", "4"});
+        stack.setValue("extendedMap[456.12]", new String[] {"5", "6", "7", "8", "9"});
+
+        System.out.println("gb.getExtendedMap(): " + gb.getExtendedMap());
+
+        assertEquals(2, gb.getExtendedMap().size());
+        System.out.println(stack.findValue("extendedMap"));
+        assertEquals(4, stack.findValue("extendedMap.get(123.12).size"));
+        assertEquals(5, stack.findValue("extendedMap.get(456.12).size"));
+
+        assertEquals("1", stack.findValue("extendedMap.get(123.12).get(0)"));
+        assertEquals("5", stack.findValue("extendedMap.get(456.12).get(0)"));
+        assertEquals(Integer.class, stack.findValue("extendedMap.get(123.12).get(0).class"));
+        assertEquals(Integer.class, stack.findValue("extendedMap.get(456.12).get(0).class"));
+
+        assertEquals(List.class, stack.findValue("extendedMap.get(123.12).class"));
+        assertEquals(List.class, stack.findValue("extendedMap.get(456.12).class"));
+
+    }
+
+    public static class Foo1 {
+        public Bar1 getBar() {
+            return new Bar1Impl();
+        }
+    }
+
+    public interface Bar1 {
+    }
+
+    public static class Bar1Impl implements Bar1 {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        converter = container.getInstance(XWorkConverter.class);
+
+        ac = ActionContext.getContext();
+        ac.setLocale(Locale.US);
+        context = ac.getContextMap();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        ActionContext.setContext(null);
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooBarConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooBarConverter.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooBarConverter.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooBarConverter.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.conversion.impl;
+
+import org.apache.struts2.xwork2.util.AnnotatedCat;
+import org.apache.struts2.xwork2.util.Bar;
+import org.apache.struts2.xwork2.util.Cat;
+
+import java.lang.reflect.Member;
+import java.util.Map;
+
+
+/**
+ * @author <a href="mailto:plightbo@cisco.com">Pat Lightbody</a>
+ * @author $Author: lukaszlenart $
+ * @version $Revision: 1209415 $
+ */
+public class FooBarConverter extends DefaultTypeConverter {
+
+    @Override
+    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
+        if (toType == String.class) {
+            Bar bar = (Bar) value;
+
+            return bar.getTitle() + ":" + bar.getSomethingElse();
+        } else if (toType == Bar.class) {
+            String valueStr = (String) value;
+            int loc = valueStr.indexOf(":");
+            String title = valueStr.substring(0, loc);
+            String rest = valueStr.substring(loc + 1);
+
+            Bar bar = new Bar();
+            bar.setTitle(title);
+            bar.setSomethingElse(Integer.parseInt(rest));
+
+            return bar;
+        } else if (toType == Cat.class) {
+            Cat cat = new Cat();
+            cat.setName((String) value);
+
+            return cat;
+        } else if (toType == AnnotatedCat.class) {
+            AnnotatedCat cat = new AnnotatedCat();
+            cat.setName((String) value);
+
+            return cat;
+        } else {
+            System.out.println("Don't know how to convert between " + value.getClass().getName() +
+                    " and " + toType.getName());
+        }
+
+        return null;
+    }
+
+    @Override
+    public Object convertValue(Map<String, Object> context, Object source, Member member, String property, Object value, Class toClass) {
+        return convertValue(context, value, toClass);
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooNumberConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooNumberConverter.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooNumberConverter.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/FooNumberConverter.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,18 @@
+package org.apache.struts2.xwork2.conversion.impl;
+
+import java.util.Map;
+
+public class FooNumberConverter extends DefaultTypeConverter {
+    @Override
+    public Object convertValue(Map<String, Object> map, Object object, Class aClass) {
+        String s = (String) object;
+
+        int length = s.length();
+        StringBuilder r = new StringBuilder();
+        for (int i = length; i > 0; i--) {
+            r.append(s.charAt(i - 1));
+        }
+
+        return super.convertValue(map, r.toString(), aClass);
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/InstantiatingNullHandlerTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/InstantiatingNullHandlerTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/InstantiatingNullHandlerTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/InstantiatingNullHandlerTest.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.conversion.impl;
+
+import junit.framework.TestCase;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision: 1209415 $
+ */
+public class InstantiatingNullHandlerTest extends TestCase {
+
+    public void testBlank() {
+
+    }
+    /*public void testInheritance() {
+        Tiger t = new Tiger();
+        CompoundRoot root = new CompoundRoot();
+        root.add(t);
+
+        Map context = new OgnlContext();
+        context.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
+
+        InstantiatingNullHandler nh = new InstantiatingNullHandler();
+
+        Object dogList = nh.nullPropertyValue(context, root, "dogs");
+        Class clazz = nh.getCollectionType(Tiger.class, "dogs");
+        assertEquals(Dog.class, clazz);
+        assertNotNull(dogList);
+        assertTrue(dogList instanceof List);
+
+        Object kittenList = nh.nullPropertyValue(context, root, "kittens");
+        clazz = nh.getCollectionType(Tiger.class, "kittens");
+        assertEquals(Cat.class, clazz);
+        assertNotNull(kittenList);
+        assertTrue(kittenList instanceof List);
+    }*/
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/ParentClass.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/ParentClass.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/ParentClass.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/ParentClass.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,27 @@
+package org.apache.struts2.xwork2.conversion.impl;
+
+/**
+ * <code>ParentClass</code>
+ *
+ * @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
+ * @version $Id: ParentClass.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class ParentClass {
+
+    public enum NestedEnum {
+        TEST,
+        TEST2,
+        TEST3
+    }
+
+
+    private NestedEnum value;
+
+    public void setValue(NestedEnum value) {
+        this.value = value;
+    }
+
+    public NestedEnum getValue() {
+        return value;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkBasicConverterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkBasicConverterTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkBasicConverterTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkBasicConverterTest.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.conversion.impl;
+
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.XWorkException;
+import org.apache.struts2.xwork2.test.annotations.Person;
+import junit.framework.TestCase;
+
+import java.text.DateFormat;
+import java.util.*;
+import java.lang.reflect.Member;
+
+/**
+ * Test case for XWorkBasicConverter
+ *
+ * @author tm_jee
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: XWorkBasicConverterTest.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class XWorkBasicConverterTest extends TestCase {
+
+    // TODO: test for every possible conversion
+    // take into account of empty string
+    // primitive -> conversion error when empty string is passed
+    // object -> return null when empty string is passed
+
+    public void testDateConversionWithEmptyValue() {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue(new HashMap<String, Object>(), null, null, null, "", Date.class);
+        // we must not get XWorkException as that will caused a conversion error
+        assertNull(convertedObject);
+    }
+
+    public void testDateConversionWithInvalidValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        try {
+            Object convertedObject = basicConverter.convertValue(new HashMap<String, Object>(), null, null, null, "asdsd", Date.class);
+            fail("XWorkException expected - conversion error occurred");
+        } catch (XWorkException e) {
+            // we MUST get this exception as this is a conversion error
+        }
+    }
+
+    public void testDateWithLocalePoland() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+
+        Map<String, Object> map = new HashMap<String, Object>();
+        Locale locale = new Locale("pl", "PL");
+        map.put(ActionContext.LOCALE, locale);
+
+        String reference = "2009-01-09";
+        Object convertedObject = basicConverter.convertValue(map, null, null, null, reference, Date.class);
+
+        assertNotNull(convertedObject);
+
+        compareDates(locale, convertedObject);
+    }
+
+    public void testDateWithLocaleFrance() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+
+        Map<String, Object> map = new HashMap<String, Object>();
+        Locale locale = new Locale("fr", "FR");
+        map.put(ActionContext.LOCALE, locale);
+
+        String reference = "09/01/2009";
+        Object convertedObject = basicConverter.convertValue(map, null, null, null, reference, Date.class);
+
+        assertNotNull(convertedObject);
+
+        compareDates(locale, convertedObject);
+    }
+
+    public void testDateWithLocaleUK() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+
+        Map<String, Object> map = new HashMap<String, Object>();
+        Locale locale = new Locale("en", "US");
+        map.put(ActionContext.LOCALE, locale);
+
+        String reference = "01/09/2009";
+        Object convertedObject = basicConverter.convertValue(map, null, null, null, reference, Date.class);
+
+        assertNotNull(convertedObject);
+
+        compareDates(locale, convertedObject);
+    }
+
+    private void compareDates(Locale locale, Object convertedObject) {
+        Calendar cal = Calendar.getInstance(locale);
+        cal.set(Calendar.YEAR, 2009);
+        cal.set(Calendar.MONTH, Calendar.JANUARY);
+        cal.set(Calendar.DATE, 9);
+
+        Calendar cal1 = Calendar.getInstance(locale);
+        cal1.setTime((Date) convertedObject);
+
+        assertEquals(cal.get(Calendar.YEAR), cal1.get(Calendar.YEAR));
+        assertEquals(cal.get(Calendar.MONTH), cal1.get(Calendar.MONTH));
+        assertEquals(cal.get(Calendar.DATE), cal1.get(Calendar.DATE));
+
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        assertEquals(df.format(cal.getTime()), df.format(convertedObject));
+    }
+
+    public void testEmptyArrayConversion() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue(new HashMap<String, Object>(), null, null, null, new Object[]{}, Object[].class);
+        // we must not get XWorkException as that will caused a conversion error
+        assertEquals(Object[].class, convertedObject.getClass());
+        Object[] obj = (Object[]) convertedObject;
+        assertEquals(0, obj.length);
+    }
+
+    public void testNullArrayConversion() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue(new HashMap<String, Object>(), null, null, null, null, Object[].class);
+        // we must not get XWorkException as that will caused a conversion error
+        assertNull(convertedObject);
+    }
+
+    /* the code below has been disabled as it causes sideffects in Strtus2 (XW-512)
+    public void testXW490ConvertStringToDouble() throws Exception {
+        Locale locale = new Locale("DA"); // let's use a not common locale such as Denmark
+
+        Map ctx = new HashMap();
+        ctx.put(ActionContext.LOCALE, locale);
+
+        XWorkBasicConverter conv = new XWorkBasicConverter();
+        // decimal seperator is , in Denmark so we should write 123,99 as input
+        Double value = (Double) conv.convertValue(ctx, null, null, null, "123,99", Double.class);
+        assertNotNull(value);
+
+        // output is as expected a real double value converted using Denmark as locale
+        assertEquals(123.99d, value.doubleValue(), 0.001d);
+    }
+
+    public void testXW49ConvertDoubleToString() throws Exception {
+        Locale locale = new Locale("DA"); // let's use a not common locale such as Denmark
+
+        Map ctx = new HashMap();
+        ctx.put(ActionContext.LOCALE, locale);
+
+        XWorkBasicConverter conv = new XWorkBasicConverter();
+        // decimal seperator is , in Denmark so we should write 123,99 as input
+        String value = (String) conv.convertValue(ctx, null, null, null, new Double("123.99"), String.class);
+        assertNotNull(value);
+
+        // output should be formatted according to Danish locale using , as decimal seperator
+        assertEquals("123,99", value);
+    }    
+    */
+
+    public void testDoubleValues() {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+
+        assertTrue(basicConverter.isInRange(-1.2, "-1.2", Double.class));
+        assertTrue(basicConverter.isInRange(1.5, "1.5", Double.class));
+
+        Object value = basicConverter.convertValue("-1.3", double.class);
+        assertNotNull(value);
+        assertEquals(-1.3, value);
+
+        value = basicConverter.convertValue("1.8", double.class);
+        assertNotNull(value);
+        assertEquals(1.8, value);
+
+        value = basicConverter.convertValue("-1.9", double.class);
+        assertNotNull(value);
+        assertEquals(-1.9, value);
+
+        value = basicConverter.convertValue("1.7", Double.class);
+        assertNotNull(value);
+        assertEquals(1.7, value);
+
+        value = basicConverter.convertValue("0.0", Double.class);
+        assertNotNull(value);
+        assertEquals(0.0, value);
+
+        value = basicConverter.convertValue("0.0", double.class);
+        assertNotNull(value);
+        assertEquals(0.0, value);
+    }
+
+    public void testFloatValues() {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+
+        assertTrue(basicConverter.isInRange(-1.65, "-1.65", Float.class));
+        assertTrue(basicConverter.isInRange(1.9876, "1.9876", float.class));
+
+        Float value = (Float) basicConverter.convertValue("-1.444401", Float.class);
+        assertNotNull(value);
+        assertEquals(Float.valueOf("-1.444401"), value);
+
+        value = (Float) basicConverter.convertValue("1.46464989", Float.class);
+        assertNotNull(value);
+        assertEquals(Float.valueOf(1.46464989f), value);
+    }
+
+    public void testNegativeFloatValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue("-94.1231233", Float.class);
+        assertTrue(convertedObject instanceof Float);
+        assertEquals(-94.1231233f, ((Float) convertedObject).floatValue(), 0.0001);
+    }
+
+    public void testPositiveFloatValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue("94.1231233", Float.class);
+        assertTrue(convertedObject instanceof Float);
+        assertEquals(94.1231233f, ((Float) convertedObject).floatValue(), 0.0001);
+    }
+
+
+    public void testNegativeDoubleValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue("-94.1231233", Double.class);
+        assertTrue(convertedObject instanceof Double);
+        assertEquals(-94.1231233d, ((Double) convertedObject).doubleValue(), 0.0001);
+    }
+
+    public void testPositiveDoubleValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue("94.1231233", Double.class);
+        assertTrue(convertedObject instanceof Double);
+        assertEquals(94.1231233d, ((Double) convertedObject).doubleValue(), 0.0001);
+    }
+
+    public void testNestedEnumValue() throws Exception {
+        XWorkBasicConverter basicConverter = new XWorkBasicConverter();
+        Object convertedObject = basicConverter.convertValue(ParentClass.NestedEnum.TEST.name(), ParentClass.NestedEnum.class);
+        assertTrue(convertedObject instanceof ParentClass.NestedEnum);
+        assertEquals(ParentClass.NestedEnum.TEST, convertedObject);
+    }
+
+
+    public void testConvert() {
+        XWorkBasicConverter converter = new XWorkBasicConverter();
+        Map context = new HashMap();
+        Person o = new Person();
+        Member member = null;
+        String s = "names";
+        Object value = new Person[0];
+        Class toType = String.class;
+        converter.convertValue(context, value, member, s, value, toType);
+    }     
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkConverterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkConverterTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkConverterTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/conversion/impl/XWorkConverterTest.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.conversion.impl;
+
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.ognl.OgnlValueStack;
+import org.apache.struts2.xwork2.test.ModelDrivenAction2;
+import org.apache.struts2.xwork2.test.User;
+import org.apache.struts2.xwork2.util.Bar;
+import org.apache.struts2.xwork2.util.Cat;
+import org.apache.struts2.xwork2.util.Foo;
+import org.apache.struts2.xwork2.util.FurColor;
+import org.apache.struts2.xwork2.util.reflection.ReflectionContextState;
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+import org.apache.struts2.xwork2.XWorkTestCase;
+import org.apache.struts2.xwork2.ModelDrivenAction;
+import org.apache.struts2.xwork2.SimpleAction;
+import org.apache.struts2.xwork2.TestBean;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * @author $Author: lukaszlenart $
+ * @version $Revision: 1209415 $
+ */
+public class XWorkConverterTest extends XWorkTestCase {
+
+    Map<String, Object> context;
+    XWorkConverter converter;
+    OgnlValueStack stack;
+
+//    public void testConversionToSetKeepsOriginalSetAndReplacesContents() {
+//        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
+//
+//        Map stackContext = stack.getContext();
+//        stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
+//        stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE);
+//        stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+//
+//        String[] param = new String[] {"abc", "def", "ghi"};
+//        List paramList = Arrays.asList(param);
+//
+//        List originalList = new ArrayList();
+//        originalList.add("jkl");
+//        originalList.add("mno");
+//
+//        User user = new User();
+//        user.setList(originalList);
+//        stack.push(user);
+//
+//        stack.setValue("list", param);
+//
+//        List userList = user.getList();
+//        assertEquals(3,userList.size());
+//        assertEquals(paramList,userList);
+//        assertSame(originalList,userList);
+//    }
+
+    public void testArrayToNumberConversion() {
+        String[] value = new String[]{"12345"};
+        assertEquals(new Integer(12345), converter.convertValue(context, null, null, null, value, Integer.class));
+        assertEquals(new Long(12345), converter.convertValue(context, null, null, null, value, Long.class));
+        value[0] = "123.45";
+        assertEquals(new Float(123.45), converter.convertValue(context, null, null, null, value, Float.class));
+        assertEquals(new Double(123.45), converter.convertValue(context, null, null, null, value, Double.class));
+        value[0] = "1234567890123456789012345678901234567890";
+        assertEquals(new BigInteger(value[0]), converter.convertValue(context, null, null, null, value, BigInteger.class));
+        value[0] = "1234567890123456789.012345678901234567890";
+        assertEquals(new BigDecimal(value[0]), converter.convertValue(context, null, null, null, value, BigDecimal.class));
+    }
+
+    public void testDateConversion() throws ParseException {
+        java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
+        assertEquals(sqlDate, converter.convertValue(context, null, null, null, sqlDate, Date.class));
+
+        SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
+        Date date = format.parse("01/10/2001 00:00:00");
+
+        SimpleDateFormat formatt = new SimpleDateFormat("hh:mm:ss");
+        java.sql.Time datet = new java.sql.Time(formatt.parse("10:11:12").getTime());
+
+        String dateStr = (String) converter.convertValue(context, null, null, null, date, String.class);
+        String datetStr = (String) converter.convertValue(context, null, null, null, datet, String.class);
+
+        Date date2 = (Date) converter.convertValue(context, null, null, null, dateStr, Date.class);
+        assertEquals(date, date2);
+        java.sql.Date date3 = (java.sql.Date) converter.convertValue(context, null, null, null, dateStr, java.sql.Date.class);
+        assertEquals(date, date3);
+        java.sql.Timestamp ts = (java.sql.Timestamp) converter.convertValue(context, null, null, null, dateStr, java.sql.Timestamp.class);
+        assertEquals(date, ts);
+        java.sql.Time time1 = (java.sql.Time) converter.convertValue(context, null, null, null, datetStr, java.sql.Time.class);
+        assertEquals(datet, time1);
+    }
+
+    public void testFieldErrorMessageAddedForComplexProperty() {
+        SimpleAction action = new SimpleAction();
+        action.setBean(new TestBean());
+
+        stack.push(action);
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+        ognlStackContext.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, "bean.birth");
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action.getBean(), null, "birth", value, Date.class));
+        stack.pop();
+
+        Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertTrue(conversionErrors.size() == 1);
+        assertEquals(value, conversionErrors.get("bean.birth"));
+    }
+
+    public void testFieldErrorMessageAddedWhenConversionFails() {
+        SimpleAction action = new SimpleAction();
+        action.setDate(null);
+
+        stack.push(action);
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "date", value, Date.class));
+        stack.pop();
+
+        Map conversionErrors = (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("date"));
+        assertEquals(value, conversionErrors.get("date"));
+    }
+
+    public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven() {
+        ModelDrivenAction action = new ModelDrivenAction();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        Map<String, Object> ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String[] value = new String[]{"invalid date"};
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "birth", value, Date.class));
+        stack.pop();
+        stack.pop();
+
+        Map conversionErrors = (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("birth"));
+        assertEquals(value, conversionErrors.get("birth"));
+    }
+
+    public void testDateStrictConversion() throws Exception {
+        // see XW-341
+        String dateStr = "13/01/2005"; // us date format is used in context
+        Object res = converter.convertValue(context, null, null, null, dateStr, Date.class);
+        assertEquals(res, OgnlRuntime.NoConversionPossible);
+
+        dateStr = "02/30/2005"; // us date format is used in context
+        res = converter.convertValue(context, null, null, null, dateStr, Date.class);
+        assertEquals(res, OgnlRuntime.NoConversionPossible);
+
+        // and test a date that is passable
+        SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
+        dateStr = "12/31/2005"; // us date format
+        res = converter.convertValue(context, null, null, null, dateStr, Date.class);
+        Date date = format.parse(dateStr);
+        assertNotSame(res, OgnlRuntime.NoConversionPossible);
+        assertEquals(date, res);
+    }
+
+
+    public void testFindConversionErrorMessage() {
+        ModelDrivenAction action = new ModelDrivenAction();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        String message = XWorkConverter.getConversionErrorMessage("birth", stack);
+        assertNotNull(message);
+        assertEquals("Invalid date for birth.", message);
+
+        message = XWorkConverter.getConversionErrorMessage("foo", stack);
+        assertNotNull(message);
+        assertEquals("Invalid field value for field \"foo\".", message);
+    }
+
+    public void testFindConversionMappingForInterface() {
+        ModelDrivenAction2 action = new ModelDrivenAction2();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        Map ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        String value = "asdf:123";
+        Object o = converter.convertValue(ognlStackContext, action.getModel(), null, "barObj", value, Bar.class);
+        assertNotNull(o);
+        assertTrue(o instanceof Bar);
+
+        Bar b = (Bar) o;
+        assertEquals(value, b.getTitle() + ":" + b.getSomethingElse());
+    }
+
+    public void testLocalizedDateConversion() throws Exception {
+        Date date = new Date(System.currentTimeMillis());
+        Locale locale = Locale.GERMANY;
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        String dateString = df.format(date);
+        context.put(ActionContext.LOCALE, locale);
+        assertEquals(dateString, converter.convertValue(context, null, null, null, date, String.class));
+    }
+
+    public void testStringToIntConversions() {
+        SimpleAction action = new SimpleAction();
+        action.setBean(new TestBean());
+
+        stack.push(action);
+
+        Map ognlStackContext = stack.getContext();
+        ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action.getBean(), null, "count", "111.1", int.class));
+        stack.pop();
+
+        Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertTrue(conversionErrors.size() == 1);
+    }
+
+    public void testStringArrayToCollection() {
+        List list = new ArrayList();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "baz"
+        }, Collection.class));
+    }
+
+    public void testStringArrayToList() {
+        List list = new ArrayList();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "baz"
+        }, List.class));
+    }
+
+    public void testStringArrayToPrimitiveWrappers() {
+        Long[] longs = (Long[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Long[].class);
+        assertNotNull(longs);
+        assertTrue(Arrays.equals(new Long[]{new Long(123), new Long(456)}, longs));
+
+        Integer[] ints = (Integer[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Integer[].class);
+        assertNotNull(ints);
+        assertTrue(Arrays.equals(new Integer[]{
+                new Integer(123), new Integer(456)
+        }, ints));
+
+        Double[] doubles = (Double[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Double[].class);
+        assertNotNull(doubles);
+        assertTrue(Arrays.equals(new Double[]{new Double(123), new Double(456)}, doubles));
+
+        Float[] floats = (Float[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, Float[].class);
+        assertNotNull(floats);
+        assertTrue(Arrays.equals(new Float[]{new Float(123), new Float(456)}, floats));
+
+        Boolean[] booleans = (Boolean[]) converter.convertValue(context, null, null, null, new String[]{
+                "true", "false"
+        }, Boolean[].class);
+        assertNotNull(booleans);
+        assertTrue(Arrays.equals(new Boolean[]{Boolean.TRUE, Boolean.FALSE}, booleans));
+    }
+
+    public void testStringArrayToPrimitives() throws OgnlException {
+        long[] longs = (long[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, long[].class);
+        assertNotNull(longs);
+        assertTrue(Arrays.equals(new long[]{123, 456}, longs));
+
+        int[] ints = (int[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, int[].class);
+        assertNotNull(ints);
+        assertTrue(Arrays.equals(new int[]{123, 456}, ints));
+
+        double[] doubles = (double[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, double[].class);
+        assertNotNull(doubles);
+        assertTrue(Arrays.equals(new double[]{123, 456}, doubles));
+
+        float[] floats = (float[]) converter.convertValue(context, null, null, null, new String[]{
+                "123", "456"
+        }, float[].class);
+        assertNotNull(floats);
+        assertTrue(Arrays.equals(new float[]{123, 456}, floats));
+
+        boolean[] booleans = (boolean[]) converter.convertValue(context, null, null, null, new String[]{
+                "true", "false"
+        }, boolean[].class);
+        assertNotNull(booleans);
+        assertTrue(Arrays.equals(new boolean[]{true, false}, booleans));
+    }
+
+    public void testStringArrayToSet() {
+        Set list = new HashSet();
+        list.add("foo");
+        list.add("bar");
+        list.add("baz");
+        assertEquals(list, converter.convertValue(context, null, null, null, new String[]{
+                "foo", "bar", "bar", "baz"
+        }, Set.class));
+    }
+
+    public void testStringToCollectionConversion() {
+        Map stackContext = stack.getContext();
+        stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE);
+        stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
+        stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+        User user = new User();
+        stack.push(user);
+
+        stack.setValue("list", "asdf");
+        assertNotNull(user.getList());
+        assertEquals(1, user.getList().size());
+        assertEquals(String.class, user.getList().get(0).getClass());
+        assertEquals("asdf", user.getList().get(0));
+    }
+
+    public void testStringToCustomTypeUsingCustomConverter() {
+        // the converter needs to be registered as the Bar.class converter 
+        // it won't be detected from the Foo-conversion.properties
+        // because the Foo-conversion.properties file is only used when converting a property of Foo
+        converter.registerConverter(Bar.class.getName(), new FooBarConverter());
+
+        Bar bar = (Bar) converter.convertValue(null, null, null, null, "blah:123", Bar.class);
+        assertNotNull("conversion failed", bar);
+        assertEquals(123, bar.getSomethingElse());
+        assertEquals("blah", bar.getTitle());
+    }
+
+    public void testStringToCustomTypeUsingCustomConverterFromProperties() throws Exception {
+
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(new ClassLoader(cl) {
+                @Override
+                public Enumeration<URL> getResources(String name) throws IOException {
+                    if ("xwork-conversion.properties".equals(name)) {
+                        return new Enumeration<URL>() {
+                            boolean done = false;
+                            public boolean hasMoreElements() {
+                                return !done;
+                            }
+
+                            public URL nextElement() {
+                                if (done) {
+                                    throw new RuntimeException("Conversion configuration loading " +
+                                        "failed because it asked the enumeration for the next URL " +
+                                        "too many times");
+                                }
+
+                                done = true;
+                                return getClass().getResource("/org/apache/struts2/xwork2/conversion/impl/test-xwork-conversion.properties");
+                            }
+                        };
+                    } else {
+                        return super.getResources(name);
+                    }
+                }
+            });
+            setUp();
+        } finally {
+            Thread.currentThread().setContextClassLoader(cl);
+        }
+        Bar bar = (Bar) converter.convertValue(null, null, null, null, "blah:123", Bar.class);
+        assertNotNull("conversion failed", bar);
+        assertEquals(123, bar.getSomethingElse());
+        assertEquals("blah", bar.getTitle());
+    }
+
+    public void testStringToPrimitiveWrappers() {
+        assertEquals(new Long(123), converter.convertValue(context, null, null, null, "123", Long.class));
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "123", Integer.class));
+        assertEquals(new Double(123.5), converter.convertValue(context, null, null, null, "123.5", Double.class));
+        assertEquals(new Float(123.5), converter.convertValue(context, null, null, null, "123.5", float.class));
+        assertEquals(new Boolean(false), converter.convertValue(context, null, null, null, "false", Boolean.class));
+        assertEquals(new Boolean(true), converter.convertValue(context, null, null, null, "true", Boolean.class));
+    }
+
+    public void testStringToPrimitives() {
+        assertEquals(new Long(123), converter.convertValue(context, null, null, null, "123", long.class));
+        assertEquals(new Double(123.5), converter.convertValue(context, null, null, null, "123.5", double.class));
+        assertEquals(new Float(123.5), converter.convertValue(context, null, null, null, "123.5", float.class));
+        assertEquals(new Boolean(false), converter.convertValue(context, null, null, null, "false", boolean.class));
+        assertEquals(new Boolean(true), converter.convertValue(context, null, null, null, "true", boolean.class));
+        assertEquals(new BigDecimal(123.5), converter.convertValue(context, null, null, null, "123.5", BigDecimal.class));
+        assertEquals(new BigInteger("123"), converter.convertValue(context, null, null, null, "123", BigInteger.class));
+    }
+
+    public void testOverflows() {
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Double.MAX_VALUE + "1", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Double.MIN_VALUE + "-1", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Double.MAX_VALUE + "1", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Double.MIN_VALUE + "-1", Double.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Float.MAX_VALUE + "1", float.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Float.MIN_VALUE + "-1", float.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Float.MAX_VALUE + "1", Float.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Float.MIN_VALUE + "-1", Float.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Integer.MAX_VALUE + "1", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Integer.MIN_VALUE + "-1", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Integer.MAX_VALUE + "1", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Integer.MIN_VALUE + "-1", Integer.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Byte.MAX_VALUE + "1", byte.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Byte.MIN_VALUE + "-1", byte.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Byte.MAX_VALUE + "1", Byte.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Byte.MIN_VALUE + "-1", Byte.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Short.MAX_VALUE + "1", short.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Short.MIN_VALUE + "-1", short.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Short.MAX_VALUE + "1", Short.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Short.MIN_VALUE + "-1", Short.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Long.MAX_VALUE + "1", long.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Long.MIN_VALUE + "-1", long.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Long.MAX_VALUE + "1", Long.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, Long.MIN_VALUE + "-1", Long.class));
+    }
+
+    public void testStringToInt() {
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "123", int.class));
+        context.put(ActionContext.LOCALE, Locale.US);
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123.12", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", int.class));
+        context.put(ActionContext.LOCALE, Locale.GERMANY);
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123.12", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234", int.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", int.class));
+    }
+
+
+    public void testStringToInteger() {
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "123", Integer.class));
+        context.put(ActionContext.LOCALE, Locale.US);
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123.12", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", Integer.class));
+        assertEquals(new Integer(1234), converter.convertValue(context, null, null, null, "1,234", Integer.class));
+        // WRONG: locale separator is wrongly placed
+        assertEquals(new Integer(123), converter.convertValue(context, null, null, null, "1,23", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", Integer.class));
+
+        context.put(ActionContext.LOCALE, Locale.GERMANY);
+        // WRONG: locale separator is wrongly placed
+        assertEquals(new Integer(12312), converter.convertValue(context, null, null, null, "123.12", Integer.class));
+        assertEquals(new Integer(1234), converter.convertValue(context, null, null, null, "1.234", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", Integer.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", Integer.class));
+    }
+
+    public void testStringToPrimitiveDouble() {
+        assertEquals(new Double(123), converter.convertValue(context, null, null, null, "123", double.class));
+        context.put(ActionContext.LOCALE, Locale.US);
+        assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", double.class));
+        assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1.234", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", double.class));
+
+        context.put(ActionContext.LOCALE, Locale.GERMANY);
+        assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", double.class));
+        assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1.234", double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", double.class));
+    }
+
+    public void testStringToDouble() {
+        assertEquals(new Double(123), converter.convertValue(context, null, null, null, "123", Double.class));
+        context.put(ActionContext.LOCALE, Locale.US);
+        assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", Double.class));
+        assertEquals(new Double(1234), converter.convertValue(context, null, null, null, "1,234", Double.class));
+        assertEquals(new Double(1234.12), converter.convertValue(context, null, null, null, "1,234.12", Double.class));
+        // WRONG: locale separator is wrongly placed 
+        assertEquals(new Double(123), converter.convertValue(context, null, null, null, "1,23", Double.class));
+        assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1.234", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", Double.class));
+
+        context.put(ActionContext.LOCALE, Locale.GERMANY);
+        // WRONG: locale separator is wrongly placed
+        assertEquals(new Double(12312), converter.convertValue(context, null, null, null, "123.12", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", Double.class));
+        assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1,234", Double.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", Double.class));
+        assertEquals(new Double(1.23), converter.convertValue(context, null, null, null, "1,23", Double.class));
+        assertEquals(new Double(1234), converter.convertValue(context, null, null, null, "1.234", Double.class));
+        assertEquals(new Double(1234.12), converter.convertValue(context, null, null, null, "1.234,12", Double.class));
+
+    }
+    
+    public void testStringToEnum() {
+        assertEquals(FurColor.BLACK, converter.convertValue(context, null, null, null, "BLACK", FurColor.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "black", FurColor.class));
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "red", FurColor.class));
+    }
+
+    // Testing for null result on non-primitive Number types supplied as empty String or 
+    public void testNotPrimitiveDefaultsToNull() {
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Double.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Double.class));
+
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Integer.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Integer.class));
+
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Float.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Float.class));
+
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Character.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Character.class));
+
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Long.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Long.class));
+
+        assertEquals(null, converter.convertValue(context, null, null, null, null, Short.class));
+        assertEquals(null, converter.convertValue(context, null, null, null, "", Short.class));
+
+    }
+
+    public void testConvertChar() {
+        assertEquals(new Character('A'), converter.convertValue(context, "A", char.class));
+        assertEquals(new Character('Z'), converter.convertValue(context, "Z", char.class));
+        assertEquals(new Character('A'), converter.convertValue(context, "A", Character.class));
+        assertEquals(new Character('Z'), converter.convertValue(context, "Z", Character.class));
+
+        assertEquals(new Character('A'), converter.convertValue(context, new Character('A'), char.class));
+        assertEquals(new Character('Z'), converter.convertValue(context, new Character('Z'), char.class));
+        assertEquals(new Character('A'), converter.convertValue(context, new Character('A'), Character.class));
+        assertEquals(new Character('Z'), converter.convertValue(context, new Character('Z'), Character.class));
+
+        assertEquals(new Character('D'), converter.convertValue(context, "DEF", char.class));
+        assertEquals(new Character('X'), converter.convertValue(context, "XYZ", Character.class));
+        assertEquals(new Character(' '), converter.convertValue(context, " ", Character.class));
+        assertEquals(new Character(' '), converter.convertValue(context, "   ", char.class));
+
+        assertEquals(null, converter.convertValue(context, "", char.class));
+    }
+
+    public void testConvertClass() {
+        Class clazz = (Class) converter.convertValue(context, "java.util.Date", Class.class);
+        assertEquals(Date.class.getName(), clazz.getName());
+
+        Class clazz2 = (Class) converter.convertValue(context, "org.apache.struts2.xwork2.util.Bar", Class.class);
+        assertEquals(Bar.class.getName(), clazz2.getName());
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, "org.apache.struts2.xwork2.util.IDoNotExist", Class.class));
+
+        assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, new Bar(), Class.class)); // only supports string values
+    }
+
+    public void testConvertBoolean() {
+        assertEquals(Boolean.TRUE, converter.convertValue(context, "true", Boolean.class));
+        assertEquals(Boolean.FALSE, converter.convertValue(context, "false", Boolean.class));
+
+        assertEquals(Boolean.TRUE, converter.convertValue(context, Boolean.TRUE, Boolean.class));
+        assertEquals(Boolean.FALSE, converter.convertValue(context, Boolean.FALSE, Boolean.class));
+
+        assertEquals(null, converter.convertValue(context, null, Boolean.class));
+        assertEquals(Boolean.TRUE, converter.convertValue(context, new Bar(), Boolean.class)); // Ognl converter will default to true
+    }
+
+    public void testConvertPrimitiveArraysToString() {
+        assertEquals("2, 3, 1", converter.convertValue(context, new int[]{2, 3, 1}, String.class));
+        assertEquals("100, 200, 300", converter.convertValue(context, new long[]{100, 200, 300}, String.class));
+        assertEquals("1.5, 2.5, 3.5", converter.convertValue(context, new double[]{1.5, 2.5, 3.5}, String.class));
+        assertEquals("true, false, true", converter.convertValue(context, new boolean[]{true, false, true}, String.class));
+    }
+
+    public void testConvertSameCollectionToCollection() {
+        Collection names = new ArrayList();
+        names.add("XWork");
+        names.add("Struts");
+
+        Collection col = (Collection) converter.convertValue(context, names, Collection.class);
+        assertSame(names, col);
+    }
+
+    public void testConvertSqlTimestamp() {
+        assertNotNull(converter.convertValue(context, new Timestamp(new Date().getTime()), String.class));
+        assertNotNull(converter.convertValue(null, new Timestamp(new Date().getTime()), String.class));
+    }
+
+    public void testValueStackWithTypeParameter() {
+        stack.push(new Foo1());
+        Bar1 bar = (Bar1) stack.findValue("bar", Bar1.class);
+        assertNotNull(bar);
+    }
+
+    public void testNestedConverters() {
+        Cat cat = new Cat();
+        cat.setFoo(new Foo());
+        stack.push(cat);
+        stack.setValue("foo.number", "123");
+        assertEquals(321, cat.getFoo().getNumber());
+    }
+
+    public static class Foo1 {
+        public Bar1 getBar() {
+            return new Bar1Impl();
+        }
+    }
+
+    public interface Bar1 {
+    }
+
+    public static class Bar1Impl implements Bar1 {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        converter = container.getInstance(XWorkConverter.class);
+
+        ActionContext ac = ActionContext.getContext();
+        ac.setLocale(Locale.US);
+        context = ac.getContextMap();
+        stack = (OgnlValueStack) ac.getValueStack();
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/inject/ContainerImplTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/inject/ContainerImplTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/inject/ContainerImplTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/inject/ContainerImplTest.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,119 @@
+package org.apache.struts2.xwork2.inject;
+
+import junit.framework.TestCase;
+
+/**
+ * ContainerImpl Tester.
+ *
+ * @author Lukasz Lenart
+ * @version 1.0
+ * @since <pre>11/26/2008</pre>
+ */
+public class ContainerImplTest extends TestCase {
+
+    private Container c;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        ContainerBuilder cb = new ContainerBuilder();
+        cb.constant("methodCheck.name", "Lukasz");
+        cb.constant("fieldCheck.name", "Lukasz");
+        c = cb.create(false);
+    }
+
+    /**
+     * Inject values into field
+     */
+    public void testFieldInjector() throws Exception {
+
+        FieldCheck fieldCheck = new FieldCheck();
+
+        try {
+            c.inject(fieldCheck);
+            assertTrue(true);
+        } catch (DependencyException expected) {
+            fail("No exception expected!");
+        }
+
+        assertEquals(fieldCheck.getName(), "Lukasz");
+    }
+
+    /**
+     * Inject values into method
+     */
+    public void testMethodInjector() throws Exception {
+
+        MethodCheck methodCheck = new MethodCheck();
+
+        try {
+            c.inject(methodCheck);
+            assertTrue(true);
+        } catch (DependencyException expected) {
+            fail("No exception expected!");
+        }
+    }
+
+    /**
+     * Inject values into field under SecurityManager
+     */
+    public void testFieldInjectorWithSecurityEnabled() throws Exception {
+
+        System.setSecurityManager(new SecurityManager());
+
+        FieldCheck fieldCheck = new FieldCheck();
+
+        try {
+            c.inject(fieldCheck);
+            assertEquals(fieldCheck.getName(), "Lukasz");
+            fail("Exception should be thrown!");
+        } catch (DependencyException expected) {
+            // that was expected
+        }
+    }
+
+    /**
+     * Inject values into method under SecurityManager
+     */
+    public void testMethodInjectorWithSecurityEnabled() throws Exception {
+
+        // not needed, already set
+        //System.setSecurityManager(new SecurityManager());
+
+        MethodCheck methodCheck = new MethodCheck();
+
+        try {
+            c.inject(methodCheck);
+            assertEquals(methodCheck.getName(), "Lukasz");
+            fail("Exception sould be thrown!");
+        } catch (DependencyException expected) {
+            // that was expected
+        }
+    }
+
+    class FieldCheck {
+
+        @Inject("fieldCheck.name")
+        private String name;
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    class MethodCheck {
+
+        private String name;
+
+        @Inject("methodCheck.name")
+        private void setName(String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+    }
+
+}