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.util.ArrayList;
027import java.util.Enumeration;
028import java.util.List;
029
030import javax.servlet.http.HttpServletRequest;
031
032import org.apache.commons.fileupload.FileItem;
033import org.apache.commons.fileupload.FileUpload;
034import org.apache.commons.fileupload.FileUploadException;
035import org.apache.commons.fileupload.disk.DiskFileItemFactory;
036import org.apache.commons.fileupload.servlet.ServletRequestContext;
037import org.jboss.seam.web.MultipartRequest;
038import org.nuxeo.ecm.core.api.Blob;
039import org.nuxeo.ecm.core.api.Blobs;
040import org.restlet.data.Request;
041
042import com.noelios.restlet.ext.servlet.ServletCall;
043import com.noelios.restlet.http.HttpCall;
044import com.noelios.restlet.http.HttpRequest;
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            HttpCall 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    /**
075     * Parses a Multipart Servlet Request to extract blobs
076     */
077    public static List<Blob> parseRequest(HttpServletRequest request) throws FileUploadException, IOException {
078        List<Blob> blobs = new ArrayList<Blob>();
079
080        if (request instanceof MultipartRequest) {
081            MultipartRequest seamMPRequest = (MultipartRequest) request;
082
083            Enumeration<String> names = seamMPRequest.getParameterNames();
084            while (names.hasMoreElements()) {
085                String name = names.nextElement();
086                try (InputStream in = seamMPRequest.getFileInputStream(name)) {
087                    if (in != null) {
088                        Blob blob = Blobs.createBlob(in);
089                        blob.setFilename(seamMPRequest.getFileName(name));
090                        blobs.add(blob);
091                    }
092                }
093            }
094        } else {
095            // fallback method for non-seam servlet request
096            FileUpload fu = new FileUpload(new DiskFileItemFactory());
097            String fileNameCharset = request.getHeader("FileNameCharset");
098            if (fileNameCharset != null) {
099                fu.setHeaderEncoding(fileNameCharset);
100            }
101            ServletRequestContext requestContext = new ServletRequestContext(request);
102            List<FileItem> fileItems = fu.parseRequest(requestContext);
103            for (FileItem item : fileItems) {
104                try (InputStream is = item.getInputStream()) {
105                    Blob blob = Blobs.createBlob(is);
106                    blob.setFilename(item.getName());
107                    blobs.add(blob);
108                }
109            }
110        }
111        return blobs;
112    }
113
114}