pt.ua.tm.neji.util.ZipGenerator.java Source code

Java tutorial

Introduction

Here is the source code for pt.ua.tm.neji.util.ZipGenerator.java

Source

/*
 * Copyright (c) 2016 BMD Software and University of Aveiro.
 *
 * Neji is a flexible and powerful platform for biomedical information extraction from text.
 *
 * This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
 * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/.
 *
 * This project is a free software, you are free to copy, distribute, change and transmit it.
 * However, you may not use it for commercial purposes.
 *
 * It 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.
 */

package pt.ua.tm.neji.util;

import com.aliasi.util.Pair;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Utility class that writes a root folder and a set of extra files in other locations
 * into a ZIP file.
 *
 * @author Eduardo Duarte (<a href="mailto:emod@ua.pt">emod@ua.pt</a>))
 * @version 1.0
 */
public final class ZipGenerator {

    private final File rootFolder;
    private final Pair<String, File>[] otherFiles;
    private final PipedOutputStream pos;
    private final PipedInputStream pis;
    private ZipOutputStream zip;
    private BufferedOutputStream out;

    /**
     * Builds a zip file generator that stores in it the specified root folder and its sub-folders and sub-files.
     * To avoid having to copy data from other paths into the root in order to add it to the resulting
     * zip file, the user can specify extra files to be added into the root on generation. The user must specify
     * a final name for each extra file object.
     */
    public ZipGenerator(final File rootFolder, final Pair<String, File>... extraFilesToAddIntoRoot)
            throws IOException {
        this.rootFolder = rootFolder;
        this.otherFiles = extraFilesToAddIntoRoot;

        // writing in the PipedOutputStream will pass the data
        // into the PipedInputStream when completed
        pos = new PipedOutputStream();
        pis = new PipedInputStream(pos);
        zip = new ZipOutputStream(pos);
        out = new BufferedOutputStream(zip);
    }

    public InputStream generate() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.print("Generating zip file");

                    fill("", new Pair[] { new Pair<>(rootFolder.getName(), rootFolder) }, zip, out);
                    fill(rootFolder.getName() + File.separator, otherFiles, zip, out);

                    System.out.println("done!");

                    out.flush();
                    out.close();

                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }).start();

        return pis;
    }

    private static void fill(String parentPath, Pair<String, File>[] files, ZipOutputStream zip,
            BufferedOutputStream out) throws IOException {
        for (Pair<String, File> pair : files) {

            if (pair.b() == null)
                continue;

            if (pair.b().isDirectory() && pair.b().list().length > 0) {
                File[] subFiles = pair.b().listFiles();
                int size = subFiles.length;
                Pair<String, File>[] subPairs = new Pair[size];
                for (int i = 0; i < size; i++) {
                    subPairs[i] = new Pair<>(subFiles[i].getName(), subFiles[i]);
                }

                fill(parentPath + pair.a() + File.separator, subPairs, zip, out);

            } else if (pair.b().isFile()) {
                zip.putNextEntry(new ZipEntry(parentPath + pair.a()));
                FileInputStream fis = new FileInputStream(pair.b());
                IOUtils.copyLarge(fis, out);
                fis.close();
                out.flush();
            }

            System.out.print(".");

            zip.closeEntry();
        }
    }
}