ch.cern.dss.teamcity.agent.util.ArchiveExtractor.java Source code

Java tutorial

Introduction

Here is the source code for ch.cern.dss.teamcity.agent.util.ArchiveExtractor.java

Source

/**
 * Copyright (c) 2012-2013 by European Organization for Nuclear Research (CERN)
 * Author: Justin Salmon <jsalmon@cern.ch>
 *
 * XRootD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XRootD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
 */

package ch.cern.dss.teamcity.agent.util;

import ch.cern.dss.teamcity.common.IOUtil;
import ch.cern.dss.teamcity.common.SystemCommandResult;
import jetbrains.buildServer.RunBuildException;
import jetbrains.buildServer.log.Loggers;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.io.FilenameUtils;

import java.io.*;

/**
 *
 */
public class ArchiveExtractor {

    private SimpleLogger logger;

    /**
     * @param logger
     */
    public ArchiveExtractor(SimpleLogger logger) {
        this.logger = logger;
    }

    /**
     * @param archivePath
     * @param outputFolder
     * @throws CompressorException
     * @throws ArchiveException
     * @throws IOException
     * @throws InterruptedException
     */
    public void extract(String archivePath, String outputFolder)
            throws CompressorException, ArchiveException, IOException, InterruptedException, RunBuildException {
        logger.message("Extracting archive: " + archivePath);

        if (!new File(archivePath).exists()) {
            throw new FileNotFoundException("Archive not found: " + archivePath);
        }

        File folder = new File(outputFolder);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        if (archivePath.endsWith(".gz") || archivePath.endsWith(".tgz") || archivePath.endsWith(".bz2")) {
            archivePath = decompress(archivePath);
            extractTar(archivePath, outputFolder);
        } else if (archivePath.endsWith(".rpm")) {
            archivePath = rpm2cpio(archivePath);
            extractCpio(archivePath, outputFolder);
        } else if (archivePath.endsWith(".cpio")) {
            extractCpio(archivePath, outputFolder);
        } else if (archivePath.endsWith(".zip")) {
            extractZip(archivePath, outputFolder);
        } else {
            throw new IOException("Unsupported archive type: " + archivePath);
        }
    }

    /**
     * @param archivePath
     * @return
     * @throws ArchiveException
     * @throws IOException
     * @throws CompressorException
     */
    public String decompress(String archivePath) throws ArchiveException, IOException, CompressorException {

        Loggers.AGENT.debug("Decompressing: " + archivePath);
        String tarPath = FilenameUtils.removeExtension(archivePath);

        final BufferedInputStream is = new BufferedInputStream(new FileInputStream(archivePath));
        CompressorInputStream in = new CompressorStreamFactory().createCompressorInputStream(is);
        org.apache.commons.compress.utils.IOUtils.copy(in, new FileOutputStream(tarPath));
        in.close();

        return tarPath;
    }

    /**
     * @param archivePath
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String rpm2cpio(String archivePath) throws IOException, InterruptedException {
        Loggers.AGENT.debug("Converting to cpio: " + archivePath);
        String cpioPath = FilenameUtils.removeExtension(archivePath) + ".cpio";
        String[] rpm2cpioCommand = { "/bin/sh", "-c", "/usr/bin/rpm2cpio " + archivePath + " > " + cpioPath };
        SystemCommandResult result = IOUtil.runSystemCommand(rpm2cpioCommand);
        Loggers.AGENT.debug("rpm2cpio returned with code " + result.getReturnCode());
        return cpioPath;
    }

    /**
     * <ugly_hack>The cpio command doesn't allow you to specify an output directory, and running commands with
     * ProcessBuilder in different directories is a pain, so we write a small script to a file and execute that
     * instead.</ugly_hack>
     *
     * @param archivePath
     * @param outputFolder
     * @throws IOException
     * @throws InterruptedException
     */
    public void extractCpio(String archivePath, String outputFolder)
            throws IOException, InterruptedException, RunBuildException {

        String command = "#!/bin/sh\n" + "cd %working_directory%\n" + "cpio -idmv < %cpio_file%\n";

        command = command.replace("%cpio_file%", archivePath);
        command = command.replace("%working_directory%", outputFolder);
        IOUtil.writeFile("extract-cpio.sh", command);
        new File("extract-cpio.sh").setExecutable(true);

        SystemCommandResult result = IOUtil.runSystemCommand(new String[] { "./extract-cpio.sh", command });
        if (result.getReturnCode() != 0) {
            throw new RunBuildException("Failed to extract cpio: " + result.getOutput());
        }
    }

    /**
     * @param archivePath
     * @param outputFolder
     * @throws IOException
     * @throws InterruptedException
     */
    public void extractTar(String archivePath, String outputFolder)
            throws IOException, InterruptedException, RunBuildException {
        String[] command = { "tar", "-xf", archivePath, "-C", outputFolder };
        SystemCommandResult result = IOUtil.runSystemCommand(command);
        if (result.getReturnCode() != 0) {
            throw new RunBuildException("Failed to extract tar: " + result.getOutput());
        }
    }

    /**
     * @param archivePath
     * @param outputFolder
     * @throws IOException
     * @throws InterruptedException
     */
    public void extractZip(String archivePath, String outputFolder)
            throws IOException, InterruptedException, RunBuildException {
        String[] command = { "unzip", archivePath, "-d", outputFolder };
        SystemCommandResult result = IOUtil.runSystemCommand(command);
        if (result.getReturnCode() != 0) {
            throw new RunBuildException("Failed to extract zip: " + result.getOutput());
        }
    }

}