1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package nl.openedge.baritus.population;
32
33 import java.lang.reflect.Member;
34 import java.util.Locale;
35 import java.util.Map;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 import nl.openedge.baritus.ConverterRegistry;
41 import nl.openedge.baritus.ExecutionParams;
42 import nl.openedge.baritus.LogConstants;
43 import nl.openedge.baritus.converters.ConversionException;
44 import nl.openedge.baritus.converters.Converter;
45
46 import ognl.DefaultTypeConverter;
47 import ognl.OgnlOps;
48
49 /***
50 * This class should be registered with the Ognl context before parsing
51 * in order to be abel to use our converters. It implements Ognl TypeConverter
52 * and uses the ConverterRegistry to lookup converters. If no converter is found
53 * for a given type, the default conversion of Ognl is used.
54 *
55 * @author Eelco Hillenius
56 */
57 public class OgnlConverterWrapper extends DefaultTypeConverter
58 {
59
60 private static Log populationLog = LogFactory.getLog(LogConstants.POPULATION_LOG);
61
62 /***
63 * Convert the provided value to provided type using provided context.
64 * @param context Ognl context
65 * @param value the current, unconverted value
66 * @param toType the type that should be converted to
67 * @return Object the converted value
68 * @see ognl.DefaultTypeConverter#convertValue(java.util.Map, java.lang.Object, java.lang.Class)
69 */
70 public Object convertValue(Map context, Object value, Class toType)
71 {
72
73 if(value == null) return null;
74
75 Object converted = null;
76
77 Locale locale = (Locale)context.get(OgnlFieldPopulator.CTX_KEY_CURRENT_LOCALE);
78 ExecutionParams executionParams = (ExecutionParams)
79 context.get(OgnlFieldPopulator.CTX_KEY_CURRENT_EXEC_PARAMS);
80
81 if((!toType.isArray()) && value instanceof String[] && ((String[])value).length == 1)
82 {
83 value = ((String[])value)[0];
84 }
85
86 if( (value instanceof String) && ((String)value).trim().equals("")
87 && executionParams.isSetNullForEmptyString())
88 {
89 if(populationLog.isDebugEnabled())
90 {
91 String name = (String)context.get(
92 OgnlFieldPopulator.CTX_KEY_CURRENT_FIELD_NAME);
93 populationLog.debug("empty input for property " + name + " converted to null");
94 }
95 return null;
96 }
97
98 context.put(OgnlFieldPopulator.CTX_KEY_CURRENT_TRIED_VALUE, value);
99
100 try
101 {
102 ConverterRegistry reg = ConverterRegistry.getInstance();
103 Converter converter = reg.lookup(toType, locale);
104
105 if(converter != null)
106 {
107 context.put(OgnlFieldPopulator.CTX_KEY_CURRENT_CONVERTER, converter);
108
109 if(populationLog.isDebugEnabled())
110 {
111 String name = (String)context.get(
112 OgnlFieldPopulator.CTX_KEY_CURRENT_FIELD_NAME);
113 populationLog.debug("using converter "
114 + converter + " for property " + name +
115 " (type " + toType + ")");
116 }
117
118 if(!toType.isArray())
119
120 {
121 if(value instanceof String[] && ((String[])value).length == 1)
122 {
123 value = ((String[])value)[0];
124 }
125 }
126
127 converted = converter.convert(toType, value);
128 }
129 else
130 {
131 converted = OgnlOps.convertValue(value, toType);
132 }
133 }
134 catch(ConversionException e)
135 {
136 context.put(OgnlFieldPopulator.CTX_KEY_CURRENT_TARGET_TYPE, toType);
137 throw e;
138 }
139 catch(Exception e)
140 {
141 context.put(OgnlFieldPopulator.CTX_KEY_CURRENT_TARGET_TYPE, toType);
142 throw new ConversionException(e);
143 }
144
145 return converted;
146 }
147
148 /***
149 * This method is only here to satisfy the interface. Method convertValue(Map, Object, Class)
150 * is called, so parameters member and propertyName are ignored.
151 * @see ognl.DefaultTypeConverter#convertValue(java.util.Map, java.lang.Object, java.lang.Class)
152 */
153 public Object convertValue(
154 Map context,
155 Object target,
156 Member member,
157 String propertyName,
158 Object value,
159 Class toType)
160 {
161 return convertValue(context, value, toType);
162 }
163
164 }