001/*
002 * Copyright 2002-2017 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.io.ByteArrayInputStream;
020import java.io.IOException;
021import java.io.InputStream;
022import java.util.Collection;
023import java.util.Collections;
024import javax.servlet.http.Part;
025
026import org.springframework.http.HttpHeaders;
027import org.springframework.http.MediaType;
028import org.springframework.util.Assert;
029
030/**
031 * Mock implementation of {@code javax.servlet.http.Part}.
032 *
033 * @author Rossen Stoyanchev
034 * @author Juergen Hoeller
035 * @since 4.3.12
036 * @see MockHttpServletRequest#addPart
037 * @see MockMultipartFile
038 */
039public class MockPart implements Part {
040
041        private final String name;
042
043        private final String filename;
044
045        private final byte[] content;
046
047        private final HttpHeaders headers = new HttpHeaders();
048
049
050        /**
051         * Constructor for a part with byte[] content only.
052         * @see #getHeaders()
053         */
054        public MockPart(String name, byte[] content) {
055                this(name, null, content);
056        }
057
058        /**
059         * Constructor for a part with a filename and byte[] content.
060         * @see #getHeaders()
061         */
062        public MockPart(String name, String filename, byte[] content) {
063                Assert.hasLength(name, "Name must not be null");
064                this.name = name;
065                this.filename = filename;
066                this.content = (content != null ? content : new byte[0]);
067                this.headers.setContentDispositionFormData(name, filename);
068        }
069
070
071        @Override
072        public String getName() {
073                return this.name;
074        }
075
076        // Servlet 3.1
077        public String getSubmittedFileName() {
078                return this.filename;
079        }
080
081        @Override
082        public String getContentType() {
083                MediaType contentType = this.headers.getContentType();
084                return (contentType != null ? contentType.toString() : null);
085        }
086
087        @Override
088        public long getSize() {
089                return this.content.length;
090        }
091
092        @Override
093        public InputStream getInputStream() throws IOException {
094                return new ByteArrayInputStream(this.content);
095        }
096
097        @Override
098        public void write(String fileName) throws IOException {
099                throw new UnsupportedOperationException();
100        }
101
102        @Override
103        public void delete() throws IOException {
104                throw new UnsupportedOperationException();
105        }
106
107        @Override
108        public String getHeader(String name) {
109                return this.headers.getFirst(name);
110        }
111
112        @Override
113        public Collection<String> getHeaders(String name) {
114                Collection<String> headerValues = this.headers.get(name);
115                return (headerValues != null ? headerValues : Collections.<String>emptyList());
116        }
117
118        @Override
119        public Collection<String> getHeaderNames() {
120                return this.headers.keySet();
121        }
122
123        /**
124         * Return the {@link HttpHeaders} backing header related accessor methods,
125         * allowing for populating selected header entries.
126         */
127        public final HttpHeaders getHeaders() {
128                return this.headers;
129        }
130
131}