org.xchain.framework.servlet.MultipartFormDataServletRequest.java Source code

Java tutorial

Introduction

Here is the source code for org.xchain.framework.servlet.MultipartFormDataServletRequest.java

Source

/**
 *    Copyright 2011 meltmedia
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.xchain.framework.servlet;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Enumeration;

import java.io.File;
import java.lang.reflect.Array;

/**
 *
 * This code was adapted from code originally written by Darius Robinson.
 *
 * @author Darius Robinson
 * @author Christian Trimble
 * @author John Trimble
 * @author Josh Kennedy
 * @version 1.0
 */
public class MultipartFormDataServletRequest extends HttpServletRequestWrapper {

    public static Logger log = LoggerFactory.getLogger(MultipartFormDataServletRequest.class);

    private Map<String, String[]> parameterMap = new HashMap<String, String[]>();
    private Map<String, FileItem[]> fileItemMap = new HashMap<String, FileItem[]>();

    public MultipartFormDataServletRequest(HttpServletRequest request, long maxSize, int sizeThreshold,
            String repositoryPath) throws FileUploadException {
        super(request);

        // Create the disk file item factory.
        DiskFileItemFactory factory = createDiskFileItemFactory(sizeThreshold, repositoryPath);
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
        // maximum size before a FileUploadException will be thrown
        servletFileUpload.setSizeMax(maxSize);

        // parse the request.
        Iterator<FileItem> fileItemIterator = servletFileUpload.parseRequest(request).iterator(); // Oye! Unchecked type conversion.

        // create temporary maps for parameters and file items.
        Map<String, List<String>> parameterMap = new HashMap<String, List<String>>();
        Map<String, List<FileItem>> fileItemMap = new HashMap<String, List<FileItem>>();

        // populate the maps.
        while (fileItemIterator.hasNext()) {
            FileItem fileItem = fileItemIterator.next();
            if (fileItem.isFormField()) {
                putListMapValue(parameterMap, fileItem.getFieldName(), fileItem.getString());
            } else {
                putListMapValue(fileItemMap, fileItem.getFieldName(), fileItem);
            }
        }

        // convert the array lists.
        convertListMapToArrayMap(parameterMap, this.parameterMap, String.class);
        convertListMapToArrayMap(fileItemMap, this.fileItemMap, FileItem.class);

        if (log.isDebugEnabled()) {
            logFileItemMap();
        }

    }

    public FileItem getFileItem(String name) {
        FileItem fileItem = null;
        FileItem[] fileItemArray = (FileItem[]) fileItemMap.get(name);

        if (fileItemArray != null)
            fileItem = fileItemArray[0];

        return fileItem;
    }

    public Enumeration<String> getFileItemNames() {
        return new IteratorEnumeration<String>(fileItemMap.keySet().iterator());
    }

    public Map<String, FileItem[]> getFileItemMap() {
        return fileItemMap;
    }

    public FileItem[] getFileItemValues(String name) {
        return (FileItem[]) fileItemMap.get(name);
    }

    public String getParameter(String name) {
        String parameter = null;
        String[] parameterList = (String[]) parameterMap.get(name);

        if (parameterList != null && parameterList.length > 0) {
            parameter = parameterList[0];
        }

        return parameter;
    }

    public Enumeration<String> getParameterNames() {
        return new IteratorEnumeration<String>(parameterMap.keySet().iterator());
    }

    public Map<String, String[]> getParameterMap() {
        return parameterMap;
    }

    public String[] getParameterValues(String name) {
        return (String[]) parameterMap.get(name);
    }

    private static <K, V> Map<K, V[]> convertListMapToArrayMap(Map<K, List<V>> listMap, Map<K, V[]> arrayMap,
            Class<V> elementType) {
        if (arrayMap == null)
            arrayMap = new HashMap<K, V[]>();
        for (Map.Entry<K, List<V>> e : listMap.entrySet()) {
            V[] valueArray = (V[]) Array.newInstance(elementType, e.getValue().size());
            arrayMap.put(e.getKey(), e.getValue().toArray(valueArray));
        }
        return arrayMap;
    }

    private static <K, V> void putListMapValue(Map<K, List<V>> map, K key, V value) {
        List<V> valueArray = map.get(key);

        if (valueArray == null) {
            valueArray = new ArrayList<V>();
            map.put(key, valueArray);
        }
        valueArray.add(value);
    }

    private static DiskFileItemFactory createDiskFileItemFactory(int sizeThreshold, String repositoryPath)
            throws FileUploadException {
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // the location for saving data that is larger than getSizeThreshold()
        File repository = new File(repositoryPath);
        factory.setRepository(repository);

        // maximum size that will be stored in memory
        factory.setSizeThreshold(sizeThreshold);

        // Check to see if repository exists; if not, try to create it; if this fails, throw an exception. 
        if (repository.exists()) {
            if (!repository.isDirectory()) {
                throw new FileUploadException("Cannot upload files because the specified temporary "
                        + "directory is of type file. (" + repository.getAbsolutePath() + ")");
            }
        } else if (!repository.mkdir()) {
            throw new FileUploadException("Cannot upload files because the specified temporary "
                    + " does not exist, and attempts to create it have failed. (" + repository.getAbsolutePath()
                    + ")");

        }
        return factory;
    }

    protected void logFileItemMap() {
        log.debug("File item map has " + fileItemMap.keySet().size() + " keys.");
        Iterator<Map.Entry<String, FileItem[]>> entryIterator = fileItemMap.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, FileItem[]> entry = entryIterator.next();
            String key = entry.getKey();
            FileItem[] fileItems = entry.getValue();

            log.debug("Key '" + key + "' has " + fileItems.length + " entries.");

            for (int i = 0; i < fileItems.length; i++) {
                log.debug("Name='" + fileItems[i].getName() + "', size=" + fileItems[i].getSize()
                        + ", content-type='" + fileItems[i].getContentType() + "'");
            }
        }
    }
}

class IteratorEnumeration<T> implements Enumeration<T> {
    Iterator<T> wrappedIterator = null;

    public IteratorEnumeration(Iterator<T> wrappedIterator) {
        this.wrappedIterator = wrappedIterator;
    }

    public boolean hasMoreElements() {
        return wrappedIterator.hasNext();
    }

    public T nextElement() {
        return wrappedIterator.next();
    }
}