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