001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                            _log.error(e, e);
132                    }
133            }
134    
135            public void cleanUp() {
136                    if ((_params != null) && !_params.isEmpty()) {
137                            for (LiferayFileItem[] liferayFileItems : _params.values()) {
138                                    for (LiferayFileItem liferayFileItem : liferayFileItems) {
139                                            liferayFileItem.delete();
140                                    }
141                            }
142                    }
143            }
144    
145            public String getContentType(String name) {
146                    LiferayFileItem[] liferayFileItems = _params.get(name);
147    
148                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
149                            LiferayFileItem liferayFileItem = liferayFileItems[0];
150    
151                            return liferayFileItem.getContentType();
152                    }
153                    else {
154                            return null;
155                    }
156            }
157    
158            public File getFile(String name) {
159                    return getFile(name, false);
160            }
161    
162            public File getFile(String name, boolean forceCreate) {
163                    if (getFileName(name) == null) {
164                            return null;
165                    }
166    
167                    LiferayFileItem[] liferayFileItems = _params.get(name);
168    
169                    File file = null;
170    
171                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
172                            LiferayFileItem liferayFileItem = liferayFileItems[0];
173    
174                            file = liferayFileItem.getStoreLocation();
175    
176                            if (liferayFileItem.isInMemory() && forceCreate) {
177                                    try {
178                                            FileUtil.write(file, liferayFileItem.getInputStream());
179                                    }
180                                    catch (IOException ioe) {
181                                            if (_log.isWarnEnabled()) {
182                                                    _log.warn(
183                                                            "Unable to write temporary file " +
184                                                                    file.getAbsolutePath(),
185                                                            ioe);
186                                            }
187                                    }
188                            }
189                    }
190    
191                    return file;
192            }
193    
194            public InputStream getFileAsStream(String name) throws IOException {
195                    return getFileAsStream(name, true);
196            }
197    
198            public InputStream getFileAsStream(String name, boolean deleteOnClose)
199                    throws IOException {
200    
201                    if (getFileName(name) == null) {
202                            return null;
203                    }
204    
205                    InputStream inputStream = null;
206    
207                    LiferayFileItem[] liferayFileItems = _params.get(name);
208    
209                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
210                            LiferayFileItem liferayFileItem = liferayFileItems[0];
211    
212                            inputStream = getInputStream(liferayFileItem, deleteOnClose);
213                    }
214    
215                    return inputStream;
216            }
217    
218            public String getFileName(String name) {
219                    LiferayFileItem[] liferayFileItems = _params.get(name);
220    
221                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
222                            LiferayFileItem liferayFileItem = liferayFileItems[0];
223    
224                            return liferayFileItem.getFileName();
225                    }
226                    else {
227                            return null;
228                    }
229            }
230    
231            public String[] getFileNames(String name) {
232                    LiferayFileItem[] liferayFileItems = _params.get(name);
233    
234                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
235                            String[] fileNames = new String[liferayFileItems.length];
236    
237                            for (int i = 0; i < liferayFileItems.length; i++) {
238                                    LiferayFileItem liferayFileItem = liferayFileItems[i];
239    
240                                    fileNames[i] = liferayFileItem.getFileName();
241                            }
242    
243                            return fileNames;
244                    }
245                    else {
246                            return null;
247                    }
248            }
249    
250            public File[] getFiles(String name) {
251                    String[] fileNames = getFileNames(name);
252    
253                    if (fileNames == null) {
254                            return null;
255                    }
256    
257                    LiferayFileItem[] liferayFileItems = _params.get(name);
258    
259                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
260                            File[] files = new File[liferayFileItems.length];
261    
262                            for (int i = 0; i < liferayFileItems.length; i++) {
263                                    LiferayFileItem liferayFileItem = liferayFileItems[i];
264    
265                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
266                                            files[i] = liferayFileItem.getStoreLocation();
267                                    }
268                            }
269    
270                            return files;
271                    }
272                    else {
273                            return null;
274                    }
275            }
276    
277            public InputStream[] getFilesAsStream(String name) throws IOException {
278                    return getFilesAsStream(name, true);
279            }
280    
281            public InputStream[] getFilesAsStream(String name, boolean deleteOnClose)
282                    throws IOException {
283    
284                    String[] fileNames = getFileNames(name);
285    
286                    if (fileNames == null) {
287                            return null;
288                    }
289    
290                    InputStream[] inputStreams = null;
291    
292                    LiferayFileItem[] liferayFileItems = _params.get(name);
293    
294                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
295                            inputStreams = new InputStream[liferayFileItems.length];
296    
297                            for (int i = 0; i < liferayFileItems.length; i++) {
298                                    LiferayFileItem liferayFileItem = liferayFileItems[i];
299    
300                                    if (Validator.isNotNull(liferayFileItem.getFileName())) {
301                                            inputStreams[i] = getInputStream(
302                                                    liferayFileItem, deleteOnClose);
303                                    }
304                            }
305                    }
306    
307                    return inputStreams;
308            }
309    
310            public String getFullFileName(String name) {
311                    LiferayFileItem[] liferayFileItems = _params.get(name);
312    
313                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
314                            LiferayFileItem liferayFileItem = liferayFileItems[0];
315    
316                            return liferayFileItem.getFullFileName();
317                    }
318                    else {
319                            return null;
320                    }
321            }
322    
323            @Override
324            public ServletInputStream getInputStream() throws IOException {
325                    return _liferayServletRequest.getInputStream();
326            }
327    
328            public Map<String, LiferayFileItem[]> getMultipartParameterMap() {
329                    return _params;
330            }
331    
332            @Override
333            public String getParameter(String name) {
334                    LiferayFileItem[] liferayFileItems = _params.get(name);
335    
336                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
337                            LiferayFileItem liferayFileItem = liferayFileItems[0];
338    
339                            File storeLocationFile = liferayFileItem.getStoreLocation();
340    
341                            if (storeLocationFile.length() > LiferayFileItem.THRESHOLD_SIZE) {
342                                    _liferayServletRequest.setAttribute(
343                                            WebKeys.FILE_ITEM_THRESHOLD_SIZE_EXCEEDED, Boolean.TRUE);
344    
345                                    return liferayFileItem.getEncodedString();
346                            }
347    
348                            return liferayFileItem.getString();
349                    }
350                    else {
351                            return super.getParameter(name);
352                    }
353            }
354    
355            @Override
356            public Map<String, String[]> getParameterMap() {
357                    Map<String, String[]> map = new HashMap<String, String[]>();
358    
359                    Enumeration<String> enu = getParameterNames();
360    
361                    while (enu.hasMoreElements()) {
362                            String name = enu.nextElement();
363    
364                            map.put(name, getParameterValues(name));
365                    }
366    
367                    return map;
368            }
369    
370            @Override
371            public Enumeration<String> getParameterNames() {
372                    Set<String> parameterNames = new LinkedHashSet<String>();
373    
374                    Enumeration<String> enu = super.getParameterNames();
375    
376                    while (enu.hasMoreElements()) {
377                            String name = enu.nextElement();
378    
379                            if (!_params.containsKey(name)) {
380                                    parameterNames.add(name);
381                            }
382                    }
383    
384                    parameterNames.addAll(_params.keySet());
385    
386                    return Collections.enumeration(parameterNames);
387            }
388    
389            @Override
390            public String[] getParameterValues(String name) {
391                    String[] parentValues = super.getParameterValues(name);
392    
393                    LiferayFileItem[] liferayFileItems = _params.get(name);
394    
395                    if ((liferayFileItems == null) || (liferayFileItems.length == 0)) {
396                            return parentValues;
397                    }
398                    else if ((parentValues == null) || (parentValues.length == 0)) {
399                            String[] values = new String[liferayFileItems.length];
400    
401                            for (int i = 0; i < values.length; i++) {
402                                    LiferayFileItem liferayFileItem = liferayFileItems[i];
403    
404                                    values[i] = liferayFileItem.getString();
405                            }
406    
407                            return values;
408                    }
409                    else {
410                            String[] values = new String[
411                                    parentValues.length + liferayFileItems.length];
412    
413                            System.arraycopy(
414                                    parentValues, 0, values, 0, parentValues.length);
415    
416                            for (int i = parentValues.length; i < values.length; i++) {
417                                    values[i] =
418                                            liferayFileItems[i - parentValues.length].getString();
419                            }
420    
421                            return values;
422                    }
423            }
424    
425            public Long getSize(String name) {
426                    LiferayFileItem[] liferayFileItems = _params.get(name);
427    
428                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
429                            LiferayFileItem liferayFileItem = liferayFileItems[0];
430    
431                            return new Long(liferayFileItem.getSize());
432                    }
433                    else {
434                            return null;
435                    }
436            }
437    
438            public Boolean isFormField(String name) {
439                    LiferayFileItem[] liferayFileItems = _params.get(name);
440    
441                    if ((liferayFileItems != null) && (liferayFileItems.length > 0)) {
442                            LiferayFileItem liferayFileItem = liferayFileItems[0];
443    
444                            return new Boolean(liferayFileItem.isFormField());
445                    }
446                    else {
447                            return null;
448                    }
449            }
450    
451            protected InputStream getInputStream(
452                            LiferayFileItem liferayFileItem, boolean deleteOnClose)
453                    throws IOException {
454    
455                    InputStream inputStream = null;
456    
457                    if (liferayFileItem.isInMemory() && (liferayFileItem.getSize() > 0)) {
458                            inputStream = liferayFileItem.getInputStream();
459                    }
460                    else if (!liferayFileItem.isInMemory()) {
461                            inputStream = new ByteArrayFileInputStream(
462                                    liferayFileItem.getStoreLocation(),
463                                    liferayFileItem.getSizeThreshold(), deleteOnClose);
464                    }
465    
466                    return inputStream;
467            }
468    
469            private static Log _log = LogFactoryUtil.getLog(
470                    UploadServletRequestImpl.class);
471    
472            private static File _tempDir;
473    
474            private LiferayServletRequest _liferayServletRequest;
475            private Map<String, LiferayFileItem[]> _params;
476    
477    }