package com.tkhoon.framework.helper;

import com.tkhoon.framework.FrameworkConstant;
import com.tkhoon.framework.bean.Multipart;
import com.tkhoon.framework.bean.Multiparts;
import com.tkhoon.framework.exception.UploadException;
import com.tkhoon.framework.util.CollectionUtil;
import com.tkhoon.framework.util.FileUtil;
import com.tkhoon.framework.util.StreamUtil;
import com.tkhoon.framework.util.StringUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UploadHelper {

    private static final Logger logger = LoggerFactory.getLogger(UploadHelper.class);

    // 获取上传限制
    private static final int uploadLimit = ConfigHelper.getConfigNumber(FrameworkConstant.APP_UPLOAD_LIMIT);

    // 定义一个 FileUpload 对象（用于解析所上传的文件）
    private static ServletFileUpload fileUpload;

    public static void init(ServletContext servletContext) {
        // 获取一个临时目录（使用 Tomcat 的 work 目录）
        File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
        // 创建 FileUpload 对象
        fileUpload = new ServletFileUpload(new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository));
        // 设置上传限制
        if (uploadLimit != 0) {
            fileUpload.setFileSizeMax(uploadLimit * 1024 * 1024); // 单位为 M
            if (logger.isDebugEnabled()) {
                logger.debug("[Smart] limit of uploading: {}M", uploadLimit);
            }
        }
    }

    public static boolean isMultipart(HttpServletRequest request) {
        // 判断上传文件的内容是否为 multipart 类型
        return ServletFileUpload.isMultipartContent(request);
    }

    public static List<Object> createMultipartParamList(HttpServletRequest request) throws Exception {
        // 定义参数列表
        List<Object> paramList = new ArrayList<Object>();
        // 创建两个对象，分别对应 普通字段 与 文件字段
        Map<String, String> fieldMap = new HashMap<String, String>();
        List<Multipart> multipartList = new ArrayList<Multipart>();
        // 获取并遍历表单项
        List<FileItem> fileItemList;
        try {
            fileItemList = fileUpload.parseRequest(request);
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            // 异常转换（抛出自定义异常）
            throw new UploadException(e);
        }
        for (FileItem fileItem : fileItemList) {
            // 分两种情况处理表单项
            String fieldName = fileItem.getFieldName();
            if (fileItem.isFormField()) {
                // 处理普通字段
                String fieldValue = fileItem.getString(FrameworkConstant.CHARSET_UTF);
                fieldMap.put(fieldName, fieldValue);
            } else {
                // 处理文件字段
                String fileName = FileUtil.getRealFileName(fileItem.getName());
                if (StringUtil.isNotEmpty(fileName)) {
                    String contentType = fileItem.getContentType();
                    long fileSize = fileItem.getSize();
                    InputStream inputSteam = fileItem.getInputStream();
                    // 创建 Multipart 对象，并将其添加到 multipartList 中
                    Multipart multipart = new Multipart(fileName, contentType, fileSize, inputSteam);
                    multipartList.add(multipart);
                }
            }
        }
        // 初始化参数列表
        paramList.add(fieldMap);
        if (CollectionUtil.isNotEmpty(multipartList)) {
            paramList.add(new Multiparts(multipartList));
        } else {
            paramList.add(null);
        }
        // 返回参数列表
        return paramList;
    }

    public static void uploadFile(String basePath, Multipart multipart) {
        try {
            if (multipart != null) {
                // 创建文件路径（绝对路径）
                String filePath = basePath + multipart.getFileName();
                FileUtil.createFile(filePath);
                // 执行流复制操作
                InputStream inputStream = new BufferedInputStream(multipart.getInputStream());
                OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
                StreamUtil.copyStream(inputStream, outputStream);
            }
        } catch (Exception e) {
            logger.error("上传文件出错！", e);
            throw new RuntimeException(e);
        }
    }

    public static void uploadFiles(String basePath, Multiparts multiparts) {
        for (Multipart multipart : multiparts.getAll()) {
            uploadFile(basePath, multipart);
        }
    }
}

@@ -3200,24 +3200,112 @@
   // %E5%A4%84%E7%90%86%E6%96%87%E4%BB%B6%E5%AD%97%E6%AE%B5%0A
+                String originalFileName = FileUtil.getRealFileName(fileItem.getName());%0A
             
@@ -3384,24 +3384,41 @@
             
+           
+      
 if (StringUt
@@ -3431,17 +3431,25 @@
 otEmpty(
-f
+originalF
 ileName)
@@ -3448,24 +3448,158 @@
 ileName)) %7B%0A
+                                        String uploadedFileName = FileUtil.getEncodedFileName(originalFileName);%0A                     
             
@@ -3674,16 +3674,37 @@
         
+            
+         
 long fil
@@ -3727,24 +3727,45 @@
 .getSize();%0A
+                     
             
@@ -3840,24 +3840,45 @@
             
+   
+                  
 // %E5%88%9B%E5%BB%BA Multip
@@ -3927,16 +3927,45 @@
         
+              
+               
 Multipar
@@ -3992,17 +3992,25 @@
 ltipart(
-f
+uploadedF
 ileName,
@@ -4066,16 +4066,37 @@
         
+        
+             
 multipar
@@ -4125,33 +4125,182 @@
                 
-%7D
+                         // %E5%B0%86%E6%89%80%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6%E7%9A%84%E6%96%87%E4%BB%B6%E5%90%8D%E5%AD%98%E5%85%A5 fieldMap %E4%B8%AD%0A                                     fieldMap.put(fieldName, uploadedFileName);%0A                %7D%0A
 %0A            %7D%0A 

解决IE8中出现的文件上传的问题