de.pksoftware.springstrap.sapi.util.WebappZipper.java Source code

Java tutorial

Introduction

Here is the source code for de.pksoftware.springstrap.sapi.util.WebappZipper.java

Source

/*
 * 
 * Springstrap
 *
 * @author Jan Philipp Knller <info@pksoftware.de>
 * 
 * Homepage: http://ui5strap.com/springstrap
 *
 * Copyright (c) 2013-2014 Jan Philipp Knller <info@pksoftware.de>
 * 
 * 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.
 * Released under Apache2 license: http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 */

package de.pksoftware.springstrap.sapi.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.web.context.support.ServletContextResourcePatternResolver;

public class WebappZipper {

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

    private ZipOutputStream zos;
    private ServletContext servletContext;

    private Map<String, Resource> files = new HashMap<String, Resource>();

    public WebappZipper(OutputStream out, ServletContext servletContext) {
        zos = new ZipOutputStream(out);

        this.servletContext = servletContext;
    }

    public void close() throws IOException {
        zos.close();
    }

    /**
      * Zip it
      * @param zipFile output ZIP file location
      */
    public void addResource(String resourcePath, boolean fromContext) {
        byte[] buffer = new byte[1024];

        try {
            logger.info("Adding resource: {}", resourcePath);

            PathMatchingResourcePatternResolver resolver;

            if (fromContext) {
                resolver = new ServletContextResourcePatternResolver(servletContext);
            } else {
                resolver = new PathMatchingResourcePatternResolver();
            }

            // Ant-style path matching
            Resource[] resources = resolver.getResources(resourcePath);

            for (Resource resource : resources) {
                String fileAbsolute = resource.getURL().toString();
                String fileRelative = null;
                boolean addFile = false;

                if (fromContext) {
                    //File comes from webapp folder
                    fileRelative = "www" + servletContext.getContextPath()
                            + ((ServletContextResource) resource).getPath();
                    if (!fileRelative.endsWith("/")) {
                        addFile = true;
                    }

                } else {
                    //Files comes from webjar
                    int jarSeparatorIndex = fileAbsolute.indexOf("!/");

                    if (jarSeparatorIndex != -1) {
                        String relativeFileName = fileAbsolute.substring(jarSeparatorIndex);

                        Pattern pathPattern = Pattern.compile("\\!\\/webjar(\\/[a-z0-9_]+)+\\/www\\/");
                        Matcher pathMatcher = pathPattern.matcher(relativeFileName);
                        if (pathMatcher.find()) {
                            fileRelative = pathMatcher.replaceFirst("www" + servletContext.getContextPath() + "/");
                            addFile = true;
                        }
                    }
                }

                if (addFile && null != fileRelative) {
                    logger.debug("Adding File: {} => {}", fileAbsolute, fileRelative);

                    if (null != files.get(fileRelative)) {
                        continue;
                    }

                    if (fileRelative.startsWith("temp")) {
                        logger.error(fileAbsolute);
                    }

                    files.put(fileRelative, resource);

                    ZipEntry ze = new ZipEntry(fileRelative);
                    zos.putNextEntry(ze);

                    InputStream in = null;
                    try {
                        in = resource.getInputStream();

                        int len;
                        while ((len = in.read(buffer)) > 0) {
                            zos.write(buffer, 0, len);
                        }
                    } catch (FileNotFoundException fio) {
                        logger.error(fio.getMessage());
                    } finally {
                        if (null != in) {
                            in.close();
                        }
                    }
                }
            }

            zos.closeEntry();
            //remember close it

            logger.info("Done");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Unzip it
     * @param zipFile input zip file
     * @param output zip file output folder
     */
    public static void unzip(String zipFile, String outputFolder) {
        logger.info("Unzipping {} into {}.", zipFile, outputFolder);

        byte[] buffer = new byte[1024];

        try {

            //get the zip file content
            ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
            //get the zipped file list entry
            ZipEntry ze = zis.getNextEntry();

            while (ze != null) {
                if (ze.isDirectory()) {
                    ze = zis.getNextEntry();
                    continue;
                }

                String fileName = ze.getName();
                File newFile = new File(outputFolder + File.separator + fileName);

                logger.debug("Unzipping: {}", newFile.getAbsoluteFile());

                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                new File(newFile.getParent()).mkdirs();

                FileOutputStream fos = new FileOutputStream(newFile);

                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }

                fos.close();
                ze = zis.getNextEntry();
            }

            zis.closeEntry();
            zis.close();

            logger.debug("Unzipping {} completed.", zipFile);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}