struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject svn commit: r1437180 - in /struts/struts2/trunk: core/src/main/java/org/apache/struts2/ core/src/main/java/org/apache/struts2/config/ core/src/main/resources/ xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/ xwork-core/src/main/java/com/op...
Date Tue, 22 Jan 2013 21:20:36 GMT
Author: lukaszlenart
Date: Tue Jan 22 21:20:35 2013
New Revision: 1437180

URL: http://svn.apache.org/viewvc?rev=1437180&view=rev
Log:
WW-3871 refactors XWorkConverter to separate logic a bit

Added:
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionAnnotationProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionFileProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionPropertiesProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterCreator.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterHolder.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionAnnotationProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionFileProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionPropertiesProcessor.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterCreator.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterHolder.java
Modified:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
    struts/struts2/trunk/core/src/main/resources/struts-default.xml
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java
    struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java Tue Jan 22 21:20:35 2013
@@ -246,4 +246,10 @@ public final class StrutsConstants {
     /** Enable handling exceptions by Dispatcher - true by default **/
     public static final String STRUTS_HANDLE_EXCEPTION = "struts.handle.exception";
 
+    public static final String STRUTS_CONVERTER_PROPERTIES_PROCESSOR = "struts.converter.properties.processor";
+    public static final String STRUTS_CONVERTER_FILE_PROCESSOR = "struts.converter.file.processor";
+    public static final String STRUTS_CONVERTER_ANNOTATION_PROCESSOR = "struts.converter.annotation.processor";
+    public static final String STRUTS_CONVERTER_CREATOR = "struts.converter.creator";
+    public static final String STRUTS_CONVERTER_HOLDER = "struts..converter.holder";
+
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java Tue Jan 22 21:20:35 2013
@@ -32,7 +32,12 @@ import com.opensymphony.xwork2.XWorkCons
 import com.opensymphony.xwork2.config.Configuration;
 import com.opensymphony.xwork2.config.ConfigurationException;
 import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.ConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.ObjectTypeDeterminer;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
 import com.opensymphony.xwork2.conversion.impl.ArrayConverter;
 import com.opensymphony.xwork2.conversion.impl.CollectionConverter;
 import com.opensymphony.xwork2.conversion.impl.DateConverter;
@@ -241,6 +246,36 @@ import java.util.StringTokenizer;
  *     <td>singleton</td>
  *     <td>Converter used to convert any object to String and back</td>
  *   </tr>
+ *   <tr>
+ *     <td>com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor</td>
+ *     <td>struts.conversion.properties.processor</td>
+ *     <td>singleton</td>
+ *     <td>Process Properties to create converters</td>
+ *   </tr>
+ *   <tr>
+ *     <td>com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor</td>
+ *     <td>struts.converter.file.processor</td>
+ *     <td>singleton</td>
+ *     <td>Process <class>-conversion.properties file create converters</class></td>
+ *   </tr>
+ *   <tr>
+ *     <td>com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor</td>
+ *     <td>struts.converter.annotation.processor</td>
+ *     <td>singleton</td>
+ *     <td>Process TypeConversion annotation to create converters</td>
+ *   </tr>
+ *   <tr>
+ *     <td>com.opensymphony.xwork2.conversion.TypeConverterCreator</td>
+ *     <td>struts.converter.creator</td>
+ *     <td>singleton</td>
+ *     <td>Creates user converters</td>
+ *   </tr>
+ *   <tr>
+ *     <td>com.opensymphony.xwork2.conversion.TypeConverterHolder</td>
+ *     <td>struts.converter.holder</td>
+ *     <td>singleton</td>
+ *     <td>Holds user converters' instances</td>
+ *   </tr>
  * </table>
  *
  * <!-- END SNIPPET: extensionPoints -->
@@ -287,8 +322,22 @@ public class BeanSelectionProvider imple
     public void register(ContainerBuilder builder, LocatableProperties props) {
         alias(ObjectFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY, builder, props);
         alias(FileManagerFactory.class, StrutsConstants.STRUTS_FILE_MANAGER_FACTORY, builder, props, Scope.SINGLETON);
+
         alias(XWorkConverter.class, StrutsConstants.STRUTS_XWORKCONVERTER, builder, props);
+        alias(CollectionConverter.class, StrutsConstants.STRUTS_CONVERTER_COLLECTION, builder, props);
+        alias(ArrayConverter.class, StrutsConstants.STRUTS_CONVERTER_ARRAY, builder, props);
+        alias(DateConverter.class, StrutsConstants.STRUTS_CONVERTER_DATE, builder, props);
+        alias(NumberConverter.class, StrutsConstants.STRUTS_CONVERTER_NUMBER, builder, props);
+        alias(StringConverter.class, StrutsConstants.STRUTS_CONVERTER_STRING, builder, props);
+
+        alias(ConversionPropertiesProcessor.class, StrutsConstants.STRUTS_CONVERTER_PROPERTIES_PROCESSOR, builder, props);
+        alias(ConversionFileProcessor.class, StrutsConstants.STRUTS_CONVERTER_FILE_PROCESSOR, builder, props);
+        alias(ConversionAnnotationProcessor.class, StrutsConstants.STRUTS_CONVERTER_ANNOTATION_PROCESSOR, builder, props);
+        alias(TypeConverterCreator.class, StrutsConstants.STRUTS_CONVERTER_CREATOR, builder, props);
+        alias(TypeConverterHolder.class, StrutsConstants.STRUTS_CONVERTER_HOLDER, builder, props);
+
         alias(TextProvider.class, StrutsConstants.STRUTS_XWORKTEXTPROVIDER, builder, props, Scope.DEFAULT);
+
         alias(LocaleProvider.class, StrutsConstants.STRUTS_LOCALE_PROVIDER, builder, props);
         alias(ActionProxyFactory.class, StrutsConstants.STRUTS_ACTIONPROXYFACTORY, builder, props);
         alias(ObjectTypeDeterminer.class, StrutsConstants.STRUTS_OBJECTTYPEDETERMINER, builder, props);
@@ -306,12 +355,6 @@ public class BeanSelectionProvider imple
         alias(UnknownHandlerManager.class, StrutsConstants.STRUTS_UNKNOWN_HANDLER_MANAGER, builder, props);
         alias(UrlHelper.class, StrutsConstants.STRUTS_URL_HELPER, builder, props);
 
-        alias(CollectionConverter.class, StrutsConstants.STRUTS_CONVERTER_COLLECTION, builder, props);
-        alias(ArrayConverter.class, StrutsConstants.STRUTS_CONVERTER_ARRAY, builder, props);
-        alias(DateConverter.class, StrutsConstants.STRUTS_CONVERTER_DATE, builder, props);
-        alias(NumberConverter.class, StrutsConstants.STRUTS_CONVERTER_NUMBER, builder, props);
-        alias(StringConverter.class, StrutsConstants.STRUTS_CONVERTER_STRING, builder, props);
-
         if ("true".equalsIgnoreCase(props.getProperty(StrutsConstants.STRUTS_DEVMODE))) {
             props.setProperty(StrutsConstants.STRUTS_I18N_RELOAD, "true");
             props.setProperty(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true");

Modified: struts/struts2/trunk/core/src/main/resources/struts-default.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/struts-default.xml?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/struts-default.xml (original)
+++ struts/struts2/trunk/core/src/main/resources/struts-default.xml Tue Jan 22 21:20:35 2013
@@ -65,6 +65,12 @@
     <bean type="org.apache.struts2.components.template.TemplateEngine" name="jsp" class="org.apache.struts2.components.template.JspTemplateEngine" />
 
     <bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" />
+    <bean type="com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor" />
+    <bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" />
+    <bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" />
+    <bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" />
+    <bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" />
+
     <bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" />
 
     <bean type="com.opensymphony.xwork2.conversion.impl.CollectionConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.CollectionConverter" scope="singleton"/>

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java Tue Jan 22 21:20:35 2013
@@ -37,12 +37,22 @@ import com.opensymphony.xwork2.config.en
 import com.opensymphony.xwork2.config.entities.ResultTypeConfig;
 import com.opensymphony.xwork2.config.entities.UnknownHandlerConfig;
 import com.opensymphony.xwork2.config.providers.InterceptorBuilder;
+import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.ConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.ObjectTypeDeterminer;
 import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
 import com.opensymphony.xwork2.conversion.impl.ArrayConverter;
 import com.opensymphony.xwork2.conversion.impl.CollectionConverter;
 import com.opensymphony.xwork2.conversion.impl.DateConverter;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer;
+import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator;
+import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder;
 import com.opensymphony.xwork2.conversion.impl.NumberConverter;
 import com.opensymphony.xwork2.conversion.impl.StringConverter;
 import com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter;
@@ -289,7 +299,14 @@ public class DefaultConfiguration implem
         }
         builder.factory(ReflectionProvider.class, OgnlReflectionProvider.class, Scope.SINGLETON);
         builder.factory(ValueStackFactory.class, OgnlValueStackFactory.class, Scope.SINGLETON);
+
         builder.factory(XWorkConverter.class, Scope.SINGLETON);
+        builder.factory(ConversionPropertiesProcessor.class, DefaultConversionPropertiesProcessor.class, Scope.SINGLETON);
+        builder.factory(ConversionFileProcessor.class, DefaultConversionFileProcessor.class, Scope.SINGLETON);
+        builder.factory(ConversionAnnotationProcessor.class, DefaultConversionAnnotationProcessor.class, Scope.SINGLETON);
+        builder.factory(TypeConverterCreator.class, DefaultTypeConverterCreator.class, Scope.SINGLETON);
+        builder.factory(TypeConverterHolder.class, DefaultTypeConverterHolder.class, Scope.SINGLETON);
+
         builder.factory(XWorkBasicConverter.class, Scope.SINGLETON);
         builder.factory(TypeConverter.class, XWorkConstants.COLLECTION_CONVERTER,  CollectionConverter.class, Scope.SINGLETON);
         builder.factory(TypeConverter.class, XWorkConstants.ARRAY_CONVERTER, ArrayConverter.class, Scope.SINGLETON);

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java Tue Jan 22 21:20:35 2013
@@ -15,12 +15,22 @@ import com.opensymphony.xwork2.XWorkCons
 import com.opensymphony.xwork2.config.Configuration;
 import com.opensymphony.xwork2.config.ConfigurationException;
 import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.ConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.NullHandler;
 import com.opensymphony.xwork2.conversion.ObjectTypeDeterminer;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
 import com.opensymphony.xwork2.conversion.impl.ArrayConverter;
 import com.opensymphony.xwork2.conversion.impl.CollectionConverter;
 import com.opensymphony.xwork2.conversion.impl.DateConverter;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer;
+import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator;
+import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder;
 import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler;
 import com.opensymphony.xwork2.conversion.impl.NumberConverter;
 import com.opensymphony.xwork2.conversion.impl.StringConverter;
@@ -92,7 +102,15 @@ public class XWorkConfigurationProvider 
         builder.factory(com.opensymphony.xwork2.ObjectFactory.class)
                 .factory(ActionProxyFactory.class, DefaultActionProxyFactory.class, Scope.SINGLETON)
                 .factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON)
+
                 .factory(XWorkConverter.class, Scope.SINGLETON)
+                .factory(XWorkBasicConverter.class, Scope.SINGLETON)
+                .factory(ConversionPropertiesProcessor.class, DefaultConversionPropertiesProcessor.class, Scope.SINGLETON)
+                .factory(ConversionFileProcessor.class, DefaultConversionFileProcessor.class, Scope.SINGLETON)
+                .factory(ConversionAnnotationProcessor.class, DefaultConversionAnnotationProcessor.class, Scope.SINGLETON)
+                .factory(TypeConverterCreator.class, DefaultTypeConverterCreator.class, Scope.SINGLETON)
+                .factory(TypeConverterHolder.class, DefaultTypeConverterHolder.class, Scope.SINGLETON)
+
                 .factory(FileManager.class, "system", DefaultFileManager.class, Scope.SINGLETON)
                 .factory(FileManagerFactory.class, DefaultFileManagerFactory.class, Scope.SINGLETON)
                 .factory(ValueStackFactory.class, OgnlValueStackFactory.class, Scope.SINGLETON)
@@ -107,18 +125,18 @@ public class XWorkConfigurationProvider 
                 .factory(PropertyAccessor.class, Enumeration.class.getName(), XWorkEnumerationAccessor.class, Scope.SINGLETON)
                 .factory(UnknownHandlerManager.class, DefaultUnknownHandlerManager.class, Scope.SINGLETON)
 
-                        // silly workarounds for ognl since there is no way to flush its caches
+                // silly workarounds for ognl since there is no way to flush its caches
                 .factory(PropertyAccessor.class, List.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, ArrayList.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, HashSet.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, Set.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, HashMap.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, Map.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
-
                 .factory(PropertyAccessor.class, Collection.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
                 .factory(PropertyAccessor.class, ObjectProxy.class.getName(), ObjectProxyPropertyAccessor.class, Scope.SINGLETON)
                 .factory(MethodAccessor.class, Object.class.getName(), XWorkMethodAccessor.class, Scope.SINGLETON)
                 .factory(MethodAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON)
+
                 .factory(NullHandler.class, Object.class.getName(), InstantiatingNullHandler.class, Scope.SINGLETON)
                 .factory(ActionValidatorManager.class, AnnotationActionValidatorManager.class, Scope.SINGLETON)
                 .factory(ActionValidatorManager.class, "no-annotations", DefaultActionValidatorManager.class, Scope.SINGLETON)
@@ -126,7 +144,6 @@ public class XWorkConfigurationProvider 
                 .factory(TextProvider.class, TextProviderSupport.class, Scope.SINGLETON)
                 .factory(LocaleProvider.class, DefaultLocaleProvider.class, Scope.SINGLETON)
                 .factory(OgnlUtil.class, Scope.SINGLETON)
-                .factory(XWorkBasicConverter.class, Scope.SINGLETON)
                 .factory(CollectionConverter.class, Scope.SINGLETON)
                 .factory(ArrayConverter.class, Scope.SINGLETON)
                 .factory(DateConverter.class, Scope.SINGLETON)

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionAnnotationProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionAnnotationProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionAnnotationProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,23 @@
+package com.opensymphony.xwork2.conversion;
+
+import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
+
+import java.util.Map;
+
+/**
+ * Used to process {@link com.opensymphony.xwork2.conversion.annotations.TypeConversion}
+ * annotation to read defined Converters
+ */
+public interface ConversionAnnotationProcessor {
+
+    /**
+     * Process annotation and build {@link TypeConverter} base on provided annotation
+     * and assigning it under given key
+     *
+     * @param mapping keeps converters per given key
+     * @param tc annotation which keeps information about converter
+     * @param key key under which converter should be registered
+     */
+    void process(Map<String, Object> mapping, TypeConversion tc, String key);
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionFileProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionFileProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionFileProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionFileProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,19 @@
+package com.opensymphony.xwork2.conversion;
+
+import java.util.Map;
+
+/**
+ * Used to process <clazz>-conversion.properties file to read defined Converters
+ */
+public interface ConversionFileProcessor {
+
+    /**
+     * Process conversion file to create mapping for key (property, type) and corresponding converter
+     *
+     * @param mapping keeps converters per given key
+     * @param clazz class which should be converted by the converter
+     * @param converterFilename to read converters from
+     */
+    void process(Map<String, Object> mapping, Class clazz, String converterFilename);
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionPropertiesProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionPropertiesProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionPropertiesProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/ConversionPropertiesProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,22 @@
+package com.opensymphony.xwork2.conversion;
+
+/**
+ * Used to read converters from Properties file
+ */
+public interface ConversionPropertiesProcessor {
+
+    /**
+     * Process given property to load converters as not required (Properties file doesn't have to exist)
+     *
+     * @param propsName Properties file name
+     */
+    void process(String propsName);
+
+    /**
+     * Process given property to load converters as required (Properties file must exist)
+     *
+     * @param propsName Properties file name
+     */
+    void processRequired(String propsName);
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterCreator.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterCreator.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterCreator.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterCreator.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,17 @@
+package com.opensymphony.xwork2.conversion;
+
+/**
+ * Instantiate converter classes, if cannot create TypeConverter throws exception
+ */
+public interface TypeConverterCreator {
+
+    /**
+     * Creates {@link TypeConverter} from given class
+     *
+     * @param className convert class
+     * @return instance of {@link TypeConverter}
+     * @throws Exception when cannot create/cast to {@link TypeConverter}
+     */
+    TypeConverter createTypeConverter(String className) throws Exception;
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterHolder.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterHolder.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterHolder.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverterHolder.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,82 @@
+package com.opensymphony.xwork2.conversion;
+
+import java.util.Map;
+
+/**
+ * Holds all mappings related to {@link TypeConverter}s
+ */
+public interface TypeConverterHolder {
+
+    /**
+     * Adds mapping for default type converters - application scoped
+     *
+     * @param className     name of the class with associated converter
+     * @param typeConverter {@link TypeConverter} instance for associated class
+     */
+    void addDefaultMapping(String className, TypeConverter typeConverter);
+
+    /**
+     * Checks if converter was already defined for given class
+     *
+     * @param className name of the class to check for
+     * @return true if default mapping was already specified
+     */
+    boolean containsDefaultMapping(String className);
+
+    /**
+     * Returns instance of {@link TypeConverter} associated with given class
+     *
+     * @param className name of the class to return converter for
+     * @return instance of {@link TypeConverter} to be used to convert class
+     */
+    TypeConverter getDefaultMapping(String className);
+
+    /**
+     * Target class conversion Mappings.
+     *
+     * @param clazz class to convert to/from
+     * @return {@link TypeConverter} for given class
+     */
+    Map<String, Object> getMapping(Class clazz);
+
+    /**
+     * Assign mapping of converters for given class
+     *
+     * @param clazz   class to convert to/from
+     * @param mapping property converters
+     */
+    void addMapping(Class clazz, Map<String, Object> mapping);
+
+    /**
+     * Check if there is no mapping for given class to convert
+     *
+     * @param clazz class to convert to/from
+     * @return true if mapping couldn't be found
+     */
+    boolean containsNoMapping(Class clazz);
+
+    /**
+     * Adds no mapping flag for give class
+     *
+     * @param clazz class to register missing converter
+     */
+    void addNoMapping(Class clazz);
+
+    /**
+     * Checks if no mapping was defined for given class name
+     * FIXME lukaszlenart: maybe it should be merged with NoMapping
+     *
+     * @param className name of the class to check for
+     * @return true if converter was defined for given class name
+     */
+    boolean containsUnknownMapping(String className);
+
+    /**
+     * Adds no converter flag for given class name
+     * FIXME lukaszlenart: maybe it should be merged with NoMapping
+     *
+     * @param className name of the class to mark there is no converter for it
+     */
+    void addUnknownMapping(String className);
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionAnnotationProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionAnnotationProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionAnnotationProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,84 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
+import com.opensymphony.xwork2.conversion.annotations.ConversionRule;
+import com.opensymphony.xwork2.conversion.annotations.ConversionType;
+import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * Default implementation of {@link ConversionAnnotationProcessor}
+ */
+public class DefaultConversionAnnotationProcessor implements ConversionAnnotationProcessor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultConversionAnnotationProcessor.class);
+
+    private TypeConverterCreator converterCreator;
+    private TypeConverterHolder converterHolder;
+
+    @Inject
+    public void setTypeConverterCreator(TypeConverterCreator converterCreator) {
+        this.converterCreator = converterCreator;
+    }
+
+    @Inject
+    public void setTypeConverterHolder(TypeConverterHolder converterHolder) {
+        this.converterHolder = converterHolder;
+    }
+
+    public void process(Map<String, Object> mapping, TypeConversion tc, String key) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("TypeConversion [#0] with key: [#1]", tc.converter(), key);
+        }
+        if (key == null) {
+            return;
+        }
+        try {
+            if (tc.type() == ConversionType.APPLICATION) {
+                converterHolder.addDefaultMapping(key, converterCreator.createTypeConverter(tc.converter()));
+            } else {
+                if (tc.rule() == ConversionRule.KEY_PROPERTY || tc.rule() == ConversionRule.CREATE_IF_NULL) {
+                    mapping.put(key, tc.value());
+                }
+                //for properties of classes
+                else if (tc.rule() != ConversionRule.ELEMENT || tc.rule() == ConversionRule.KEY || tc.rule() == ConversionRule.COLLECTION) {
+                    mapping.put(key, converterCreator.createTypeConverter(tc.converter()));
+                }
+                //for keys of Maps
+                else if (tc.rule() == ConversionRule.KEY) {
+                    Class converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter());
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Converter class: [#0]", converterClass);
+                    }
+                    //check if the converter is a type converter if it is one
+                    //then just put it in the map as is. Otherwise
+                    //put a value in for the type converter of the class
+                    if (converterClass.isAssignableFrom(TypeConverter.class)) {
+                        mapping.put(key, converterCreator.createTypeConverter(tc.converter()));
+                    } else {
+                        mapping.put(key, converterClass);
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Object placed in mapping for key [#0] is [#1]", key, mapping.get(key));
+                        }
+                    }
+                }
+                //elements(values) of maps / lists
+                else {
+                    mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter()));
+                }
+            }
+        } catch (Exception e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Got exception for #0", e, key);
+            }
+        }
+    }
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionFileProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionFileProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionFileProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionFileProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,112 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.FileManager;
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.conversion.ConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Default implementation of {@link ConversionFileProcessor}
+ */
+public class DefaultConversionFileProcessor implements ConversionFileProcessor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultConversionFileProcessor.class);
+
+    private FileManager fileManager;
+    private TypeConverterCreator converterCreator;
+
+    @Inject
+    public void setFileManagerFactory(FileManagerFactory factory) {
+        fileManager = factory.getFileManager();
+    }
+
+    @Inject
+    public void setTypeConverterCreator(TypeConverterCreator converterCreator) {
+        this.converterCreator = converterCreator;
+    }
+
+    public void process(Map<String, Object> mapping, Class clazz, String converterFilename) {
+        try {
+            InputStream is = fileManager.loadFile(ClassLoaderUtil.getResource(converterFilename, clazz));
+
+            if (is != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Processing conversion file [#0] for class [#1]", converterFilename, clazz);
+                }
+
+                Properties prop = new Properties();
+                prop.load(is);
+
+                for (Map.Entry<Object, Object> entry : prop.entrySet()) {
+                    String key = (String) entry.getKey();
+
+                    if (mapping.containsKey(key)) {
+                        break;
+                    }
+                    // for keyProperty of Set
+                    if (key.startsWith(DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX)
+                            || key.startsWith(DefaultObjectTypeDeterminer.CREATE_IF_NULL_PREFIX)) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as String]");
+                        }
+                        mapping.put(key, entry.getValue());
+                    }
+                    //for properties of classes
+                    else if (!(key.startsWith(DefaultObjectTypeDeterminer.ELEMENT_PREFIX) ||
+                            key.startsWith(DefaultObjectTypeDeterminer.KEY_PREFIX) ||
+                            key.startsWith(DefaultObjectTypeDeterminer.DEPRECATED_ELEMENT_PREFIX))
+                            ) {
+                        TypeConverter _typeConverter = converterCreator.createTypeConverter((String) entry.getValue());
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as TypeConverter " + _typeConverter + "]");
+                        }
+                        mapping.put(key, _typeConverter);
+                    }
+                    //for keys of Maps
+                    else if (key.startsWith(DefaultObjectTypeDeterminer.KEY_PREFIX)) {
+
+                        Class converterClass = Thread.currentThread().getContextClassLoader().loadClass((String) entry.getValue());
+
+                        //check if the converter is a type converter if it is one
+                        //then just put it in the map as is. Otherwise
+                        //put a value in for the type converter of the class
+                        if (converterClass.isAssignableFrom(TypeConverter.class)) {
+                            TypeConverter _typeConverter = converterCreator.createTypeConverter((String) entry.getValue());
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as TypeConverter " + _typeConverter + "]");
+                            }
+                            mapping.put(key, _typeConverter);
+                        } else {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as Class " + converterClass + "]");
+                            }
+                            mapping.put(key, converterClass);
+                        }
+                    }
+                    //elements(values) of maps / lists
+                    else {
+                        Class _c = Thread.currentThread().getContextClassLoader().loadClass((String) entry.getValue());
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as Class " + _c + "]");
+                        }
+                        mapping.put(key, _c);
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            if (LOG.isErrorEnabled()) {
+                LOG.error("Problem loading properties for #0", ex, clazz.getName());
+            }
+        }
+    }
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionPropertiesProcessor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionPropertiesProcessor.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionPropertiesProcessor.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultConversionPropertiesProcessor.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,85 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor;
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * TODO lukaszlenart: add a comment
+ */
+public class DefaultConversionPropertiesProcessor implements ConversionPropertiesProcessor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultConversionPropertiesProcessor.class);
+
+    private TypeConverterCreator converterCreator;
+    private TypeConverterHolder converterHolder;
+
+    @Inject
+    public void setTypeConverterCreator(TypeConverterCreator converterCreator) {
+        this.converterCreator = converterCreator;
+    }
+
+    @Inject
+    public void setTypeConverterHolder(TypeConverterHolder converterHolder) {
+        this.converterHolder = converterHolder;
+    }
+
+    public void process(String propsName) {
+        loadConversionProperties(propsName, false);
+    }
+
+    public void processRequired(String propsName) {
+        loadConversionProperties(propsName, true);
+    }
+
+    public void loadConversionProperties(String propsName, boolean require) {
+        try {
+            Iterator<URL> resources = ClassLoaderUtil.getResources(propsName, getClass(), true);
+            while (resources.hasNext()) {
+                URL url = resources.next();
+                Properties props = new Properties();
+                props.load(url.openStream());
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("processing conversion file [" + propsName + "]");
+                }
+
+                for (Object o : props.entrySet()) {
+                    Map.Entry entry = (Map.Entry) o;
+                    String key = (String) entry.getKey();
+
+                    try {
+                        TypeConverter _typeConverter = converterCreator.createTypeConverter((String) entry.getValue());
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("\t" + key + ":" + entry.getValue() + " [treated as TypeConverter " + _typeConverter + "]");
+                        }
+                        converterHolder.addDefaultMapping(key, _typeConverter);
+                    } catch (Exception e) {
+                        LOG.error("Conversion registration error", e);
+                    }
+                }
+            }
+        } catch (IOException ex) {
+            if (require) {
+                throw new XWorkException("Cannot load conversion properties file: "+propsName, ex);
+            } else {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Cannot load conversion properties file: #0", ex, propsName);
+                }
+            }
+        }
+    }
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterCreator.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterCreator.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterCreator.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterCreator.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,35 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterCreator;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.ognl.XWorkTypeConverterWrapper;
+
+/**
+ * Default implementation of {@link TypeConverterCreator}
+ */
+public class DefaultTypeConverterCreator implements TypeConverterCreator {
+
+    private ObjectFactory objectFactory;
+
+    @Inject
+    public void setObjectFactory(ObjectFactory objectFactory) {
+        this.objectFactory = objectFactory;
+    }
+
+    public TypeConverter createTypeConverter(String className) throws Exception {
+        // type converters are used across users
+        Object obj = objectFactory.buildBean(className, null);
+        if (obj instanceof TypeConverter) {
+            return (TypeConverter) obj;
+
+            // For backwards compatibility
+        } else if (obj instanceof ognl.TypeConverter) {
+            return new XWorkTypeConverterWrapper((ognl.TypeConverter) obj);
+        } else {
+            throw new IllegalArgumentException("Type converter class " + obj.getClass() + " doesn't implement com.opensymphony.xwork2.conversion.TypeConverter");
+        }
+    }
+
+}

Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterHolder.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterHolder.java?rev=1437180&view=auto
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterHolder.java (added)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverterHolder.java Tue Jan 22 21:20:35 2013
@@ -0,0 +1,97 @@
+package com.opensymphony.xwork2.conversion.impl;
+
+import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Default implementation of {@link TypeConverterHolder}
+ */
+public class DefaultTypeConverterHolder implements TypeConverterHolder {
+
+    /**
+     * Record class and its type converter mapping.
+     * <pre>
+     * - String - classname as String
+     * - TypeConverter - instance of TypeConverter
+     * </pre>
+     */
+    private HashMap<String, TypeConverter> defaultMappings = new HashMap<String, TypeConverter>();  // non-action (eg. returned value)
+
+    /**
+     * Target class conversion Mappings.
+     * <pre>
+     * Map<Class, Map<String, Object>>
+     *  - Class -> convert to class
+     *  - Map<String, Object>
+     *    - String -> property name
+     *                eg. Element_property, property etc.
+     *    - Object -> String to represent properties
+     *                eg. value part of
+     *                    KeyProperty_property=id
+     *             -> TypeConverter to represent an Ognl TypeConverter
+     *                eg. value part of
+     *                    property=foo.bar.MyConverter
+     *             -> Class to represent a class
+     *                eg. value part of
+     *                    Element_property=foo.bar.MyObject
+     * </pre>
+     */
+    private HashMap<Class, Map<String, Object>> mappings = new HashMap<Class, Map<String, Object>>(); // action
+
+    /**
+     * Unavailable target class conversion mappings, serves as a simple cache.
+     */
+    private HashSet<Class> noMapping = new HashSet<Class>(); // action
+
+    /**
+     * Record classes that doesn't have conversion mapping defined.
+     * <pre>
+     * - String -> classname as String
+     * </pre>
+     */
+    protected HashSet<String> unknownMappings = new HashSet<String>();     // non-action (eg. returned value)
+
+    public void addDefaultMapping(String className, TypeConverter typeConverter) {
+        defaultMappings.put(className, typeConverter);
+        if (unknownMappings.contains(className)) {
+            unknownMappings.remove(className);
+        }
+    }
+
+    public boolean containsDefaultMapping(String className) {
+        return defaultMappings.containsKey(className);
+    }
+
+    public TypeConverter getDefaultMapping(String className) {
+        return defaultMappings.get(className);
+    }
+
+    public Map<String, Object> getMapping(Class clazz) {
+        return mappings.get(clazz);
+    }
+
+    public void addMapping(Class clazz, Map<String, Object> mapping) {
+        mappings.put(clazz, mapping);
+    }
+
+    public boolean containsNoMapping(Class clazz) {
+        return noMapping.contains(clazz);
+    }
+
+    public void addNoMapping(Class clazz) {
+        noMapping.add(clazz);
+    }
+
+    public boolean containsUnknownMapping(String className) {
+        return unknownMappings.contains(className);
+    }
+
+    public void addUnknownMapping(String className) {
+        unknownMappings.add(className);
+    }
+
+}

