001/*
002 * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.ui.web.util;
021
022import java.io.IOException;
023import java.io.InputStream;
024import java.util.ArrayList;
025import java.util.Enumeration;
026import java.util.List;
027
028import javax.servlet.http.HttpServletRequest;
029
030import org.apache.commons.fileupload.FileItem;
031import org.apache.commons.fileupload.FileUpload;
032import org.apache.commons.fileupload.FileUploadException;
033import org.apache.commons.fileupload.disk.DiskFileItemFactory;
034import org.apache.commons.fileupload.servlet.ServletRequestContext;
035import org.jboss.seam.web.MultipartRequest;
036import org.nuxeo.ecm.core.api.Blob;
037import org.nuxeo.ecm.core.api.Blobs;
038import org.restlet.data.Request;
039
040import com.noelios.restlet.ext.servlet.ServletCall;
041import com.noelios.restlet.http.HttpCall;
042import com.noelios.restlet.http.HttpRequest;
043
044/**
045 * Helper to encapsulate Multipart requests parsing to extract blobs.
046 * <p>
047 * This helper is needed to provide the indirection between - the Apache file upload based solution (5.1) and - the Seam
048 * MultiPartFilter bases solution (5.1 / Seam 2.x).
049 *
050 * @author tiry
051 */
052public class FileUploadHelper {
053
054    private FileUploadHelper() {
055    }
056
057    /**
058     * Parses a Multipart Restlet Request to extract blobs.
059     */
060    public static List<Blob> parseRequest(Request request) throws FileUploadException, IOException {
061        if (request instanceof HttpRequest) {
062            HttpRequest httpRequest = (HttpRequest) request;
063            HttpCall httpCall = httpRequest.getHttpCall();
064            if (httpCall instanceof ServletCall) {
065                HttpServletRequest httpServletRequest = ((ServletCall) httpCall).getRequest();
066                return parseRequest(httpServletRequest);
067            }
068        }
069        return null;
070    }
071
072    /**
073     * Parses a Multipart Servlet Request to extract blobs
074     */
075    public static List<Blob> parseRequest(HttpServletRequest request) throws FileUploadException, IOException {
076        List<Blob> blobs = new ArrayList<Blob>();
077
078        if (request instanceof MultipartRequest) {
079            MultipartRequest seamMPRequest = (MultipartRequest) request;
080
081            Enumeration<String> names = seamMPRequest.getParameterNames();
082            while (names.hasMoreElements()) {
083                String name = names.nextElement();
084                try (InputStream in = seamMPRequest.getFileInputStream(name)) {
085                    if (in != null) {
086                        Blob blob = Blobs.createBlob(in);
087                        blob.setFilename(seamMPRequest.getFileName(name));
088                        blobs.add(blob);
089                    }
090                }
091            }
092        } else {
093            // fallback method for non-seam servlet request
094            FileUpload fu = new FileUpload(new DiskFileItemFactory());
095            String fileNameCharset = request.getHeader("FileNameCharset");
096            if (fileNameCharset != null) {
097                fu.setHeaderEncoding(fileNameCharset);
098            }
099            ServletRequestContext requestContext = new ServletRequestContext(request);
100            List<FileItem> fileItems = fu.parseRequest(requestContext);
101            for (FileItem item : fileItems) {
102                try (InputStream is = item.getInputStream()) {
103                    Blob blob = Blobs.createBlob(is);
104                    blob.setFilename(item.getName());
105                    blobs.add(blob);
106                }
107            }
108        }
109        return blobs;
110    }
111
112}