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