Package org.ngrinder.common.util

Source Code of org.ngrinder.common.util.CompressionUtils$FilePredicate

/*
* 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.
*/
package org.ngrinder.common.util;

import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import static org.ngrinder.common.util.ExceptionUtils.processException;
import static org.ngrinder.common.util.Preconditions.checkNotNull;

/**
* Compression utility.
*
* @author JunHo Yoon
*/
@SuppressWarnings("All")
public abstract class CompressionUtils {
  private static final Logger LOGGER = LoggerFactory.getLogger(CompressionUtils.class);

  /**
   * Unzip the given zipped file with given character set.
   *
   * @param zippedFile  zipped file
   * @param charsetName character set
   */
  public static void unzip(File zippedFile, String charsetName) {
    unzip(zippedFile, zippedFile.getParentFile(), charsetName);
  }

  /**
   * Unzip the given zipped file into destination directory.
   *
   * @param zippedFile zipped file
   * @param destDir    destination directory
   */
  public static void unzip(File zippedFile, File destDir) {
    try {
      unzip(new FileInputStream(zippedFile), destDir, Charset.defaultCharset().name());
    } catch (FileNotFoundException e) {
      throw processException(e);
    }
  }

  /**
   * Unzip the given zipped file into destination directory with the given
   * character set.
   *
   * @param zippedFile  zipped file
   * @param destDir     destination directory
   * @param charsetName character set name
   */
  public static void unzip(File zippedFile, File destDir, String charsetName) {
    try {
      unzip(new FileInputStream(zippedFile), destDir, charsetName);
    } catch (FileNotFoundException e) {
      throw processException(e);
    }
  }

  /**
   * Unzip the given input stream into destination directory with the default
   * character set.
   *
   * @param is      input stream
   * @param destDir destination directory
   */
  public static void unzip(InputStream is, File destDir) {
    unzip(is, destDir, Charset.defaultCharset().name());
  }

  /**
   * Unzip the given input stream into destination directory with the given
   * character set.
   *
   * @param is          input stream
   * @param destDir     destination directory
   * @param charsetName character set name
   */
  public static void unzip(InputStream is, File destDir, String charsetName) {
    byte[] buffer = new byte[1024];
    ZipInputStream zis = null;
    FileOutputStream fos = null;
    try {
      File folder = destDir;
      if (!folder.exists()) {
        folder.mkdir();
      }

      zis = new ZipInputStream(is);
      ZipEntry ze = zis.getNextEntry();

      while (ze != null) {
        String fileName = ze.getName();

        File newFile = new File(destDir.getAbsolutePath(), fileName);
        if (newFile.getPath().contains("..")) {
          throw new IllegalArgumentException("zip entry should not contain .. in the path.");
        }
        if (ze.isDirectory()) {
          newFile.mkdirs();
        } else {
          fos = new FileOutputStream(newFile);
          int len;
          while ((len = zis.read(buffer)) > 0) {
            fos.write(buffer, 0, len);
          }
          IOUtils.closeQuietly(fos);
        }

        ze = zis.getNextEntry();
      }
    } catch (Exception e) {
      throw processException(e);
    } finally {
      IOUtils.closeQuietly(fos);
      IOUtils.closeQuietly(is);
      IOUtils.closeQuietly(zis);
    }
  }

  /**
   * Compresses the given file(or dir) and creates new file under the same
   * directory.
   *
   * @param src file or directory
   * @throws IOException IOException
   */
  public static void zip(File src) throws IOException {
    zip(src, Charset.defaultCharset().name(), true);
  }

  /**
   * Zips the given file(or dir) and create.
   *
   * @param src        file or directory to compress
   * @param includeSrc if true and src is directory, then src is not included in the
   *                   compression. if false, src is included.
   * @throws IOException IOException
   */
  public static void zip(File src, boolean includeSrc) throws IOException {
    zip(src, Charset.defaultCharset().name(), includeSrc);
  }

  /**
   * Compresses the given src file (or directory) with the given encoding.
   *
   * @param src         src
   * @param charSetName character set
   * @param includeSrc  true if sub-directory will be zipped as well.
   * @throws IOException IOException
   */
  public static void zip(File src, String charSetName, boolean includeSrc) throws IOException {
    zip(src, src.getParentFile(), charSetName, includeSrc);
  }

  /**
   * Compresses the given src file(or directory) and writes to the given
   * output stream with sub directory.
   *
   * @param src src
   * @param os  output stream
   * @throws IOException IOException
   */
  public static void zip(File src, OutputStream os) throws IOException {
    zip(src, os, Charset.defaultCharset().name(), true);
  }

