1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.internal.controller.impl;
17  
18  import static org.easymock.EasyMock.createNiceMock;
19  import static org.easymock.EasyMock.replay;
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotNull;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertSame;
25  import static org.junit.Assert.assertTrue;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.ByteArrayOutputStream;
29  import java.io.File;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.OutputStream;
33  import java.io.UnsupportedEncodingException;
34  import java.lang.reflect.Method;
35  import java.math.BigDecimal;
36  import java.math.BigInteger;
37  import java.sql.Time;
38  import java.sql.Timestamp;
39  import java.text.SimpleDateFormat;
40  import java.util.Calendar;
41  import java.util.Collections;
42  import java.util.Date;
43  import java.util.HashMap;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Map;
47  import java.util.Set;
48  
49  import javax.servlet.http.HttpServletRequest;
50  import javax.servlet.http.HttpServletResponse;
51  
52  import org.apache.commons.fileupload.FileItem;
53  import org.junit.After;
54  import org.junit.Before;
55  import org.junit.Test;
56  import org.seasar.cubby.action.Action;
57  import org.seasar.cubby.action.ActionContext;
58  import org.seasar.cubby.action.ActionErrors;
59  import org.seasar.cubby.action.ActionResult;
60  import org.seasar.cubby.action.FieldInfo;
61  import org.seasar.cubby.action.Form;
62  import org.seasar.cubby.action.MessageInfo;
63  import org.seasar.cubby.action.RequestParameter;
64  import org.seasar.cubby.action.RequestParameterBindingType;
65  import org.seasar.cubby.action.impl.ActionErrorsImpl;
66  import org.seasar.cubby.controller.FormatPattern;
67  import org.seasar.cubby.controller.MessagesBehaviour;
68  import org.seasar.cubby.controller.impl.DefaultFormatPattern;
69  import org.seasar.cubby.controller.impl.DefaultMessagesBehaviour;
70  import org.seasar.cubby.converter.ConversionHelper;
71  import org.seasar.cubby.converter.Converter;
72  import org.seasar.cubby.internal.controller.ConversionFailure;
73  import org.seasar.cubby.internal.controller.RequestParameterBinder;
74  import org.seasar.cubby.internal.controller.ThreadContext;
75  import org.seasar.cubby.internal.controller.ThreadContext.Command;
76  import org.seasar.cubby.mock.MockActionContext;
77  import org.seasar.cubby.mock.MockContainerProvider;
78  import org.seasar.cubby.mock.MockConverterProvider;
79  import org.seasar.cubby.plugin.PluginRegistry;
80  import org.seasar.cubby.plugins.BinderPlugin;
81  import org.seasar.cubby.spi.BeanDescProvider;
82  import org.seasar.cubby.spi.ContainerProvider;
83  import org.seasar.cubby.spi.ConverterProvider;
84  import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
85  import org.seasar.cubby.spi.container.Container;
86  import org.seasar.cubby.spi.container.LookupException;
87  
88  /**
89   * 
90   * @author baba
91   */
92  public class RequestParameterBinderImplTest {
93  
94  	private final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
95  
96  	private RequestParameterBinder requestParameterBinder;
97  
98  	@Before
99  	public void setup() {
100 		final BinderPlugin binderPlugin = new BinderPlugin();
101 		final FormatPattern formatPattern = new DefaultFormatPattern();
102 		final MessagesBehaviour messagesBehaviour = new DefaultMessagesBehaviour();
103 		binderPlugin.bind(ContainerProvider.class).toInstance(
104 				new MockContainerProvider(new Container() {
105 
106 					public <T> T lookup(final Class<T> type) {
107 						if (FormatPattern.class.equals(type)) {
108 							return type.cast(formatPattern);
109 						}
110 						if (MessagesBehaviour.class.equals(type)) {
111 							return type.cast(messagesBehaviour);
112 						}
113 						throw new LookupException(type.getName());
114 					}
115 				}));
116 		binderPlugin.bind(ConverterProvider.class).toInstance(
117 				new MockConverterProvider(new BraceConverter()));
118 		binderPlugin.bind(BeanDescProvider.class).toInstance(
119 				new DefaultBeanDescProvider());
120 
121 		pluginRegistry.register(binderPlugin);
122 
123 		requestParameterBinder = new RequestParameterBinderImpl();
124 	}
125 
126 	@After
127 	public void teardown() {
128 		pluginRegistry.clear();
129 	}
130 
131 	@Test
132 	public void mapToBeanNullSource() {
133 		final FormDto dto = new FormDto();
134 		final ActionContext actionContext = new MockActionContext(null,
135 				MockAction.class, actionMethod(MockAction.class, "all"));
136 		final List<ConversionFailure> conversionFailures = requestParameterBinder
137 				.bind(null, dto, actionContext);
138 		assertTrue(conversionFailures.isEmpty());
139 	}
140 
141 	@Test
142 	public void mapToBean() {
143 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
144 		map.put("date", new Object[] { "2006-01-01" });
145 
146 		final FormDto dto = new FormDto();
147 
148 		final ActionContext actionContext = new MockActionContext(null,
149 				MockAction.class, actionMethod(MockAction.class, "all"));
150 		final List<ConversionFailure> conversionFailures = requestParameterBinder
151 				.bind(map, dto, actionContext);
152 		final Calendar cal = Calendar.getInstance();
153 		cal.set(2006, 0, 1);
154 		final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
155 		assertEquals(format.format(cal.getTime()), format.format(dto.getDate()));
156 		assertTrue(conversionFailures.isEmpty());
157 	}
158 
159 	@Test
160 	public void mapToBean_OneValue() {
161 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
162 		map.put("num1", new Object[] { "1" });
163 		map.put("num2", new Object[] { "2" });
164 		map.put("num3", new Object[] { "def" });
165 
166 		final FormDto dto = new FormDto();
167 
168 		final ActionContext actionContext = new MockActionContext(null,
169 				MockAction.class, actionMethod(MockAction.class, "all"));
170 		final List<ConversionFailure> conversionFailures = requestParameterBinder
171 				.bind(map, dto, actionContext);
172 		assertNotNull(dto.getNum1());
173 		assertEquals(Integer.valueOf(1), dto.getNum1());
174 		assertNotNull(dto.getNum2());
175 		assertEquals(1, dto.getNum2().length);
176 		assertEquals(Integer.valueOf(2), dto.getNum2()[0]);
177 		assertNotNull(dto.getNum3());
178 		assertEquals(1, dto.getNum3().size());
179 		assertEquals("def", dto.getNum3().get(0));
180 		assertTrue(conversionFailures.isEmpty());
181 	}
182 
183 	@Test
184 	public void mapToBean_MultiValue() {
185 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
186 		map.put("num2", new Object[] { "1", "2" });
187 		map.put("num3", new Object[] { "abc", "def" });
188 
189 		final FormDto dto = new FormDto();
190 
191 		final ActionContext actionContext = new MockActionContext(null,
192 				MockAction.class, actionMethod(MockAction.class, "all"));
193 		final List<ConversionFailure> conversionFailures = requestParameterBinder
194 				.bind(map, dto, actionContext);
195 		assertNotNull(dto.getNum2());
196 		assertEquals(2, dto.getNum2().length);
197 		assertEquals(Integer.valueOf(1), dto.getNum2()[0]);
198 		assertEquals(Integer.valueOf(2), dto.getNum2()[1]);
199 		assertNotNull(dto.getNum3());
200 		assertEquals(2, dto.getNum3().size());
201 		assertEquals("abc", dto.getNum3().get(0));
202 		assertEquals("def", dto.getNum3().get(1));
203 		assertTrue(conversionFailures.isEmpty());
204 	}
205 
206 	@Test
207 	public void mapToBean_MultiValueIncludesEmptyValue() {
208 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
209 		map.put("num2", new String[] { "1", "", "2" });
210 
211 		final FormDto dto = new FormDto();
212 
213 		final ActionContext actionContext = new MockActionContext(null,
214 				MockAction.class, actionMethod(MockAction.class, "all"));
215 		final List<ConversionFailure> conversionFailures = requestParameterBinder
216 				.bind(map, dto, actionContext);
217 		assertEquals(3, dto.getNum2().length);
218 		assertEquals(Integer.valueOf(1), dto.getNum2()[0]);
219 		assertEquals(null, dto.getNum2()[1]);
220 		assertEquals(Integer.valueOf(2), dto.getNum2()[2]);
221 		assertTrue(conversionFailures.isEmpty());
222 	}
223 
224 	@Test
225 	public void mapToBean_MultiValueIncludesNullValue() {
226 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
227 		map.put("num3", new String[] { "zzz", null, "xxx" });
228 
229 		final FormDto dto = new FormDto();
230 
231 		final ActionContext actionContext = new MockActionContext(null,
232 				MockAction.class, actionMethod(MockAction.class, "all"));
233 		final List<ConversionFailure> conversionFailures = requestParameterBinder
234 				.bind(map, dto, actionContext);
235 		assertEquals(3, dto.getNum3().size());
236 		assertEquals("zzz", dto.getNum3().get(0));
237 		assertNull(dto.getNum3().get(1));
238 		assertEquals("xxx", dto.getNum3().get(2));
239 		assertTrue(conversionFailures.isEmpty());
240 	}
241 
242 	@Test
243 	public void mapToBean_annotated() {
244 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
245 		map.put("normal", new Object[] { "abcd" });
246 		map.put("specifiedName", new Object[] { "efgh" });
247 		map.put("foo", new Object[] { "ijkl" });
248 		map.put("specifiedConverter", new Object[] { "mnop" });
249 		map.put("specifiedNameAndConverter", new Object[] { "qrst" });
250 		map.put("bar", new Object[] { "uvwx" });
251 
252 		final AnnotatedDto dto = new AnnotatedDto();
253 
254 		final ActionContext actionContext = new MockActionContext(null,
255 				MockAction.class, actionMethod(MockAction.class, "all"));
256 		final List<ConversionFailure> conversionFailures = requestParameterBinder
257 				.bind(map, dto, actionContext);
258 		assertEquals("abcd", dto.getNormal());
259 		assertEquals("ijkl", dto.getSpecifiedName());
260 		assertEquals("{mnop}", dto.getSpecifiedConverter());
261 		assertEquals("{uvwx}", dto.getSpecifiedNameAndConverter());
262 		assertTrue(conversionFailures.isEmpty());
263 	}
264 
265 	@Test
266 	public void converters() {
267 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
268 		map.put("decimal", new Object[] { "12.3" });
269 		map.put("decimals", new Object[] { "45.6", "78.9" });
270 		map.put("bigint", new Object[] { "9876" });
271 		map.put("bigints", new Object[] { "5432", "10" });
272 		map.put("bool1", new Object[] { "true" });
273 		map.put("bools1", new Object[] { "true", "false" });
274 		map.put("bool2", new Object[] { "false" });
275 		map.put("bools2", new Object[] { "false", "true", "false" });
276 		map.put("byte1", new Object[] { "12" });
277 		map.put("bytes1", new Object[] { "34", "56" });
278 		map.put("byte2", new Object[] { "98" });
279 		map.put("bytes2", new Object[] { "76", "54" });
280 		map.put("char1", new Object[] { "a" });
281 		map.put("chars1", new Object[] { "b", "c" });
282 		map.put("char2", new Object[] { "d" });
283 		map.put("chars2", new Object[] { "e", "f" });
284 		map.put("date", new Object[] { "2008-7-28" });
285 		map.put("dates", new Object[] { "2008-8-14", "2008-10-30" });
286 		map.put("double1", new Object[] { "1.2" });
287 		map.put("doubles1", new Object[] { "3.4", "5.6" });
288 		map.put("double2", new Object[] { "9.8" });
289 		map.put("doubles2", new Object[] { "7.6", "5.4" });
290 		map.put("en", new Object[] { "VALUE1" });
291 		map.put("ens", new Object[] { "VALUE2", "VALUE3" });
292 		map.put("float1", new Object[] { "1.2" });
293 		map.put("floats1", new Object[] { "3.4", "5.6" });
294 		map.put("float2", new Object[] { "9.8" });
295 		map.put("floats2", new Object[] { "7.6", "5.4" });
296 		map.put("int1", new Object[] { "12" });
297 		map.put("ints1", new Object[] { "34", "56" });
298 		map.put("int2", new Object[] { "98" });
299 		map.put("ints2", new Object[] { "76", "54" });
300 		map.put("long1", new Object[] { "12" });
301 		map.put("longs1", new Object[] { "34", "56" });
302 		map.put("long2", new Object[] { "98" });
303 		map.put("longs2", new Object[] { "76", "54" });
304 		map.put("short1", new Object[] { "12" });
305 		map.put("shorts1", new Object[] { "34", "56" });
306 		map.put("short2", new Object[] { "98" });
307 		map.put("shorts2", new Object[] { "76", "54" });
308 		map.put("sqldate", new Object[] { "2008-7-28" });
309 		map.put("sqldates", new Object[] { "2008-8-14", "2008-10-30" });
310 		map.put("sqltime", new Object[] { "12:34:56" });
311 		map.put("sqltimes", new Object[] { "13:45:24", "23:44:00" });
312 		map.put("sqltimestamp", new Object[] { "2008-7-28 12:34:56" });
313 		map.put("sqltimestamps", new Object[] { "2008-8-14 13:45:24",
314 				"2008-10-30 23:44:00" });
315 
316 		final ConvertersDto dto = new ConvertersDto();
317 
318 		final ActionContext actionContext = new MockActionContext(null,
319 				MockAction.class, actionMethod(MockAction.class, "all"));
320 		final List<ConversionFailure> conversionFailures = requestParameterBinder
321 				.bind(map, dto, actionContext);
322 
323 		assertNotNull(dto.getDecimal());
324 		assertTrue(new BigDecimal("12.3").compareTo(dto.getDecimal()) == 0);
325 
326 		assertNotNull(dto.getDecimals());
327 		assertEquals(2, dto.getDecimals().length);
328 		assertTrue(new BigDecimal("45.6").compareTo(dto.getDecimals()[0]) == 0);
329 		assertTrue(new BigDecimal("78.9").compareTo(dto.getDecimals()[1]) == 0);
330 
331 		assertNotNull(dto.getBigint());
332 		assertTrue(new BigInteger("9876").compareTo(dto.getBigint()) == 0);
333 
334 		assertNotNull(dto.getBigints());
335 		assertEquals(2, dto.getBigints().length);
336 		assertTrue(new BigInteger("5432").compareTo(dto.getBigints()[0]) == 0);
337 		assertTrue(new BigInteger("10").compareTo(dto.getBigints()[1]) == 0);
338 
339 		assertNotNull(dto.getBool1());
340 		assertTrue(dto.getBool1());
341 
342 		assertNotNull(dto.getBools1());
343 		assertEquals(2, dto.getBools1().length);
344 		assertTrue(dto.getBools1()[0]);
345 		assertFalse(dto.getBools1()[1]);
346 
347 		assertFalse(dto.isBool2());
348 
349 		assertNotNull(dto.getBools2());
350 		assertEquals(3, dto.getBools2().length);
351 		assertFalse(dto.getBools2()[0]);
352 		assertTrue(dto.getBools2()[1]);
353 		assertFalse(dto.getBools2()[2]);
354 
355 		assertNotNull(dto.getByte1());
356 		assertEquals(Byte.valueOf((byte) 12), dto.getByte1());
357 
358 		assertNotNull(dto.getBytes1());
359 		assertEquals(2, dto.getBytes1().length);
360 		assertEquals(Byte.valueOf((byte) 34), dto.getBytes1()[0]);
361 		assertEquals(Byte.valueOf((byte) 56), dto.getBytes1()[1]);
362 
363 		assertEquals((byte) 98, dto.getByte2());
364 
365 		assertNotNull(dto.getBytes2());
366 		assertEquals(2, dto.getBytes2().length);
367 		assertEquals((byte) 76, dto.getBytes2()[0]);
368 		assertEquals((byte) 54, dto.getBytes2()[1]);
369 
370 		assertNotNull(dto.getChar1());
371 		assertEquals(Character.valueOf('a'), dto.getChar1());
372 
373 		assertNotNull(dto.getChars1());
374 		assertEquals(2, dto.getChars1().length);
375 		assertEquals(Character.valueOf('b'), dto.getChars1()[0]);
376 		assertEquals(Character.valueOf('c'), dto.getChars1()[1]);
377 
378 		assertNotNull(dto.getChar2());
379 		assertEquals('d', dto.getChar2());
380 
381 		assertNotNull(dto.getChars2());
382 		assertEquals(2, dto.getChars2().length);
383 		assertEquals('e', dto.getChars2()[0]);
384 		assertEquals('f', dto.getChars2()[1]);
385 
386 		assertNotNull(dto.getDate());
387 		assertEquals(new Date(fromDateToMillis(2008, 7, 28)), dto.getDate());
388 
389 		assertNotNull(dto.getDates());
390 		assertEquals(2, dto.getDates().length);
391 		assertEquals(new Date(fromDateToMillis(2008, 8, 14)), dto.getDates()[0]);
392 		assertEquals(new Date(fromDateToMillis(2008, 10, 30)),
393 				dto.getDates()[1]);
394 
395 		assertNotNull(dto.getDouble1());
396 		assertEquals(new Double(1.2d), dto.getDouble1());
397 
398 		assertNotNull(dto.getDoubles1());
399 		assertEquals(2, dto.getDoubles1().length);
400 		assertEquals(new Double(3.4d), dto.getDoubles1()[0]);
401 		assertEquals(new Double(5.6d), dto.getDoubles1()[1]);
402 
403 		assertEquals(9.8d, dto.getDouble2(), 0.0d);
404 
405 		assertNotNull(dto.getDoubles2());
406 		assertEquals(2, dto.getDoubles2().length);
407 		assertEquals(7.6d, dto.getDoubles2()[0], 0.0d);
408 		assertEquals(5.4d, dto.getDoubles2()[1], 0.0d);
409 
410 		assertNotNull(dto.getEn());
411 		assertSame(ExEnum.VALUE1, dto.getEn());
412 
413 		assertNotNull(dto.getEns());
414 		assertEquals(2, dto.getEns().length);
415 		assertSame(ExEnum.VALUE2, dto.getEns()[0]);
416 		assertSame(ExEnum.VALUE3, dto.getEns()[1]);
417 
418 		assertNotNull(dto.getFloat1());
419 		assertEquals(new Float(1.2f), dto.getFloat1());
420 
421 		assertNotNull(dto.getFloats1());
422 		assertEquals(2, dto.getFloats1().length);
423 		assertEquals(new Float(3.4f), dto.getFloats1()[0]);
424 		assertEquals(new Float(5.6f), dto.getFloats1()[1]);
425 
426 		assertEquals(9.8f, dto.getFloat2(), 0.0f);
427 
428 		assertNotNull(dto.getFloats2());
429 		assertEquals(2, dto.getFloats2().length);
430 		assertEquals(7.6f, dto.getFloats2()[0], 0.0f);
431 		assertEquals(5.4f, dto.getFloats2()[1], 0.0f);
432 
433 		assertNotNull(dto.getInt1());
434 		assertEquals(Integer.valueOf(12), dto.getInt1());
435 
436 		assertNotNull(dto.getInts1());
437 		assertEquals(2, dto.getInts1().length);
438 		assertEquals(Integer.valueOf(34), dto.getInts1()[0]);
439 		assertEquals(Integer.valueOf(56), dto.getInts1()[1]);
440 
441 		assertEquals(98, dto.getInt2());
442 
443 		assertNotNull(dto.getInts2());
444 		assertEquals(2, dto.getInts2().length);
445 		assertEquals(76, dto.getInts2()[0]);
446 		assertEquals(54, dto.getInts2()[1]);
447 
448 		assertNotNull(dto.getLong1());
449 		assertEquals(Long.valueOf(12l), dto.getLong1());
450 
451 		assertNotNull(dto.getLongs1());
452 		assertEquals(2, dto.getLongs1().length);
453 		assertEquals(Long.valueOf(34l), dto.getLongs1()[0]);
454 		assertEquals(Long.valueOf(56l), dto.getLongs1()[1]);
455 
456 		assertEquals(98l, dto.getLong2());
457 
458 		assertNotNull(dto.getLongs2());
459 		assertEquals(2, dto.getLongs2().length);
460 		assertEquals(76l, dto.getLongs2()[0]);
461 		assertEquals(54l, dto.getLongs2()[1]);
462 
463 		assertNotNull(dto.getShort1());
464 		assertEquals(Short.valueOf((short) 12), dto.getShort1());
465 
466 		assertNotNull(dto.getShorts1());
467 		assertEquals(2, dto.getShorts1().length);
468 		assertEquals(Short.valueOf((short) 34), dto.getShorts1()[0]);
469 		assertEquals(Short.valueOf((short) 56), dto.getShorts1()[1]);
470 
471 		assertEquals((short) 98, dto.getShort2());
472 
473 		assertNotNull(dto.getShorts2());
474 		assertEquals(2, dto.getShorts2().length);
475 		assertEquals((short) 76, dto.getShorts2()[0]);
476 		assertEquals((short) 54, dto.getShorts2()[1]);
477 
478 		assertNotNull(dto.getSqldate());
479 		assertEquals(new java.sql.Date(fromDateToMillis(2008, 7, 28)), dto
480 				.getSqldate());
481 
482 		assertNotNull(dto.getSqldates());
483 		assertEquals(2, dto.getSqldates().length);
484 		assertEquals(new java.sql.Date(fromDateToMillis(2008, 8, 14)), dto
485 				.getSqldates()[0]);
486 		assertEquals(new java.sql.Date(fromDateToMillis(2008, 10, 30)), dto
487 				.getSqldates()[1]);
488 
489 		assertNotNull(dto.getSqltime());
490 		assertEquals(new Time(fromTimeToMillis(12, 34, 56)), dto.getSqltime());
491 
492 		assertNotNull(dto.getSqltimes());
493 		assertEquals(2, dto.getSqltimes().length);
494 		assertEquals(new Time(fromTimeToMillis(13, 45, 24)),
495 				dto.getSqltimes()[0]);
496 		assertEquals(new Time(fromTimeToMillis(23, 44, 00)),
497 				dto.getSqltimes()[1]);
498 
499 		assertNotNull(dto.getSqltimestamp());
500 		assertEquals(new Timestamp(fromTimestampToMillis(2008, 7, 28, 12, 34,
501 				56)), dto.getSqltimestamp());
502 
503 		assertNotNull(dto.getSqltimestamps());
504 		assertEquals(2, dto.getSqltimestamps().length);
505 		assertEquals(new Timestamp(fromTimestampToMillis(2008, 8, 14, 13, 45,
506 				24)), dto.getSqltimestamps()[0]);
507 		assertEquals(new Timestamp(fromTimestampToMillis(2008, 10, 30, 23, 44,
508 				00)), dto.getSqltimestamps()[1]);
509 
510 		assertTrue(conversionFailures.isEmpty());
511 
512 		System.out.println(dto);
513 	}
514 
515 	@Test
516 	public void convertersWithError() throws Exception {
517 		final HttpServletRequest request = createNiceMock(HttpServletRequest.class);
518 		final HttpServletResponse response = createNiceMock(HttpServletResponse.class);
519 		replay(request, response);
520 
521 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
522 		map.put("decimal", new Object[] { "a" });
523 		map.put("decimals", new Object[] { "45.6", "b" });
524 		map.put("bigint", new Object[] { "c" });
525 		map.put("bigints", new Object[] { "d", "10" });
526 		map.put("byte1", new Object[] { "12a" });
527 		map.put("bytes1", new Object[] { "3324234456789", "56" });
528 		map.put("byte2", new Object[] { "98o" });
529 		map.put("bytes2", new Object[] { "76p", "54" });
530 		map.put("date", new Object[] { "2009-2-29" });
531 		map.put("dates", new Object[] { "2008-8-14", "2008/10/30" });
532 		map.put("double1", new Object[] { "1.2a" });
533 		map.put("doubles1", new Object[] { "3.4", "5.6b" });
534 		map.put("double2", new Object[] { "9.8c" });
535 		map.put("doubles2", new Object[] { "7.6d", "5.4" });
536 		map.put("en", new Object[] { "VALUE4" });
537 		map.put("ens", new Object[] { "VALUE2", "VALUE5" });
538 		map.put("float1", new Object[] { "1.2a" });
539 		map.put("floats1", new Object[] { "3.4b", "5.6" });
540 		map.put("float2", new Object[] { "9.8c" });
541 		map.put("floats2", new Object[] { "7.6d", "5.4" });
542 		map.put("int1", new Object[] { "12.1" });
543 		map.put("ints1", new Object[] { "34f", "56" });
544 		map.put("int2", new Object[] { "98g" });
545 		map.put("ints2", new Object[] { "76", "54h" });
546 		map.put("long1", new Object[] { "12i" });
547 		map.put("longs1", new Object[] { "34j", "56" });
548 		map.put("long2", new Object[] { "98k" });
549 		map.put("longs2", new Object[] { "76l", "54" });
550 		map.put("short1", new Object[] { "12m" });
551 		map.put("shorts1", new Object[] { "34n", "56" });
552 		map.put("short2", new Object[] { "98o" });
553 		map.put("shorts2", new Object[] { "76p", "54" });
554 		map.put("sqldate", new Object[] { "2008-7-280" });
555 		map.put("sqldates", new Object[] { "2008-8-14-", "2008-10-30" });
556 		map.put("sqltime", new Object[] { "25:34:56" });
557 		map.put("sqltimes", new Object[] { "13:45:99", "23:44:00" });
558 		map.put("sqltimestamp", new Object[] { "2008-7-28-12:34:56" });
559 		map.put("sqltimestamps", new Object[] { "2008-8-32 13:45:24",
560 				"2008-10-30 23:44:00" });
561 
562 		final ConvertersDto dto = new ConvertersDto();
563 
564 		final ActionContext actionContext = new MockActionContext(null,
565 				MockAction.class, actionMethod(MockAction.class, "all"));
566 		// requestParameterBinder.bind(map, dto, actionContext, errors);
567 
568 		final ActionErrors errors = new ActionErrorsImpl();
569 
570 		ThreadContext.runInContext(request, response, new Command() {
571 
572 			public void execute(final HttpServletRequest request,
573 					final HttpServletResponse response) throws Exception {
574 				final List<ConversionFailure> conversionFailures = requestParameterBinder
575 						.bind(map, dto, actionContext);
576 				for (final ConversionFailure conversionFailure : conversionFailures) {
577 					final MessageInfo messageInfo = conversionFailure
578 							.getMessageInfo();
579 					final FieldInfo[] fieldInfos = conversionFailure
580 							.getFieldInfos();
581 					final String message = messageInfo
582 							.toMessage(conversionFailure.getFieldName());
583 					errors.add(message, fieldInfos);
584 				}
585 
586 			}
587 
588 		});
589 
590 		assertFalse(errors.isEmpty());
591 
592 		System.out.println(errors.getFields().get("decimals"));
593 		assertFalse(errors.getFields().get("decimals").isEmpty());
594 		System.out.println(errors.getIndexedFields().get("decimals").get(0));
595 		assertTrue(errors.getIndexedFields().get("decimals").get(0).isEmpty());
596 		System.out.println(errors.getIndexedFields().get("decimals").get(1));
597 		assertFalse(errors.getIndexedFields().get("decimals").get(1).isEmpty());
598 
599 		System.out.println(errors.getFields().get("bigint"));
600 		assertFalse(errors.getFields().get("bigint").isEmpty());
601 		System.out.println(errors.getIndexedFields().get("bigints").get(0));
602 		assertFalse(errors.getIndexedFields().get("bigints").get(0).isEmpty());
603 		System.out.println(errors.getIndexedFields().get("bigints").get(1));
604 		assertTrue(errors.getIndexedFields().get("bigints").get(1).isEmpty());
605 
606 		System.out.println(errors.getFields().get("byte1"));
607 		assertFalse(errors.getFields().get("byte1").isEmpty());
608 		System.out.println(errors.getIndexedFields().get("bytes1").get(0));
609 		assertFalse(errors.getIndexedFields().get("bytes1").get(0).isEmpty());
610 		System.out.println(errors.getIndexedFields().get("bytes1").get(1));
611 		assertTrue(errors.getIndexedFields().get("bytes1").get(1).isEmpty());
612 
613 		System.out.println(errors.getFields().get("byte2"));
614 		assertFalse(errors.getFields().get("byte2").isEmpty());
615 		System.out.println(errors.getIndexedFields().get("bytes2").get(0));
616 		assertFalse(errors.getIndexedFields().get("bytes2").get(0).isEmpty());
617 		System.out.println(errors.getIndexedFields().get("bytes2").get(1));
618 		assertTrue(errors.getIndexedFields().get("bytes2").get(1).isEmpty());
619 
620 		System.out.println(errors.getFields().get("double1"));
621 		assertFalse(errors.getFields().get("double1").isEmpty());
622 		System.out.println(errors.getIndexedFields().get("doubles1").get(0));
623 		assertTrue(errors.getIndexedFields().get("doubles1").get(0).isEmpty());
624 		System.out.println(errors.getIndexedFields().get("doubles1").get(1));
625 		assertFalse(errors.getIndexedFields().get("doubles1").get(1).isEmpty());
626 
627 		System.out.println(errors.getFields().get("double2"));
628 		assertFalse(errors.getFields().get("double2").isEmpty());
629 		System.out.println(errors.getIndexedFields().get("doubles2").get(0));
630 		assertFalse(errors.getIndexedFields().get("doubles2").get(0).isEmpty());
631 		System.out.println(errors.getIndexedFields().get("doubles2").get(1));
632 		assertTrue(errors.getIndexedFields().get("doubles2").get(1).isEmpty());
633 
634 		System.out.println(errors.getFields().get("float1"));
635 		assertFalse(errors.getFields().get("float1").isEmpty());
636 		System.out.println(errors.getIndexedFields().get("floats1").get(0));
637 		assertFalse(errors.getIndexedFields().get("floats1").get(0).isEmpty());
638 		System.out.println(errors.getIndexedFields().get("floats1").get(1));
639 		assertTrue(errors.getIndexedFields().get("floats1").get(1).isEmpty());
640 
641 		System.out.println(errors.getFields().get("float2"));
642 		assertFalse(errors.getFields().get("float2").isEmpty());
643 		System.out.println(errors.getIndexedFields().get("floats2").get(0));
644 		assertFalse(errors.getIndexedFields().get("floats2").get(0).isEmpty());
645 		System.out.println(errors.getIndexedFields().get("floats2").get(1));
646 		assertTrue(errors.getIndexedFields().get("floats2").get(1).isEmpty());
647 
648 		System.out.println(errors.getFields().get("int1"));
649 		assertFalse(errors.getFields().get("int1").isEmpty());
650 		System.out.println(errors.getIndexedFields().get("ints1").get(0));
651 		assertFalse(errors.getIndexedFields().get("ints1").get(0).isEmpty());
652 		System.out.println(errors.getIndexedFields().get("ints1").get(1));
653 		assertTrue(errors.getIndexedFields().get("ints1").get(1).isEmpty());
654 
655 		System.out.println(errors.getFields().get("int2"));
656 		assertFalse(errors.getFields().get("int2").isEmpty());
657 		System.out.println(errors.getIndexedFields().get("ints2").get(0));
658 		assertTrue(errors.getIndexedFields().get("ints2").get(0).isEmpty());
659 		System.out.println(errors.getIndexedFields().get("ints2").get(1));
660 		assertFalse(errors.getIndexedFields().get("ints2").get(1).isEmpty());
661 
662 		System.out.println(errors.getFields().get("long1"));
663 		assertFalse(errors.getFields().get("long1").isEmpty());
664 		System.out.println(errors.getIndexedFields().get("longs1").get(0));
665 		assertFalse(errors.getIndexedFields().get("longs1").get(0).isEmpty());
666 		System.out.println(errors.getIndexedFields().get("longs1").get(1));
667 		assertTrue(errors.getIndexedFields().get("longs1").get(1).isEmpty());
668 
669 		System.out.println(errors.getFields().get("long2"));
670 		assertFalse(errors.getFields().get("long2").isEmpty());
671 		System.out.println(errors.getIndexedFields().get("longs2").get(0));
672 		assertFalse(errors.getIndexedFields().get("longs2").get(0).isEmpty());
673 		System.out.println(errors.getIndexedFields().get("longs2").get(1));
674 		assertTrue(errors.getIndexedFields().get("longs2").get(1).isEmpty());
675 
676 		System.out.println(errors.getFields().get("short1"));
677 		assertFalse(errors.getFields().get("short1").isEmpty());
678 		System.out.println(errors.getIndexedFields().get("shorts1").get(0));
679 		assertFalse(errors.getIndexedFields().get("shorts1").get(0).isEmpty());
680 		System.out.println(errors.getIndexedFields().get("shorts1").get(1));
681 		assertTrue(errors.getIndexedFields().get("shorts1").get(1).isEmpty());
682 
683 		System.out.println(errors.getFields().get("short2"));
684 		assertFalse(errors.getFields().get("short2").isEmpty());
685 		System.out.println(errors.getIndexedFields().get("shorts2").get(0));
686 		assertFalse(errors.getIndexedFields().get("shorts2").get(0).isEmpty());
687 		System.out.println(errors.getIndexedFields().get("shorts2").get(1));
688 		assertTrue(errors.getIndexedFields().get("shorts2").get(1).isEmpty());
689 
690 		System.out.println(errors.getFields().get("date"));
691 		assertFalse(errors.getFields().get("date").isEmpty());
692 		System.out.println(errors.getIndexedFields().get("dates").get(0));
693 		assertTrue(errors.getIndexedFields().get("dates").get(0).isEmpty());
694 		System.out.println(errors.getIndexedFields().get("dates").get(1));
695 		assertFalse(errors.getIndexedFields().get("dates").get(1).isEmpty());
696 
697 		System.out.println(errors.getFields().get("sqldate"));
698 		assertFalse(errors.getFields().get("sqldate").isEmpty());
699 		System.out.println(errors.getIndexedFields().get("sqldates").get(0));
700 		assertFalse(errors.getIndexedFields().get("sqldates").get(0).isEmpty());
701 		System.out.println(errors.getIndexedFields().get("sqldates").get(1));
702 		assertTrue(errors.getIndexedFields().get("sqldates").get(1).isEmpty());
703 
704 		System.out.println(errors.getFields().get("sqltime"));
705 		assertFalse(errors.getFields().get("sqltime").isEmpty());
706 		System.out.println(errors.getIndexedFields().get("sqltimes").get(0));
707 		assertFalse(errors.getIndexedFields().get("sqltimes").get(0).isEmpty());
708 		System.out.println(errors.getIndexedFields().get("sqltimes").get(1));
709 		assertTrue(errors.getIndexedFields().get("sqltimes").get(1).isEmpty());
710 
711 		System.out.println(errors.getFields().get("sqltimestamp"));
712 		assertFalse(errors.getFields().get("sqltimestamp").isEmpty());
713 		System.out.println(errors.getIndexedFields().get("sqltimestamps")
714 				.get(0));
715 		assertFalse(errors.getIndexedFields().get("sqltimestamps").get(0)
716 				.isEmpty());
717 		System.out.println(errors.getIndexedFields().get("sqltimestamps")
718 				.get(1));
719 		assertTrue(errors.getIndexedFields().get("sqltimestamps").get(1)
720 				.isEmpty());
721 
722 		System.out.println(errors.getFields().get("en"));
723 		assertFalse(errors.getFields().get("en").isEmpty());
724 		System.out.println(errors.getIndexedFields().get("ens").get(0));
725 		assertTrue(errors.getIndexedFields().get("ens").get(0).isEmpty());
726 		System.out.println(errors.getIndexedFields().get("ens").get(1));
727 		assertFalse(errors.getIndexedFields().get("ens").get(1).isEmpty());
728 	}
729 
730 	@Test
731 	public void convertFileItem() throws Exception {
732 		final HttpServletRequest request = createNiceMock(HttpServletRequest.class);
733 		final HttpServletResponse response = createNiceMock(HttpServletResponse.class);
734 		replay(request, response);
735 
736 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
737 		map.put("file", new FileItem[] { new MockFileItem("123") });
738 		map.put("bytefile", new FileItem[] { new MockFileItem("456") });
739 		map.put("bytefiles", new FileItem[] { new MockFileItem("abc"),
740 				new MockFileItem("def") });
741 		map.put("bytefilelist", new FileItem[] { new MockFileItem("GHI"),
742 				new MockFileItem("JKL") });
743 		map.put("input", new FileItem[] { new MockFileItem("QQ") });
744 
745 		final FileItemDto dto = new FileItemDto();
746 
747 		final ActionContext actionContext = new MockActionContext(null,
748 				MockAction.class, actionMethod(MockAction.class, "all"));
749 		final ActionErrors errors = new ActionErrorsImpl();
750 		ThreadContext.runInContext(request, response, new Command() {
751 
752 			public void execute(final HttpServletRequest request,
753 					final HttpServletResponse response) throws Exception {
754 				final List<ConversionFailure> conversionFailures = requestParameterBinder
755 						.bind(map, dto, actionContext);
756 				for (final ConversionFailure conversionFailure : conversionFailures) {
757 					final MessageInfo messageInfo = conversionFailure
758 							.getMessageInfo();
759 					final String message = messageInfo
760 							.toMessage(conversionFailure.getFieldName());
761 					errors.add(message);
762 				}
763 			}
764 
765 		});
766 
767 		final String encoding = "UTF-8";
768 		assertNotNull(dto.getFile());
769 		assertEquals("123", new String(dto.getFile().get(), encoding));
770 		assertNotNull(dto.getBytefile());
771 		assertEquals("456", new String(dto.getBytefile(), encoding));
772 		assertNotNull(dto.getBytefiles());
773 		assertEquals(2, dto.getBytefiles().length);
774 		assertEquals("abc", new String(dto.getBytefiles()[0], encoding));
775 		assertEquals("def", new String(dto.getBytefiles()[1], encoding));
776 		assertNotNull(dto.getBytefilelist());
777 		assertEquals(2, dto.getBytefilelist().size());
778 		final Iterator<byte[]> it = dto.getBytefilelist().iterator();
779 		assertEquals("GHI", new String(it.next(), encoding));
780 		assertEquals("JKL", new String(it.next(), encoding));
781 		assertNotNull(dto.getInput());
782 		assertEquals("QQ", new String(getBytes(dto.getInput()), encoding));
783 		assertTrue(errors.isEmpty());
784 	}
785 
786 	public void testBindTypeNoAnnotated() {
787 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
788 		map.put("hasRequestParameter", new Object[] { "abc" });
789 		map.put("noRequestParameter", new Object[] { "def" });
790 		final FormDto2 dto = new FormDto2();
791 		final ActionContext actionContext = new MockActionContext(null,
792 				MockAction.class, actionMethod(MockAction.class, "noAnnotated"));
793 		final List<ConversionFailure> conversionFailures = requestParameterBinder
794 				.bind(map, dto, actionContext);
795 		assertNotNull(dto.getHasRequestParameter());
796 		assertEquals("abc", dto.getHasRequestParameter());
797 		assertNull(dto.getNoRequestParameter());
798 		assertTrue(conversionFailures.isEmpty());
799 	}
800 
801 	public void testBindTypeNoBindingType() {
802 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
803 		map.put("hasRequestParameter", new Object[] { "abc" });
804 		map.put("noRequestParameter", new Object[] { "def" });
805 		final FormDto2 dto = new FormDto2();
806 		final ActionContext actionContext = new MockActionContext(null,
807 				MockAction.class, actionMethod(MockAction.class,
808 						"noBindingType"));
809 		final List<ConversionFailure> conversionFailures = requestParameterBinder
810 				.bind(map, dto, actionContext);
811 		assertNotNull(dto.getHasRequestParameter());
812 		assertEquals("abc", dto.getHasRequestParameter());
813 		assertNotNull(dto.getNoRequestParameter());
814 		assertEquals("def", dto.getNoRequestParameter());
815 		assertTrue(conversionFailures.isEmpty());
816 	}
817 
818 	public void testBindTypeAllProperties() {
819 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
820 		map.put("hasRequestParameter", new Object[] { "abc" });
821 		map.put("noRequestParameter", new Object[] { "def" });
822 		final FormDto2 dto = new FormDto2();
823 		final ActionContext actionContext = new MockActionContext(null,
824 				MockAction.class, actionMethod(MockAction.class, "all"));
825 		final List<ConversionFailure> conversionFailures = requestParameterBinder
826 				.bind(map, dto, actionContext);
827 		assertNotNull(dto.getHasRequestParameter());
828 		assertEquals("abc", dto.getHasRequestParameter());
829 		assertNotNull(dto.getNoRequestParameter());
830 		assertEquals("def", dto.getNoRequestParameter());
831 		assertTrue(conversionFailures.isEmpty());
832 	}
833 
834 	public void testBindTypeOnlySpecifiedProperties() {
835 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
836 		map.put("hasRequestParameter", new Object[] { "abc" });
837 		map.put("noRequestParameter", new Object[] { "def" });
838 		final FormDto2 dto = new FormDto2();
839 		final ActionContext actionContext = new MockActionContext(null,
840 				MockAction.class, actionMethod(MockAction.class, "specified"));
841 		final List<ConversionFailure> conversionFailures = requestParameterBinder
842 				.bind(map, dto, actionContext);
843 		assertNotNull(dto.getHasRequestParameter());
844 		assertEquals("abc", dto.getHasRequestParameter());
845 		assertNull(dto.getNoRequestParameter());
846 		assertTrue(conversionFailures.isEmpty());
847 	}
848 
849 	public void testBindTypeNoAnnotatedOnClass() {
850 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
851 		map.put("hasRequestParameter", new Object[] { "abc" });
852 		map.put("noRequestParameter", new Object[] { "def" });
853 		final FormDto2 dto = new FormDto2();
854 		final ActionContext actionContext = new MockActionContext(null,
855 				MockAction2.class, actionMethod(MockAction2.class,
856 						"noAnnotated"));
857 		final List<ConversionFailure> conversionFailures = requestParameterBinder
858 				.bind(map, dto, actionContext);
859 		assertNotNull(dto.getHasRequestParameter());
860 		assertEquals("abc", dto.getHasRequestParameter());
861 		assertNotNull(dto.getNoRequestParameter());
862 		assertEquals("def", dto.getNoRequestParameter());
863 		assertTrue(conversionFailures.isEmpty());
864 	}
865 
866 	public void testBindTypeOnlySpecifiedPropertiesOnClass() {
867 		final Map<String, Object[]> map = new HashMap<String, Object[]>();
868 		map.put("hasRequestParameter", new Object[] { "abc" });
869 		map.put("noRequestParameter", new Object[] { "def" });
870 		final FormDto2 dto = new FormDto2();
871 		final ActionContext actionContext = new MockActionContext(null,
872 				MockAction2.class, actionMethod(MockAction2.class, "specified"));
873 		final List<ConversionFailure> conversionFailures = requestParameterBinder
874 				.bind(map, dto, actionContext);
875 		assertNotNull(dto.getHasRequestParameter());
876 		assertEquals("abc", dto.getHasRequestParameter());
877 		assertNull(dto.getNoRequestParameter());
878 		assertTrue(conversionFailures.isEmpty());
879 	}
880 
881 	private Method actionMethod(final Class<? extends Action> actionClass,
882 			final String methodName) {
883 		try {
884 			return actionClass.getMethod(methodName);
885 		} catch (final NoSuchMethodException ex) {
886 			throw new RuntimeException();
887 		}
888 	}
889 
890 	private class MockAction extends Action {
891 		@Form(bindingType = RequestParameterBindingType.ALL_PROPERTIES)
892 		public ActionResult all() {
893 			return null;
894 		}
895 
896 		@Form(bindingType = RequestParameterBindingType.ONLY_SPECIFIED_PROPERTIES)
897 		public ActionResult specified() {
898 			return null;
899 		}
900 
901 		@Form
902 		public ActionResult noBindingType() {
903 			return null;
904 		}
905 
906 		public ActionResult noAnnotated() {
907 			return null;
908 		}
909 	}
910 
911 	@Form(bindingType = RequestParameterBindingType.ALL_PROPERTIES)
912 	private class MockAction2 extends Action {
913 		@Form(bindingType = RequestParameterBindingType.ONLY_SPECIFIED_PROPERTIES)
914 		public ActionResult specified() {
915 			return null;
916 		}
917 
918 		public ActionResult noAnnotated() {
919 			return null;
920 		}
921 	}
922 
923 	public static class FormDto2 {
924 		private String hasRequestParameter;
925 
926 		public String getHasRequestParameter() {
927 			return hasRequestParameter;
928 		}
929 
930 		@RequestParameter
931 		public void setHasRequestParameter(final String hasRequestParameter) {
932 			this.hasRequestParameter = hasRequestParameter;
933 		}
934 
935 		private String noRequestParameter;
936 
937 		public String getNoRequestParameter() {
938 			return noRequestParameter;
939 		}
940 
941 		public void setNoRequestParameter(final String noRequestParameter) {
942 			this.noRequestParameter = noRequestParameter;
943 		}
944 	}
945 
946 	public static class FormDto {
947 		private Date date;
948 		private Integer num1;
949 		private Integer[] num2;
950 		private List<String> num3;
951 
952 		public Date getDate() {
953 			return date;
954 		}
955 
956 		public void setDate(final Date date) {
957 			this.date = date;
958 		}
959 
960 		public Integer getNum1() {
961 			return num1;
962 		}
963 
964 		public void setNum1(final Integer num1) {
965 			this.num1 = num1;
966 		}
967 
968 		public Integer[] getNum2() {
969 			return num2;
970 		}
971 
972 		public void setNum2(final Integer[] num2) {
973 			this.num2 = num2;
974 		}
975 
976 		public List<String> getNum3() {
977 			return num3;
978 		}
979 
980 		public void setNum3(final List<String> num3) {
981 			this.num3 = num3;
982 		}
983 	}
984 
985 	public static class ConvertersDto {
986 		private BigDecimal decimal;
987 		private BigDecimal[] decimals;
988 		private BigInteger bigint;
989 		private BigInteger[] bigints;
990 		private Boolean bool1;
991 		private Boolean[] bools1;
992 		private boolean bool2;
993 		private boolean[] bools2;
994 		private Byte byte1;
995 		private Byte[] bytes1;
996 		private byte byte2;
997 		private byte[] bytes2;
998 		private Character char1;
999 		private Character[] chars1;
1000 		private char char2;
1001 		private char[] chars2;
1002 		private Date date;
1003 		private Date[] dates;
1004 		private Double double1;
1005 		private Double[] doubles1;
1006 		private double double2;
1007 		private double[] doubles2;
1008 		private ExEnum en;
1009 		private ExEnum[] ens;
1010 		private Float float1;
1011 		private Float[] floats1;
1012 		private float float2;
1013 		private float[] floats2;
1014 		private Integer int1;
1015 		private Integer[] ints1;
1016 		private int int2;
1017 		private int[] ints2;
1018 		private Long long1;
1019 		private Long[] longs1;
1020 		private long long2;
1021 		private long[] longs2;
1022 		private Short short1;
1023 		private Short[] shorts1;
1024 		private short short2;
1025 		private short[] shorts2;
1026 		private java.sql.Date sqldate;
1027 		private java.sql.Date[] sqldates;
1028 		private Time sqltime;
1029 		private Time[] sqltimes;
1030 		private Timestamp sqltimestamp;
1031 		private Timestamp[] sqltimestamps;
1032 
1033 		public BigDecimal getDecimal() {
1034 			return decimal;
1035 		}
1036 
1037 		public void setDecimal(final BigDecimal decimal) {
1038 			this.decimal = decimal;
1039 		}
1040 
1041 		public BigDecimal[] getDecimals() {
1042 			return decimals;
1043 		}
1044 
1045 		public void setDecimals(final BigDecimal[] decimals) {
1046 			this.decimals = decimals;
1047 		}
1048 
1049 		public BigInteger getBigint() {
1050 			return bigint;
1051 		}
1052 
1053 		public void setBigint(final BigInteger bigint) {
1054 			this.bigint = bigint;
1055 		}
1056 
1057 		public BigInteger[] getBigints() {
1058 			return bigints;
1059 		}
1060 
1061 		public void setBigints(final BigInteger[] bigints) {
1062 			this.bigints = bigints;
1063 		}
1064 
1065 		public Boolean getBool1() {
1066 			return bool1;
1067 		}
1068 
1069 		public void setBool1(final Boolean bool1) {
1070 			this.bool1 = bool1;
1071 		}
1072 
1073 		public Boolean[] getBools1() {
1074 			return bools1;
1075 		}
1076 
1077 		public void setBools1(final Boolean[] bools1) {
1078 			this.bools1 = bools1;
1079 		}
1080 
1081 		public boolean isBool2() {
1082 			return bool2;
1083 		}
1084 
1085 		public void setBool2(final boolean bool2) {
1086 			this.bool2 = bool2;
1087 		}
1088 
1089 		public boolean[] getBools2() {
1090 			return bools2;
1091 		}
1092 
1093 		public void setBools2(final boolean[] bools2) {
1094 			this.bools2 = bools2;
1095 		}
1096 
1097 		public Byte getByte1() {
1098 			return byte1;
1099 		}
1100 
1101 		public void setByte1(final Byte byte1) {
1102 			this.byte1 = byte1;
1103 		}
1104 
1105 		public Byte[] getBytes1() {
1106 			return bytes1;
1107 		}
1108 
1109 		public void setBytes1(final Byte[] bytes1) {
1110 			this.bytes1 = bytes1;
1111 		}
1112 
1113 		public byte getByte2() {
1114 			return byte2;
1115 		}
1116 
1117 		public void setByte2(final byte byte2) {
1118 			this.byte2 = byte2;
1119 		}
1120 
1121 		public byte[] getBytes2() {
1122 			return bytes2;
1123 		}
1124 
1125 		public void setBytes2(final byte[] bytes2) {
1126 			this.bytes2 = bytes2;
1127 		}
1128 
1129 		public Character getChar1() {
1130 			return char1;
1131 		}
1132 
1133 		public void setChar1(final Character char1) {
1134 			this.char1 = char1;
1135 		}
1136 
1137 		public Character[] getChars1() {
1138 			return chars1;
1139 		}
1140 
1141 		public void setChars1(final Character[] chars1) {
1142 			this.chars1 = chars1;
1143 		}
1144 
1145 		public char getChar2() {
1146 			return char2;
1147 		}
1148 
1149 		public void setChar2(final char char2) {
1150 			this.char2 = char2;
1151 		}
1152 
1153 		public char[] getChars2() {
1154 			return chars2;
1155 		}
1156 
1157 		public void setChars2(final char[] chars2) {
1158 			this.chars2 = chars2;
1159 		}
1160 
1161 		public Date getDate() {
1162 			return date;
1163 		}
1164 
1165 		public void setDate(final Date date) {
1166 			this.date = date;
1167 		}
1168 
1169 		public Date[] getDates() {
1170 			return dates;
1171 		}
1172 
1173 		public void setDates(final Date[] dates) {
1174 			this.dates = dates;
1175 		}
1176 
1177 		public Double getDouble1() {
1178 			return double1;
1179 		}
1180 
1181 		public void setDouble1(final Double double1) {
1182 			this.double1 = double1;
1183 		}
1184 
1185 		public Double[] getDoubles1() {
1186 			return doubles1;
1187 		}
1188 
1189 		public void setDoubles1(final Double[] doubles1) {
1190 			this.doubles1 = doubles1;
1191 		}
1192 
1193 		public double getDouble2() {
1194 			return double2;
1195 		}
1196 
1197 		public void setDouble2(final double double2) {
1198 			this.double2 = double2;
1199 		}
1200 
1201 		public double[] getDoubles2() {
1202 			return doubles2;
1203 		}
1204 
1205 		public void setDoubles2(final double[] doubles2) {
1206 			this.doubles2 = doubles2;
1207 		}
1208 
1209 		public ExEnum getEn() {
1210 			return en;
1211 		}
1212 
1213 		public void setEn(final ExEnum en) {
1214 			this.en = en;
1215 		}
1216 
1217 		public ExEnum[] getEns() {
1218 			return ens;
1219 		}
1220 
1221 		public void setEns(final ExEnum[] ens) {
1222 			this.ens = ens;
1223 		}
1224 
1225 		public Float getFloat1() {
1226 			return float1;
1227 		}
1228 
1229 		public void setFloat1(final Float float1) {
1230 			this.float1 = float1;
1231 		}
1232 
1233 		public Float[] getFloats1() {
1234 			return floats1;
1235 		}
1236 
1237 		public void setFloats1(final Float[] floats1) {
1238 			this.floats1 = floats1;
1239 		}
1240 
1241 		public float getFloat2() {
1242 			return float2;
1243 		}
1244 
1245 		public void setFloat2(final float float2) {
1246 			this.float2 = float2;
1247 		}
1248 
1249 		public float[] getFloats2() {
1250 			return floats2;
1251 		}
1252 
1253 		public void setFloats2(final float[] floats2) {
1254 			this.floats2 = floats2;
1255 		}
1256 
1257 		public Integer getInt1() {
1258 			return int1;
1259 		}
1260 
1261 		public void setInt1(final Integer int1) {
1262 			this.int1 = int1;
1263 		}
1264 
1265 		public Integer[] getInts1() {
1266 			return ints1;
1267 		}
1268 
1269 		public void setInts1(final Integer[] ints1) {
1270 			this.ints1 = ints1;
1271 		}
1272 
1273 		public int getInt2() {
1274 			return int2;
1275 		}
1276 
1277 		public void setInt2(final int int2) {
1278 			this.int2 = int2;
1279 		}
1280 
1281 		public int[] getInts2() {
1282 			return ints2;
1283 		}
1284 
1285 		public void setInts2(final int[] ints2) {
1286 			this.ints2 = ints2;
1287 		}
1288 
1289 		public Long getLong1() {
1290 			return long1;
1291 		}
1292 
1293 		public void setLong1(final Long long1) {
1294 			this.long1 = long1;
1295 		}
1296 
1297 		public Long[] getLongs1() {
1298 			return longs1;
1299 		}
1300 
1301 		public void setLongs1(final Long[] longs1) {
1302 			this.longs1 = longs1;
1303 		}
1304 
1305 		public long getLong2() {
1306 			return long2;
1307 		}
1308 
1309 		public void setLong2(final long long2) {
1310 			this.long2 = long2;
1311 		}
1312 
1313 		public long[] getLongs2() {
1314 			return longs2;
1315 		}
1316 
1317 		public void setLongs2(final long[] longs2) {
1318 			this.longs2 = longs2;
1319 		}
1320 
1321 		public Short getShort1() {
1322 			return short1;
1323 		}
1324 
1325 		public void setShort1(final Short short1) {
1326 			this.short1 = short1;
1327 		}
1328 
1329 		public Short[] getShorts1() {
1330 			return shorts1;
1331 		}
1332 
1333 		public void setShorts1(final Short[] shorts1) {
1334 			this.shorts1 = shorts1;
1335 		}
1336 
1337 		public short getShort2() {
1338 			return short2;
1339 		}
1340 
1341 		public void setShort2(final short short2) {
1342 			this.short2 = short2;
1343 		}
1344 
1345 		public short[] getShorts2() {
1346 			return shorts2;
1347 		}
1348 
1349 		public void setShorts2(final short[] shorts2) {
1350 			this.shorts2 = shorts2;
1351 		}
1352 
1353 		public java.sql.Date getSqldate() {
1354 			return sqldate;
1355 		}
1356 
1357 		public void setSqldate(final java.sql.Date sqldate) {
1358 			this.sqldate = sqldate;
1359 		}
1360 
1361 		public java.sql.Date[] getSqldates() {
1362 			return sqldates;
1363 		}
1364 
1365 		public void setSqldates(final java.sql.Date[] sqldates) {
1366 			this.sqldates = sqldates;
1367 		}
1368 
1369 		public Time getSqltime() {
1370 			return sqltime;
1371 		}
1372 
1373 		public void setSqltime(final Time sqltime) {
1374 			this.sqltime = sqltime;
1375 		}
1376 
1377 		public Time[] getSqltimes() {
1378 			return sqltimes;
1379 		}
1380 
1381 		public void setSqltimes(final Time[] sqltimes) {
1382 			this.sqltimes = sqltimes;
1383 		}
1384 
1385 		public Timestamp getSqltimestamp() {
1386 			return sqltimestamp;
1387 		}
1388 
1389 		public void setSqltimestamp(final Timestamp sqltimestamp) {
1390 			this.sqltimestamp = sqltimestamp;
1391 		}
1392 
1393 		public Timestamp[] getSqltimestamps() {
1394 			return sqltimestamps;
1395 		}
1396 
1397 		public void setSqltimestamps(final Timestamp[] sqltimestamps) {
1398 			this.sqltimestamps = sqltimestamps;
1399 		}
1400 	}
1401 
1402 	public enum ExEnum {
1403 		VALUE1, VALUE2, VALUE3;
1404 	}
1405 
1406 	public static class FileItemDto {
1407 		private FileItem file;
1408 		private byte[] bytefile;
1409 		private byte[][] bytefiles;
1410 		private Set<byte[]> bytefilelist;
1411 		private InputStream input;
1412 
1413 		public FileItem getFile() {
1414 			return file;
1415 		}
1416 
1417 		public void setFile(final FileItem file) {
1418 			this.file = file;
1419 		}
1420 
1421 		public byte[] getBytefile() {
1422 			return bytefile;
1423 		}
1424 
1425 		public void setBytefile(final byte[] bytefile) {
1426 			this.bytefile = bytefile;
1427 		}
1428 
1429 		public byte[][] getBytefiles() {
1430 			return bytefiles;
1431 		}
1432 
1433 		public void setBytefiles(final byte[][] bytefiles) {
1434 			this.bytefiles = bytefiles;
1435 		}
1436 
1437 		public Set<byte[]> getBytefilelist() {
1438 			return bytefilelist;
1439 		}
1440 
1441 		public void setBytefilelist(final Set<byte[]> bytefilelist) {
1442 			this.bytefilelist = bytefilelist;
1443 		}
1444 
1445 		public InputStream getInput() {
1446 			return input;
1447 		}
1448 
1449 		public void setInput(final InputStream input) {
1450 			this.input = input;
1451 		}
1452 	}
1453 
1454 	private static class MockFileItem implements FileItem {
1455 
1456 		private static final long serialVersionUID = 1L;
1457 
1458 		private final String name;
1459 
1460 		public MockFileItem(final String name) {
1461 			this.name = name;
1462 		}
1463 
1464 		public void delete() {
1465 		}
1466 
1467 		public byte[] get() {
1468 			try {
1469 				return name.getBytes("UTF-8");
1470 			} catch (final UnsupportedEncodingException e) {
1471 				throw new RuntimeException();
1472 			}
1473 		}
1474 
1475 		public String getContentType() {
1476 			return null;
1477 		}
1478 
1479 		public String getFieldName() {
1480 			return null;
1481 		}
1482 
1483 		public InputStream getInputStream() throws IOException {
1484 			return new ByteArrayInputStream(get());
1485 		}
1486 
1487 		public String getName() {
1488 			return this.name;
1489 		}
1490 
1491 		public OutputStream getOutputStream() throws IOException {
1492 			return null;
1493 		}
1494 
1495 		public long getSize() {
1496 			return 0;
1497 		}
1498 
1499 		public String getString() {
1500 			return null;
1501 		}
1502 
1503 		public String getString(final String encoding)
1504 				throws UnsupportedEncodingException {
1505 			return null;
1506 		}
1507 
1508 		public boolean isFormField() {
1509 			return false;
1510 		}
1511 
1512 		public boolean isInMemory() {
1513 			return false;
1514 		}
1515 
1516 		public void setFieldName(final String name) {
1517 		}
1518 
1519 		public void setFormField(final boolean state) {
1520 		}
1521 
1522 		public void write(final File file) throws Exception {
1523 		}
1524 	}
1525 
1526 	private static final Map<Integer, Integer> MONTHS;
1527 	static {
1528 		final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
1529 		map.put(1, Calendar.JANUARY);
1530 		map.put(2, Calendar.FEBRUARY);
1531 		map.put(3, Calendar.MARCH);
1532 		map.put(4, Calendar.APRIL);
1533 		map.put(5, Calendar.MAY);
1534 		map.put(6, Calendar.JUNE);
1535 		map.put(7, Calendar.JULY);
1536 		map.put(8, Calendar.AUGUST);
1537 		map.put(9, Calendar.SEPTEMBER);
1538 		map.put(10, Calendar.OCTOBER);
1539 		map.put(11, Calendar.NOVEMBER);
1540 		map.put(12, Calendar.DECEMBER);
1541 		MONTHS = Collections.unmodifiableMap(map);
1542 	}
1543 
1544 	private static long fromDateToMillis(final int year, final int month,
1545 			final int date) {
1546 		final Calendar c = Calendar.getInstance();
1547 		c.clear();
1548 		c.set(Calendar.YEAR, year);
1549 		c.set(Calendar.MONTH, MONTHS.get(month));
1550 		c.set(Calendar.DATE, date);
1551 		return c.getTimeInMillis();
1552 	}
1553 
1554 	private static long fromTimeToMillis(final int hour, final int minute,
1555 			final int second) {
1556 		final Calendar c = Calendar.getInstance();
1557 		c.clear();
1558 		c.set(Calendar.HOUR, hour);
1559 		c.set(Calendar.MINUTE, minute);
1560 		c.set(Calendar.SECOND, second);
1561 		return c.getTimeInMillis();
1562 	}
1563 
1564 	private static long fromTimestampToMillis(final int year, final int month,
1565 			final int date, final int hour, final int minute, final int second) {
1566 		final Calendar c = Calendar.getInstance();
1567 		c.clear();
1568 		c.set(Calendar.YEAR, year);
1569 		c.set(Calendar.MONTH, MONTHS.get(month));
1570 		c.set(Calendar.DATE, date);
1571 		c.set(Calendar.HOUR, hour);
1572 		c.set(Calendar.MINUTE, minute);
1573 		c.set(Calendar.SECOND, second);
1574 		return c.getTimeInMillis();
1575 	}
1576 
1577 	private static final byte[] getBytes(final InputStream is) {
1578 		byte[] bytes = null;
1579 		final byte[] buf = new byte[8192];
1580 		try {
1581 			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
1582 			int n = 0;
1583 			while ((n = is.read(buf, 0, buf.length)) != -1) {
1584 				baos.write(buf, 0, n);
1585 			}
1586 			bytes = baos.toByteArray();
1587 		} catch (final IOException e) {
1588 			throw new RuntimeException(e);
1589 		} finally {
1590 			if (is != null) {
1591 				try {
1592 					is.close();
1593 				} catch (final IOException e) {
1594 				}
1595 			}
1596 		}
1597 		return bytes;
1598 	}
1599 
1600 	public interface SeparationAction {
1601 
1602 	}
1603 
1604 	public static class SeparationActionImpl implements SeparationAction {
1605 
1606 	}
1607 
1608 	public static class AnnotatedDto {
1609 
1610 		private String normal;
1611 
1612 		private String specifiedName;
1613 
1614 		private String specifiedConverter;
1615 
1616 		private String specifiedNameAndConverter;
1617 
1618 		public String getNormal() {
1619 			return normal;
1620 		}
1621 
1622 		@RequestParameter
1623 		public void setNormal(final String normal) {
1624 			this.normal = normal;
1625 		}
1626 
1627 		public String getSpecifiedName() {
1628 			return specifiedName;
1629 		}
1630 
1631 		@RequestParameter(name = "foo")
1632 		public void setSpecifiedName(final String specifiedName) {
1633 			this.specifiedName = specifiedName;
1634 		}
1635 
1636 		public String getSpecifiedConverter() {
1637 			return specifiedConverter;
1638 		}
1639 
1640 		@RequestParameter(converter = BraceConverter.class)
1641 		public void setSpecifiedConverter(final String specifiedConverter) {
1642 			this.specifiedConverter = specifiedConverter;
1643 		}
1644 
1645 		public String getSpecifiedNameAndConverter() {
1646 			return specifiedNameAndConverter;
1647 		}
1648 
1649 		@RequestParameter(name = "bar", converter = BraceConverter.class)
1650 		public void setSpecifiedNameAndConverter(
1651 				final String specifiedNameAndConverter) {
1652 			this.specifiedNameAndConverter = specifiedNameAndConverter;
1653 		}
1654 
1655 	}
1656 
1657 	public static class BraceConverter implements Converter {
1658 
1659 		public Object convertToObject(final Object value,
1660 				final Class<?> objectType, final ConversionHelper helper) {
1661 			if (value == null) {
1662 				return null;
1663 			}
1664 			return "{" + value + "}";
1665 		}
1666 
1667 		public String convertToString(final Object value,
1668 				final ConversionHelper helper) {
1669 			if (value == null) {
1670 				return null;
1671 			}
1672 			return value.toString().substring(1, value.toString().length() - 1);
1673 		}
1674 
1675 		public Class<?> getObjectType() {
1676 			return String.class;
1677 		}
1678 
1679 		public boolean canConvert(final Class<?> parameterType,
1680 				final Class<?> objectType) {
1681 			return false;
1682 		}
1683 
1684 	}
1685 
1686 }