com.netfinworks.rest.convert.MultiPartFormDataParamConvert.java Source code

Java tutorial

Introduction

Here is the source code for com.netfinworks.rest.convert.MultiPartFormDataParamConvert.java

Source

/*
 * Copyright 2012 weibopay.com, Inc. All rights reserved.
 * weibopay.com PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.netfinworks.rest.convert;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileCleaningTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;

import com.netfinworks.rest.filter.Request;
import com.netfinworks.rest.util.ConvertUtil;
import com.netfinworks.rest.util.Magic;

/**
 * <p>?multipartform??</p>
 * @author zhangjiewen
 * @version $Id: FileParamConvert.java, v 0.1 2012-11-15 ?6:09:32 zhangjiewen Exp $
 */
public class MultiPartFormDataParamConvert extends Form2PojoParamConvert implements DisposableBean {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private static FileCleaningTracker tracker = new FileCleaningTracker();
    private static DiskFileItemFactory factory = new DiskFileItemFactory();
    static {
        factory.setSizeThreshold(Magic.MultiPartMaxMemorySize);
        //factory.setRepository(yourTempDirectory);
        factory.setFileCleaningTracker(tracker);
    }

    public void destroy() throws Exception {
        logger.info("MultiPartFormDataParamConvert destroy.");
        tracker.exitWhenFinished();
    }

    @Override
    public <T> T convert(String paramString, Class<T> paramClass) {
        throw new IllegalAccessError("multipart form can't convert by string.");
    }

    @SuppressWarnings("rawtypes")
    public <T> T convert(Request restRequest, Class<T> paramClass) {
        //multipart/form-data??requestString/inputStream        
        T pojo;
        try {
            pojo = paramClass.newInstance();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(Magic.MultiPartFileSizeMax);
            List items = upload.parseRequest(restRequest.getRawRequest());
            Iterator iter = items.iterator();//upload.getItemIterator(restRequest.getRawRequest());
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();
                logger.debug(item.toString());
                if (item.isFormField()) {
                    processFormField(item, pojo);
                } else {
                    processUploadedFile(item, pojo);
                }
            }
            return pojo;
        } catch (InstantiationException e) {
            logger.error("can't instantiate a pojo of {}, please check the Pojo", paramClass);
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            logger.error("can't invoke none-args constructor of a pojo of {}, please check the Pojo", paramClass);
            throw new RuntimeException(e);
        } catch (FileUploadException e) {
            logger.error("fileupload error.", paramClass);
            throw new RuntimeException(e);
        }
    }

    public <T> void processUploadedFile(FileItem item, T pojo) {
        try {
            String name = item.getFieldName();
            if (name == null || Magic.EmtpyString.equals(name)) {
                return;
            }
            Class<?> cls = getPropertyClass(pojo.getClass(), name);
            if (cls == null) {
                return;
            }
            if (cls.equals(String.class)) {
                String value = item.getString(encoding);
                IParamConvert paramConvert = classParamConvertRegistry.get(cls.getName());
                Object oldValue = getPropertyValue(pojo, pojo.getClass(), name);
                Object convertedValue = ConvertUtil.addUrlEncodedStringIfArray(oldValue, value, encoding, cls,
                        paramConvert == null ? primitiveConvert : paramConvert);
                if (convertedValue != null) {
                    BeanUtils.setProperty(pojo, name, convertedValue);
                }
            } else if (cls.equals(InputStream.class)) {
                Object convertedValue = item.getInputStream();
                if (convertedValue != null) {
                    BeanUtils.setProperty(pojo, name, convertedValue);
                }
            } else if (cls.equals(FileItem.class)) {
                BeanUtils.setProperty(pojo, name, item);
            } else {
                logger.warn("Not support field[{}] type:{}.", name, cls);
            }
        } catch (IllegalAccessException e) {
            logger.error("can't invoke none-args constructor of a pojo of {}, please check the Pojo",
                    pojo.getClass());
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            logger.error("set pojo property error!", e);
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            logger.error("can't convert stream to " + encoding, e);
            throw new RuntimeException(e);
        } catch (IOException e) {
            logger.error("getInputStream from item error!", e);
            throw new RuntimeException(e);
        }
    }

    public <T> void processFormField(FileItem item, T pojo) {
        try {
            String value = item.getString(encoding);
            String name = item.getFieldName();
            if (name == null || Magic.EmtpyString.equals(name)) {
                return;
            }
            Class<?> cls = getPropertyClass(pojo.getClass(), name);
            if (cls == null) {
                return;
            }
            IParamConvert paramConvert = classParamConvertRegistry.get(cls.getName());
            Object oldValue = getPropertyValue(pojo, pojo.getClass(), name);
            Object convertedValue = ConvertUtil.addUrlEncodedStringIfArray(oldValue, value, encoding, cls,
                    paramConvert == null ? primitiveConvert : paramConvert);
            if (convertedValue != null) {
                BeanUtils.setProperty(pojo, name, convertedValue);
            }

        } catch (IllegalAccessException e) {
            logger.error("can't invoke none-args constructor of a pojo of {}, please check the Pojo",
                    pojo.getClass());
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            logger.error("set pojo property error!", e);
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            logger.error("can't convert stream to " + encoding, e);
            throw new RuntimeException(e);
        }
    }

    protected <T> Object getPropertyValue(T pojo, Class<?> clazz, String propertyName) {
        Object v = null;
        try {
            v = getPropertyValue(pojo, clazz, propertyName, "get");
        } catch (NoSuchMethodException e) {
            try {
                v = getPropertyValue(pojo, clazz, propertyName, "is");
            } catch (NoSuchMethodException e1) {
                logger.debug("property '{}' doesn't exist! ", propertyName);
            }
        }
        return v;

    }

    private <T> Object getPropertyValue(T pojo, Class<?> clazz, String propertyName, String prefix)
            throws NoSuchMethodException {
        StringBuffer buf = new StringBuffer(propertyName);
        int char0 = buf.charAt(0);
        buf.setCharAt(0, (char) (char0 >= 97 ? char0 - 32 : char0));
        buf.insert(0, prefix);
        Method m = null;
        try {
            m = clazz.getMethod(buf.toString(), emptyClazzArray);
            return m.invoke(pojo, new Object[0]);
        } catch (SecurityException e) {
            logger.debug("property can't be access! ");
            return null;
        } catch (NoSuchMethodException e) {
            logger.debug("property '{}' doesn't exist! ", buf.toString());
            throw e;
        } catch (IllegalArgumentException e) {
            logger.debug("method can't be invoke! wrong argument. " + e.toString());
            return null;
        } catch (IllegalAccessException e) {
            logger.debug("method can't be invoke! access exception. " + e.toString());
            return null;
        } catch (InvocationTargetException e) {
            logger.debug("method can't be invoke! invocation target. " + e.toString());
            return null;
        }

    }
}