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