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/10/17 15:27:45 UTC

svn commit: r1185159 [1/2] - in /struts/struts2/branches/new_conversion: core/src/main/java/org/apache/struts2/util/ core/src/test/java/org/apache/struts2/util/ core/src/test/java/org/apache/struts2/views/jsp/ui/ core/src/test/resources/org/apache/stru...

Author: lukaszlenart
Date: Mon Oct 17 13:27:43 2011
New Revision: 1185159

URL: http://svn.apache.org/viewvc?rev=1185159&view=rev
Log:
Refactors DefaultTypeConverter to use Locale for conversion

Added:
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/Converter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ValueConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/AbstractConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/BooleanConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ByteConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/CharacterConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DoubleConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/FloatConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/IntegerConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/LongConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ShortConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterTest.java
Modified:
    struts/struts2/branches/new_conversion/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java
    struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java
    struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
    struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java
    struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
    struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-12.txt
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverterTest.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java
    struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeValidatorTest.java

Modified: struts/struts2/branches/new_conversion/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java (original)
+++ struts/struts2/branches/new_conversion/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java Mon Oct 17 13:27:43 2011
@@ -21,10 +21,10 @@
 
 package org.apache.struts2.util;
 
-import java.util.Map;
-
 import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
 
+import java.util.Map;
+
 /**
  * <!-- START SNIPPET: javadoc -->
  *

Modified: struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java (original)
+++ struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java Mon Oct 17 13:27:43 2011
@@ -21,12 +21,12 @@
 
 package org.apache.struts2.util;
 
+import junit.framework.TestCase;
+
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
-import junit.framework.TestCase;
-
 
 /**
  * Test case for Struts Type Converter.

Modified: struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java (original)
+++ struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java Mon Oct 17 13:27:43 2011
@@ -21,12 +21,19 @@
 
 package org.apache.struts2.views.jsp.ui;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.RuntimeConfiguration;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.InterceptorMapping;
+import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
+import com.opensymphony.xwork2.inject.Container;
+import com.opensymphony.xwork2.inject.Scope.Strategy;
+import com.opensymphony.xwork2.validator.ValidationInterceptor;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.TestAction;
 import org.apache.struts2.TestConfigurationProvider;
@@ -35,14 +42,12 @@ import org.apache.struts2.views.jsp.Abst
 import org.apache.struts2.views.jsp.ActionTag;
 import org.easymock.EasyMock;
 
-import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.config.RuntimeConfiguration;
-import com.opensymphony.xwork2.config.entities.ActionConfig;
-import com.opensymphony.xwork2.config.entities.InterceptorMapping;
-import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
-import com.opensymphony.xwork2.inject.Container;
-import com.opensymphony.xwork2.inject.Scope.Strategy;
-import com.opensymphony.xwork2.validator.ValidationInterceptor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 
 
 /**
@@ -366,6 +371,9 @@ public class FormTagTest extends Abstrac
      */
     public void testFormWithCustomOnsubmitEnabledWithValidateEnabled3() throws Exception {
 
+        Locale defaultLocale = Locale.getDefault();
+        Locale.setDefault(Locale.US);
+
         final Container cont = container;
         // used to determined if the form action needs js validation
         configurationManager.setConfiguration(new com.opensymphony.xwork2.config.impl.DefaultConfiguration() {
@@ -440,6 +448,8 @@ public class FormTagTest extends Abstrac
         tag.doEndTag();
 
         verify(FormTag.class.getResource("Formtag-22.txt"));
+
+        Locale.setDefault(defaultLocale);
     }
 
 /**

Modified: struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java (original)
+++ struts/struts2/branches/new_conversion/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java Mon Oct 17 13:27:43 2011
@@ -21,13 +21,14 @@
 
 package org.apache.struts2.views.jsp.ui;
 
+import org.apache.struts2.TestAction;
+import org.apache.struts2.views.jsp.AbstractUITagTest;
+
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-
-import org.apache.struts2.TestAction;
-import org.apache.struts2.views.jsp.AbstractUITagTest;
+import java.util.Locale;
 
 
 /**
@@ -272,6 +273,9 @@ public class SelectTest extends Abstract
      * @throws Exception
      */
     public void testMultipleWithLists() throws Exception {
+        Locale defaultLocale = Locale.getDefault();
+        Locale.setDefault(Locale.US);
+
         TestAction testAction = (TestAction) action;
         Collection collection = new ArrayList(2);
 
@@ -303,6 +307,8 @@ public class SelectTest extends Abstract
         tag.doEndTag();
 
         verify(SelectTag.class.getResource("Select-12.txt"));
+
+        Locale.setDefault(defaultLocale);
     }
 
     public void testSimple() throws Exception {

Modified: struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt (original)
+++ struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt Mon Oct 17 13:27:43 2011
@@ -42,7 +42,7 @@
          //validatorname:int
          if(form.elements['myUpDownSelectTag']){
             field=form.elements['myUpDownSelectTag'];
-            var error="bar must be between 6000 and 10000.";
+            var error="bar must be between 6,000 and 10,000.";
             if(continueValidation && field.value!=null){
                 if(parseInt(field.value)<6000||parseInt(field.value)>10000){
                     addError(field,error);

Modified: struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-12.txt
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-12.txt?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-12.txt (original)
+++ struts/struts2/branches/new_conversion/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-12.txt Mon Oct 17 13:27:43 2011
@@ -3,7 +3,7 @@
     <td><select name="collection" id="collection" multiple="multiple" onmousedown="alert('onmousedown');" onmouseup="alert('onmouseup');" onmouseover="alert('onmouseover');" onmousemove="alert('onmousemove');" onmouseout="alert('onmouseout');">
     <option value="1" selected="selected">foo</option>
     <option value="2">bar</option>
-    <option value="300000000" selected="selected">foobar</option>
+    <option value="300,000,000" selected="selected">foobar</option>
 </select>
 <inputtype="hidden" id="__multiselect_collection" name="__multiselect_collection" value=""/>
 </td>

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/Converter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/Converter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/Converter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/Converter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,9 @@
+package com.opensymphony.xwork2.conversion;
+
+import java.util.Map;
+
+public interface Converter {
+
+    Object convert(Object value, Map<String, Object> context);
+
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ValueConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ValueConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ValueConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ValueConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,9 @@
+package com.opensymphony.xwork2.conversion;
+
+import java.util.Map;
+
+public interface ValueConverter {
+
+    Object convertValue(Object value, Map<String, Object> context);
+
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/AbstractConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/AbstractConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/AbstractConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/AbstractConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,81 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.conversion.Converter;
+import com.opensymphony.xwork2.conversion.TypeConversionException;
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.ValueConverter;
+
+import java.lang.reflect.Member;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+
+public abstract class AbstractConverter implements TypeConverter, Converter {
+
+    private final Map<Class, ValueConverter> converters;
+    private Class clazz;
+    private Class type;
+
+    protected AbstractConverter() {
+        converters = new HashMap<Class, ValueConverter>();
+    }
+
+    public AbstractConverter(Class clazz, Class type) {
+        this();
+        this.clazz = clazz;
+        this.type = type;
+    }
+
+    public Object convert(Object value, Map<String, Object> context) {
+        if (value == null) {
+            return getDefaultConverter().convertValue(value, context);
+        }
+        return findConverter(value.getClass()).convertValue(value, context);
+    }
+
+    public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) {
+        return convert(value, context);
+    }
+
+    private ValueConverter findConverter(Class clazz) {
+        if (converters.containsKey(clazz)) {
+            return converters.get(clazz);
+        } else if (converters.containsKey(clazz.getSuperclass())) {
+            return converters.get(clazz.getSuperclass());
+        } else {
+            return getDefaultConverter();
+        }
+    }
+
+    protected void register(Class clazz, ValueConverter valueConverter) {
+        converters.put(clazz, valueConverter);
+    }
+
+    protected ValueConverter getDefaultConverter() {
+        return new ValueConverter() {
+            public Object convertValue(Object value, Map<String, Object> context) {
+                if (isAssignable(value)) {
+                    return value;
+                }
+                throw new TypeConversionException("Cannot convert [" + value + "] to class [" + clazz +"]");
+            }
+        };
+    }
+
+    private boolean isAssignable(Object value) {
+        return value != null && ((value.getClass().isAssignableFrom(clazz)) || value.getClass().isAssignableFrom(type));
+    }
+
+    protected Locale getLocale(Map<String, Object> context) {
+        Locale locale = null;
+        if (context != null) {
+            locale = (Locale) context.get(ActionContext.LOCALE);
+        }
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return locale;
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/BooleanConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/BooleanConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/BooleanConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/BooleanConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,52 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+
+import java.util.Map;
+
+public class BooleanConverter extends AbstractConverter {
+
+    public BooleanConverter() {
+        super(Boolean.class, Boolean.TYPE);
+        register(String.class, new StringToBooleanConverter());
+        register(Character.class, new CharacterToBooleanConverter());
+        register(Number.class, new NumberToBooleanConverter());
+    }
+
+    public ValueConverter getDefaultConverter() {
+        return new ValueConverter() {
+            public Object convertValue(Object value, Map<String, Object> context) {
+                if (value != null) {
+                    return Boolean.TRUE;
+                }
+                return Boolean.FALSE;
+            }
+        };
+    }
+
+    private class StringToBooleanConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            String strValue = (String) value;
+            return Boolean.valueOf(strValue);
+        }
+
+    }
+
+    private class CharacterToBooleanConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return Character.valueOf('1').equals(value);
+        }
+
+    }
+
+    private class NumberToBooleanConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).doubleValue() != 0;
+        }
+
+    }
+
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ByteConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ByteConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ByteConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ByteConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,69 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class ByteConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(ByteConverter.class);
+
+    public ByteConverter() {
+        super(Byte.class, Byte.TYPE);
+        register(String.class, new StringToByteConverter());
+        register(Number.class, new NumberToByteConverter());
+        register(Boolean.class, new BooleanToByteConverter());
+        register(Character.class, new CharacterToByteConverter());
+    }
+
+    private class StringToByteConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Byte!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Byte tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).byteValue();
+        }
+
+    }
+
+    private class NumberToByteConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).byteValue();
+        }
+
+    }
+
+    private class BooleanToByteConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return (byte) 1;
+            } else{
+                return (byte) 0;
+            }
+        }
+    }
+
+    private class CharacterToByteConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Character character = (Character) value;
+            return (byte) character.charValue();
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/CharacterConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/CharacterConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/CharacterConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/CharacterConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,46 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+
+import java.util.Map;
+
+public class CharacterConverter extends AbstractConverter {
+
+    public CharacterConverter() {
+        super(Character.class, Character.TYPE);
+        register(String.class, new StringToCharacterConverter());
+        register(Number.class, new NumberToCharacterConverter());
+        register(Boolean.class, new BooleanToCharacterConverter());
+    }
+
+
+    private class StringToCharacterConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            String strValue = (String) value;
+            return strValue.charAt(0);
+        }
+
+    }
+
+    private class NumberToCharacterConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return (char) ((Number) value).longValue();
+        }
+
+    }
+
+    private class BooleanToCharacterConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return (char) 1;
+            } else {
+                return (char) 0;
+            }
+        }
+
+    }
+}

