001 // Copyright 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.multipart; 016 017 import java.io.UnsupportedEncodingException; 018 import java.util.HashMap; 019 import java.util.Iterator; 020 import java.util.List; 021 import java.util.Map; 022 023 import javax.servlet.http.HttpServletRequest; 024 025 import org.apache.commons.fileupload.DiskFileUpload; 026 import org.apache.commons.fileupload.FileItem; 027 import org.apache.commons.fileupload.FileUploadException; 028 import org.apache.hivemind.ApplicationRuntimeException; 029 import org.apache.tapestry.request.IUploadFile; 030 031 /** 032 * Implementation of {@link org.apache.tapestry.multipart.MultipartDecoder}that is based on <a 033 * href="http://jakarta.apache.org/commons/fileupload/">Jakarta FileUpload </a>. 034 * 035 * @author Howard M. Lewis Ship 036 * @author Joe Panico 037 * @since 4.0 038 */ 039 public class MultipartDecoderImpl implements MultipartDecoder 040 { 041 /** 042 * Map of UploadPart (which implements IUploadFile), keyed on parameter name. 043 */ 044 045 private Map _uploadParts = new HashMap(); 046 047 /** 048 * Map of ValuePart, keyed on parameter name. 049 */ 050 private Map _valueParts = new HashMap(); 051 052 private int _maxSize = 10000000; 053 054 private int _thresholdSize = 1024; 055 056 private String _repositoryPath = System.getProperty("java.io.tmpdir"); 057 058 private String _encoding; 059 060 public HttpServletRequest decode(HttpServletRequest request) 061 { 062 _encoding = request.getCharacterEncoding(); 063 064 DiskFileUpload upload = createUpload(request); 065 066 try 067 { 068 List fileItems = upload 069 .parseRequest(request, _thresholdSize, _maxSize, _repositoryPath); 070 071 processFileItems(fileItems); 072 } 073 catch (FileUploadException ex) 074 { 075 throw new ApplicationRuntimeException(MultipartMessages.unableToDecode(ex), ex); 076 } 077 078 Map parameterMap = buildParameterMap(); 079 080 return new UploadFormParametersWrapper(request, parameterMap); 081 } 082 083 private Map buildParameterMap() 084 { 085 Map result = new HashMap(); 086 087 Iterator i = _valueParts.entrySet().iterator(); 088 while (i.hasNext()) 089 { 090 Map.Entry e = (Map.Entry) i.next(); 091 092 String name = (String) e.getKey(); 093 ValuePart part = (ValuePart) e.getValue(); 094 095 result.put(name, part.getValues()); 096 } 097 098 return result; 099 } 100 101 private void processFileItems(List parts) 102 { 103 if (parts == null) 104 return; 105 106 Iterator i = parts.iterator(); 107 108 while (i.hasNext()) 109 { 110 FileItem item = (FileItem) i.next(); 111 112 processFileItem(item); 113 } 114 } 115 116 private void processFileItem(FileItem item) 117 { 118 if (item.isFormField()) 119 { 120 processFormFieldItem(item); 121 return; 122 } 123 124 processUploadFileItem(item); 125 } 126 127 private void processUploadFileItem(FileItem item) 128 { 129 String name = item.getFieldName(); 130 131 UploadPart part = new UploadPart(item); 132 133 _uploadParts.put(name, part); 134 } 135 136 void processFormFieldItem(FileItem item) 137 { 138 String name = item.getFieldName(); 139 140 String value = extractFileItemValue(item); 141 142 ValuePart part = (ValuePart) _valueParts.get(name); 143 144 if (part == null) 145 _valueParts.put(name, new ValuePart(value)); 146 else 147 part.add(value); 148 } 149 150 private String extractFileItemValue(FileItem item) 151 { 152 try 153 { 154 return (_encoding == null) ? item.getString() : item.getString(_encoding); 155 } 156 catch (UnsupportedEncodingException ex) 157 { 158 throw new ApplicationRuntimeException(MultipartMessages.unsupportedEncoding( 159 _encoding, 160 ex), ex); 161 } 162 } 163 164 protected DiskFileUpload createUpload(HttpServletRequest request) 165 { 166 DiskFileUpload upload = new DiskFileUpload(); 167 168 if (_encoding != null) 169 upload.setHeaderEncoding(_encoding); 170 171 return upload; 172 } 173 174 public IUploadFile getFileUpload(String parameterName) 175 { 176 return (IUploadFile) _uploadParts.get(parameterName); 177 } 178 179 public void cleanup() 180 { 181 Iterator i = _uploadParts.values().iterator(); 182 183 while (i.hasNext()) 184 { 185 UploadPart part = (UploadPart) i.next(); 186 187 part.cleanup(); 188 } 189 } 190 191 }