me.doshou.admin.maintain.staticresource.web.controller.StaticResourceVersionController.java Source code

Java tutorial

Introduction

Here is the source code for me.doshou.admin.maintain.staticresource.web.controller.StaticResourceVersionController.java

Source

/**
 * Copyright (c) 2005-2012 https://github.com/zhangkaitao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package me.doshou.admin.maintain.staticresource.web.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import me.doshou.common.web.controller.BaseController;
import me.doshou.admin.maintain.staticresource.web.controller.utils.YuiCompressorUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * ???
 * ?
 *  ???? .jspf? webapp/WEB-INF/jsp/common
 * ????
 *
 * @author YorkChow<york.chow@actionsky.com>
 * @since 2014/12/4
 * Time: 23:01
 */
@Controller
@RequestMapping("/admin/maintain/staticResource")
@RequiresPermissions("maintain:staticResource:*")
public class StaticResourceVersionController extends BaseController {

    private final String versionedResourcePath = "/WEB-INF/jsp/common";
    private final Pattern scriptPattern = Pattern.compile("(.*<script.* src=[\'\"])(.*?)(\\??)(\\d*)([\'\"].*>.*)",
            Pattern.CASE_INSENSITIVE);
    private final Pattern linkPattern = Pattern.compile("(.*<link.* href=[\'\"])(.*?)(\\??)(\\d*)([\'\"].*>.*)",
            Pattern.CASE_INSENSITIVE);

    @Autowired
    private ServletContext sc;

    @RequestMapping()
    public String list(Model model) throws IOException {

        String realPath = sc.getRealPath(versionedResourcePath);

        model.addAttribute("resources", findStaticResources(realPath));

        return viewName("list");
    }

    @RequestMapping(value = "incVersion", method = RequestMethod.POST)
    @ResponseBody
    public String incVersion(@RequestParam("fileName") String fileName, @RequestParam("content") String content,
            @RequestParam("newVersion") String newVersion) throws IOException {

        String realPath = sc.getRealPath(versionedResourcePath);

        return versionedStaticResourceContent(realPath + fileName, content, newVersion);

    }

    @RequestMapping(value = "batchIncVersion", method = RequestMethod.POST)
    @ResponseBody
    public String batchIncVersion(@RequestParam("fileNames[]") String[] fileNames,
            @RequestParam("contents[]") String[] contents, @RequestParam("newVersions[]") String[] newVersions)
            throws IOException {

        String realPath = sc.getRealPath(versionedResourcePath);

        for (int i = 0, l = fileNames.length; i < l; i++) {
            versionedStaticResourceContent(realPath + fileNames[i], contents[i], newVersions[i]);
        }

        return "??";

    }

    @RequestMapping(value = "clearVersion", method = RequestMethod.POST)
    @ResponseBody
    public String clearVersion(@RequestParam("fileNames[]") String[] fileNames,
            @RequestParam("contents[]") String[] contents) throws IOException {

        String realPath = sc.getRealPath(versionedResourcePath);

        for (int i = 0, l = fileNames.length; i < l; i++) {
            versionedStaticResourceContent(realPath + fileNames[i], contents[i], null);
        }

        return "??";

    }

    @RequestMapping("compress")
    @ResponseBody
    public String compress(@RequestParam("fileName") String fileName, @RequestParam("content") String content) {

        String rootRealPath = sc.getRealPath("/WEB-INF");
        String versionedResourceRealPath = sc.getRealPath(versionedResourcePath);

        try {
            String minFilePath = compressStaticResource(rootRealPath, versionedResourceRealPath + fileName,
                    content);
            return "?" + minFilePath;
        } catch (Exception e) {
            return "" + e.getMessage();
        }
    }