Modified: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java (original)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java Mon Oct 17 13:27:43 2011
@@ -30,6 +30,7 @@
 //--------------------------------------------------------------------------
 package com.opensymphony.xwork2.conversion.impl;
 
+import com.opensymphony.xwork2.conversion.Converter;
 import com.opensymphony.xwork2.conversion.TypeConverter;
 import com.opensymphony.xwork2.ognl.XWorkTypeConverterWrapper;
 
@@ -37,73 +38,144 @@ import java.lang.reflect.Array;
 import java.lang.reflect.Member;
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 /**
- * Default type conversion. Converts among numeric types and also strings.  Contains the basic 
+ * Default type conversion. Converts among numeric types and also strings.  Contains the basic
  * type mapping code from OGNL.
- * 
+ *
  * @author Luke Blanshard (blanshlu@netscape.net)
  * @author Drew Davidson (drew@ognl.org)
  */
 public class DefaultTypeConverter implements TypeConverter {
+
     private static final String NULL_STRING = "null";
 
-    private final Map<Class, Object> primitiveDefaults;
+    private Map<Class, Object> primitiveDefaults;
+    private Map<Class, Converter> defaultConverters;
 
     public DefaultTypeConverter() {
-        Map<Class, Object> map = new HashMap<Class, Object>();
-        map.put(Boolean.TYPE, Boolean.FALSE);
-        map.put(Byte.TYPE, Byte.valueOf((byte) 0));
-        map.put(Short.TYPE, Short.valueOf((short) 0));
-        map.put(Character.TYPE, new Character((char) 0));
-        map.put(Integer.TYPE, Integer.valueOf(0));
-        map.put(Long.TYPE, Long.valueOf(0L));
-        map.put(Float.TYPE, new Float(0.0f));
-        map.put(Double.TYPE, new Double(0.0));
-        map.put(BigInteger.class, new BigInteger("0"));
-        map.put(BigDecimal.class, new BigDecimal(0.0));
-        primitiveDefaults = Collections.unmodifiableMap(map);
+        primitiveDefaults = new HashMap<Class, Object>();
+        defaultConverters = new HashMap<Class, Converter>();
+        initPrimitiveDefaults();
+        initDefaultConverters();
+    }
+
+    private void initDefaultConverters() {
+        register(Boolean.TYPE, Boolean.class, new BooleanConverter());
+        register(Character.TYPE, Character.class, new CharacterConverter());
+        register(Double.TYPE, Double.class, new DoubleConverter());
+        register(Float.TYPE, Float.class, new FloatConverter());
+        register(Byte.TYPE, Byte.class, new ByteConverter());
+        register(Integer.TYPE, Integer.class, new IntegerConverter());
+        register(Long.TYPE, Long.class, new LongConverter());
+        register(Short.TYPE, Short.class, new ShortConverter());
+        register(String.class, new StringConverter());
+    }
+
+    private void register(Class clazz, Converter converter) {
+        defaultConverters.put(clazz, converter);
+    }
+
+    private void register(Class primitiveClazz, Class clazz, Converter converter) {
+        defaultConverters.put(primitiveClazz, converter);
+        defaultConverters.put(clazz, converter);
+    }
+
+    private void initPrimitiveDefaults() {
+        primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
+        primitiveDefaults.put(Byte.TYPE, (byte) 0);
+        primitiveDefaults.put(Short.TYPE, (short) 0);
+        primitiveDefaults.put(Character.TYPE, (char) 0);
+        primitiveDefaults.put(Integer.TYPE, 0);
+        primitiveDefaults.put(Long.TYPE, 0L);
+        primitiveDefaults.put(Float.TYPE, 0.0f);
+        primitiveDefaults.put(Double.TYPE, 0.0);
+        primitiveDefaults.put(BigInteger.class, BigInteger.valueOf(0L));
+        primitiveDefaults.put(BigDecimal.class, BigDecimal.valueOf(0.0));
     }
 
     public Object convertValue(Map<String, Object> context, Object value, Class toType) {
-        return convertValue(value, toType);
+        Object result = null;
+
+        if (value != null) {
+            /* If array -> array then convert components of array individually */
+            if (value.getClass().isArray() && toType.isArray()) {
+                Class componentType = toType.getComponentType();
+
+                result = Array.newInstance(componentType, Array
+                        .getLength(value));
+                for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
+                    Array.set(result, i, convertValue(Array.get(value, i), componentType, context));
+                }
+            } else {
+                if ((toType == Integer.class) || (toType == Integer.TYPE))
+                    result = defaultConverters.get(Integer.class).convert(value, context);
+                if ((toType == Double.class) || (toType == Double.TYPE))
+                    result = defaultConverters.get(Double.class).convert(value, context);
+                if ((toType == Boolean.class) || (toType == Boolean.TYPE))
+                    result = defaultConverters.get(Boolean.TYPE).convert(value, context);
+                if ((toType == Byte.class) || (toType == Byte.TYPE))
+                    result = defaultConverters.get(Byte.class).convert(value, context);
+                if ((toType == Character.class) || (toType == Character.TYPE))
+                    result = defaultConverters.get(Character.class).convert(value, context);
+                if ((toType == Short.class) || (toType == Short.TYPE))
+                    result = defaultConverters.get(Short.class).convert(value, context);
+                if ((toType == Long.class) || (toType == Long.TYPE))
+                    result = defaultConverters.get(Long.class).convert(value, context);
+                if ((toType == Float.class) || (toType == Float.TYPE))
+                    result = defaultConverters.get(Float.class).convert(value, context);
+                if (toType == BigInteger.class)
+                    result = bigIntValue(value);
+                if (toType == BigDecimal.class)
+                    result = bigDecValue(value);
+                if (toType == String.class)
+                    result = defaultConverters.get(String.class).convert(value, context);
+                if (Enum.class.isAssignableFrom(toType))
+                    result = enumValue((Class<Enum>) toType, value);
+                if (result == null && toType.isPrimitive()) {
+                    result = primitiveDefaults.get(toType);
+                }
+            }
+        } else {
+            if (toType.isPrimitive()) {
+                result = primitiveDefaults.get(toType);
+            }
+        }
+        return result;
     }
 
     public Object convertValue(Map<String, Object> context, Object target, Member member,
-            String propertyName, Object value, Class toType) {
+                               String propertyName, Object value, Class toType) {
         return convertValue(context, value, toType);
     }
