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  
11  import javax.servlet.http.HttpServletRequest;
12  
13  import org.apache.commons.fileupload.FileItem;
14  import org.apache.commons.fileupload.FileUpload;
15  import org.apache.commons.fileupload.FileUploadException;
16  import org.apache.commons.fileupload.RequestContext;
17  import org.apache.commons.fileupload.servlet.ServletFileUpload;
18  import org.seasar.cubby.controller.RequestParser;
19  import org.seasar.cubby.exception.FileUploadRuntimeException;
20  import org.seasar.framework.container.SingletonS2Container;
21  import org.seasar.framework.exception.IORuntimeException;
22  import org.seasar.framework.util.StringUtil;
23  
24  public class MultipartRequestParserImpl implements RequestParser {
25  
26  	@SuppressWarnings("unchecked")
27  	public Map<String, Object> getParameterMap(final HttpServletRequest request) {
28  		Map<String, Object> parameterMap;
29  		if (ServletFileUpload.isMultipartContent(request)) {
30  			final FileUpload fileUpload = SingletonS2Container
31  					.getComponent(FileUpload.class);
32  			final RequestContext requestContext = SingletonS2Container
33  					.getComponent(RequestContext.class);
34  			parameterMap = this.getMultipartParameterMap(fileUpload,
35  					requestContext);
36  		} else {
37  			parameterMap = request.getParameterMap();
38  		}
39  		return parameterMap;
40  	}
41  
42  	@SuppressWarnings("unchecked")
43  	private Map<String, Object> getMultipartParameterMap(
44  			final FileUpload fileUpload, final RequestContext requestContext) {
45  		try {
46  			final String encoding = requestContext.getCharacterEncoding();
47  			fileUpload.setHeaderEncoding(encoding);
48  			final List<FileItem> items = fileUpload
49  					.parseRequest(requestContext);
50  
51  			// Fieldごとにパラメータを集める
52  			final Map<String, Object> parameterMap = toParameterMap(encoding,
53  					items);
54  
55  			return parameterMap;
56  		} catch (final FileUploadException e) {
57  			throw new FileUploadRuntimeException(e);
58  		} catch (final IOException e) {
59  			throw new IORuntimeException(e);
60  		}
61  	}
62  
63  	private Map<String, Object> toParameterMap(final String encoding,
64  			final List<FileItem> items) throws UnsupportedEncodingException {
65  		final Map<String, List<Object>> valueListParameterMap = new LinkedHashMap<String, List<Object>>();
66  		for (final FileItem item : items) {
67  			Object value = null;
68  			if (item.isFormField()) {
69  				value = item.getString(encoding);
70  			} else {
71  				if (StringUtil.isEmpty(item.getName()) || item.getSize() == 0) {
72  					// ファイル名無し、あるいは0バイトのファイル
73  					value = null;
74  				} else {
75  					value = item;
76  				}
77  			}
78  			List<Object> values = null;
79  			if (valueListParameterMap.containsKey(item.getFieldName())) {
80  				values = valueListParameterMap.get(item.getFieldName());
81  			} else {
82  				values = new ArrayList<Object>();
83  				valueListParameterMap.put(item.getFieldName(), values);
84  			}
85  			values.add(value);
86  		}
87  
88  		final Map<String, Object> parameterMap = fromValueListToValueArray(valueListParameterMap);
89  		return parameterMap;
90  	}
91  
92  	private Map<String, Object> fromValueListToValueArray(
93  			final Map<String, List<Object>> collectParameterMap) {
94  		// 配列でパラメータMapを構築
95  		final Map<String, Object> parameterMap = new HashMap<String, Object>();
96  		for (final String key : collectParameterMap.keySet()) {
97  			final List<?> values = collectParameterMap.get(key);
98  			Object[] valueArray = null;
99  			if (values.get(0) instanceof String) {
100 				valueArray = new String[values.size()];
101 			} else {
102 				valueArray = new FileItem[values.size()];
103 			}
104 			parameterMap.put(key, values.toArray(valueArray));
105 		}
106 		return parameterMap;
107 	}
108 
109 }