    @RequestMapping("batchCompress")
    @ResponseBody
    public String batchCompress(@RequestParam("fileNames[]") String[] fileNames,
            @RequestParam("contents[]") String[] contents) throws IOException {

        String rootRealPath = sc.getRealPath("/WEB-INF");
        String versionedResourceRealPath = sc.getRealPath(versionedResourcePath);

        StringBuilder success = new StringBuilder();
        StringBuilder error = new StringBuilder();

        for (int i = 0, l = fileNames.length; i < l; i++) {
            try {
                String fileName = fileNames[i];
                String content = contents[i];
                String minFilePath = compressStaticResource(rootRealPath, versionedResourceRealPath + fileName,
                        content);
                success.append("?" + minFilePath + "<br/>");
            } catch (Exception e) {
                error.append("" + e.getMessage() + "<br/>");
            }
        }

        return success.insert(0, "?<br/>").append("<br/><br/>").append(error)
                .toString();
    }

    /**
     * ?
     * @param fileName
     * @param content
     * @return
     */
    @RequestMapping("switch")
    @ResponseBody
    public Object switchStaticResource(@RequestParam("fileName") String fileName,
            @RequestParam("content") String content,
            @RequestParam(value = "min", required = false, defaultValue = "false") boolean isMin

    ) {

        Map<String, Object> data = Maps.newHashMap();
        data.put("msg", "??");
        data.put("success", true);

        String rootRealPath = sc.getRealPath("/WEB-INF");
        String versionedResourceRealPath = sc.getRealPath(versionedResourcePath);

        try {
            StaticResource resource = switchStaticResourceContent(rootRealPath, versionedResourceRealPath, fileName,
                    content, isMin);
            data.put("content", resource.getContent());
            data.put("url", resource.getUrl());
            return data;
        } catch (Exception e) {
            data.put("msg", "?" + e.getMessage());
            data.put("success", false);
            return data;
        }
    }

    /**
     * ??
     * @param fileNames
     * @param contents
     * @return
     * @throws java.io.IOException
     */
    @RequestMapping("batchSwitch")
    @ResponseBody
    public String batchSwitchStaticResource(@RequestParam("fileNames[]") String[] fileNames,
            @RequestParam("contents[]") String[] contents,
            @RequestParam(value = "min", required = false, defaultValue = "false") boolean isMin

    ) throws IOException {

        String rootRealPath = sc.getRealPath("/WEB-INF");
        String versionedResourceRealPath = sc.getRealPath(versionedResourcePath);

        StringBuilder success = new StringBuilder();
        StringBuilder error = new StringBuilder();

        for (int i = 0, l = fileNames.length; i < l; i++) {
            try {
                String fileName = fileNames[i];
                String content = contents[i];
                StaticResource resource = switchStaticResourceContent(rootRealPath, versionedResourceRealPath,
                        fileName, content, isMin);
                success.append("???" + resource.getUrl() + "<br/>");
            } catch (Exception e) {
                error.append("?" + e.getMessage() + "<br/>");
            }
        }

        return success.insert(0, "??<br/>").append("<br/>?<br/>").append(error)
                .toString();
    }

    private StaticResource switchStaticResourceContent(String rootRealPath, String versionedResourceRealPath,
            String fileName, String content, boolean isMin) throws IOException {

        StaticResource resource = extractResource(fileName, content);
        String filePath = resource.getUrl();
        filePath = filePath.replace("${ctx}", rootRealPath);

        if (isMin) {
            File file = new File(YuiCompressorUtils.getCompressFileName(filePath));
            if (!file.exists()) {
                throw new RuntimeException("" + resource.getUrl());
            }
        } else {
            File file = new File(YuiCompressorUtils.getNoneCompressFileName(filePath));
            if (!file.exists()) {
                throw new RuntimeException("?" + resource.getUrl());
            }
        }

        content = StringEscapeUtils.unescapeXml(content);

        File file = new File(versionedResourceRealPath + fileName);

        List<String> contents = FileUtils.readLines(file);

        for (int i = 0, l = contents.size(); i < l; i++) {
            String fileContent = contents.get(i);
            if (content.equals(fileContent)) {
                Matcher matcher = scriptPattern.matcher(content);
                if (!matcher.matches()) {
                    matcher = linkPattern.matcher(content);
                }
                String newUrl = isMin ? YuiCompressorUtils.getCompressFileName(resource.getUrl())
                        : YuiCompressorUtils.getNoneCompressFileName(resource.getUrl());

                content = matcher.replaceAll("$1" + Matcher.quoteReplacement(newUrl) + "$3$4$5");
                contents.set(i, content);

                resource.setContent(content);
                resource.setUrl(newUrl);

                break;
            }
        }
        FileUtils.writeLines(file, contents);

        return resource;
    }

