001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.multipart.support;
018
019import java.util.Collections;
020import java.util.Enumeration;
021import java.util.LinkedHashMap;
022import java.util.LinkedHashSet;
023import java.util.Map;
024import java.util.Set;
025import javax.servlet.http.HttpServletRequest;
026
027import org.springframework.http.HttpHeaders;
028import org.springframework.util.MultiValueMap;
029import org.springframework.web.multipart.MultipartFile;
030
031/**
032 * Default implementation of the
033 * {@link org.springframework.web.multipart.MultipartHttpServletRequest}
034 * interface. Provides management of pre-generated parameter values.
035 *
036 * <p>Used by {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
037 *
038 * @author Trevor D. Cook
039 * @author Juergen Hoeller
040 * @author Arjen Poutsma
041 * @since 29.09.2003
042 * @see org.springframework.web.multipart.MultipartResolver
043 */
044public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
045
046        private static final String CONTENT_TYPE = "Content-Type";
047
048        private Map<String, String[]> multipartParameters;
049
050        private Map<String, String> multipartParameterContentTypes;
051
052
053        /**
054         * Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
055         * @param request the servlet request to wrap
056         * @param mpFiles a map of the multipart files
057         * @param mpParams a map of the parameters to expose,
058         * with Strings as keys and String arrays as values
059         */
060        public DefaultMultipartHttpServletRequest(HttpServletRequest request, MultiValueMap<String, MultipartFile> mpFiles,
061                        Map<String, String[]> mpParams, Map<String, String> mpParamContentTypes) {
062
063                super(request);
064                setMultipartFiles(mpFiles);
065                setMultipartParameters(mpParams);
066                setMultipartParameterContentTypes(mpParamContentTypes);
067        }
068
069        /**
070         * Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
071         * @param request the servlet request to wrap
072         */
073        public DefaultMultipartHttpServletRequest(HttpServletRequest request) {
074                super(request);
075        }
076
077
078        @Override
079        public String getParameter(String name) {
080                String[] values = getMultipartParameters().get(name);
081                if (values != null) {
082                        return (values.length > 0 ? values[0] : null);
083                }
084                return super.getParameter(name);
085        }
086
087        @Override
088        public String[] getParameterValues(String name) {
089                String[] values = getMultipartParameters().get(name);
090                if (values != null) {
091                        return values;
092                }
093                return super.getParameterValues(name);
094        }
095
096        @Override
097        public Enumeration<String> getParameterNames() {
098                Map<String, String[]> multipartParameters = getMultipartParameters();
099                if (multipartParameters.isEmpty()) {
100                        return super.getParameterNames();
101                }
102
103                Set<String> paramNames = new LinkedHashSet<String>();
104                Enumeration<String> paramEnum = super.getParameterNames();
105                while (paramEnum.hasMoreElements()) {
106                        paramNames.add(paramEnum.nextElement());
107                }
108                paramNames.addAll(multipartParameters.keySet());
109                return Collections.enumeration(paramNames);
110        }
111
112        @Override
113        public Map<String, String[]> getParameterMap() {
114                Map<String, String[]> multipartParameters = getMultipartParameters();
115                if (multipartParameters.isEmpty()) {
116                        return super.getParameterMap();
117                }
118
119                Map<String, String[]> paramMap = new LinkedHashMap<String, String[]>();
120                paramMap.putAll(super.getParameterMap());
121                paramMap.putAll(multipartParameters);
122                return paramMap;
123        }
124
125        @Override
126        public String getMultipartContentType(String paramOrFileName) {
127                MultipartFile file = getFile(paramOrFileName);
128                if (file != null) {
129                        return file.getContentType();
130                }
131                else {
132                        return getMultipartParameterContentTypes().get(paramOrFileName);
133                }
134        }
135
136        @Override
137        public HttpHeaders getMultipartHeaders(String paramOrFileName) {
138                String contentType = getMultipartContentType(paramOrFileName);
139                if (contentType != null) {
140                        HttpHeaders headers = new HttpHeaders();
141                        headers.add(CONTENT_TYPE, contentType);
142                        return headers;
143                }
144                else {
145                        return null;
146                }
147        }
148
149
150        /**
151         * Set a Map with parameter names as keys and String array objects as values.
152         * To be invoked by subclasses on initialization.
153         */
154        protected final void setMultipartParameters(Map<String, String[]> multipartParameters) {
155                this.multipartParameters = multipartParameters;
156        }
157
158        /**
159         * Obtain the multipart parameter Map for retrieval,
160         * lazily initializing it if necessary.
161         * @see #initializeMultipart()
162         */
163        protected Map<String, String[]> getMultipartParameters() {
164                if (this.multipartParameters == null) {
165                        initializeMultipart();
166                }
167                return this.multipartParameters;
168        }
169
170        /**
171         * Set a Map with parameter names as keys and content type Strings as values.
172         * To be invoked by subclasses on initialization.
173         */
174        protected final void setMultipartParameterContentTypes(Map<String, String> multipartParameterContentTypes) {
175                this.multipartParameterContentTypes = multipartParameterContentTypes;
176        }
177
178        /**
179         * Obtain the multipart parameter content type Map for retrieval,
180         * lazily initializing it if necessary.
181         * @see #initializeMultipart()
182         */
183        protected Map<String, String> getMultipartParameterContentTypes() {
184                if (this.multipartParameterContentTypes == null) {
185                        initializeMultipart();
186                }
187                return this.multipartParameterContentTypes;
188        }
189
190}