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