Modified: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java?rev=1437180&r1=1437179&r2=1437180&view=diff
==============================================================================
--- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java (original)
+++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConverter.java Tue Jan 22 21:20:35 2013
@@ -18,17 +18,16 @@ package com.opensymphony.xwork2.conversi
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.FileManager;
 import com.opensymphony.xwork2.FileManagerFactory;
-import com.opensymphony.xwork2.ObjectFactory;
 import com.opensymphony.xwork2.XWorkConstants;
-import com.opensymphony.xwork2.XWorkException;
 import com.opensymphony.xwork2.XWorkMessages;
+import com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor;
+import com.opensymphony.xwork2.conversion.ConversionFileProcessor;
+import com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor;
 import com.opensymphony.xwork2.conversion.TypeConverter;
+import com.opensymphony.xwork2.conversion.TypeConverterHolder;
 import com.opensymphony.xwork2.conversion.annotations.Conversion;
-import com.opensymphony.xwork2.conversion.annotations.ConversionRule;
-import com.opensymphony.xwork2.conversion.annotations.ConversionType;
 import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
 import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.ognl.XWorkTypeConverterWrapper;
 import com.opensymphony.xwork2.util.AnnotationUtils;
 import com.opensymphony.xwork2.util.ClassLoaderUtil;
 import com.opensymphony.xwork2.util.CompoundRoot;
