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.io.IOException;
19 import java.io.UnsupportedEncodingException;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.LinkedHashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26
27 import javax.servlet.http.HttpServletRequest;
28
29 import org.apache.commons.fileupload.FileItem;
30 import org.apache.commons.fileupload.FileUpload;
31 import org.apache.commons.fileupload.FileUploadException;
32 import org.apache.commons.fileupload.RequestContext;
33 import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
34 import org.apache.commons.fileupload.servlet.ServletFileUpload;
35 import org.seasar.cubby.controller.RequestParser;
36 import org.seasar.cubby.exception.FileUploadRuntimeException;
37 import org.seasar.framework.container.S2Container;
38 import org.seasar.framework.exception.IORuntimeException;
39 import org.seasar.framework.util.StringUtil;
40
41
42
43
44
45
46
47
48
49
50
51
52 public class MultipartRequestParserImpl implements RequestParser {
53
54
55 private final S2Container container;
56
57
58
59
60
61
62
63 public MultipartRequestParserImpl(final S2Container container) {
64 this.container = container;
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 @SuppressWarnings("unchecked")
96 public Map<String, Object[]> getParameterMap(
97 final HttpServletRequest request) {
98 final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>(
99 request.getParameterMap());
100 if (ServletFileUpload.isMultipartContent(request)) {
101 final S2Container root = container.getRoot();
102 final FileUpload fileUpload = (FileUpload) root
103 .getComponent(FileUpload.class);
104 final RequestContext requestContext = (RequestContext) root
105 .getComponent(RequestContext.class);
106 parameterMap.putAll(this.getMultipartParameterMap(fileUpload,
107 requestContext));
108 }
109 return parameterMap;
110 }
111
112 @SuppressWarnings("unchecked")
113 Map<String, Object[]> getMultipartParameterMap(final FileUpload fileUpload,
114 final RequestContext requestContext) {
115 try {
116 final String encoding = requestContext.getCharacterEncoding();
117 fileUpload.setHeaderEncoding(encoding);
118 final List<FileItem> items = fileUpload
119 .parseRequest(requestContext);
120
121
122 final Map<String, Object[]> parameterMap = toParameterMap(encoding,
123 items);
124
125 return parameterMap;
126 } catch (final FileUploadException e) {
127 final String messageCode;
128 final Object[] args;
129 if (e instanceof SizeLimitExceededException) {
130 final SizeLimitExceededException sle = (SizeLimitExceededException) e;
131 messageCode = "ECUB0202";
132 args = new Object[] { sle.getPermittedSize(), sle.getActualSize() };
133 } else {
134 messageCode = "ECUB0201";
135 args = new Object[] { e };
136 }
137 throw new FileUploadRuntimeException(messageCode, args, e);
138 } catch (final IOException e) {
139 throw new IORuntimeException(e);
140 }
141 }
142
143 Map<String, Object[]> toParameterMap(final String encoding,
144 final List<FileItem> items) throws UnsupportedEncodingException {
145 final Map<String, List<Object>> valueListParameterMap = new LinkedHashMap<String, List<Object>>();
146 for (final FileItem item : items) {
147 final Object value;
148 if (item.isFormField()) {
149 value = item.getString(encoding);
150 } else {
151 if (StringUtil.isEmpty(item.getName()) || item.getSize() == 0) {
152
153 value = null;
154 } else {
155 value = item;
156 }
157 }
158 final List<Object> values;
159 if (valueListParameterMap.containsKey(item.getFieldName())) {
160 values = valueListParameterMap.get(item.getFieldName());
161 } else {
162 values = new ArrayList<Object>();
163 valueListParameterMap.put(item.getFieldName(), values);
164 }
165 values.add(value);
166 }
167
168 final Map<String, Object[]> parameterMap = fromValueListToValueArray(valueListParameterMap);
169 return parameterMap;
170 }
171
172 Map<String, Object[]> fromValueListToValueArray(
173 final Map<String, List<Object>> collectParameterMap) {
174
175 final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>();
176 for (final Entry<String, List<Object>> entry : collectParameterMap
177 .entrySet()) {
178 final List<Object> values = entry.getValue();
179 final Object[] valueArray;
180 if (values.get(0) instanceof String) {
181 valueArray = new String[values.size()];
182 } else {
183 valueArray = new FileItem[values.size()];
184 }
185 parameterMap.put(entry.getKey(), values.toArray(valueArray));
186 }
187 return parameterMap;
188 }
189
190 }