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 static final int DEFAULT_PRIORITY = DefaultRequestParserImpl.DEFAULT_PRIORITY - 1;
56
57
58 private final S2Container container;
59
60
61 private int priority = DEFAULT_PRIORITY;
62
63
64
65
66
67
68
69 public MultipartRequestParserImpl(final S2Container container) {
70 this.container = container;
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
96
97
98
99
100
101 @SuppressWarnings("unchecked")
102 public Map<String, Object[]> getParameterMap(
103 final HttpServletRequest request) {
104 final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>(
105 request.getParameterMap());
106 if (ServletFileUpload.isMultipartContent(request)) {
107 final S2Container root = container.getRoot();
108 final FileUpload fileUpload = (FileUpload) root
109 .getComponent(FileUpload.class);
110 final RequestContext requestContext = (RequestContext) root
111 .getComponent(RequestContext.class);
112 parameterMap.putAll(this.getMultipartParameterMap(fileUpload,
113 requestContext));
114 }
115 return parameterMap;
116 }
117
118 @SuppressWarnings("unchecked")
119 Map<String, Object[]> getMultipartParameterMap(final FileUpload fileUpload,
120 final RequestContext requestContext) {
121 try {
122 final String encoding = requestContext.getCharacterEncoding();
123 fileUpload.setHeaderEncoding(encoding);
124 final List<FileItem> items = fileUpload
125 .parseRequest(requestContext);
126
127
128 final Map<String, Object[]> parameterMap = toParameterMap(encoding,
129 items);
130
131 return parameterMap;
132 } catch (final FileUploadException e) {
133 final String messageCode;
134 final Object[] args;
135 if (e instanceof SizeLimitExceededException) {
136 final SizeLimitExceededException sle = (SizeLimitExceededException) e;
137 messageCode = "ECUB0202";
138 args = new Object[] { sle.getPermittedSize(),
139 sle.getActualSize() };
140 } else {
141 messageCode = "ECUB0201";
142 args = new Object[] { e };
143 }
144 throw new FileUploadRuntimeException(messageCode, args, e);
145 } catch (final IOException e) {
146 throw new IORuntimeException(e);
147 }
148 }
149
150 Map<String, Object[]> toParameterMap(final String encoding,
151 final List<FileItem> items) throws UnsupportedEncodingException {
152 final Map<String, List<Object>> valueListParameterMap = new LinkedHashMap<String, List<Object>>();
153 for (final FileItem item : items) {
154 final Object value;
155 if (item.isFormField()) {
156 value = item.getString(encoding);
157 } else {
158 if (StringUtil.isEmpty(item.getName()) || item.getSize() == 0) {
159
160 value = null;
161 } else {
162 value = item;
163 }
164 }
165 final List<Object> values;
166 if (valueListParameterMap.containsKey(item.getFieldName())) {
167 values = valueListParameterMap.get(item.getFieldName());
168 } else {
169 values = new ArrayList<Object>();
170 valueListParameterMap.put(item.getFieldName(), values);
171 }
172 values.add(value);
173 }
174
175 final Map<String, Object[]> parameterMap = fromValueListToValueArray(valueListParameterMap);
176 return parameterMap;
177 }
178
179 Map<String, Object[]> fromValueListToValueArray(
180 final Map<String, List<Object>> collectParameterMap) {
181
182 final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>();
183 for (final Entry<String, List<Object>> entry : collectParameterMap
184 .entrySet()) {
185 final List<Object> values = entry.getValue();
186 final Object[] valueArray;
187 if (values.get(0) instanceof String) {
188 valueArray = new String[values.size()];
189 } else {
190 valueArray = new FileItem[values.size()];
191 }
192 parameterMap.put(entry.getKey(), values.toArray(valueArray));
193 }
194 return parameterMap;
195 }
196
197
198
199
200 public boolean isParsable(final HttpServletRequest request) {
201 final S2Container root = container.getRoot();
202 if (root.hasComponentDef(RequestContext.class)) {
203 final RequestContext requestContext = (RequestContext) root
204 .getComponent(RequestContext.class);
205 return FileUpload.isMultipartContent(requestContext);
206 }
207 return false;
208 }
209
210
211
212
213
214
215
216 public int getPriority() {
217 return priority;
218 }
219
220
221
222
223
224
225
226 public void setPriority(final int priority) {
227 this.priority = priority;
228 }
229
230 }