slash.navigation.download.actions.Extractor.java Source code

Java tutorial

Introduction

Here is the source code for slash.navigation.download.actions.Extractor.java

Source

/*
This file is part of RouteConverter.
    
RouteConverter is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
RouteConverter 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 General Public License
along with RouteConverter; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    
Copyright (C) 2007 Christian Pesch. All Rights Reserved.
*/
package slash.navigation.download.actions;

import slash.navigation.download.Download;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import static java.lang.Integer.MAX_VALUE;
import static java.lang.String.format;
import static java.util.logging.Logger.getLogger;
import static org.apache.commons.io.IOUtils.closeQuietly;
import static slash.common.io.Directories.ensureDirectory;
import static slash.common.io.Files.lastPathFragment;
import static slash.common.io.Files.setLastModified;
import static slash.common.type.CompactCalendar.fromMillis;

/**
 * Extracts a {@link Download} to a target directory.
 *
 * @author Christian Pesch
 */
public class Extractor {
    private static final Logger log = getLogger(Extractor.class.getName());
    private final CopierListener listener;

    public Extractor(CopierListener listener) {
        this.listener = listener;
    }

    private void doExtract(File tempFile, File destination, boolean flatten) throws IOException {
        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(tempFile))) {
            ZipEntry entry = zipInputStream.getNextEntry();
            while (entry != null) {
                if (entry.isDirectory()) {
                    if (!flatten) {
                        File directory = new File(destination, entry.getName());
                        handleDirectory(directory, entry);
                    }

                } else {
                    File extracted;
                    if (flatten)
                        extracted = new File(destination, lastPathFragment(entry.getName(), MAX_VALUE));
                    else {
                        extracted = new File(destination, entry.getName());
                    }
                    File directory = extracted.getParentFile();
                    handleDirectory(directory, entry);

                    log.info(format("Extracting from %s to %s", tempFile, extracted));
                    FileOutputStream output = new FileOutputStream(extracted);
                    new Copier(listener).copy(zipInputStream, output, 0, entry.getSize());
                    // do not close zip input stream
                    closeQuietly(output);
                    setLastModified(extracted, fromMillis(entry.getTime()));

                    zipInputStream.closeEntry();
                }

                entry = zipInputStream.getNextEntry();
            }
        }
    }

    private void handleDirectory(File directory, ZipEntry entry) throws IOException {
        ensureDirectory(directory.getPath());
        setLastModified(directory, fromMillis(entry.getTime()));
    }

    public void flatten(File tempFile, File destination) throws IOException {
        doExtract(tempFile, destination, true);
    }

    public void extract(File tempFile, File destination) throws IOException {
        doExtract(tempFile, destination, false);
    }
}