-    
-    public TypeConverter getTypeConverter( Map<String, Object> context )
-    {
+
+    @SuppressWarnings(value = "unchecked")
+    public TypeConverter getTypeConverter(Map<String, Object> context) {
         Object obj = context.get(TypeConverter.TYPE_CONVERTER_CONTEXT_KEY);
         if (obj instanceof TypeConverter) {
             return (TypeConverter) obj;
-            
-        // for backwards-compatibility
+
+            // for backwards-compatibility
         } else if (obj instanceof ognl.TypeConverter) {
             return new XWorkTypeConverterWrapper((ognl.TypeConverter) obj);
         }
-        return null; 
+        return null;
     }
 
     /**
      * Returns the value converted numerically to the given class type
-     * 
+     * <p/>
      * This method also detects when arrays are being converted and converts the
      * components of one array to the type of the other.
-     * 
-     * @param value
-     *            an object to be converted to the given type
-     * @param toType
-     *            class type to be converted to
+     *
+     * @param value  an object to be converted to the given type
+     * @param toType class type to be converted to
      * @return converted value of the type given, or value if the value cannot
      *         be converted to the given type.
      */
-    public Object convertValue(Object value, Class toType) {
+    private Object convertValue(Object value, Class toType, Map<String, Object> context) {
         Object result = null;
 
         if (value != null) {
@@ -114,34 +186,36 @@ public class DefaultTypeConverter implem
                 result = Array.newInstance(componentType, Array
                         .getLength(value));
                 for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
-                    Array.set(result, i, convertValue(Array.get(value, i),
-                            componentType));
+                    Array.set(result, i, convertValue(Array.get(value, i), componentType, context));
                 }
             } else {
                 if ((toType == Integer.class) || (toType == Integer.TYPE))
-                    result = Integer.valueOf((int) longValue(value));
+                    result = defaultConverters.get(Integer.class).convert(value, context);
                 if ((toType == Double.class) || (toType == Double.TYPE))
-                    result = new Double(doubleValue(value));
+                    result = defaultConverters.get(Double.class).convert(value, context);
                 if ((toType == Boolean.class) || (toType == Boolean.TYPE))
-                    result = booleanValue(value) ? Boolean.TRUE : Boolean.FALSE;
+                    result = defaultConverters.get(Boolean.TYPE).convert(value, context);
                 if ((toType == Byte.class) || (toType == Byte.TYPE))
-                    result = Byte.valueOf((byte) longValue(value));
+                    result = defaultConverters.get(Byte.class).convert(value, context);
                 if ((toType == Character.class) || (toType == Character.TYPE))
-                    result = new Character((char) longValue(value));
+                    result = defaultConverters.get(Character.class).convert(value, context);
                 if ((toType == Short.class) || (toType == Short.TYPE))
-                    result = Short.valueOf((short) longValue(value));
+                    result = defaultConverters.get(Short.class).convert(value, context);
                 if ((toType == Long.class) || (toType == Long.TYPE))
-                    result = Long.valueOf(longValue(value));
+                    result = defaultConverters.get(Long.class).convert(value, context);
                 if ((toType == Float.class) || (toType == Float.TYPE))
-                    result = new Float(doubleValue(value));
+                    result = defaultConverters.get(Float.class).convert(value, context);
                 if (toType == BigInteger.class)
                     result = bigIntValue(value);
                 if (toType == BigDecimal.class)
                     result = bigDecValue(value);
                 if (toType == String.class)
-                    result = stringValue(value);
+                    result = defaultConverters.get(String.class).convert(value, context);
                 if (Enum.class.isAssignableFrom(toType))
-                    result = enumValue((Class<Enum>)toType, value);
+                    result = enumValue((Class<Enum>) toType, value);
+                if (result == null && toType.isPrimitive()) {
+                    result = primitiveDefaults.get(toType);
+                }
             }
         } else {
             if (toType.isPrimitive()) {
@@ -155,9 +229,8 @@ public class DefaultTypeConverter implem
      * Evaluates the given object as a boolean: if it is a Boolean object, it's
      * easy; if it's a Number or a Character, returns true for non-zero objects;
      * and otherwise returns true for non-null objects.
-     * 
-     * @param value
-     *            an object to interpret as a boolean
+     *
+     * @param value an object to interpret as a boolean
      * @return the boolean value implied by the given object
      */
     public static boolean booleanValue(Object value) {
@@ -174,7 +247,7 @@ public class DefaultTypeConverter implem
             return ((Number) value).doubleValue() != 0;
         return true; // non-null
     }
-    
+
     public Enum<?> enumValue(Class toClass, Object o) {
         Enum<?> result = null;
         if (o == null) {
@@ -189,12 +262,10 @@ public class DefaultTypeConverter implem
 
     /**
      * Evaluates the given object as a long integer.
-     * 
-     * @param value
-     *            an object to interpret as a long integer
+     *
+     * @param value an object to interpret as a long integer
      * @return the long integer value implied by the given object
-     * @throws NumberFormatException
-     *             if the given object can't be understood as a long integer
+     * @throws NumberFormatException if the given object can't be understood as a long integer
      */
     public static long longValue(Object value) throws NumberFormatException {
         if (value == null)
@@ -211,12 +282,10 @@ public class DefaultTypeConverter implem
 
     /**
      * Evaluates the given object as a double-precision floating-point number.
-     * 
-     * @param value
-     *            an object to interpret as a double
+     *
+     * @param value an object to interpret as a double
      * @return the double value implied by the given object
-     * @throws NumberFormatException
-     *             if the given object can't be understood as a double
+     * @throws NumberFormatException if the given object can't be understood as a double
      */
     public static double doubleValue(Object value) throws NumberFormatException {
         if (value == null)
@@ -239,12 +308,10 @@ public class DefaultTypeConverter implem
 
     /**
      * Evaluates the given object as a BigInteger.
-     * 
-     * @param value
-     *            an object to interpret as a BigInteger
+     *
+     * @param value an object to interpret as a BigInteger
      * @return the BigInteger value implied by the given object
-     * @throws NumberFormatException
-     *             if the given object can't be understood as a BigInteger
+     * @throws NumberFormatException if the given object can't be understood as a BigInteger
      */
     public static BigInteger bigIntValue(Object value)
             throws NumberFormatException {
@@ -258,20 +325,18 @@ public class DefaultTypeConverter implem
         if (c.getSuperclass() == Number.class)
             return BigInteger.valueOf(((Number) value).longValue());
         if (c == Boolean.class)
-            return BigInteger.valueOf(((Boolean) value).booleanValue() ? 1 : 0);
+            return BigInteger.valueOf((Boolean) value ? 1 : 0);
         if (c == Character.class)
-            return BigInteger.valueOf(((Character) value).charValue());
+            return BigInteger.valueOf((Character) value);
         return new BigInteger(stringValue(value, true));
     }
 
     /**
      * Evaluates the given object as a BigDecimal.
-     * 
-     * @param value
-     *            an object to interpret as a BigDecimal
+     *
+     * @param value an object to interpret as a BigDecimal
      * @return the BigDecimal value implied by the given object
-     * @throws NumberFormatException
-     *             if the given object can't be understood as a BigDecimal
+     * @throws NumberFormatException if the given object can't be understood as a BigDecimal
      */
     public static BigDecimal bigDecValue(Object value)
             throws NumberFormatException {
@@ -294,9 +359,8 @@ public class DefaultTypeConverter implem
     /**
      * Evaluates the given object as a String and trims it if the trim flag is
      * true.
-     * 
-     * @param value
-     *            an object to interpret as a String
+     *
+     * @param value an object to interpret as a String
      * @return the String value implied by the given object as returned by the
      *         toString() method, or "null" if the object is null.
      */
@@ -316,9 +380,8 @@ public class DefaultTypeConverter implem
 
     /**
      * Evaluates the given object as a String.
-     * 
-     * @param value
-     *            an object to interpret as a String
+     *
+     * @param value an object to interpret as a String
      * @return the String value implied by the given object as returned by the
      *         toString() method, or "null" if the object is null.
      */

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DoubleConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DoubleConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DoubleConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DoubleConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,69 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class DoubleConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(DoubleConverter.class);
+
+    public DoubleConverter() {
+        super(Double.class, Double.TYPE);
+        register(String.class, new StringToDoubleConverter());
+        register(Number.class, new NumberToDoubleConverter());
+        register(Boolean.class, new BooleanToDoubleConverter());
+        register(Character.class, new CharacterToDoubleConverter());
+    }
+
+    private class StringToDoubleConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Double!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Double tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).doubleValue();
+        }
+
+    }
+
+    private class NumberToDoubleConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).doubleValue();
+        }
+
+    }
+
+    private class BooleanToDoubleConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return 1.0;
+            } else {
+                return 0.0;
+            }
+        }
+
+    }
+
+    private class CharacterToDoubleConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return Double.valueOf(((Character) value));
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/FloatConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/FloatConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/FloatConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/FloatConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,69 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class FloatConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(FloatConverter.class);
+
+    public FloatConverter() {
+        super(Float.class, Float.TYPE);
+        register(String.class, new StringToFloatConverter());
+        register(Number.class, new NumberToFloatConverter());
+        register(Boolean.class, new BooleanToFloatConverter());
+        register(Character.class, new CharacterToFloatConverter());
+    }
+
+    private class StringToFloatConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Float!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Float tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).floatValue();
+        }
+
+    }
+
+    private class NumberToFloatConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).floatValue();
+        }
+
+    }
+
+    private class BooleanToFloatConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return 1.0F;
+            } else {
+                return 0.0F;
+            }
+        }
+
+    }
+
+    private class CharacterToFloatConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return Float.valueOf((Character) value);
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/IntegerConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/IntegerConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/IntegerConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/IntegerConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,70 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class IntegerConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(IntegerConverter.class);
+
+    public IntegerConverter() {
+        super(Integer.class, Integer.TYPE);
+        register(String.class, new StringToIntegerConverter());
+        register(Number.class, new NumberToIntegerConverter());
+        register(Boolean.class, new BooleanToIntegerConverter());
+        register(Character.class, new CharacterToIntegerConverter());
+    }
+
+    private class StringToIntegerConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Integer!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Integer tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).intValue();
+        }
+
+    }
+
+    private class NumberToIntegerConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).intValue();
+        }
+
+    }
+
+    private class BooleanToIntegerConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return 1;
+            } else {
+                return 0;
+            }
+        }
+
+    }
+
+    private class CharacterToIntegerConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Character character = (Character) value;
+            return (int) character.charValue();
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/LongConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/LongConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/LongConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/LongConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,70 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class LongConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(LongConverter.class);
+
+    public LongConverter() {
+        super(Long.class, Long.TYPE);
+        register(String.class, new StringToLongConverter());
+        register(Number.class, new NumberToLongConverter());
+        register(Boolean.class, new BooleanToLongConverter());
+        register(Character.class, new CharacterToLongConverter());
+    }
+
+    private class StringToLongConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Long!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Long tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).longValue();
+        }
+
+    }
+
+    private class NumberToLongConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).longValue();
+        }
+
+    }
+
+    private class BooleanToLongConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return 1L;
+            } else {
+                return 0L;
+            }
+        }
+
+    }
+
+    private class CharacterToLongConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Character character = (Character) value;
+            return (long) character.charValue();
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ShortConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ShortConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ShortConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/ShortConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,70 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Map;
+
+public class ShortConverter extends AbstractConverter {
+
+    private static Logger LOG = LoggerFactory.getLogger(ShortConverter.class);
+
+    public ShortConverter() {
+        super(Short.class, Short.TYPE);
+        register(String.class, new StringToShortConverter());
+        register(Number.class, new NumberToShortConverter());
+        register(Boolean.class, new BooleanToShortConverter());
+        register(Character.class, new CharacterToShortConverter());
+    }
+
+    private class StringToShortConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            try {
+                return tryConvertValue((String) value, context);
+            } catch (ParseException e) {
+                LOG.warn("Could not convert [" + value + "] to Short!");
+                return getDefaultConverter().convertValue(value, context);
+            }
+        }
+
+        private Short tryConvertValue(String value, Map<String, Object> context) throws ParseException {
+            NumberFormat numberFormat = NumberFormat.getInstance(getLocale(context));
+            return numberFormat.parse(value).shortValue();
+        }
+
+    }
+
+    private class NumberToShortConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            return ((Number) value).shortValue();
+        }
+
+    }
+
+    private class BooleanToShortConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Boolean bool = (Boolean) value;
+            if (bool) {
+                return (short) 1;
+            } else {
+                return (short) 0;
+            }
+        }
+
+    }
+
+    private class CharacterToShortConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            Character character = (Character) value;
+            return (short) character.charValue();
+        }
+
+    }
+}

