001/*
002 * Copyright 2002-2015 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.mock.web;
018
019import java.util.Collections;
020import java.util.Enumeration;
021import java.util.Iterator;
022import java.util.List;
023import java.util.Map;
024import javax.servlet.ServletContext;
025
026import org.springframework.http.HttpHeaders;
027import org.springframework.http.HttpMethod;
028import org.springframework.util.Assert;
029import org.springframework.util.LinkedMultiValueMap;
030import org.springframework.util.MultiValueMap;
031import org.springframework.web.multipart.MultipartFile;
032import org.springframework.web.multipart.MultipartHttpServletRequest;
033
034/**
035 * Mock implementation of the
036 * {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface.
037 *
038 * <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
039 *
040 * <p>Useful for testing application controllers that access multipart uploads.
041 * The {@link MockMultipartFile} can be used to populate these mock requests
042 * with files.
043 *
044 * @author Juergen Hoeller
045 * @author Eric Crampton
046 * @author Arjen Poutsma
047 * @since 2.0
048 * @see MockMultipartFile
049 */
050public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest {
051
052        private final MultiValueMap<String, MultipartFile> multipartFiles =
053                        new LinkedMultiValueMap<String, MultipartFile>();
054
055
056        /**
057         * Create a new {@code MockMultipartHttpServletRequest} with a default
058         * {@link MockServletContext}.
059         * @see #MockMultipartHttpServletRequest(ServletContext)
060         */
061        public MockMultipartHttpServletRequest() {
062                this(null);
063        }
064
065        /**
066         * Create a new {@code MockMultipartHttpServletRequest} with the supplied {@link ServletContext}.
067         * @param servletContext the ServletContext that the request runs in
068         * (may be {@code null} to use a default {@link MockServletContext})
069         */
070        public MockMultipartHttpServletRequest(ServletContext servletContext) {
071                super(servletContext);
072                setMethod("POST");
073                setContentType("multipart/form-data");
074        }
075
076
077        /**
078         * Add a file to this request. The parameter name from the multipart
079         * form is taken from the {@link MultipartFile#getName()}.
080         * @param file multipart file to be added
081         */
082        public void addFile(MultipartFile file) {
083                Assert.notNull(file, "MultipartFile must not be null");
084                this.multipartFiles.add(file.getName(), file);
085        }
086
087        @Override
088        public Iterator<String> getFileNames() {
089                return this.multipartFiles.keySet().iterator();
090        }
091
092        @Override
093        public MultipartFile getFile(String name) {
094                return this.multipartFiles.getFirst(name);
095        }
096
097        @Override
098        public List<MultipartFile> getFiles(String name) {
099                List<MultipartFile> multipartFiles = this.multipartFiles.get(name);
100                if (multipartFiles != null) {
101                        return multipartFiles;
102                }
103                else {
104                        return Collections.emptyList();
105                }
106        }
107
108        @Override
109        public Map<String, MultipartFile> getFileMap() {
110                return this.multipartFiles.toSingleValueMap();
111        }
112
113        @Override
114        public MultiValueMap<String, MultipartFile> getMultiFileMap() {
115                return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
116        }
117
118        @Override
119        public String getMultipartContentType(String paramOrFileName) {
120                MultipartFile file = getFile(paramOrFileName);
121                if (file != null) {
122                        return file.getContentType();
123                }
124                else {
125                        return null;
126                }
127        }
128
129        @Override
130        public HttpMethod getRequestMethod() {
131                return HttpMethod.resolve(getMethod());
132        }
133
134        @Override
135        public HttpHeaders getRequestHeaders() {
136                HttpHeaders headers = new HttpHeaders();
137                Enumeration<String> headerNames = getHeaderNames();
138                while (headerNames.hasMoreElements()) {
139                        String headerName = headerNames.nextElement();
140                        headers.put(headerName, Collections.list(getHeaders(headerName)));
141                }
142                return headers;
143        }
144
145        @Override
146        public HttpHeaders getMultipartHeaders(String paramOrFileName) {
147                String contentType = getMultipartContentType(paramOrFileName);
148                if (contentType != null) {
149                        HttpHeaders headers = new HttpHeaders();
150                        headers.add("Content-Type", contentType);
151                        return headers;
152                }
153                else {
154                        return null;
155                }
156        }
157
158}