org.savantbuild.io.tar.TarBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.savantbuild.io.tar.TarBuilder.java

Source

/*
 * Copyright (c) 2014, Inversoft Inc., 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.savantbuild.io.tar;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.savantbuild.io.Directory;
import org.savantbuild.io.FileInfo;
import org.savantbuild.io.FileSet;
import org.savantbuild.io.FileTools;

/**
 * Helps build Tar files.
 *
 * @author Brian Pontarelli
 */
public class TarBuilder {
    public final Set<Directory> directories = new TreeSet<>();

    public final Path file;

    public final List<FileSet> fileSets = new ArrayList<>();

    public boolean compress = true;

    public boolean storeGroupName = false;

    public boolean storeUserName = false;

    public TarBuilder(String file) {
        this(Paths.get(file));
    }

    public TarBuilder(Path file) {
        this.file = file;

        // Guess at the compression
        this.compress = file.toString().endsWith(".gz");
    }

    /**
     * Builds the TAR file using the fileSets and Directories provided.
     *
     * @return The number of entries added to the TAR file including the directories.
     * @throws IOException If the build fails.
     */
    public int build() throws IOException {
        if (Files.exists(file)) {
            Files.delete(file);
        }

        if (!Files.isDirectory(file.getParent())) {
            Files.createDirectories(file.getParent());
        }

        // Sort the file infos and add the directories
        Set<FileInfo> fileInfos = new TreeSet<>();
        for (FileSet fileSet : fileSets) {
            Set<Directory> dirs = fileSet.toDirectories();
            dirs.removeAll(directories);
            for (Directory dir : dirs) {
                directories.add(dir);
            }

            fileInfos.addAll(fileSet.toFileInfos());
        }

        int count = 0;
        OutputStream os = Files.newOutputStream(file);
        try (TarArchiveOutputStream tos = new TarArchiveOutputStream(compress ? new GZIPOutputStream(os) : os)) {
            tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

            for (Directory directory : directories) {
                String name = directory.name;
                TarArchiveEntry entry = new TarArchiveEntry(name.endsWith("/") ? name : name + "/");
                if (directory.lastModifiedTime != null) {
                    entry.setModTime(directory.lastModifiedTime.toMillis());
                }
                if (directory.mode != null) {
                    entry.setMode(FileTools.toMode(directory.mode));
                }
                if (storeGroupName && directory.groupName != null) {
                    entry.setGroupName(directory.groupName);
                }
                if (storeUserName && directory.userName != null) {
                    entry.setUserName(directory.userName);
                }
                tos.putArchiveEntry(entry);
                tos.closeArchiveEntry();
                count++;
            }

            for (FileInfo fileInfo : fileInfos) {
                TarArchiveEntry entry = new TarArchiveEntry(fileInfo.relative.toString());
                entry.setModTime(fileInfo.lastModifiedTime.toMillis());
                if (storeGroupName) {
                    entry.setGroupName(fileInfo.groupName);
                }
                if (storeUserName) {
                    entry.setUserName(fileInfo.userName);
                }
                entry.setSize(fileInfo.size);
                entry.setMode(fileInfo.toMode());
                tos.putArchiveEntry(entry);
                Files.copy(fileInfo.origin, tos);
                tos.closeArchiveEntry();
                count++;
            }
        }

        return count;
    }

    public TarBuilder directory(Directory directory) throws IOException {
        directories.add(directory);
        return this;
    }

    public long getExplodedSize() throws IOException {
        long size = 0;
        for (FileSet fileSet : fileSets) {
            for (FileInfo info : fileSet.toFileInfos()) {
                size += info.size;
            }
        }

        return size;
    }

    public TarBuilder fileSet(Path directory) throws IOException {
        return fileSet(new FileSet(directory));
    }

    public TarBuilder fileSet(String directory) throws IOException {
        return fileSet(Paths.get(directory));
    }

    public TarBuilder fileSet(FileSet fileSet) throws IOException {
        if (Files.isRegularFile(fileSet.directory)) {
            throw new IOException(
                    "The [fileSet.directory] path [" + fileSet.directory + "] is a file and must be a directory");
        }

        if (!Files.isDirectory(fileSet.directory)) {
            throw new IOException("The [fileSet.directory] path [" + fileSet.directory + "] does not exist");
        }

        fileSets.add(fileSet);
        return this;
    }

    public TarBuilder optionalFileSet(Path directory) throws IOException {
        return optionalFileSet(new FileSet(directory));
    }

    public TarBuilder optionalFileSet(String directory) throws IOException {
        return optionalFileSet(Paths.get(directory));
    }

    public TarBuilder optionalFileSet(FileSet fileSet) throws IOException {
        if (Files.isRegularFile(fileSet.directory)) {
            throw new IOException(
                    "The [fileSet.directory] path [" + fileSet.directory + "] is a file and must be a directory");
        }

        // Only add if it exists
        if (Files.isDirectory(fileSet.directory)) {
            fileSets.add(fileSet);
        }

        return this;
    }
}