@@ -39,8 +38,6 @@ import com.opensymphony.xwork2.util.logg
 import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
 import org.apache.commons.lang3.StringUtils;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -48,11 +45,8 @@ import java.net.URL;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -137,7 +131,8 @@ import java.util.regex.Pattern;
  */
 public class XWorkConverter extends DefaultTypeConverter {
 
-    protected static final Logger LOG = LoggerFactory.getLogger(XWorkConverter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(XWorkConverter.class);
+
     public static final String REPORT_CONVERSION_ERRORS = "report.conversion.errors";
     public static final String CONVERSION_PROPERTY_FULLNAME = "conversion.property.fullName";
     public static final String CONVERSION_ERROR_PROPERTY_PREFIX = "invalid.fieldvalue.";
@@ -148,66 +143,18 @@ public class XWorkConverter extends Defa
     public static final String MESSAGE_INDEX_PATTERN = "\\[\\d+\\]\\.";
     public static final String MESSAGE_INDEX_BRACKET_PATTERN = "[\\[\\]\\.]";
     public static final String PERIOD = ".";
-    public static final Pattern messageIndexPattern = Pattern.compile(MESSAGE_INDEX_PATTERN); 
-
-    /**
-     * Target class conversion Mappings.
-     * <pre>
-     * Map<Class, Map<String, Object>>
-     *  - Class -> convert to class
-     *  - Map<String, Object>
-     *    - String -> property name
-     *                eg. Element_property, property etc.
-     *    - Object -> String to represent properties
-     *                eg. value part of
-     *                    KeyProperty_property=id
-     *             -> TypeConverter to represent an Ognl TypeConverter
-     *                eg. value part of
-     *                    property=foo.bar.MyConverter
-     *             -> Class to represent a class
-     *                eg. value part of
-     *                    Element_property=foo.bar.MyObject
-     * </pre>
-     */
-    protected HashMap<Class, Map<String, Object>> mappings = new HashMap<Class, Map<String, Object>>(); // action
-
-    /**
-     * Unavailable target class conversion mappings, serves as a simple cache.
-     */
-    protected HashSet<Class> noMapping = new HashSet<Class>(); // action
-
-    /**
-     * Record class and its type converter mapping.
-     * <pre>
-     * - String - classname as String
-     * - TypeConverter - instance of TypeConverter
-     * </pre>
-     */
-    protected HashMap<String, TypeConverter> defaultMappings = new HashMap<String, TypeConverter>();  // non-action (eg. returned value)
-
-    /**
-     * Record classes that doesn't have conversion mapping defined.
-     * <pre>
-     * - String -> classname as String
-     * </pre>
-     */
-    protected HashSet<String> unknownMappings = new HashSet<String>();     // non-action (eg. returned value)
+    public static final Pattern messageIndexPattern = Pattern.compile(MESSAGE_INDEX_PATTERN);
 
     private TypeConverter defaultTypeConverter;
-    private ObjectFactory objectFactory;
     private FileManager fileManager;
     private boolean reloadingConfigs;
 
-    protected XWorkConverter() {
-    }
+    private ConversionFileProcessor fileProcessor;
+    private ConversionAnnotationProcessor annotationProcessor;
 
-    @Inject
-    public void setObjectFactory(ObjectFactory factory) {
-        this.objectFactory = factory;
-        // note: this file is deprecated
-        loadConversionProperties("xwork-default-conversion.properties");
+    private TypeConverterHolder converterHolder;
 
-        loadConversionProperties("xwork-conversion.properties");
+    protected XWorkConverter() {
     }
 
     @Inject
@@ -225,6 +172,28 @@ public class XWorkConverter extends Defa
         this.reloadingConfigs = Boolean.parseBoolean(reloadingConfigs);
     }
 
+    @Inject
+    public void setConversionPropertiesProcessor(ConversionPropertiesProcessor propertiesProcessor) {
+        // note: this file is deprecated
+        propertiesProcessor.process("xwork-default-conversion.properties");
+        propertiesProcessor.process("xwork-conversion.properties");
+    }
+
+    @Inject
+    public void setConversionFileProcessor(ConversionFileProcessor fileProcessor) {
+        this.fileProcessor = fileProcessor;
+    }
+
+    @Inject
+    public void setConversionAnnotationProcessor(ConversionAnnotationProcessor annotationProcessor) {
+        this.annotationProcessor = annotationProcessor;
+    }
+
+    @Inject
+    public void setTypeConverterHolder(TypeConverterHolder converterHolder) {
+        this.converterHolder = converterHolder;
+    }
+
     public static String getConversionErrorMessage(String propertyName, ValueStack stack) {
         String defaultMessage = LocalizedTextUtil.findDefaultText(XWorkMessages.DEFAULT_INVALID_FIELDVALUE,
                 ActionContext.getContext().getLocale(),
@@ -234,7 +203,7 @@ public class XWorkConverter extends Defa
 
         List<String> indexValues = getIndexValues(propertyName);
 
-        propertyName = removeAllIndexesInProperyName(propertyName);
+        propertyName = removeAllIndexesInProperytName(propertyName);
 
         String getTextExpression = "getText('" + CONVERSION_ERROR_PROPERTY_PREFIX + propertyName + "','" + defaultMessage + "')";
         String message = (String) stack.findValue(getTextExpression);
@@ -248,7 +217,7 @@ public class XWorkConverter extends Defa
         return message;
     }
 
-    private static String removeAllIndexesInProperyName(String propertyName) {
+    private static String removeAllIndexesInProperytName(String propertyName) {
         return propertyName.replaceAll(MESSAGE_INDEX_PATTERN, PERIOD);
     }
 
@@ -386,11 +355,11 @@ public class XWorkConverter extends Defa
      * @return a TypeConverter to handle the specified class or null if none can be found
      */
     public TypeConverter lookup(String className) {
-        if (unknownMappings.contains(className) && !defaultMappings.containsKey(className)) {
+        if (converterHolder.containsUnknownMapping(className) && !converterHolder.containsDefaultMapping(className)) {
             return null;
         }
 
-        TypeConverter result = defaultMappings.get(className);
+        TypeConverter result = converterHolder.getDefaultMapping(className);
 
         //Looks for super classes
         if (result == null) {
@@ -430,13 +399,12 @@ public class XWorkConverter extends Defa
 
     protected Object getConverter(Class clazz, String property) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Property: " + property);
-            LOG.debug("Class: " + clazz.getName());
+            LOG.debug("Retrieving convert for class [#0] and property [#1]", clazz, property);
         }
         synchronized (clazz) {
-            if ((property != null) && !noMapping.contains(clazz)) {
+            if ((property != null) && !converterHolder.containsNoMapping(clazz)) {
                 try {
-                    Map<String, Object> mapping = mappings.get(clazz);
+                    Map<String, Object> mapping = converterHolder.getMapping(clazz);
 
                     if (mapping == null) {
                         mapping = buildConverterMapping(clazz);
@@ -446,7 +414,7 @@ public class XWorkConverter extends Defa
 
                     Object converter = mapping.get(property);
                     if (LOG.isDebugEnabled() && converter == null) {
-                        LOG.debug("converter is null for property " + property + ". Mapping size: " + mapping.size());
+                        LOG.debug("Converter is null for property [#0]. Mapping size [#1]:", property, mapping.size());
                         for (String next : mapping.keySet()) {
                             LOG.debug(next + ":" + mapping.get(next));
                         }
@@ -454,13 +422,12 @@ public class XWorkConverter extends Defa
                     return converter;
                 } catch (Throwable t) {
                     if (LOG.isDebugEnabled()) {
-                        LOG.debug("Got exception trying to resolve convert for class [#0] and property [#1]", t, clazz.getName(), property);
+                        LOG.debug("Got exception trying to resolve convert for class [#0] and property [#1]", t, clazz, property);
                     }
-                    noMapping.add(clazz);
+                    converterHolder.addNoMapping(clazz);
                 }
             }
         }
-
         return null;
     }
 
@@ -485,14 +452,11 @@ public class XWorkConverter extends Defa
     }
 
     public synchronized void registerConverter(String className, TypeConverter converter) {
-        defaultMappings.put(className, converter);
-        if (unknownMappings.contains(className)) {
-            unknownMappings.remove(className);
-        }
+        converterHolder.addDefaultMapping(className, converter);
     }
 
     public synchronized void registerConverterNotFound(String className) {
-        unknownMappings.add(className);
+        converterHolder.addUnknownMapping(className);
     }
 
     private Object[] getClassProperty(Map<String, Object> context) {
@@ -509,79 +473,9 @@ public class XWorkConverter extends Defa
      * @param clazz   class to look for converter mappings for
      */
     protected void addConverterMapping(Map<String, Object> mapping, Class clazz) {
-        try {
-            String converterFilename = buildConverterFilename(clazz);
-            InputStream is = fileManager.loadFile(ClassLoaderUtil.getResource(converterFilename, clazz));
-
-            if (is != null) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("processing conversion file [" + converterFilename + "] [class=" + clazz + "]");
-                }
-
-                Properties prop = new Properties();
-                prop.load(is);
-
-                for (Map.Entry<Object, Object> entry : prop.entrySet()) {
-                    String key = (String) entry.getKey();
-
-                    if (mapping.containsKey(key)) {
-                        break;
-                    }
-                    // for keyProperty of Set
-                    if (key.startsWith(DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX)
-                            || key.startsWith(DefaultObjectTypeDeterminer.CREATE_IF_NULL_PREFIX)) {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as String]");
-                        }
-                        mapping.put(key, entry.getValue());
-                    }
-                    //for properties of classes
-                    else if (!(key.startsWith(DefaultObjectTypeDeterminer.ELEMENT_PREFIX) ||
-                            key.startsWith(DefaultObjectTypeDeterminer.KEY_PREFIX) ||
-                            key.startsWith(DefaultObjectTypeDeterminer.DEPRECATED_ELEMENT_PREFIX))
-                            ) {
-                        TypeConverter _typeConverter = createTypeConverter((String) entry.getValue());
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as TypeConverter " + _typeConverter + "]");
-                        }
-                        mapping.put(key, _typeConverter);
-                    }
-                    //for keys of Maps
-                    else if (key.startsWith(DefaultObjectTypeDeterminer.KEY_PREFIX)) {
-
-                        Class converterClass = Thread.currentThread().getContextClassLoader().loadClass((String) entry.getValue());
-
-                        //check if the converter is a type converter if it is one
-                        //then just put it in the map as is. Otherwise
-                        //put a value in for the type converter of the class
-                        if (converterClass.isAssignableFrom(TypeConverter.class)) {
-                            TypeConverter _typeConverter = createTypeConverter((String) entry.getValue());
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as TypeConverter " + _typeConverter + "]");
-                            }
-                            mapping.put(key, _typeConverter);
-                        } else {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as Class " + converterClass + "]");
-                            }
-                            mapping.put(key, converterClass);
-                        }
-                    }
-                    //elements(values) of maps / lists
-                    else {
-                        Class _c = Thread.currentThread().getContextClassLoader().loadClass((String) entry.getValue());
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("\t" + key + ":" + entry.getValue() + "[treated as Class " + _c + "]");
-                        }
-                        mapping.put(key, _c);
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            if (LOG.isErrorEnabled()) {
-                LOG.error("Problem loading properties for #0", ex, clazz.getName());
-            }
-        }
+        // Process <clazz>-conversion.properties file
+        String converterFilename = buildConverterFilename(clazz);
+        fileProcessor.process(mapping, clazz, converterFilename);
 
         // Process annotations
         Annotation[] annotations = clazz.getAnnotations();
@@ -589,156 +483,46 @@ public class XWorkConverter extends Defa
         for (Annotation annotation : annotations) {
             if (annotation instanceof Conversion) {
                 Conversion conversion = (Conversion) annotation;
-
                 for (TypeConversion tc : conversion.conversions()) {
-
-                    String key = tc.key();
-
-                    if (mapping.containsKey(key)) {
+                    if (mapping.containsKey(tc.key())) {
                         break;
                     }
                     if (LOG.isDebugEnabled()) {
-                        if (StringUtils.isEmpty(key)) {
+                        if (StringUtils.isEmpty(tc.key())) {
                             LOG.debug("WARNING! key of @TypeConversion [#0] applied to [#1] is empty!", tc.converter(), clazz.getName());
                         } else {
-                            LOG.debug("TypeConversion [#0] with key: [#1]", tc.converter(), key);
-                        }
-                    }
-
-                    if (key != null) {
-                        try {
-                            if (tc.type() == ConversionType.APPLICATION) {
-                                defaultMappings.put(key, createTypeConverter(tc.converter()));
-                            } else {
-                                if (tc.rule().toString().equals(ConversionRule.KEY_PROPERTY) || tc.rule().toString().equals(ConversionRule.CREATE_IF_NULL)) {
-                                    mapping.put(key, tc.value());
-                                }
-                                //for properties of classes
-                                else if (!(tc.rule().toString().equals(ConversionRule.ELEMENT.toString())) ||
-                                        tc.rule().toString().equals(ConversionRule.KEY.toString()) ||
-                                        tc.rule().toString().equals(ConversionRule.COLLECTION.toString())
-                                        ) {
-                                    mapping.put(key, createTypeConverter(tc.converter()));
-
-
-                                }
-                                //for keys of Maps
-                                else if (tc.rule().toString().equals(ConversionRule.KEY.toString())) {
-                                    Class converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter());
-                                    if (LOG.isDebugEnabled()) {
-                                        LOG.debug("Converter class: " + converterClass);
-                                    }
-                                    //check if the converter is a type converter if it is one
-                                    //then just put it in the map as is. Otherwise
-                                    //put a value in for the type converter of the class
-                                    if (converterClass.isAssignableFrom(TypeConverter.class)) {
-                                        mapping.put(key, createTypeConverter(tc.converter()));
-                                    } else {
-                                        mapping.put(key, converterClass);
-                                        if (LOG.isDebugEnabled()) {
-                                            LOG.debug("Object placed in mapping for key "
-                                                    + key
-                                                    + " is "
-                                                    + mapping.get(key));
-                                        }
-
-                                    }
-
-                                }
-                                //elements(values) of maps / lists
-                                else {
-                                    mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter()));
-                                }
-                            }
-                        } catch (Exception e) {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("Got exception for #0", e, key);
-                            }
+                            LOG.debug("TypeConversion [#0] with key: [#1]", tc.converter(), tc.key());
                         }
                     }
+                    annotationProcessor.process(mapping, tc, tc.key());
                 }
             }
         }
 
