001: /*
002: * Copyright 2002-2006 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: * http://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:
017: package org.springframework.web.multipart.cos;
018:
019: import java.io.ByteArrayInputStream;
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.util.Collections;
025: import java.util.Enumeration;
026: import java.util.HashMap;
027: import java.util.Map;
028:
029: import javax.servlet.http.HttpServletRequest;
030:
031: import com.oreilly.servlet.MultipartRequest;
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: import org.springframework.util.FileCopyUtils;
036: import org.springframework.web.multipart.MultipartFile;
037: import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest;
038:
039: /**
040: * MultipartHttpServletRequest implementation for Jason Hunter's COS.
041: * Wraps a COS MultipartRequest with Spring MultipartFile instances.
042: *
043: * <p>Not intended for direct application usage. Application code can cast
044: * to this implementation to access the underlying COS MultipartRequest,
045: * if it ever needs to.
046: *
047: * @author Juergen Hoeller
048: * @since 06.10.2003
049: * @see CosMultipartResolver
050: * @see com.oreilly.servlet.MultipartRequest
051: */
052: public class CosMultipartHttpServletRequest extends
053: AbstractMultipartHttpServletRequest {
054:
055: protected static final Log logger = LogFactory
056: .getLog(CosMultipartHttpServletRequest.class);
057:
058: private final MultipartRequest multipartRequest;
059:
060: /**
061: * Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
062: * @param request the servlet request to wrap
063: * @param multipartRequest the COS multipart request to wrap
064: */
065: protected CosMultipartHttpServletRequest(
066: HttpServletRequest request,
067: MultipartRequest multipartRequest) {
068: super (request);
069: this .multipartRequest = multipartRequest;
070: setMultipartFiles(initFileMap(multipartRequest));
071: }
072:
073: /**
074: * Return the underlying <code>com.oreilly.servlet.MultipartRequest</code>
075: * instance. There is hardly any need to access this.
076: */
077: public MultipartRequest getMultipartRequest() {
078: return multipartRequest;
079: }
080:
081: /**
082: * Initialize a Map with file name Strings as keys and
083: * CosMultipartFile instances as values.
084: * @param multipartRequest the COS multipart request
085: * to get the multipart file data from
086: * @return the Map with CosMultipartFile values
087: */
088: private Map initFileMap(MultipartRequest multipartRequest) {
089: Map files = new HashMap();
090: Enumeration fileNames = multipartRequest.getFileNames();
091: while (fileNames.hasMoreElements()) {
092: String fileName = (String) fileNames.nextElement();
093: files.put(fileName, new CosMultipartFile(fileName));
094: }
095: return files;
096: }
097:
098: public Enumeration getParameterNames() {
099: return this .multipartRequest.getParameterNames();
100: }
101:
102: public String getParameter(String name) {
103: return this .multipartRequest.getParameter(name);
104: }
105:
106: public String[] getParameterValues(String name) {
107: return this .multipartRequest.getParameterValues(name);
108: }
109:
110: public Map getParameterMap() {
111: Map params = new HashMap();
112: Enumeration names = getParameterNames();
113: while (names.hasMoreElements()) {
114: String name = (String) names.nextElement();
115: params.put(name, getParameterValues(name));
116: }
117: return Collections.unmodifiableMap(params);
118: }
119:
120: /**
121: * Implementation of Spring's MultipartFile interface on top
122: * of a COS MultipartRequest object.
123: */
124: private class CosMultipartFile implements MultipartFile {
125:
126: private final String name;
127:
128: private final File file;
129:
130: private final long size;
131:
132: public CosMultipartFile(String name) {
133: this .name = name;
134: this .file = multipartRequest.getFile(this .name);
135: this .size = (this .file != null ? this .file.length() : 0);
136: }
137:
138: public String getName() {
139: return name;
140: }
141:
142: public String getOriginalFilename() {
143: String filename = multipartRequest
144: .getOriginalFileName(this .name);
145: return (filename != null ? filename : "");
146: }
147:
148: public String getContentType() {
149: return multipartRequest.getContentType(this .name);
150: }
151:
152: public boolean isEmpty() {
153: return (this .size == 0);
154: }
155:
156: public long getSize() {
157: return this .size;
158: }
159:
160: public byte[] getBytes() throws IOException {
161: if (this .file != null && !this .file.exists()) {
162: throw new IllegalStateException(
163: "File has been moved - cannot be read again");
164: }
165: return (this .size > 0 ? FileCopyUtils
166: .copyToByteArray(this .file) : new byte[0]);
167: }
168:
169: public InputStream getInputStream() throws IOException {
170: if (this .file != null && !this .file.exists()) {
171: throw new IllegalStateException(
172: "File has been moved - cannot be read again");
173: }
174: if (this .size != 0) {
175: return new FileInputStream(this .file);
176: } else {
177: return new ByteArrayInputStream(new byte[0]);
178: }
179: }
180:
181: public void transferTo(File dest) throws IOException,
182: IllegalStateException {
183: if (this .file != null && !this .file.exists()) {
184: throw new IllegalStateException(
185: "File has already been moved - cannot be transferred again");
186: }
187:
188: if (dest.exists() && !dest.delete()) {
189: throw new IOException("Destination file ["
190: + dest.getAbsolutePath()
191: + "] already exists and could not be deleted");
192: }
193:
194: boolean moved = false;
195: if (this .file != null) {
196: moved = this .file.renameTo(dest);
197: if (!moved) {
198: FileCopyUtils.copy(this .file, dest);
199: }
200: } else {
201: dest.createNewFile();
202: }
203:
204: if (logger.isDebugEnabled()) {
205: logger.debug("Multipart file '"
206: + getName()
207: + "' with original filename ["
208: + getOriginalFilename()
209: + "], stored "
210: + (this .file != null ? "at ["
211: + this .file.getAbsolutePath() + "]"
212: : "in memory") + ": "
213: + (moved ? "moved" : "copied") + " to ["
214: + dest.getAbsolutePath() + "]");
215: }
216: }
217: }
218:
219: }
|