View Javadoc

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  			// Fieldごとにパラメータを集める
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  					// ファイル名無し、あるいは0バイトのファイル
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 		// 配列でパラメータMapを構築
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 }