    private String compressStaticResource(String rootRealPath, String includeFilePath, String content) {
        StaticResource resource = extractResource(includeFilePath, content);
        String filePath = resource.getUrl();
        filePath = filePath.replace("${ctx}", rootRealPath);

        if (YuiCompressorUtils.hasCompress(filePath)) {
            throw new RuntimeException("[" + filePath + "]????");
        }

        if (filePath.startsWith("http://")) {
            throw new RuntimeException("[" + filePath + "]?");
        }

        String minFilePath = YuiCompressorUtils.compress(filePath);

        return minFilePath.replace(rootRealPath, "${ctx}");

    }

    private String versionedStaticResourceContent(String fileRealPath, String content, String newVersion)
            throws IOException {

        content = StringEscapeUtils.unescapeXml(content);
        if (newVersion != null && newVersion.equals("1")) {
            newVersion = "?" + newVersion;
        }

        File file = new File(fileRealPath);

        List<String> contents = FileUtils.readLines(file);

        for (int i = 0, l = contents.size(); i < l; i++) {
            String fileContent = contents.get(i);
            if (content.equals(fileContent)) {
                Matcher matcher = scriptPattern.matcher(content);
                if (!matcher.matches()) {
                    matcher = linkPattern.matcher(content);
                }
                if (newVersion == null) { //
                    content = matcher.replaceAll("$1$2$5");
                } else {
                    content = matcher.replaceAll("$1$2$3" + newVersion + "$5");
                }
                contents.set(i, content);
                break;
            }
        }
        FileUtils.writeLines(file, contents);

        return content;
    }

    private Map<String, List<StaticResource>> findStaticResources(String realPath) throws IOException {

        final Map<String, List<StaticResource>> resources = Maps.newTreeMap();

        final int realPathLength = realPath.length();

        Collection<File> files = FileUtils.listFiles(new File(realPath), new String[] { "jspf" }, true);

        for (File file : files) {

            String fileName = file.getAbsolutePath().substring(realPathLength);
            List<String> contents = FileUtils.readLines(file);

            List<StaticResource> resourceList = resources.get(fileName);
            if (resourceList == null) {
                resourceList = Lists.newArrayList();
            }

            for (String content : contents) {
                if (!StringUtils.isEmpty(content)) {
                    StaticResource resource = extractResource(fileName, content);
                    if (resource != null) {
                        resourceList.add(resource);
                    }
                }
            }

            if (CollectionUtils.isNotEmpty(resourceList)) {
                resources.put(fileName, resourceList);
            }
        }

        return resources;
    }

    private StaticResource extractResource(String fileName, String content) {

        Matcher matcher = scriptPattern.matcher(content);
        if (!matcher.matches()) {
            matcher = linkPattern.matcher(content);
        }

        if (!matcher.matches()) {
            return null;
        }

        String url = matcher.group(2);
        String version = "";
        version = matcher.group(4);

        StaticResource resource = new StaticResource(fileName, content);
        resource.setUrl(url);
        resource.setVersion(version);

        return resource;
    }

    public static class StaticResource {
        private String fileName;
        private String content;
        private String url;
        private String version;

        private StaticResource(String fileName, String content) {
            this.fileName = fileName;
            this.content = content;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getVersion() {
            return version;
        }

        public void setVersion(String version) {
            this.version = version;
        }

        @Override
        public String toString() {
            return "StaticResource{" + "fileName='" + fileName + '\'' + ", content='" + content + '\'' + ", url='"
                    + url + '\'' + ", version=" + version + '}';
        }
    }

}