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 | 82 | 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 | 82 | this.converterFactory = converterFactory; |
65 | 82 | } |
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
public void setConversionHelper(final ConversionHelper conversionHelper) { |
74 | 82 | this.conversionHelper = conversionHelper; |
75 | 82 | } |
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 | 16 | if (parameterMap == null) { |
84 | 1 | return; |
85 | |
} |
86 | 15 | final BeanDesc destBeanDesc = BeanDescFactory.getBeanDesc(dest |
87 | |
.getClass()); |
88 | 15 | for (final Entry<String, Object[]> entry : parameterMap.entrySet()) { |
89 | 71 | final String sourceName = entry.getKey(); |
90 | 71 | if (destBeanDesc.hasPropertyDesc(sourceName)) { |
91 | 71 | final PropertyDesc destPropertyDesc = destBeanDesc |
92 | |
.getPropertyDesc(sourceName); |
93 | 71 | if (destPropertyDesc.isReadable() |
94 | |
&& destPropertyDesc.isWritable()) { |
95 | 71 | if (!isBindToAllProperties(actionClass, method)) { |
96 | 6 | final RequestParameter requestParameter = getRequestParameterAnnotation(destPropertyDesc); |
97 | 6 | if (requestParameter == null) { |
98 | 3 | continue; |
99 | |
} |
100 | |
} |
101 | |
|
102 | |
try { |
103 | 68 | final Object value = convert(entry.getValue(), |
104 | |
destPropertyDesc); |
105 | 68 | destPropertyDesc.setValue(dest, value); |
106 | 0 | } catch (final Exception e) { |
107 | 0 | destPropertyDesc.setValue(dest, null); |
108 | 68 | } |
109 | |
} |
110 | |
} |
111 | 68 | } |
112 | 15 | } |
113 | |
|
114 | |
|
115 | |
|
116 | |
|
117 | |
|
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
|
123 | |
private Object convert(final Object[] values, |
124 | |
final PropertyDesc destPropertyDesc) { |
125 | 68 | final Class<?> destClass = destPropertyDesc.getPropertyType(); |
126 | |
|
127 | 68 | final Converter converter = converterFactory.getConverter(values[0] |
128 | |
.getClass(), destClass); |
129 | 68 | if (converter != null) { |
130 | 27 | return converter.convertToObject(values[0], destClass, |
131 | |
conversionHelper); |
132 | |
} |
133 | |
|
134 | 41 | if (destClass.isArray()) { |
135 | 27 | return convertToArray(values, destClass.getComponentType()); |
136 | |
} |
137 | 14 | if (List.class.isAssignableFrom(destClass)) { |
138 | 3 | final List<Object> list = new ArrayList<Object>(); |
139 | 3 | convertToCollection(values, list, destPropertyDesc); |
140 | 3 | return list; |
141 | |
} |
142 | 11 | if (Set.class.isAssignableFrom(destClass)) { |
143 | 1 | final Set<Object> set = new LinkedHashSet<Object>(); |
144 | 1 | convertToCollection(values, set, destPropertyDesc); |
145 | 1 | return set; |
146 | |
} |
147 | 10 | 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 | 27 | final Object dest = Array.newInstance(componentType, values.length); |
162 | 82 | for (int i = 0; i < values.length; i++) { |
163 | 55 | final Object convertedValue = convertToScalar(values[i], |
164 | |
componentType); |
165 | 55 | Array.set(dest, i, convertedValue); |
166 | |
} |
167 | 27 | 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 | 4 | if (propertyDesc.isParameterized()) { |
183 | 4 | final ParameterizedClassDesc parameterizedClassDesc = propertyDesc |
184 | |
.getParameterizedClassDesc(); |
185 | 4 | final Class<?> destElementType = parameterizedClassDesc |
186 | |
.getArguments()[0].getRawClass(); |
187 | 12 | for (final Object value : values) { |
188 | 8 | final Object convertedValue = convertToScalar(value, |
189 | |
destElementType); |
190 | 8 | collection.add(convertedValue); |
191 | |
} |
192 | 4 | } else { |
193 | 0 | for (final Object value : values) { |
194 | 0 | collection.add(value); |
195 | |
} |
196 | |
} |
197 | 4 | } |
198 | |
|
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
private Object convertToScalar(final Object value, final Class<?> destClass) { |
209 | 73 | if (value == null) { |
210 | 1 | return null; |
211 | |
} |
212 | 72 | if (destClass.isAssignableFrom(value.getClass())) { |
213 | 15 | return value; |
214 | |
} |
215 | 57 | final Converter converter = converterFactory.getConverter(value |
216 | |
.getClass(), destClass); |
217 | 57 | if (converter == null) { |
218 | 0 | return null; |
219 | |
} |
220 | 57 | 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 | 71 | final Form form = CubbyUtils.getForm(actionClass, method); |
234 | 71 | if (form == null) { |
235 | 2 | return false; |
236 | |
} |
237 | |
|
238 | 69 | final RequestParameterBindingType type = form.bindingType(); |
239 | 69 | switch (type) { |
240 | |
case ALL_PROPERTIES: |
241 | 65 | return true; |
242 | |
case ONLY_SPECIFIED_PROPERTIES: |
243 | 4 | return false; |
244 | |
default: |
245 | 82 | 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 | 6 | if (propertyDesc.hasWriteMethod()) { |
261 | 0 | final Method method = propertyDesc.getWriteMethod(); |
262 | 0 | if (method.isAnnotationPresent(RequestParameter.class)) { |
263 | 0 | request = method.getAnnotation(RequestParameter.class); |
264 | |
} else { |
265 | 0 | final Field field = propertyDesc.getField(); |
266 | 0 | request = field.getAnnotation(RequestParameter.class); |
267 | |
} |
268 | 0 | } else { |
269 | 6 | final Field field = propertyDesc.getField(); |
270 | 6 | request = field.getAnnotation(RequestParameter.class); |
271 | |
} |
272 | 6 | return request; |
273 | |
} |
274 | |
|
275 | |
} |