1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.internal.controller.impl;
17
18 import java.lang.reflect.Array;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.LinkedHashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.seasar.cubby.action.ActionContext;
27 import org.seasar.cubby.action.ActionErrors;
28 import org.seasar.cubby.action.FieldInfo;
29 import org.seasar.cubby.action.RequestParameter;
30 import org.seasar.cubby.converter.ConversionException;
31 import org.seasar.cubby.converter.ConversionHelper;
32 import org.seasar.cubby.converter.Converter;
33 import org.seasar.cubby.converter.impl.ConversionHelperImpl;
34 import org.seasar.cubby.internal.controller.RequestParameterBinder;
35 import org.seasar.cubby.internal.util.StringUtils;
36 import org.seasar.cubby.spi.ConverterProvider;
37 import org.seasar.cubby.spi.ProviderFactory;
38 import org.seasar.cubby.spi.beans.BeanDesc;
39 import org.seasar.cubby.spi.beans.BeanDescFactory;
40 import org.seasar.cubby.spi.beans.ParameterizedClassDesc;
41 import org.seasar.cubby.spi.beans.PropertyDesc;
42 import org.seasar.cubby.validator.MessageInfo;
43
44
45
46
47
48
49
50 public class RequestParameterBinderImpl implements RequestParameterBinder {
51
52
53 private final ConversionHelper conversionHelper = new ConversionHelperImpl();
54
55
56
57
58 public void bind(final Map<String, Object[]> parameterMap,
59 final Object dest, final ActionContext actionContext,
60 final ActionErrors errors) {
61 if (parameterMap == null || parameterMap.isEmpty()) {
62 return;
63 }
64 final ConverterProvider converterProvider = ProviderFactory
65 .get(ConverterProvider.class);
66 final BeanDesc destBeanDesc = BeanDescFactory.getBeanDesc(dest
67 .getClass());
68
69 for (final PropertyDesc destPropertyDesc : destBeanDesc
70 .getPropertyDescs()) {
71 final RequestParameter requestParameter = destPropertyDesc
72 .getAnnotation(RequestParameter.class);
73 if (!actionContext.isBindRequestParameterToAllProperties()
74 && requestParameter == null) {
75 continue;
76 }
77
78 final String parameterName;
79 if (requestParameter != null
80 && !StringUtils.isEmpty(requestParameter.name())) {
81 parameterName = requestParameter.name();
82 } else {
83 parameterName = destPropertyDesc.getPropertyName();
84 }
85
86 if (!parameterMap.containsKey(parameterName)) {
87 continue;
88 }
89 final Object[] parameterValue = parameterMap.get(parameterName);
90
91 final Class<? extends Converter> converterType;
92 if (requestParameter != null) {
93 converterType = requestParameter.converter();
94 } else {
95 converterType = null;
96 }
97
98 final Object value = convert(converterProvider, parameterValue,
99 destPropertyDesc, converterType, parameterName, errors);
100 destPropertyDesc.setValue(dest, value);
101 }
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 private Object convert(final ConverterProvider converterProvider,
120 final Object[] values, final PropertyDesc destPropertyDesc,
121 final Class<? extends Converter> converterType,
122 final String parameterName, final ActionErrors errors) {
123 final Class<?> destClass = destPropertyDesc.getPropertyType();
124
125 final Converter converter;
126 if (converterType != null && !converterType.equals(Converter.class)) {
127 converter = converterProvider.getConverter(converterType);
128 } else {
129 final Class<?> componentType = values.getClass().getComponentType();
130 converter = converterProvider
131 .getConverter(componentType, destClass);
132 }
133 if (converter != null) {
134 try {
135 return converter.convertToObject(values[0], destClass,
136 conversionHelper);
137 } catch (final ConversionException e) {
138 final FieldInfo fieldInfo = new FieldInfo(parameterName);
139 final MessageInfo messageInfo = e.getMessageInfo();
140 errors.add(messageInfo.builder().fieldNameKey(parameterName)
141 .toString(), fieldInfo);
142 return null;
143 }
144 }
145
146 if (destClass.isArray()) {
147 return convertToArray(converterProvider, values, destClass
148 .getComponentType(), parameterName, errors);
149 }
150 if (List.class.isAssignableFrom(destClass)) {
151 final List<Object> list = new ArrayList<Object>();
152 convertToCollection(converterProvider, values, list,
153 destPropertyDesc, parameterName, errors);
154 return list;
155 }
156 if (Set.class.isAssignableFrom(destClass)) {
157 final Set<Object> set = new LinkedHashSet<Object>();
158 convertToCollection(converterProvider, values, set,
159 destPropertyDesc, parameterName, errors);
160 return set;
161 }
162
163 try {
164 return convertToScalar(converterProvider, values[0], destClass);
165 } catch (final ConversionException e) {
166 final FieldInfo fieldInfo = new FieldInfo(parameterName);
167 final MessageInfo messageInfo = e.getMessageInfo();
168 errors.add(messageInfo.builder().fieldNameKey(parameterName)
169 .toString(), fieldInfo);
170 return null;
171 }
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185 private Object convertToArray(final ConverterProvider converterProvider,
186 final Object[] values, final Class<?> componentType,
187 final String parameterName, final ActionErrors errors) {
188 final Object dest = Array.newInstance(componentType, values.length);
189 for (int i = 0; i < values.length; i++) {
190 try {
191 final Object convertedValue = convertToScalar(
192 converterProvider, values[i], componentType);
193 Array.set(dest, i, convertedValue);
194 } catch (final ConversionException e) {
195 final FieldInfo fieldInfo = new FieldInfo(parameterName, i);
196 final MessageInfo messageInfo = e.getMessageInfo();
197 errors.add(messageInfo.builder().fieldNameKey(parameterName)
198 .toString(), fieldInfo);
199 }
200 }
201 return dest;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216 private void convertToCollection(final ConverterProvider converterProvider,
217 final Object[] values, final Collection<Object> collection,
218 final PropertyDesc propertyDesc, final String parameterName,
219 final ActionErrors errors) {
220 if (propertyDesc.isParameterized()) {
221 final ParameterizedClassDesc parameterizedClassDesc = propertyDesc
222 .getParameterizedClassDesc();
223 final Class<?> destElementType = parameterizedClassDesc
224 .getArguments()[0].getRawClass();
225 for (int i = 0; i < values.length; i++) {
226 final Object value = values[i];
227 try {
228 final Object convertedValue = convertToScalar(
229 converterProvider, value, destElementType);
230 collection.add(convertedValue);
231 } catch (final ConversionException e) {
232 collection.add(null);
233 final FieldInfo fieldInfo = new FieldInfo(parameterName, i);
234 final MessageInfo messageInfo = e.getMessageInfo();
235 errors.add(messageInfo.builder()
236 .fieldNameKey(parameterName).toString(), fieldInfo);
237 }
238 }
239 } else {
240 for (final Object value : values) {
241 collection.add(value);
242 }
243 }
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 private Object convertToScalar(final ConverterProvider converterProvider,
260 final Object value, final Class<?> destClass)
261 throws ConversionException {
262 if (value == null) {
263 return null;
264 }
265 if (destClass.isAssignableFrom(value.getClass())) {
266 return value;
267 }
268 final Converter converter = converterProvider.getConverter(value
269 .getClass(), destClass);
270 if (converter == null) {
271 return null;
272 }
273 return converter.convertToObject(value, destClass, conversionHelper);
274 }
275
276 }