1 package org.seasar.cubby.controller.impl;
2
3 import java.io.IOException;
4 import java.io.UnsupportedEncodingException;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.LinkedHashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Map.Entry;
11
12 import javax.servlet.http.HttpServletRequest;
13
14 import org.apache.commons.fileupload.FileItem;
15 import org.apache.commons.fileupload.FileUpload;
16 import org.apache.commons.fileupload.FileUploadException;
17 import org.apache.commons.fileupload.RequestContext;
18 import org.apache.commons.fileupload.servlet.ServletFileUpload;
19 import org.seasar.cubby.controller.RequestParser;
20 import org.seasar.cubby.exception.FileUploadRuntimeException;
21 import org.seasar.framework.container.S2Container;
22 import org.seasar.framework.exception.IORuntimeException;
23 import org.seasar.framework.util.StringUtil;
24
25 public class MultipartRequestParserImpl implements RequestParser {
26
27 private final S2Container container;
28
29 public MultipartRequestParserImpl(final S2Container container) {
30 this.container = container;
31 }
32
33 @SuppressWarnings("unchecked")
34 public Map<String, Object> getParameterMap(final HttpServletRequest request) {
35 Map<String, Object> parameterMap;
36 if (ServletFileUpload.isMultipartContent(request)) {
37 final S2Container root = container.getRoot();
38 final FileUpload fileUpload = (FileUpload) root
39 .getComponent(FileUpload.class);
40 final RequestContext requestContext = (RequestContext) root
41 .getComponent(RequestContext.class);
42 parameterMap = this.getMultipartParameterMap(fileUpload,
43 requestContext);
44 } else {
45 parameterMap = request.getParameterMap();
46 }
47 return parameterMap;
48 }
49
50 @SuppressWarnings("unchecked")
51 private Map<String, Object> getMultipartParameterMap(
52 final FileUpload fileUpload, final RequestContext requestContext) {
53 try {
54 final String encoding = requestContext.getCharacterEncoding();
55 fileUpload.setHeaderEncoding(encoding);
56 final List<FileItem> items = fileUpload
57 .parseRequest(requestContext);
58
59
60 final Map<String, Object> parameterMap = toParameterMap(encoding,
61 items);
62
63 return parameterMap;
64 } catch (final FileUploadException e) {
65 throw new FileUploadRuntimeException(e);
66 } catch (final IOException e) {
67 throw new IORuntimeException(e);
68 }
69 }
70
71 private Map<String, Object> toParameterMap(final String encoding,
72 final List<FileItem> items) throws UnsupportedEncodingException {
73 final Map<String, List<Object>> valueListParameterMap = new LinkedHashMap<String, List<Object>>();
74 for (final FileItem item : items) {
75 final Object value;
76 if (item.isFormField()) {
77 value = item.getString(encoding);
78 } else {
79 if (StringUtil.isEmpty(item.getName()) || item.getSize() == 0) {
80
81 value = null;
82 } else {
83 value = item;
84 }
85 }
86 final List<Object> values;
87 if (valueListParameterMap.containsKey(item.getFieldName())) {
88 values = valueListParameterMap.get(item.getFieldName());
89 } else {
90 values = new ArrayList<Object>();
91 valueListParameterMap.put(item.getFieldName(), values);
92 }
93 values.add(value);
94 }
95
96 final Map<String, Object> parameterMap = fromValueListToValueArray(valueListParameterMap);
97 return parameterMap;
98 }
99
100 private Map<String, Object> fromValueListToValueArray(
101 final Map<String, List<Object>> collectParameterMap) {
102
103 final Map<String, Object> parameterMap = new HashMap<String, Object>();
104 for (final Entry<String, List<Object>> entry : collectParameterMap
105 .entrySet()) {
106 final List<Object> values = entry.getValue();
107 final Object[] valueArray;
108 if (values.get(0) instanceof String) {
109 valueArray = new String[values.size()];
110 } else {
111 valueArray = new FileItem[values.size()];
112 }
113 parameterMap.put(entry.getKey(), values.toArray(valueArray));
114 }
115 return parameterMap;
116 }
117
118 }