  /**
   * Compresses the given src file(or directory) and create the compressed
   * file under the given destDir.
   *
   * @param src         src to be zipped.
   * @param destDir     destination directory
   * @param charSetName character set to be used
   * @param includeSrc  true if sub-directory will be zipped as well.
   * @throws IOException IOException
   */
  public static void zip(File src, File destDir, String charSetName, boolean includeSrc) throws IOException {
    String fileName = src.getName();
    if (!src.isDirectory()) {
      int pos = fileName.lastIndexOf(".");
      if (pos > 0) {
        fileName = fileName.substring(0, pos);
      }
    }
    fileName += ".zip";

    File zippedFile = new File(destDir, fileName);
    if (!zippedFile.exists()) {
      zippedFile.createNewFile();
    }
    FileOutputStream os = null;
    try {
      os = new FileOutputStream(zippedFile);
      zip(src, os, charSetName, includeSrc);
    } finally {
      IOUtils.closeQuietly(os);
    }
  }

  /**
   * Zip the given src into the given output stream.
   *
   * @param src         src to be zipped
   * @param os          output stream
   * @param charsetName character set to be used
   * @param includeSrc  true if src will be included.
   * @throws IOException IOException
   */
  public static void zip(File src, OutputStream os, String charsetName, boolean includeSrc) throws IOException {
    ZipArchiveOutputStream zos = new ZipArchiveOutputStream(os);
    zos.setEncoding(charsetName);
    FileInputStream fis = null;

    int length;
    ZipArchiveEntry ze;
    byte[] buf = new byte[8 * 1024];
    String name;

    Stack<File> stack = new Stack<File>();
    File root;
    if (src.isDirectory()) {
      if (includeSrc) {
        stack.push(src);
        root = src.getParentFile();
      } else {
        File[] fs = checkNotNull(src.listFiles());
        for (int i = 0; i < fs.length; i++) {
          stack.push(fs[i]);
        }

        root = src;
      }
    } else {
      stack.push(src);
      root = src.getParentFile();
    }

    while (!stack.isEmpty()) {
      File f = stack.pop();
      name = toPath(root, f);
      if (f.isDirectory()) {
        File[] fs = checkNotNull(f.listFiles());
        for (int i = 0; i < fs.length; i++) {
          if (fs[i].isDirectory()) {
            stack.push(fs[i]);
          } else {
            stack.add(0, fs[i]);
          }
        }
      } else {
        ze = new ZipArchiveEntry(name);
        zos.putArchiveEntry(ze);
        try {
          fis = new FileInputStream(f);
          while ((length = fis.read(buf, 0, buf.length)) >= 0) {
            zos.write(buf, 0, length);
          }
        } finally {
          IOUtils.closeQuietly(fis);
        }
        zos.closeArchiveEntry();
      }
    }
    zos.close();
  }

  private static String toPath(File root, File dir) {
    String path = dir.getAbsolutePath();
    path = path.substring(root.getAbsolutePath().length()).replace(File.separatorChar, '/');
    if (path.startsWith("/")) {
      path = path.substring(1);
    }
    if (dir.isDirectory() && !path.endsWith("/")) {
      path += "/";
    }
    return path;
  }

  public static final List<String> EXECUTABLE_EXTENSION = Arrays.asList("bat", "sh");

