org.cloudifysource.esc.util.TarGzUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudifysource.esc.util.TarGzUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved
 * 
 * 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.cloudifysource.esc.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

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.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

/**
 * Class utility to create TAR.GZ archives.
 * 
 */
public final class TarGzUtils {

    private static final Logger LOGGER = Logger.getLogger(TarGzUtils.class.getName());

    private static final String DEFAULT_PREFIX = "cloudFolder";
    private static final int BUFFER = 2048;

    private TarGzUtils() {
    }

    /**
     * Create a temporary tar gz file.
     * 
     * @return The temporary file
     * @throws IOException
     *             If the file cannot be created.
     */
    private static File createTempTarGzFile() throws IOException {
        final File archiveFile = File.createTempFile(DEFAULT_PREFIX, ".tar.gz");
        archiveFile.deleteOnExit();
        if (LOGGER.isLoggable(Level.FINE)) {
            System.out.println(archiveFile);
            LOGGER.finest("Created tar.gz file: " + archiveFile);
        }

        return archiveFile;
    }

    /**
     * Create a tar.gz file.
     * 
     * @param sourcePaths
     *            Folders or files to add in the archive.
     * @param addRoot
     *            When <code>sourcePath</code> is a folder. if true, it will add the folder in the archive.<br/>
     *            <i>i.e: if sourcepath=/tmp/folderToInclude, archive.tar.gz will include the folder
     *            <b>folderToInclude</b> in the archive.</i>
     * @return The created archive.
     * @throws IOException
     *             If the archive cannot be create.
     */
    public static File createTarGz(final String sourcePaths, final boolean addRoot) throws IOException {
        return createTarGz(new String[] { sourcePaths }, "", addRoot);
    }

    /**
     * Create a tar.gz file.
     * 
     * @param sourcePaths
     *            Folders or files to add in the archive.
     * @param addRoot
     *            When <code>sourcePath</code> is a folder. if true, it will add the folder in the archive.<br/>
     *            <i>i.e: if sourcepath=/tmp/folderToInclude, archive.tar.gz will include the folder
     *            <b>folderToInclude</b> in the archive.</i>
     * @return The created archive.
     * @throws IOException
     *             If the archive cannot be create.
     */
    public static File createTarGz(final String[] sourcePaths, final boolean addRoot) throws IOException {
        return createTarGz(sourcePaths, "", addRoot);
    }

    /**
     * Create a tar.gz file.
     * 
     * @param sourcePaths
     *            Folders or files to add in the archive.
     * @param base
     *            The name to be use in the archive.
     * @param addRoot
     *            When <code>sourcePath</code> is a folder. if true, it will add the folder in the archive.<br/>
     *            <i>i.e: if sourcepath=/tmp/folderToInclude, archive.tar.gz will include the folder
     *            <b>folderToInclude</b> in the archive.</i>
     * @return The created archive.
     * @throws IOException
     *             If the archive cannot be create.
     */
    public static File createTarGz(final String[] sourcePaths, final String base, final boolean addRoot)
            throws IOException {
        File tarGzFile = createTempTarGzFile();

        if (!FilenameUtils.getExtension(tarGzFile.getName().toLowerCase()).equals("gz")) {
            throw new IllegalArgumentException("Expecting tar.gz file: " + tarGzFile.getAbsolutePath());
        }

        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        GzipCompressorOutputStream gzOut = null;
        TarArchiveOutputStream tOut = null;
        try {
            fOut = new FileOutputStream(tarGzFile);
            bOut = new BufferedOutputStream(fOut);
            gzOut = new GzipCompressorOutputStream(bOut);
            tOut = new TarArchiveOutputStream(gzOut);
            for (String path : sourcePaths) {
                addFileToTarGz(tOut, path, base, addRoot);
            }
        } finally {
            if (tOut != null) {
                tOut.close();
            }
            if (gzOut != null) {
                gzOut.close();
            }
            if (bOut != null) {
                bOut.close();
            }
            if (fOut != null) {
                fOut.close();
            }
        }

        return tarGzFile;
    }

    private static void addFileToTarGz(final TarArchiveOutputStream tOut, final String path, final String base,
            final boolean addRoot) throws IOException {
        File f = new File(path);
        String entryName = base + f.getName();

        if (f.isFile()) {
            TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
            tOut.putArchiveEntry(tarEntry);
            IOUtils.copy(new FileInputStream(f), tOut);
            tOut.closeArchiveEntry();
        } else {
            if (addRoot) {
                TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
                tOut.putArchiveEntry(tarEntry);
                tOut.closeArchiveEntry();
            }
            File[] children = f.listFiles();
            if (children != null) {
                for (File child : children) {
                    if (addRoot) {
                        addFileToTarGz(tOut, child.getAbsolutePath(), entryName + "/", true);
                    } else {
                        addFileToTarGz(tOut, child.getAbsolutePath(), "", true);
                    }
                }
            }
        }
    }

    /**
     * Extract a tar.gz file.
     * 
     * @param source
     *            The file to extract from.
     * @param destination
     *            The destination folder.
     * @throws IOException
     *             An error occured during the extraction.
     */
    public static void extract(final File source, final String destination) throws IOException {

        LOGGER.fine(String.format("Extracting %s to %s", source.getName(), destination));

        if (!FilenameUtils.getExtension(source.getName().toLowerCase()).equals("gz")) {
            throw new IllegalArgumentException("Expecting tar.gz file: " + source.getAbsolutePath());
        }
        if (!new File(destination).isDirectory()) {
            throw new IllegalArgumentException("Destination should be a folder: " + destination);
        }

        /** create a TarArchiveInputStream object. **/
        FileInputStream fin = new FileInputStream(source);
        BufferedInputStream in = new BufferedInputStream(fin);
        GzipCompressorInputStream gzIn = new GzipCompressorInputStream(in);
        TarArchiveInputStream tarIn = new TarArchiveInputStream(gzIn);

        TarArchiveEntry entry = null;

        /** Read the tar entries using the getNextEntry method **/
        while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {

            LOGGER.finer("Extracting: " + entry.getName());

            /** If the entry is a directory, create the directory. **/
            if (entry.isDirectory()) {

                File f = new File(destination, entry.getName());
                f.mkdirs();
            } else {
                int count;
                byte[] data = new byte[BUFFER];
                FileOutputStream fos = new FileOutputStream(new File(destination, entry.getName()));
                BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = tarIn.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                dest.close();
            }
        }

        /** Close the input stream **/
        tarIn.close();
    }

}