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