  /**
   * Untar an input file into an output file.
   * The output file is created in the output folder, having the same name as
   * the input file, minus the '.tar' extension.
   *
   * @param inFile    the input .tar file
   * @param outputDir the output directory file.
   * @return The {@link List} of {@link File}s with the untared content.
   */
  @SuppressWarnings("resource")
  public static List<File> untar(final File inFile, final File outputDir) {
    final List<File> untaredFiles = new LinkedList<File>();
    InputStream is = null;
    TarArchiveInputStream debInputStream = null;
    try {
      is = new FileInputStream(inFile);
      debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is);
      TarArchiveEntry entry;
      while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {
        final File outputFile = new File(outputDir, entry.getName());
        if (entry.isDirectory()) {
          if (!outputFile.exists()) {
            if (!outputFile.mkdirs()) {
              throw new IllegalStateException(String.format("Couldn't create directory %s.",
                  outputFile.getAbsolutePath()));
            }
          }
        } else {
          File parentFile = outputFile.getParentFile();
          if (!parentFile.exists()) {
            parentFile.mkdirs();
          }
          final OutputStream outputFileStream = new FileOutputStream(outputFile);
          try {
            IOUtils.copy(debInputStream, outputFileStream);
          } finally {
            IOUtils.closeQuietly(outputFileStream);
          }

          if (FilenameUtils.isExtension(outputFile.getName(), EXECUTABLE_EXTENSION)) {
            outputFile.setExecutable(true, true);
          }
          outputFile.setReadable(true);
          outputFile.setWritable(true, true);
        }
        untaredFiles.add(outputFile);
      }
    } catch (Exception e) {
      throw processException("Error while untar file", e);
    } finally {
      IOUtils.closeQuietly(is);
      IOUtils.closeQuietly(debInputStream);
    }
    return untaredFiles;
  }

  /**
   * Ungzip the given file.
   *
   * @param inFile  file
   * @param outFile to
   * @return ungzipped file.
   */
  public static File ungzip(final File inFile, final File outFile) {
    FileInputStream fin = null;
    BufferedInputStream in = null;
    FileOutputStream fout = null;
    GzipCompressorInputStream gzIn = null;
    try {
      fin = new FileInputStream(inFile);
      in = new BufferedInputStream(fin);
      gzIn = new GzipCompressorInputStream(in);
      if (!outFile.getParentFile().exists()) {
        outFile.getParentFile().mkdirs();
      }
      fout = new FileOutputStream(outFile);
      final byte[] buffer = new byte[4048];
      int n;
      while (-1 != (n = gzIn.read(buffer))) {
        fout.write(buffer, 0, n);
      }
    } catch (Exception e) {
      throw processException("Error while ungzip file", e);
    } finally {
      IOUtils.closeQuietly(fin);
      IOUtils.closeQuietly(in);
      IOUtils.closeQuietly(fout);
      IOUtils.closeQuietly(gzIn);
    }
    return outFile;
  }

  /**
   * Process each jar entry in the  given jar file.
   *
   * @param jarFile   jar file
   * @param processor jar file entry predicate
   * @throws IOException thrown when having IO problem.
   */
  public static void processJarEntries(File jarFile, ZipEntryProcessor processor) {
    try {
      JarFile jarfile = new JarFile(jarFile);
      Enumeration<java.util.jar.JarEntry> enu = jarfile.entries();
      while (enu.hasMoreElements()) {
        JarEntry je = enu.nextElement();
        if (je.isDirectory()) {
          continue;
        }
        processor.process(jarfile, je);
      }
    } catch (IOException e) {
      throw processException("Error while extracting jar file", e);
    }
  }


  /**
   * Add a file into tar.
   *
   * @param tarStream TarArchive outputStream
   * @param file      file
   * @param path      relative path to append
   * @throws IOException thrown when having IO problem.
   */
  public static void addFileToTar(TarArchiveOutputStream tarStream, File file, String path) throws IOException {
    int mode = file.isDirectory() ? TarArchiveEntry.DEFAULT_DIR_MODE : TarArchiveEntry.DEFAULT_FILE_MODE;
    addFileToTar(tarStream, file, path, mode);
  }


  /**
   * Add a folder into tar.
   *
   * @param tarStream TarArchive outputStream
   * @param path      path to append
   * @throws IOException thrown when having IO problem.
   */
  public static void addFolderToTar(TarArchiveOutputStream tarStream, String path) throws IOException {
    TarArchiveEntry archiveEntry = new TarArchiveEntry(path);
    archiveEntry.setMode(TarArchiveEntry.DEFAULT_DIR_MODE);
    tarStream.putArchiveEntry(archiveEntry);
    tarStream.closeArchiveEntry();
  }


  /**
   * Add the given input stream into tar.
   *
   * @param tarStream   TarArchive outputStream
   * @param inputStream input stream
   * @param path        relative path to append
   * @param size        size of stream
   * @param mode        mode for this entry
   * @throws IOException thrown when having IO problem.
   */
  public static void addInputStreamToTar(TarArchiveOutputStream tarStream, InputStream inputStream, String path,
                                         long size, int mode) throws IOException {
    TarArchiveEntry entry = new TarArchiveEntry(path);
    entry.setSize(size);
    entry.setMode(mode);
    try {
      tarStream.putArchiveEntry(entry);
      IOUtils.copy(inputStream, tarStream);
    } catch (IOException e) {
      throw processException("Error while adding File to Tar file", e);
    } finally {
      tarStream.closeArchiveEntry();
    }
  }


  /**
   * Add a file into tar.
   *
   * @param tarStream TarArchive outputStream
   * @param file      file
   * @param path      relative path to append
   * @param mode      mode for this entry
   * @throws IOException thrown when having IO problem.
   */
  public static void addFileToTar(TarArchiveOutputStream tarStream, File file, String path, int mode) throws IOException {
    TarArchiveEntry entry = new TarArchiveEntry(path);
    entry.setSize(file.length());
    entry.setMode(mode);
    BufferedInputStream bis = null;
    try {
      tarStream.putArchiveEntry(entry);
      bis = new BufferedInputStream(new FileInputStream(file));
      IOUtils.copy(bis, tarStream);
    } catch (IOException e) {
      throw processException("Error while adding File to Tar file", e);
    } finally {
      IOUtils.closeQuietly(bis);
      tarStream.closeArchiveEntry();
    }
  }


  public interface ZipEntryProcessor {
    public void process(ZipFile zipFile, ZipEntry je) throws IOException;
  }

  public interface FilePredicate {
    public boolean evaluate(Object object);
  }
}
TOP

Related Classes of org.ngrinder.common.util.CompressionUtils$FilePredicate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.