001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.upload;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.io.ByteArrayFileInputStream;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.upload.FileItem;
022    import com.liferay.portal.kernel.upload.UploadException;
023    import com.liferay.portal.kernel.upload.UploadServletRequest;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.FileUtil;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.SystemProperties;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.util.PrefsPropsUtil;
030    import com.liferay.portal.util.WebKeys;
031    
032    import java.io.File;
033    import java.io.IOException;
034    import java.io.InputStream;
035    
036    import java.util.ArrayList;
037    import java.util.Collections;
038    import java.util.Enumeration;
039    import java.util.HashMap;
040    import java.util.LinkedHashMap;
041    import java.util.LinkedHashSet;
042    import java.util.List;
043    import java.util.Map;
044    import java.util.Set;
045    
046    import javax.servlet.ServletInputStream;
047    import javax.servlet.http.HttpServletRequest;
048    import javax.servlet.http.HttpServletRequestWrapper;
049    
050    import org.apache.commons.fileupload.FileUploadBase;
051    import org.apache.commons.fileupload.servlet.ServletFileUpload;
052    
053    /**
054     * @author Brian Wing Shun Chan
055     * @author Zongliang Li
056     * @author Harry Mark
057     * @author Raymond Augé
058     */
059    public class UploadServletRequestImpl
060            extends HttpServletRequestWrapper implements UploadServletRequest {
061    
062            public static File getTempDir() throws SystemException {
063                    if (_tempDir == null) {
064                            _tempDir = new File(
065                                    PrefsPropsUtil.getString(
066                                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
067                                            SystemProperties.get(SystemProperties.TMP_DIR)));
068                    }
069    
070                    return _tempDir;
071            }
072    
073            public static void setTempDir(File tempDir) {
074                    _tempDir = tempDir;
075            }
076    
077            public UploadServletRequestImpl(HttpServletRequest request) {
078                    super(request);
079    
080                    _fileParams = new LinkedHashMap<String, FileItem[]>();
081                    _regularParams = new LinkedHashMap<String, List<String>>();
082    
083                    try {
084                            ServletFileUpload servletFileUpload = new LiferayFileUpload(
085                                    new LiferayFileItemFactory(getTempDir()), request);
086    
087                            servletFileUpload.setSizeMax(
088                                    PrefsPropsUtil.getLong(
089                                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE));
090    
091                            _liferayServletRequest = new LiferayServletRequest(request);
092    
093                            List<LiferayFileItem> liferayFileItemsList =
094                                    servletFileUpload.parseRequest(_liferayServletRequest);
095    
096                            for (LiferayFileItem liferayFileItem : liferayFileItemsList) {
097                                    if (liferayFileItem.isFormField()) {
098                                            liferayFileItem.setString(request.getCharacterEncoding());
099    
100                                            String fieldName = liferayFileItem.getFieldName();
101    
102                                            if (!_regularParams.containsKey(fieldName)) {
103                                                    _regularParams.put(fieldName, new ArrayList<String>());
104                                            }
105    
106                                            List<String> values = _regularParams.get(fieldName);
107    
108                                            values.add(liferayFileItem.getString());
109    
110                                            continue;
111                                    }
112    
113                                    FileItem[] liferayFileItems = _fileParams.get(
114                                            liferayFileItem.getFieldName());
115    
116                                    if (liferayFileItems == null) {
117                                            liferayFileItems = new LiferayFileItem[] {liferayFileItem};
118                                    }
119                                    else {
120                                            LiferayFileItem[] newLiferayFileItems =
121                                                    new LiferayFileItem[liferayFileItems.length + 1];
122    
123                                            System.arraycopy(
124                                                    liferayFileItems, 0, newLiferayFileItems, 0,
125                                                    liferayFileItems.length);
126    
127                                            newLiferayFileItems[newLiferayFileItems.length - 1] =
128                                                    liferayFileItem;
129    
130                                            liferayFileItems = newLiferayFileItems;
131                                    }
132    
133                                    _fileParams.put(
134                                            liferayFileItem.getFieldName(), liferayFileItems);
135                            }
136                    }
137                    catch (Exception e) {
138                            UploadException uploadException = new UploadException(e);
139    
140                            if (e instanceof FileUploadBase.FileSizeLimitExceededException ||
141                                    e instanceof FileUploadBase.SizeLimitExceededException ) {
142    
143                                    uploadException.setExceededSizeLimit(true);
144                            }
145    
146                            request.setAttribute(WebKeys.UPLOAD_EXCEPTION, uploadException);
147    
148                            if (_log.isDebugEnabled()) {
149                                    _log.debug(e, e);
150                            }
151                    }
152            }
153    
154            public void cleanUp() {
155                    if ((_fileParams != null) && !_fileParams.isEmpty()) {
156                            for (FileItem[] liferayFileItems : _fileParams.values()) {
157                                    for (FileItem liferayFileItem : liferayFileItems) {
158                                            liferayFileItem.delete();
159                                    }
160                            }
161                    }
162            }
163    
164            public String getContentType(String name) {
165                    FileItem[] liferayFileItems = _fileParams.get(name);
166    
167                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
168                            FileItem liferayFileItem = liferayFileItems[0];
169    
170                            return liferayFileItem.getContentType();
171                    }
172    
173                    return null;
174            }
175    
176            public File getFile(String name) {
177                    return getFile(name, false);
178            }
179    
180            public File getFile(String name, boolean forceCreate) {
181                    if (getFileName(name) == null) {
182                            return null;
183                    }
184    
185                    FileItem[] liferayFileItems = _fileParams.get(name);
186    
187                    if ((liferayFileItems == null) || (liferayFileItems.length == 0)) {
188                            return null;
189                    }
190    
191                    FileItem liferayFileItem = liferayFileItems[0];
192    
193                    long size = liferayFileItem.getSize();
194    
195                    if ((size > 0) && (size <= liferayFileItem.getSizeThreshold())) {
196                            forceCreate = true;
197                    }
198    
199                    File file = liferayFileItem.getStoreLocation();
200    
201                    if (liferayFileItem.isInMemory() && forceCreate) {
202                            try {
203                                    FileUtil.write(file, liferayFileItem.getInputStream());
204                            }
205                            catch (IOException ioe) {
206                                    if (_log.isWarnEnabled()) {
207                                            _log.warn(
208                                                    "Unable to write temporary file " +
209                                                            file.getAbsolutePath(),
210                                                    ioe);
211                                    }
212                            }
213                    }
214    
215                    return file;
216            }
217    
218            public InputStream getFileAsStream(String name) throws IOException {
219                    return getFileAsStream(name, true);
220            }
221    
222            public InputStream getFileAsStream(String name, boolean deleteOnClose)
223                    throws IOException {
224    
225                    if (getFileName(name) == null) {
226                            return null;
227                    }
228    
229                    InputStream inputStream = null;
230    
231                    FileItem[] liferayFileItems = _fileParams.get(name);
232    
233                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
234                            FileItem liferayFileItem = liferayFileItems[0];
235    
236                            inputStream = getInputStream(liferayFileItem, deleteOnClose);
237                    }
238    
239                    return inputStream;
240            }
241    
242            public String getFileName(String name) {
243                    FileItem[] liferayFileItems = _fileParams.get(name);
244    
245                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
246                            FileItem liferayFileItem = liferayFileItems[0];
247    
248                            return liferayFileItem.getFileName();
249                    }
250    
251                    return null;
252            }
253    
254            public String[] getFileNames(String name) {
255                    FileItem[] liferayFileItems = _fileParams.get(name);
256    
257                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
258                            String[] fileNames = new String[liferayFileItems.length];
259    
260                            for (int i = 0; i < liferayFileItems.length; i++) {
261                                    FileItem liferayFileItem = liferayFileItems[i];
262    
263                                    fileNames[i] = liferayFileItem.getFileName();
264                            }
265    
266                            return fileNames;
267                    }
268    
269                    return null;
270            }
271    
272            public File[] getFiles(String name) {
273                    String[] fileNames = getFileNames(name);
274    
275                    if (fileNames == null) {
276                            return null;
277                    }
278    
279                    FileItem[] liferayFileItems = _fileParams.get(name);
280    
281                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
282                            File[] files = new File[liferayFileItems.length];
283    
284                            for (int i = 0; i < liferayFileItems.length; i++) {
285                                    FileItem liferayFileItem = liferayFileItems[i];
286    
287                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
288                                            files[i] = liferayFileItem.getStoreLocation();
289                                    }
290                            }
291    
292                            return files;
293                    }
294    
295                    return null;
296            }
297    
298            public InputStream[] getFilesAsStream(String name) throws IOException {
299                    return getFilesAsStream(name, true);
300            }
301    
302            public InputStream[] getFilesAsStream(String name, boolean deleteOnClose)
303                    throws IOException {
304    
305                    String[] fileNames = getFileNames(name);
306    
307                    if (fileNames == null) {
308                            return null;
309                    }
310    
311                    InputStream[] inputStreams = null;
312    
313                    FileItem[] liferayFileItems = _fileParams.get(name);
314    
315                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
316                            inputStreams = new InputStream[liferayFileItems.length];
317    
318                            for (int i = 0; i < liferayFileItems.length; i++) {
319                                    FileItem liferayFileItem = liferayFileItems[i];
320    
321                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
322                                            inputStreams[i] = getInputStream(
323                                                    liferayFileItem, deleteOnClose);
324                                    }
325                            }
326                    }
327    
328                    return inputStreams;
329            }
330    
331            public String getFullFileName(String name) {
332                    FileItem[] liferayFileItems = _fileParams.get(name);
333    
334                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
335                            FileItem liferayFileItem = liferayFileItems[0];
336    
337                            return liferayFileItem.getFullFileName();
338                    }
339    
340                    return null;
341            }
342    
343            @Override
344            public ServletInputStream getInputStream() throws IOException {
345                    return _liferayServletRequest.getInputStream();
346            }
347    
348            public Map<String, FileItem[]> getMultipartParameterMap() {
349                    return _fileParams;
350            }
351    
352            @Override
353            public String getParameter(String name) {
354                    List<String> values = _regularParams.get(name);
355    
356                    if ((values != null) && !values.isEmpty()) {
357                            return values.get(0);
358                    }
359    
360                    return super.getParameter(name);
361            }
362    
363            @Override
364            public Map<String, String[]> getParameterMap() {
365                    Map<String, String[]> map = new HashMap<String, String[]>();
366    
367                    Enumeration<String> enu = getParameterNames();
368    
369                    while (enu.hasMoreElements()) {
370                            String name = enu.nextElement();
371    
372                            map.put(name, getParameterValues(name));
373                    }
374    
375                    return map;
376            }
377    
378            @Override
379            public Enumeration<String> getParameterNames() {
380                    Set<String> parameterNames = new LinkedHashSet<String>();
381    
382                    Enumeration<String> enu = super.getParameterNames();
383    
384                    while (enu.hasMoreElements()) {
385                            parameterNames.add(enu.nextElement());
386                    }
387    
388                    parameterNames.addAll(_regularParams.keySet());
389                    parameterNames.addAll(_fileParams.keySet());
390    
391                    return Collections.enumeration(parameterNames);
392            }
393    
394            @Override
395            public String[] getParameterValues(String name) {
396                    String[] parameterValues = null;
397    
398                    List<String> values = _regularParams.get(name);
399    
400                    if (values != null) {
401                            parameterValues = values.toArray(new String[values.size()]);
402                    }
403    
404                    String[] parentParameterValues = super.getParameterValues(name);
405    
406                    if (parameterValues == null) {
407                            return parentParameterValues;
408                    }
409                    else if (parentParameterValues == null) {
410                            return parameterValues;
411                    }
412    
413                    return ArrayUtil.append(parameterValues, parentParameterValues);
414            }
415    
416            public Long getSize(String name) {
417                    FileItem[] liferayFileItems = _fileParams.get(name);
418    
419                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
420                            FileItem liferayFileItem = liferayFileItems[0];
421    
422                            return new Long(liferayFileItem.getSize());
423                    }
424    
425                    return null;
426            }
427    
428            public Boolean isFormField(String name) {
429                    FileItem[] liferayFileItems = _fileParams.get(name);
430    
431                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
432                            FileItem liferayFileItem = liferayFileItems[0];
433    
434                            return new Boolean(liferayFileItem.isFormField());
435                    }
436    
437                    return null;
438            }
439    
440            protected InputStream getInputStream(
441                            FileItem liferayFileItem, boolean deleteOnClose)
442                    throws IOException {
443    
444                    InputStream inputStream = null;
445    
446                    if (liferayFileItem.isInMemory() && (liferayFileItem.getSize() > 0)) {
447                            inputStream = liferayFileItem.getInputStream();
448                    }
449                    else if (!liferayFileItem.isInMemory()) {
450                            inputStream = new ByteArrayFileInputStream(
451                                    liferayFileItem.getStoreLocation(),
452                                    liferayFileItem.getSizeThreshold(), deleteOnClose);
453                    }
454    
455                    return inputStream;
456            }
457    
458            private static Log _log = LogFactoryUtil.getLog(
459                    UploadServletRequestImpl.class);
460    
461            private static File _tempDir;
462    
463            private Map<String, FileItem[]> _fileParams;
464            private LiferayServletRequest _liferayServletRequest;
465            private Map<String, List<String>> _regularParams;
466    
467    }