Added: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/StringConverter.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,41 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ValueConverter;
+
+import java.text.NumberFormat;
+import java.util.Map;
+
+public class StringConverter extends AbstractConverter {
+
+    public StringConverter() {
+        register(Number.class, new NumberToStringConverter());
+    }
+
+    @Override
+    protected ValueConverter getDefaultConverter() {
+        return new ValueConverter() {
+            public Object convertValue(Object value, Map<String, Object> context) {
+                return value.toString();
+            }
+        };
+    }
+
+    private class NumberToStringConverter implements ValueConverter {
+
+        public Object convertValue(Object value, Map<String, Object> context) {
+            NumberFormat format = NumberFormat.getInstance(getLocale(context));
+            updateFractionDigits(format, value.toString());
+            return format.format(value);
+        }
+
+        private void updateFractionDigits(NumberFormat format, String strValue) {
+            int digits = 0;
+            int startIndex = (strValue.lastIndexOf(",") > -1 ? strValue.lastIndexOf(",") : strValue.lastIndexOf("."));
+            if (startIndex > -1) {
+                digits = strValue.substring(startIndex + 1, strValue.length()).length();
+            }
+            format.setMaximumFractionDigits(digits);
+        }
+
+    }
+}

Modified: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java (original)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverter.java Mon Oct 17 13:27:43 2011
@@ -22,16 +22,29 @@ import com.opensymphony.xwork2.conversio
 import com.opensymphony.xwork2.conversion.TypeConverter;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.XWorkList;
