001/*
002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.ui.web.util;
023
024import java.io.IOException;
025import java.io.InputStream;
026import java.nio.charset.Charset;
027import java.util.ArrayList;
028import java.util.Collections;
029import java.util.List;
030
031import javax.servlet.http.HttpServletRequest;
032
033import org.apache.commons.fileupload.FileItem;
034import org.apache.commons.fileupload.FileUpload;
035import org.apache.commons.fileupload.FileUploadException;
036import org.apache.commons.fileupload.disk.DiskFileItemFactory;
037import org.apache.commons.fileupload.servlet.ServletRequestContext;
038import org.apache.http.entity.ContentType;
039import org.nuxeo.ecm.core.api.Blob;
040import org.nuxeo.ecm.core.api.Blobs;
041import org.restlet.Request;
042import org.restlet.engine.adapter.HttpRequest;
043import org.restlet.engine.adapter.ServerCall;
044import org.restlet.ext.servlet.internal.ServletCall;
045
046/**
047 * Helper to encapsulate Multipart requests parsing to extract blobs.
048 * <p>
049 * This helper is needed to provide the indirection between - the Apache file upload based solution (5.1) and - the Seam
050 * MultiPartFilter bases solution (5.1 / Seam 2.x).
051 *
052 * @author tiry
053 */
054public class FileUploadHelper {
055
056    private FileUploadHelper() {
057    }
058
059    /**
060     * Parses a Multipart Restlet Request to extract blobs.
061     */
062    public static List<Blob> parseRequest(Request request) throws FileUploadException, IOException {
063        if (request instanceof HttpRequest) {
064            HttpRequest httpRequest = (HttpRequest) request;
065            ServerCall httpCall = httpRequest.getHttpCall();
066            if (httpCall instanceof ServletCall) {
067                HttpServletRequest httpServletRequest = ((ServletCall) httpCall).getRequest();
068                return parseRequest(httpServletRequest);
069            }
070        }
071        return null;
072    }
073
074    public static List<Blob> parseRequest(HttpServletRequest request) throws FileUploadException, IOException {
075        if (!isMultipartRequest(request)) {
076            try (InputStream in = request.getInputStream()) {
077                Blob blob = createBlob(in, request.getContentType());
078                return Collections.singletonList(blob);
079            }
080        } else {
081            FileUpload fileUpload = new FileUpload(new DiskFileItemFactory());
082            String fileNameCharset = request.getHeader("FileNameCharset"); // compat with old code
083            if (fileNameCharset != null) {
084                fileUpload.setHeaderEncoding(fileNameCharset);
085            }
086            List<Blob> blobs = new ArrayList<>();
087            for (FileItem item : fileUpload.parseRequest(new ServletRequestContext(request))) {
088                try (InputStream is = item.getInputStream()) {
089                    Blob blob = createBlob(is, item.getContentType());
090                    blob.setFilename(item.getName());
091                    blobs.add(blob);
092                }
093            }
094            return blobs;
095        }
096    }
097
098    public static boolean isMultipartRequest(Request request) {
099        HttpServletRequest httpServletRequest = ((ServletCall) ((HttpRequest) request).getHttpCall()).getRequest();
100        return isMultipartRequest(httpServletRequest);
101    }
102
103    public static boolean isMultipartRequest(HttpServletRequest request) {
104        if (!"POST".equalsIgnoreCase(request.getMethod())) {
105            return false;
106        }
107        String contentType = request.getContentType();
108        return contentType == null ? false : contentType.toLowerCase().startsWith("multipart/");
109    }
110
111    public static Blob createBlob(InputStream in, String contentType) throws IOException {
112        ContentType ct = ContentType.parse(contentType);
113        String mimeType = ct.getMimeType();
114        Charset charset = ct.getCharset();
115        String encoding = charset == null ? null : charset.name();
116        return Blobs.createBlob(in, mimeType, encoding);
117    }
118
119}