-        Method[] methods = clazz.getMethods();
-
-        for (Method method : methods) {
-
+        // Process annotated methods
+        for (Method method : clazz.getMethods()) {
             annotations = method.getAnnotations();
-
             for (Annotation annotation : annotations) {
                 if (annotation instanceof TypeConversion) {
                     TypeConversion tc = (TypeConversion) annotation;
-
-                    String key = tc.key();
-                    if (mapping.containsKey(key)) {
+                    if (mapping.containsKey(tc.key())) {
                         break;
                     }
+                    String key = tc.key();
                     // Default to the property name
-                    if (key != null && key.length() == 0) {
+                    if (StringUtils.isEmpty(key)) {
                         key = AnnotationUtils.resolvePropertyName(method);
-                        LOG.debug("key from method name... " + key + " - " + method.getName());
-                    }
-
-
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug(key + ":" + key);
-                    }
-
-                    if (key != null) {
-                        try {
-                            if (tc.type() == ConversionType.APPLICATION) {
-                                defaultMappings.put(key, createTypeConverter(tc.converter()));
-                            } else {
-                                if (tc.rule().toString().equals(ConversionRule.KEY_PROPERTY)) {
-                                    mapping.put(key, tc.value());
-                                }
-                                //for properties of classes
-                                else if (!(tc.rule().toString().equals(ConversionRule.ELEMENT.toString())) ||
-                                        tc.rule().toString().equals(ConversionRule.KEY.toString()) ||
-                                        tc.rule().toString().equals(ConversionRule.COLLECTION.toString())
-                                        ) {
-                                    mapping.put(key, createTypeConverter(tc.converter()));
-                                }
-                                //for keys of Maps
-                                else if (tc.rule().toString().equals(ConversionRule.KEY.toString())) {
-                                    Class converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter());
-                                    if (LOG.isDebugEnabled()) {
-                                        LOG.debug("Converter class: " + converterClass);
-                                    }
-                                    //check if the converter is a type converter if it is one
-                                    //then just put it in the map as is. Otherwise
-                                    //put a value in for the type converter of the class
-                                    if (converterClass.isAssignableFrom(TypeConverter.class)) {
-                                        mapping.put(key, createTypeConverter(tc.converter()));
-                                    } else {
-                                        mapping.put(key, converterClass);
-                                        if (LOG.isDebugEnabled()) {
-                                            LOG.debug("Object placed in mapping for key "
-                                                    + key
-                                                    + " is "
-                                                    + mapping.get(key));
-                                        }
-
-                                    }
-
-                                }
-                                //elements(values) of maps / lists
-                                else {
-                                    mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter()));
-                                }
-                            }
-                        } catch (Exception e) {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("Got exception for #0", e, key);
-                            }
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Retrieved key [#0] from method name [#1]", key, method.getName());
                         }
                     }
+                    annotationProcessor.process(mapping, tc, key);
                 }
             }
         }
     }
 
