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