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