+import org.apache.commons.lang.StringUtils;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.text.*;
-import java.util.*;
-
-import org.apache.commons.lang.StringUtils;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 
 
 /**

Modified: struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java (original)
+++ struts/struts2/branches/new_conversion/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java Mon Oct 17 13:27:43 2011
@@ -343,7 +343,7 @@ public class XWorkConverter extends Defa
             try {
                 if (LOG.isDebugEnabled())
                     LOG.debug("falling back to Ognl's default type conversion");
-                return super.convertValue(value, toClass);
+                return super.convertValue(null, value, toClass);
             } catch (Exception e) {
                 if (LOG.isDebugEnabled())
                     LOG.debug("unable to convert value using type converter [#0]", e, super.getClass().getName());

Modified: struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java?rev=1185159&r1=1185158&r2=1185159&view=diff
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java (original)
+++ struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java Mon Oct 17 13:27:43 2011
@@ -142,7 +142,7 @@ public class MockConfigurationProvider i
         params.put("date", new java.util.Date(2002 - 1900, 11, 20));
 
         //Explicitly set an out-of-range double for DoubleRangeValidatorTest
-        params.put("percentage", new Double(100.0123));
+        params.put("percentage", 100.0123);
 
         ActionConfig validationActionConfig = new ActionConfig.Builder("defaultPackage", VALIDATION_ACTION_NAME, SimpleAction.class.getName())
             .addInterceptors(interceptors)

Added: struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterTest.java?rev=1185159&view=auto
==============================================================================
--- struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterTest.java (added)
+++ struts/struts2/branches/new_conversion/xwork-core/src/test/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterTest.java Mon Oct 17 13:27:43 2011
@@ -0,0 +1,455 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.ActionContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class DefaultTypeConverterTest {
+
+    private DefaultTypeConverter converter;
+
+    @Before
+    public void setUp() {
+        converter = new DefaultTypeConverter();
+    }
+
+    @After
+    public void tearDown() {
+        converter = null;
+    }
+
+    public void check(Object value, Class toType, Object expected, String message, Map<String, Object> context) throws Exception {
+        Object result = converter.convertValue(context, value, toType);
+        assertEquals(message, expected, result);
+    }
+
+    @Test
+    public void shouldConvertToTrue() throws Exception {
+        // String
+        check("true", Boolean.TYPE, Boolean.TRUE, "Literally 'true' should be true!", null);
+        check("True", Boolean.TYPE, Boolean.TRUE, "Literally 'True' should be true!", null);
+        check("true", Boolean.class, Boolean.TRUE, "Literally 'true' should be true!", null);
+        check("True", Boolean.class, Boolean.TRUE, "Literally 'True' should be true!", null);
+
+        // String's array
+        Object converted = converter.convertValue(null, new String[]{"true", "true"}, boolean[].class);
+        assertTrue("Array of Strings should be converted to [true, true]", Arrays.equals(new boolean[]{true, true}, (boolean[]) converted));
+
+        // Character
+        check('1', Boolean.class, Boolean.TRUE, "Character '1' should be converted to true", null);
+
+        // Integer
+        check(2, Boolean.TYPE, Boolean.TRUE, "Integer 2 should be converted to true", null);
+
+        // Long
+        check(1L, Boolean.TYPE, Boolean.TRUE, "Long 1 should be converted to true", null);
+        check(110L, Boolean.TYPE, Boolean.TRUE, "Long 110 should be converted to true", null);
+
+        // Double
+        check(1.0, Boolean.class, Boolean.TRUE, "Double 1.0 should be converted to true", null);
+        check(-1.0, Boolean.class, Boolean.TRUE, "Double -1.0 should be converted to true", null);
+        check(1.3, Boolean.class, Boolean.TRUE, "Double 1.3 should be converted to true", null);
+
+        // Float
+        check(1.0F, Boolean.class, Boolean.TRUE, "Float 1.0 should be converted to true", null);
+        check(-1.0F, Boolean.class, Boolean.TRUE, "Float -1.0 should be converted to true", null);
+        check(1.3F, Boolean.class, Boolean.TRUE, "Float 1.3 should be converted to true", null);
+
+        // Byte
+        check(Byte.valueOf("2"), Boolean.class, Boolean.TRUE, "Byte 2 should be converted to true", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(20L), Boolean.class, Boolean.TRUE, "BigInteger 20 should be converted to true", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(30L), Boolean.class, Boolean.TRUE, "BigDecimal 30 should be converted to true", null);
+
+        // Short
+        check((short) 30, Boolean.class, Boolean.TRUE, "Short 30 should be converted to true", null);
+    }
+
+    @Test
+    public void shouldConvertToFalse() throws Exception {
+        // String
+        check(null, Boolean.TYPE, Boolean.FALSE, "Converting null should return false!", null);
+        check(null, Boolean.class, null, "Converting null should return null!", null);
+        check("FalsE", Boolean.TYPE, Boolean.FALSE, "Literally 'FalsE' should be false!", null);
+        check("false", Boolean.class, Boolean.FALSE, "Literally 'false' should be false!", null);
+        check("0", Boolean.class, Boolean.FALSE, "Literally '0' should be false!", null);
+        check("1", Boolean.class, Boolean.FALSE, "Literally '1' should be false!", null);
+
+        // Character
+        check('0', Boolean.class, Boolean.FALSE, "Character '0' should be converted to false", null);
+        check('A', Boolean.class, Boolean.FALSE, "Character 'A' should be converted to false", null);
+
+        // Integer
+        check(0, Boolean.TYPE, Boolean.FALSE, "Integer 0 should be converted to false", null);
+
+        // Long
+        check(0L, Boolean.TYPE, Boolean.FALSE, "Long 1 should be converted to false", null);
+
+        // Double
+        check(0.0, Boolean.class, Boolean.FALSE, "Double 0.0 should be converted to false", null);
+
+        // Float
+        check(0.0F, Boolean.class, Boolean.FALSE, "Float 0.0 should be converted to false", null);
+
+        // Byte
+        check(Byte.valueOf("0"), Boolean.class, Boolean.FALSE, "Byte 0 should be converted to false", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(0L), Boolean.class, Boolean.FALSE, "BigInteger 0 should be converted to false", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(0L), Boolean.class, Boolean.FALSE, "BigDecimal 0 should be converted to false", null);
+
+        // Short
+        check((short) 0, Boolean.class, Boolean.FALSE, "Short 0 should be converted to false", null);
+    }
+
+    @Test
+    public void shouldConvertToDouble() throws Exception {
+        // null
+        check(null, Double.class, null, "Null should be converted to null", null);
+
+        check(null, Double.TYPE, 0.0, "Null (primitive type) should be converted 0.0", null);
+
+        // String PL-pl
+        check("1,2", Double.TYPE, 1.2, "'1,2' (Polish) should be converted to 1.2", buildContext("pl", "PL"));
+        // English
+        check("1.2", Double.class, 1.2, "'1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Double.TYPE, 1.2, "'1.2foo' (English) should be converted to 1.2", buildContext("en", "GB"));
+        check("boo3.4", Double.class, null, "'boo1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+        check("boo3.4", Double.TYPE, 0.0, "'boo1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Double.class, 200.0, "200 should be converted to 200.0", null);
+
+        // Boolean
+        check(Boolean.FALSE, Double.TYPE, 0.0, "False should be converted to 0.0", null);
+        check(Boolean.TRUE, Double.TYPE, 1.0, "True should be converted to 1.0", null);
+
+        // Character
+        check('W', Double.class, 87.0, "Character 'W' should be converted to 87.0", null);
+
+        // Long
+        check(100L, Double.class, 100.0, "Long 100 should be converted to 100.0", null);
+
+        // Float
+        check(40F, Double.class, 40.0, "Float 40 should be converted to 40.0", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Double.class, 1.0, "Byte 1 should be converted to 11", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Double.class, 145.0, "BigInteger 145 should be converted to 145.0", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Double.class, 23.44, "BigDecimal 23.44 should be converted to 23.44", null);
+
+        // Short
+        check((short) 30, Double.class, 30.0, "Short 30 should be converted to 30.0", null);
+    }
+
+    @Test
+    public void shouldConvertToFloat() throws Exception {
+        // null
+        check(null, Float.class, null, "Null should be converted to null", null);
+
+        check(null, Float.TYPE, 0.0F, "Null (primitive type) should be converted 0.0", null);
+
+        // String PL-pl
+        check("1,2", Float.TYPE, 1.2F, "'1,2' (Polish) should be converted to 1.2", buildContext("pl", "PL"));
+        // English
+        check("1.2", Float.class, 1.2F, "'1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+
+        float[] floats = (float[]) converter.convertValue(null, new String[]{"123", "456"}, float[].class);
+        assertTrue(Arrays.equals(floats, new float[]{123F, 456F}));
+
+        // English with text
+        check("1.2foo", Float.TYPE, 1.2F, "'1.2foo' (English) should be converted to 1.2", buildContext("en", "GB"));
+        check("boo3.4", Float.class, null, "'boo1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+        check("boo3.4", Float.TYPE, 0F, "'boo1.2' (English) should be converted to 1.2", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Float.class, 200.0F, "200 should be converted to 200.0", null);
+
+        // Boolean
+        check(Boolean.FALSE, Float.TYPE, 0.0F, "False should be converted to 0.0", null);
+        check(Boolean.TRUE, Float.TYPE, 1.0F, "True should be converted to 1.0", null);
+
+        // Character
+        check('W', Float.class, 87.0F, "Character 'W' should be converted to 87.0", null);
+
+        // Long
+        check(100L, Float.class, 100.0F, "Long 100 should be converted to 100.0", null);
+
+        // Float
+        check(40F, Float.class, 40.0F, "Float 40 should be converted to 40.0", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Float.class, 1.0F, "Byte 1 should be converted to 11", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Float.class, 145.0F, "BigInteger 145 should be converted to 145.0", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Float.class, 23.44F, "BigDecimal 23.44 should be converted to 23.44", null);
+
+        // Short
+        check((short) 30, Float.class, 30.0F, "Short 30 should be converted to 30.0", null);
+    }
+
+    @Test
+    public void shouldConvertToByte() throws Exception {
+        // null
+        check(null, Byte.class, null, "Null should be converted to null", null);
+
+        check(null, Byte.TYPE, (byte) 0, "Null (primitive type) should be converted 0", null);
+
+        // String PL-pl
+        check("1,2", Byte.TYPE, (byte) 1, "'1,2' (Polish) should be converted to 1", buildContext("pl", "PL"));
+        // English
+        check("1.2", Byte.class, (byte) 1, "'1.2' (English) should be converted to 1", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Byte.TYPE, (byte) 1, "'1.2foo' (English) should be converted to 1", buildContext("en", "GB"));
+        check("boo3.4", Byte.class, null, "'boo1.2' (English) should be converted to null", buildContext("en", "GB"));
+        check("boo3.4", Byte.TYPE, (byte) 0, "'boo1.2' (English) should be converted to 0", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Byte.class, (byte) -56, "200 should be converted to -56", null);
+
+        // Boolean
+        check(Boolean.FALSE, Byte.TYPE, (byte) 0, "False should be converted to 0", null);
+        check(Boolean.TRUE, Byte.TYPE, (byte) 1, "True should be converted to 1", null);
+
+        // Character
+        check('W', Byte.class, (byte) 87, "Character 'W' should be converted to 87", null);
+
+        // Long
+        check(100L, Byte.class, (byte) 100, "Long 100 should be converted to 100", null);
+
+        // Float
+        check(40F, Byte.class, (byte) 40, "Float 40 should be converted to 40", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Byte.class, (byte) 1, "Byte 1 should be converted to 1", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Byte.class, (byte) 145, "BigInteger 145 should be converted to 145", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Byte.class, (byte) 23.44, "BigDecimal 23.44 should be converted to 23", null);
+
+        // Short
+        check((short) 30, Byte.class, (byte) 30, "Short 30 should be converted to 30", null);
+    }
+
+    @Test
+    public void shouldConvertToInteger() throws Exception {
+        // null
+        check(null, Integer.class, null, "Null should be converted to null", null);
+
+        check(null, Integer.TYPE, 0, "Null (primitive type) should be converted 0", null);
+
+        // String PL-pl
+        check("1,2", Integer.TYPE, 1, "'1,2' (Polish) should be converted to 1", buildContext("pl", "PL"));
+        // English
+        check("1.2", Integer.class, 1, "'1.2' (English) should be converted to 1", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Integer.TYPE, 1, "'1.2foo' (English) should be converted to 1", buildContext("en", "GB"));
+        check("boo3.4", Integer.class, null, "'boo1.2' (English) should be converted to null", buildContext("en", "GB"));
+        check("boo3.4", Integer.TYPE, 0, "'boo1.2' (English) should be converted to 0", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Integer.class, 200, "200 should be converted to 200", null);
+
+        // Boolean
+        check(Boolean.FALSE, Integer.TYPE, 0, "False should be converted to 0", null);
+        check(Boolean.TRUE, Integer.TYPE, 1, "True should be converted to 1", null);
+
+        // Character
+        check('W', Integer.class, 87, "Character 'W' should be converted to 87", null);
+
+        // Long
+        check(100L, Integer.class, 100, "Long 100 should be converted to 100", null);
+
+        // Float
+        check(40F, Integer.class, 40, "Float 40 should be converted to 40", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Integer.class, 1, "Byte 1 should be converted to 1", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Integer.class, 145, "BigInteger 145 should be converted to 145", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Integer.class, 23, "BigDecimal 23.44 should be converted to 23", null);
+
+        // Short
+        check((short) 30, Integer.class, 30, "Short 30 should be converted to 30", null);
+    }
+
+    @Test
+    public void shouldConvertToLong() throws Exception {
+        // null
+        check(null, Long.class, null, "Null should be converted to null", null);
+
+        check(null, Long.TYPE, 0L, "Null (primitive type) should be converted 0", null);
+
+        // String PL-pl
+        check("1,2", Long.TYPE, 1L, "'1,2' (Polish) should be converted to 1", buildContext("pl", "PL"));
+        // English
+        check("1.2", Long.class, 1L, "'1.2' (English) should be converted to 1", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Long.TYPE, 1L, "'1.2foo' (English) should be converted to 1", buildContext("en", "GB"));
+        check("boo3.4", Long.class, null, "'boo1.2' (English) should be converted to null", buildContext("en", "GB"));
+        check("boo3.4", Long.TYPE, 0L, "'boo1.2' (English) should be converted to 0", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Long.class, 200L, "200 should be converted to 200", null);
+
+        // Boolean
+        check(Boolean.FALSE, Long.TYPE, 0L, "False should be converted to 0", null);
+        check(Boolean.TRUE, Long.TYPE, 1L, "True should be converted to 1", null);
+
+        // Character
+        check('W', Long.class, 87L, "Character 'W' should be converted to 87", null);
+
+        // Long
+        check(100L, Long.class, 100L, "Long 100 should be converted to 100", null);
+
+        // Float
+        check(40F, Long.class, 40L, "Float 40 should be converted to 40", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Long.class, 1L, "Byte 1 should be converted to 1", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Long.class, 145L, "BigInteger 145 should be converted to 145", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Long.class, 23L, "BigDecimal 23.44 should be converted to 23", null);
+
+        // Short
+        check((short) 30, Long.class, 30L, "Short 30 should be converted to 30", null);
+    }
+
+    @Test
+    public void shouldConvertToShort() throws Exception {
+        // null
+        check(null, Short.class, null, "Null should be converted to null", null);
+
+        check(null, Short.TYPE, (short) 0, "Null (primitive type) should be converted 0", null);
+
+        // String PL-pl
+        check("1,2", Short.TYPE, (short) 1, "'1,2' (Polish) should be converted to 1", buildContext("pl", "PL"));
+        // English
+        check("1.2", Short.class, (short) 1, "'1.2' (English) should be converted to 1", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Short.TYPE, (short) 1, "'1.2foo' (English) should be converted to 1", buildContext("en", "GB"));
+        check("boo3.4", Short.class, null, "'boo1.2' (English) should be converted to null", buildContext("en", "GB"));
+        check("boo3.4", Short.TYPE, (short) 0, "'boo1.2' (English) should be converted to 0", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Short.class, (short) 200, "200 should be converted to 200", null);
+
+        // Boolean
+        check(Boolean.FALSE, Short.TYPE, (short) 0, "False should be converted to 0", null);
+        check(Boolean.TRUE, Short.TYPE, (short) 1, "True should be converted to 1", null);
+
+        // Character
+        check('W', Short.class, (short) 87, "Character 'W' should be converted to 87", null);
+
+        // Long
+        check(100L, Short.class, (short) 100, "Long 100 should be converted to 100", null);
+
+        // Float
+        check(40F, Short.class, (short) 40, "Float 40 should be converted to 40", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Short.class, (short) 1, "Byte 1 should be converted to 1", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Short.class, (short) 145, "BigInteger 145 should be converted to 145", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Short.class, (short) 23, "BigDecimal 23.44 should be converted to 23", null);
+
+        // Short
+        check((short) 30, Short.class, (short) 30, "Short 30 should be converted to 30", null);
+    }
+
+    @Test
+    public void shouldConvertToCharacter() throws Exception {
+        // null
+        check(null, Character.class, null, "Null should be converted to null", null);
+
+        check(null, Character.TYPE, (char) 0, "Null (primitive type) should be converted 0", null);
+
+        // String PL-pl
+        check("1,2", Character.TYPE, "1".charAt(0), "'1,2' (Polish) should be converted to 1", buildContext("pl", "PL"));
+        // English
+        check("1.2", Character.class, "1".charAt(0), "'1.2' (English) should be converted to 1", buildContext("en", "GB"));
+
+        // English with text
+        check("1.2foo", Character.TYPE, "1".charAt(0), "'1.2foo' (English) should be converted to 1", buildContext("en", "GB"));
+        check("boo3.4", Character.class, "b".charAt(0), "'boo1.2' (English) should be converted to null", buildContext("en", "GB"));
+        check("boo3.4", Character.TYPE, "b".charAt(0), "'boo1.2' (English) should be converted to 0", buildContext("en", "GB"));
+
+        // Integer
+        check(Integer.valueOf("200"), Character.class, (char) 200, "200 should be converted to 200", null);
+
+        // Boolean
+        check(Boolean.FALSE, Character.TYPE, (char) 0, "False should be converted to 0", null);
+        check(Boolean.TRUE, Character.TYPE, (char) 1, "True should be converted to 1", null);
+
+        // Character
+        check('W', Character.class, 'W', "Character 'W' should be converted to W", null);
+        check('W', Character.TYPE, 'W', "Character 'W' should be converted to W", null);
+
+        // Long
+        check(100L, Character.class, (char) 100, "Long 100 should be converted to 100", null);
+
+        // Float
+        check(40F, Character.class, (char) 40, "Float 40 should be converted to 40", null);
+
+        // Byte
+        check(Byte.valueOf("1"), Character.class, (char) 1, "Byte 1 should be converted to 1", null);
+
+        // BigInteger
+        check(BigInteger.valueOf(145L), Character.class, (char) 145, "BigInteger 145 should be converted to 145", null);
+
+        // BigDecimal
+        check(BigDecimal.valueOf(23.44), Character.class, (char) 23, "BigDecimal 23.44 should be converted to 23", null);
+
+        // Short
+        check((short) 30, Character.class, (char) 30, "Short 30 should be converted to 30", null);
+    }
+
+    private Map<String, Object> buildContext(final String language, final String country) {
+        return new HashMap<String, Object>() {
+            {
+                put(ActionContext.LOCALE, new Locale(language, country));
+            }
+        };
+    }
+
+}