com.amazonaws.codepipeline.jenkinsplugin.CompressionTools.java Source code

Java tutorial

Introduction

Here is the source code for com.amazonaws.codepipeline.jenkinsplugin.CompressionTools.java

Source

/*
 * Copyright 2015 Amazon.com, Inc. or its affiliates. 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.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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 com.amazonaws.codepipeline.jenkinsplugin;

import hudson.model.BuildListener;
import hudson.util.IOUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;

import com.amazonaws.codepipeline.jenkinsplugin.CodePipelineStateModel.CompressionType;

public final class CompressionTools {

    private CompressionTools() {
    }

    // Compressing the file to upload to S3 should use the same type of compression as the customer
    // used for the input artifact.
    public static File compressFile(final String projectName, final Path pathToCompress,
            final CompressionType compressionType, final BuildListener listener) throws IOException {
        File compressedArtifacts = null;

        try {
            switch (compressionType) {
            case Zip:
                compressedArtifacts = File.createTempFile(projectName + "-", ".zip");
                compressZipFile(compressedArtifacts, pathToCompress, listener);
                break;
            case Tar:
                compressedArtifacts = File.createTempFile(projectName + "-", ".tar");
                compressTarFile(compressedArtifacts, pathToCompress, listener);
                break;
            case TarGz:
                compressedArtifacts = File.createTempFile(projectName + "-", ".tar.gz");
                compressTarGzFile(compressedArtifacts, pathToCompress, listener);
                break;
            case None:
                throw new IllegalArgumentException("No compression type specified.");
            }
        } catch (final IOException e) {
            if (compressedArtifacts != null) {
                if (!compressedArtifacts.delete()) {
                    compressedArtifacts.deleteOnExit();
                }
            }
            throw e;
        }

        return compressedArtifacts;
    }

    public static void compressZipFile(final File temporaryZipFile, final Path pathToCompress,
            final BuildListener listener) throws IOException {
        try (final ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(
                new BufferedOutputStream(new FileOutputStream(temporaryZipFile)))) {

            compressArchive(pathToCompress, zipArchiveOutputStream, new ArchiveEntryFactory(CompressionType.Zip),
                    CompressionType.Zip, listener);
        }
    }

    public static void compressTarFile(final File temporaryTarFile, final Path pathToCompress,
            final BuildListener listener) throws IOException {
        try (final TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(
                new BufferedOutputStream(new FileOutputStream(temporaryTarFile)))) {

            compressArchive(pathToCompress, tarArchiveOutputStream, new ArchiveEntryFactory(CompressionType.Tar),
                    CompressionType.Tar, listener);
        }
    }

    public static void compressTarGzFile(final File temporaryTarGzFile, final Path pathToCompress,
            final BuildListener listener) throws IOException {
        try (final TarArchiveOutputStream tarGzArchiveOutputStream = new TarArchiveOutputStream(
                new BufferedOutputStream(
                        new GzipCompressorOutputStream(new FileOutputStream(temporaryTarGzFile))))) {

            compressArchive(pathToCompress, tarGzArchiveOutputStream,
                    new ArchiveEntryFactory(CompressionType.TarGz), CompressionType.TarGz, listener);
        }
    }

    private static void compressArchive(final Path pathToCompress, final ArchiveOutputStream archiveOutputStream,
            final ArchiveEntryFactory archiveEntryFactory, final CompressionType compressionType,
            final BuildListener listener) throws IOException {
        final List<File> files = addFilesToCompress(pathToCompress, listener);

        LoggingHelper.log(listener, "Compressing directory '%s' as a '%s' archive", pathToCompress.toString(),
                compressionType.name());

        for (final File file : files) {
            final String newTarFileName = pathToCompress.relativize(file.toPath()).toString();
            final ArchiveEntry archiveEntry = archiveEntryFactory.create(file, newTarFileName);
            archiveOutputStream.putArchiveEntry(archiveEntry);

            try (final FileInputStream fileInputStream = new FileInputStream(file)) {
                IOUtils.copy(fileInputStream, archiveOutputStream);
            }

            archiveOutputStream.closeArchiveEntry();
        }
    }

    public static List<File> addFilesToCompress(final Path pathToCompress, final BuildListener listener)
            throws IOException {
        final List<File> files = new ArrayList<>();

        if (pathToCompress != null) {
            Files.walkFileTree(pathToCompress, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
                    new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
                                throws IOException {
                            files.add(file.toFile());
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult visitFileFailed(final Path file, final IOException e)
                                throws IOException {
                            if (e != null) {
                                LoggingHelper.log(listener, "Failed to visit file '%s'. Error: %s.",
                                        file.toString(), e.getMessage());
                                LoggingHelper.log(listener, e);
                                throw e;
                            }
                            return FileVisitResult.CONTINUE;
                        }
                    });
        }

        return files;
    }

    public static Path resolveWorkspacePath(final File workspace, final String outputPath)
            throws FileNotFoundException {
        Path path = null;

        if (workspace != null) {
            if (!outputPath.contains(workspace.getAbsolutePath())) {
                path = Paths.get(workspace.getAbsolutePath(), outputPath);
            } else {
                path = Paths.get(outputPath);
            }
        } else {
            final String attemptPath;
            final URL tmp = CompressionTools.class.getClassLoader().getResource("");
            if (tmp != null) {
                attemptPath = tmp.getPath();
            } else {
                attemptPath = "";
            }

            if (attemptPath != null) {
                path = Paths.get(attemptPath);
            }
        }

        if (path == null) {
            throw new FileNotFoundException("Could not resolve path for " + outputPath);
        }

        path.resolve(outputPath);

        return path;
    }

}