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