View Javadoc

1   /*
2    * Copyright 2004-2008 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
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.servlet.ServletFileUpload;
34  import org.seasar.cubby.controller.RequestParser;
35  import org.seasar.cubby.exception.FileUploadRuntimeException;
36  import org.seasar.framework.container.S2Container;
37  import org.seasar.framework.exception.IORuntimeException;
38  import org.seasar.framework.util.StringUtil;
39  
40  /**
41   * 
42   * @author baba
43   * 
44   */
45  public class MultipartRequestParserImpl implements RequestParser {
46  
47  	private final S2Container container;
48  
49  	public MultipartRequestParserImpl(final S2Container container) {
50  		this.container = container;
51  	}
52  
53  	@SuppressWarnings("unchecked")
54  	public Map<String, Object[]> getParameterMap(
55  			final HttpServletRequest request) {
56  		final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>(
57  				request.getParameterMap());
58  		if (ServletFileUpload.isMultipartContent(request)) {
59  			final S2Container root = container.getRoot();
60  			final FileUpload fileUpload = (FileUpload) root
61  					.getComponent(FileUpload.class);
62  			final RequestContext requestContext = (RequestContext) root
63  					.getComponent(RequestContext.class);
64  			parameterMap.putAll(this.getMultipartParameterMap(fileUpload,
65  					requestContext));
66  		}
67  		return parameterMap;
68  	}
69  
70  	@SuppressWarnings("unchecked")
71  	Map<String, Object[]> getMultipartParameterMap(final FileUpload fileUpload,
72  			final RequestContext requestContext) {
73  		try {
74  			final String encoding = requestContext.getCharacterEncoding();
75  			fileUpload.setHeaderEncoding(encoding);
76  			final List<FileItem> items = fileUpload
77  					.parseRequest(requestContext);
78  
79  			// Fieldごとにパラメータを集める
80  			final Map<String, Object[]> parameterMap = toParameterMap(encoding,
81  					items);
82  
83  			return parameterMap;
84  		} catch (final FileUploadException e) {
85  			throw new FileUploadRuntimeException(e);
86  		} catch (final IOException e) {
87  			throw new IORuntimeException(e);
88  		}
89  	}
90  
91  	Map<String, Object[]> toParameterMap(final String encoding,
92  			final List<FileItem> items) throws UnsupportedEncodingException {
93  		final Map<String, List<Object>> valueListParameterMap = new LinkedHashMap<String, List<Object>>();
94  		for (final FileItem item : items) {
95  			final Object value;
96  			if (item.isFormField()) {
97  				value = item.getString(encoding);
98  			} else {
99  				if (StringUtil.isEmpty(item.getName()) || item.getSize() == 0) {
100 					// ファイル名無し、あるいは0バイトのファイル
101 					value = null;
102 				} else {
103 					value = item;
104 				}
105 			}
106 			final List<Object> values;
107 			if (valueListParameterMap.containsKey(item.getFieldName())) {
108 				values = valueListParameterMap.get(item.getFieldName());
109 			} else {
110 				values = new ArrayList<Object>();
111 				valueListParameterMap.put(item.getFieldName(), values);
112 			}
113 			values.add(value);
114 		}
115 
116 		final Map<String, Object[]> parameterMap = fromValueListToValueArray(valueListParameterMap);
117 		return parameterMap;
118 	}
119 
120 	Map<String, Object[]> fromValueListToValueArray(
121 			final Map<String, List<Object>> collectParameterMap) {
122 		// 配列でパラメータMapを構築
123 		final Map<String, Object[]> parameterMap = new HashMap<String, Object[]>();
124 		for (final Entry<String, List<Object>> entry : collectParameterMap
125 				.entrySet()) {
126 			final List<Object> values = entry.getValue();
127 			final Object[] valueArray;
128 			if (values.get(0) instanceof String) {
129 				valueArray = new String[values.size()];
130 			} else {
131 				valueArray = new FileItem[values.size()];
132 			}
133 			parameterMap.put(entry.getKey(), values.toArray(valueArray));
134 		}
135 		return parameterMap;
136 	}
137 
138 }