package com.muchencute.commons.sparkjava;

import org.apache.commons.io.FilenameUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.UnaryOperator;

/**
 * 文件上传请求 Handler
 *
 * @author miguoliang
 */
public class FileUploadHandler {

    private static final String FIELD_NAME = "file";

    private final String mFieldName;

    private final HttpServletRequest mRequest;

    private final String mDestination;

    private final Set<String> mExtensions;

    private final boolean mMultiple;

    public FileUploadHandler(HttpServletRequest req, String destination, Set<String> extensions) {

        this(req, destination, extensions, FIELD_NAME, false);
    }

    public FileUploadHandler(final HttpServletRequest req, final String destination, final Set<String> extensions,
                             final String fieldName, final boolean multiple) {

        this.mFieldName = fieldName;
        this.mRequest = req;
        this.mDestination = destination;
        this.mMultiple = multiple;

        extensions.forEach(s -> s = s.toLowerCase());
        this.mExtensions = extensions;
    }

    public void handle(UnaryOperator<String> filenameOperator) throws IOException, ServletException {

        for (Part part : mRequest.getParts()) {
            if (part.getName().equalsIgnoreCase(mFieldName) &&
                    mExtensions.contains(FilenameUtils.getExtension(part.getSubmittedFileName()).toLowerCase())) {
                persistOnDisk(part, filenameOperator);
                if (!mMultiple) {
                    return;
                }
            }
        }
    }

    private void persistOnDisk(Part part, UnaryOperator<String> filenameOperator) throws IOException {

        Set<PosixFilePermission> defaultPermissions = new HashSet<PosixFilePermission>() {{
            add(PosixFilePermission.OWNER_READ);
            add(PosixFilePermission.OWNER_WRITE);
            add(PosixFilePermission.GROUP_READ);
            add(PosixFilePermission.OTHERS_READ);
        }};

        Path target = Paths.get(mDestination, filenameOperator.apply(part.getSubmittedFileName()));
        Files.copy(part.getInputStream(), target, StandardCopyOption.REPLACE_EXISTING);
        Files.setPosixFilePermissions(target, defaultPermissions);
    }

}

@@ -198,16 +198,37 @@
 p.Part;%0A
+import java.io.File;%0A
 import j
@@ -783,22 +783,20 @@
 e final 
-String
+File
  mDestin
@@ -938,22 +938,20 @@
 st req, 
-String
+File
  destina
@@ -1118,22 +1118,20 @@
 , final 
-String
+File
  destina
@@ -2431,24 +2431,42 @@
 mDestination
+.getAbsolutePath()
 , filenameOp

update FileUploadHandler