+
     /**
      * Looks for converter mappings for the specified class, traversing up its class hierarchy and interfaces and adding
      * any additional mappings it may find.  Mappings lower in the hierarchy have priority over those higher in the
@@ -768,9 +552,9 @@ public class XWorkConverter extends Defa
         }
 
         if (mapping.size() > 0) {
-            mappings.put(clazz, mapping);
+            converterHolder.addMapping(clazz, mapping);
         } else {
-            noMapping.add(clazz);
+            converterHolder.addNoMapping(clazz);
         }
 
         return mapping;
@@ -789,62 +573,6 @@ public class XWorkConverter extends Defa
         return mapping;
     }
 
-    TypeConverter createTypeConverter(String className) throws Exception {
-        // type converters are used across users
-        Object obj = objectFactory.buildBean(className, null);
-        if (obj instanceof TypeConverter) {
-            return (TypeConverter) obj;
-
-            // For backwards compatibility
-        } else if (obj instanceof ognl.TypeConverter) {
-            return new XWorkTypeConverterWrapper((ognl.TypeConverter) obj);
-        } else {
-            throw new IllegalArgumentException("Type converter class " + obj.getClass() + " doesn't implement com.opensymphony.xwork2.conversion.TypeConverter");
-        }
-    }
-
-    public void loadConversionProperties(String propsName) {
-        loadConversionProperties(propsName, false);
-    }
-
-    public void loadConversionProperties(String propsName, boolean require) {
-        try {
-            Iterator<URL> resources = ClassLoaderUtil.getResources(propsName, getClass(), true);
-            while (resources.hasNext()) {
-                URL url = resources.next();
-                Properties props = new Properties();
-                props.load(url.openStream());
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("processing conversion file [" + propsName + "]");
-                }
-
-                for (Object o : props.entrySet()) {
-                    Map.Entry entry = (Map.Entry) o;
-                    String key = (String) entry.getKey();
-
-                    try {
-                        TypeConverter _typeConverter = createTypeConverter((String) entry.getValue());
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("\t" + key + ":" + entry.getValue() + " [treated as TypeConverter " + _typeConverter + "]");
-                        }
-                        defaultMappings.put(key, _typeConverter);
-                    } catch (Exception e) {
-                        LOG.error("Conversion registration error", e);
-                    }
-                }
-            }
-        } catch (IOException ex) {
-            if (require) {
-                throw new XWorkException("Cannot load conversion properties file: "+propsName, ex);
-            } else {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Cannot load conversion properties file: #0", ex, propsName);
-                }
-            }
-        }
-    }
-
     /**
      * Recurses through a class' interfaces and class hierarchy looking for a TypeConverter in the default mapping that
      * can handle the specified class.
@@ -856,15 +584,15 @@ public class XWorkConverter extends Defa
         TypeConverter result = null;
 
         if (clazz != null) {
-            result = defaultMappings.get(clazz.getName());
+            result = converterHolder.getDefaultMapping(clazz.getName());
 
             if (result == null) {
                 // Looks for direct interfaces (depth = 1 )
                 Class[] interfaces = clazz.getInterfaces();
 
                 for (Class anInterface : interfaces) {
-                    if (defaultMappings.containsKey(anInterface.getName())) {
-                        result = (TypeConverter) defaultMappings.get(anInterface.getName());
+                    if (converterHolder.containsDefaultMapping(anInterface.getName())) {
+                        result = converterHolder.getDefaultMapping(anInterface.getName());
                         break;
                     }
                 }
@@ -880,5 +608,4 @@ public class XWorkConverter extends Defa
         return result;
     }
 
-
 }



Mime
View raw message