001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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            @Override
155            public void cleanUp() {
156                    if ((_fileParams != null) && !_fileParams.isEmpty()) {
157                            for (FileItem[] liferayFileItems : _fileParams.values()) {
158                                    for (FileItem liferayFileItem : liferayFileItems) {
159                                            liferayFileItem.delete();
160                                    }
161                            }
162                    }
163            }
164    
165            @Override
166            public String getContentType(String name) {
167                    FileItem[] liferayFileItems = _fileParams.get(name);
168    
169                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
170                            FileItem liferayFileItem = liferayFileItems[0];
171    
172                            return liferayFileItem.getContentType();
173                    }
174    
175                    return null;
176            }
177    
178            @Override
179            public File getFile(String name) {
180                    return getFile(name, false);
181            }
182    
183            @Override
184            public File getFile(String name, boolean forceCreate) {
185                    if (getFileName(name) == null) {
186                            return null;
187                    }
188    
189                    FileItem[] liferayFileItems = _fileParams.get(name);
190    
191                    if ((liferayFileItems == null) || (liferayFileItems.length == 0)) {
192                            return null;
193                    }
194    
195                    FileItem liferayFileItem = liferayFileItems[0];
196    
197                    long size = liferayFileItem.getSize();
198    
199                    if ((size > 0) && (size <= liferayFileItem.getSizeThreshold())) {
200                            forceCreate = true;
201                    }
202    
203                    File file = liferayFileItem.getStoreLocation();
204    
205                    if (liferayFileItem.isInMemory() && forceCreate) {
206                            try {
207                                    FileUtil.write(file, liferayFileItem.getInputStream());
208                            }
209                            catch (IOException ioe) {
210                                    if (_log.isWarnEnabled()) {
211                                            _log.warn(
212                                                    "Unable to write temporary file " +
213                                                            file.getAbsolutePath(),
214                                                    ioe);
215                                    }
216                            }
217                    }
218    
219                    return file;
220            }
221    
222            @Override
223            public InputStream getFileAsStream(String name) throws IOException {
224                    return getFileAsStream(name, true);
225            }
226    
227            @Override
228            public InputStream getFileAsStream(String name, boolean deleteOnClose)
229                    throws IOException {
230    
231                    if (getFileName(name) == null) {
232                            return null;
233                    }
234    
235                    InputStream inputStream = null;
236    
237                    FileItem[] liferayFileItems = _fileParams.get(name);
238    
239                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
240                            FileItem liferayFileItem = liferayFileItems[0];
241    
242                            inputStream = getInputStream(liferayFileItem, deleteOnClose);
243                    }
244    
245                    return inputStream;
246            }
247    
248            @Override
249            public String getFileName(String name) {
250                    FileItem[] liferayFileItems = _fileParams.get(name);
251    
252                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
253                            FileItem liferayFileItem = liferayFileItems[0];
254    
255                            return liferayFileItem.getFileName();
256                    }
257    
258                    return null;
259            }
260    
261            @Override
262            public String[] getFileNames(String name) {
263                    FileItem[] liferayFileItems = _fileParams.get(name);
264    
265                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
266                            String[] fileNames = new String[liferayFileItems.length];
267    
268                            for (int i = 0; i < liferayFileItems.length; i++) {
269                                    FileItem liferayFileItem = liferayFileItems[i];
270    
271                                    fileNames[i] = liferayFileItem.getFileName();
272                            }
273    
274                            return fileNames;
275                    }
276    
277                    return null;
278            }
279    
280            @Override
281            public File[] getFiles(String name) {
282                    String[] fileNames = getFileNames(name);
283    
284                    if (fileNames == null) {
285                            return null;
286                    }
287    
288                    FileItem[] liferayFileItems = _fileParams.get(name);
289    
290                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
291                            File[] files = new File[liferayFileItems.length];
292    
293                            for (int i = 0; i < liferayFileItems.length; i++) {
294                                    FileItem liferayFileItem = liferayFileItems[i];
295    
296                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
297                                            files[i] = liferayFileItem.getStoreLocation();
298                                    }
299                            }
300    
301                            return files;
302                    }
303    
304                    return null;
305            }
306    
307            @Override
308            public InputStream[] getFilesAsStream(String name) throws IOException {
309                    return getFilesAsStream(name, true);
310            }
311    
312            @Override
313            public InputStream[] getFilesAsStream(String name, boolean deleteOnClose)
314                    throws IOException {
315    
316                    String[] fileNames = getFileNames(name);
317    
318                    if (fileNames == null) {
319                            return null;
320                    }
321    
322                    InputStream[] inputStreams = null;
323    
324                    FileItem[] liferayFileItems = _fileParams.get(name);
325    
326                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
327                            inputStreams = new InputStream[liferayFileItems.length];
328    
329                            for (int i = 0; i < liferayFileItems.length; i++) {
330                                    FileItem liferayFileItem = liferayFileItems[i];
331    
332                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
333                                            inputStreams[i] = getInputStream(
334                                                    liferayFileItem, deleteOnClose);
335                                    }
336                            }
337                    }
338    
339                    return inputStreams;
340            }
341    
342            @Override
343            public String getFullFileName(String name) {
344                    FileItem[] liferayFileItems = _fileParams.get(name);
345    
346                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
347                            FileItem liferayFileItem = liferayFileItems[0];
348    
349                            return liferayFileItem.getFullFileName();
350                    }
351    
352                    return null;
353            }
354    
355            @Override
356            public ServletInputStream getInputStream() throws IOException {
357                    return _liferayServletRequest.getInputStream();
358            }
359    
360            @Override
361            public Map<String, FileItem[]> getMultipartParameterMap() {
362                    return _fileParams;
363            }
364    
365            @Override
366            public String getParameter(String name) {
367                    List<String> values = _regularParams.get(name);
368    
369                    if ((values != null) && !values.isEmpty()) {
370                            return values.get(0);
371                    }
372    
373                    return super.getParameter(name);
374            }
375    
376            @Override
377            public Map<String, String[]> getParameterMap() {
378                    Map<String, String[]> map = new HashMap<String, String[]>();
379    
380                    Enumeration<String> enu = getParameterNames();
381    
382                    while (enu.hasMoreElements()) {
383                            String name = enu.nextElement();
384    
385                            map.put(name, getParameterValues(name));
386                    }
387    
388                    return map;
389            }
390    
391            @Override
392            public Enumeration<String> getParameterNames() {
393                    Set<String> parameterNames = new LinkedHashSet<String>();
394    
395                    Enumeration<String> enu = super.getParameterNames();
396    
397                    while (enu.hasMoreElements()) {
398                            parameterNames.add(enu.nextElement());
399                    }
400    
401                    parameterNames.addAll(_regularParams.keySet());
402                    parameterNames.addAll(_fileParams.keySet());
403    
404                    return Collections.enumeration(parameterNames);
405            }
406    
407            @Override
408            public String[] getParameterValues(String name) {
409                    String[] parameterValues = null;
410    
411                    List<String> values = _regularParams.get(name);
412    
413                    if (values != null) {
414                            parameterValues = values.toArray(new String[values.size()]);
415                    }
416    
417                    String[] parentParameterValues = super.getParameterValues(name);
418    
419                    if (parameterValues == null) {
420                            return parentParameterValues;
421                    }
422                    else if (parentParameterValues == null) {
423                            return parameterValues;
424                    }
425    
426                    return ArrayUtil.append(parameterValues, parentParameterValues);
427            }
428    
429            @Override
430            public Long getSize(String name) {
431                    FileItem[] liferayFileItems = _fileParams.get(name);
432    
433                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
434                            FileItem liferayFileItem = liferayFileItems[0];
435    
436                            return new Long(liferayFileItem.getSize());
437                    }
438    
439                    return null;
440            }
441    
442            @Override
443            public Boolean isFormField(String name) {
444                    FileItem[] liferayFileItems = _fileParams.get(name);
445    
446                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
447                            FileItem liferayFileItem = liferayFileItems[0];
448    
449                            return new Boolean(liferayFileItem.isFormField());
450                    }
451    
452                    return null;
453            }
454    
455            protected InputStream getInputStream(
456                            FileItem liferayFileItem, boolean deleteOnClose)
457                    throws IOException {
458    
459                    InputStream inputStream = null;
460    
461                    if (liferayFileItem.isInMemory() && (liferayFileItem.getSize() > 0)) {
462                            inputStream = liferayFileItem.getInputStream();
463                    }
464                    else if (!liferayFileItem.isInMemory()) {
465                            inputStream = new ByteArrayFileInputStream(
466                                    liferayFileItem.getStoreLocation(),
467                                    liferayFileItem.getSizeThreshold(), deleteOnClose);
468                    }
469    
470                    return inputStream;
471            }
472    
473            private static Log _log = LogFactoryUtil.getLog(
474                    UploadServletRequestImpl.class);
475    
476            private static File _tempDir;
477    
478            private Map<String, FileItem[]> _fileParams;
479            private LiferayServletRequest _liferayServletRequest;
480            private Map<String, List<String>> _regularParams;
481    
482    }