com.vividsolutions.jump.io.CompressedFile.java Source code

Java tutorial

Introduction

Here is the source code for com.vividsolutions.jump.io.CompressedFile.java

Source

/*
 * CompressedFile.java
 *
 * Created on December 12, 2002, 9:51 AM
 */
/*
 * The Unified Mapping Platform (JUMP) is an extensible, interactive
 * GUI for visualizing and manipulating spatial features with geometry
 * and attributes.
 *
 * Copyright (C) 2003 Vivid Solutions
 * 
 * This program 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.
 * 
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 * For more information, contact:
 *
 * Vivid Solutions
 * Suite #1A
 * 2328 Government Street
 * Victoria BC  V8T 5G5
 * Canada
 *
 * (250)385-6040
 * www.vividsolutions.com
 */

package com.vividsolutions.jump.io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFileGiveStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.openjump.util.UriUtil;

import com.vividsolutions.jump.util.FileUtil;

/**
 * Utility class for dealing with compressed files.
 * @see #isCompressed(URI)
 * 
 * @author dblasby
 * @author ede
 */
// TODO :I18N
public class CompressedFile {

    /** Creates a new CompressedFile */
    public CompressedFile() {
    }

    /**
     * Searches through the .zip file looking for a file with the given extension.
     * Returns null if it doesn't find one.
     * 
     * @deprecated only used by very old data readers which only deliver the first file in zip file [ede 05.2012]
     */
    public static String getInternalZipFnameByExtension(String extension, String compressedFile) throws Exception {
        // zip file
        String inside_zip_extension;
        InputStream IS_low = new FileInputStream(compressedFile);
        ZipInputStream fr_high = new ZipInputStream(IS_low);

        // need to find the correct file within the .zip file
        ZipEntry entry;

        entry = fr_high.getNextEntry();

        while (entry != null) {
            inside_zip_extension = entry.getName().substring(entry.getName().length() - extension.length());

            if (inside_zip_extension.compareToIgnoreCase(extension) == 0) {
                return (entry.getName());
            }

            entry = fr_high.getNextEntry();
        }

        return null;
    }

    //
    // /**
    // * Utility file open function - handles compressed and un-compressed files.
    // *
    // * @param compressedFile
    // * name of file to open.
    // * @param extension
    // * look for file with this extension in zipfile.
    // *
    // * <p>
    // * compressedFile = null, then opens a FileInputStream on
    // * COMPRESSEDFILE (!) should be file.shp or such
    // * </p>
    // *
    // * <p>
    // * compressedFile ends in ".zip" - opens the compressed zipfile and
    // * lookes for first file with extension 'extension'
    // * </p>
    // *
    // * <p>
    // * compressedFile ends in ".gz" - opens the compressed .gz file.
    // * </p>
    // */
    // static InputStream openFileExtension(String extension, String
    // compressedFile)
    // throws Exception {
    // String compressed_extension;
    // String inside_zip_extension;
    //
    // if ((compressedFile == null) || (compressedFile.length() == 0)) {
    // throw new Exception("openFileExtension- no compressed file given.");
    // }
    //
    // compressed_extension = compressedFile
    // .substring(compressedFile.length() - 3);
    //
    // if (compressed_extension.compareToIgnoreCase(".gz") == 0) {
    // // gz file -- easy
    //
    // // low-level reader
    // InputStream IS_low = new FileInputStream(compressedFile);
    //
    // // high-level reader
    // return (new java.util.zip.GZIPInputStream(IS_low));
    // }
    //
    // if (compressed_extension.compareToIgnoreCase("zip") == 0) {
    // // zip file
    // InputStream IS_low = new FileInputStream(compressedFile);
    // ZipInputStream fr_high = new ZipInputStream(IS_low);
    //
    // // need to find the correct file within the .zip file
    // ZipEntry entry;
    //
    // entry = fr_high.getNextEntry();
    //
    // while (entry != null) {
    // inside_zip_extension = entry.getName().substring(
    // entry.getName().length() - extension.length());
    //
    // if (inside_zip_extension.compareToIgnoreCase(extension) == 0) {
    // return (fr_high);
    // }
    //
    // entry = fr_high.getNextEntry();
    // }
    //
    // throw new Exception("couldnt find file with extension" + extension
    // + " in compressed file " + compressedFile);
    // }
    //
    // throw new Exception("couldnt determine compressed file type for file "
    // + compressedFile + "- should end in .zip or .gz");
    // }

    public static InputStream openFile(String uri_string) throws URISyntaxException, IOException {
        return openFile(new URI(uri_string));
    }

    public static InputStream openFile(URI uri) throws IOException {
        return openFile(UriUtil.getZipFilePath(uri), UriUtil.getZipEntryName(uri));
    }

    /**
     * Utility file open function - handles compressed and un-compressed files.
     * 
     * @param filePath
     *          name of the file to search for.
     * @param compressedEntry
     *          name of the compressed file.
     * 
     *          <p>
     *          If compressedEntry = null, opens a FileInputStream on filePath
     *          </p>
     * 
     *          <p>
     *          If filePath ends in ".zip" - opens the compressed Zip and
     *          looks for the file called compressedEntry
     *          </p>
     * 
     *          <p>
     *          If filePath ends in ".gz" - opens the compressed .gz file.
     *          </p>
     */
    public static InputStream openFile(String filePath, String compressedEntry) throws IOException {

        System.out.println(filePath + " extract " + compressedEntry);

        if (isTar(filePath)) {
            InputStream is = new BufferedInputStream(new FileInputStream(filePath));
            if (filePath.toLowerCase().endsWith("gz"))
                is = new GzipCompressorInputStream(is, true);
            else if (filePath.matches("(?i).*bz2?"))
                is = new BZip2CompressorInputStream(is, true);
            else if (filePath.matches("(?i).*xz"))
                is = new XZCompressorInputStream(is, true);

            TarArchiveInputStream tis = new TarArchiveInputStream(is);
            if (compressedEntry == null)
                return is;

            TarArchiveEntry entry;
            while ((entry = tis.getNextTarEntry()) != null) {
                if (entry.getName().equals(compressedEntry))
                    return tis;
            }

            throw createArchiveFNFE(filePath, compressedEntry);
        }

        else if (compressedEntry == null && isGZip(filePath)) {
            // gz compressed file -- easy
            InputStream is = new BufferedInputStream(new FileInputStream(filePath));
            return new GzipCompressorInputStream(is, true);
        }

        else if (compressedEntry == null && isBZip(filePath)) {
            // bz compressed file -- easy
            InputStream is = new BufferedInputStream(new FileInputStream(filePath));
            return new BZip2CompressorInputStream(is, true);
            //return new org.itadaki.bzip2.BZip2InputStream(is, false);
        }

        else if (compressedEntry == null && isXZ(filePath)) {
            InputStream is = new BufferedInputStream(new FileInputStream(filePath));
            return new XZCompressorInputStream(is, true);
        }

        else if (compressedEntry != null && isZip(filePath)) {

            ZipFile zipFile = new ZipFile(filePath);
            ZipArchiveEntry zipEntry = zipFile.getEntry(compressedEntry);

            if (zipEntry != null)
                return zipFile.getInputStream(zipEntry);

            throw createArchiveFNFE(filePath, compressedEntry);
        }

        else if (compressedEntry != null && isSevenZ(filePath)) {

            SevenZFileGiveStream sevenZFile = new SevenZFileGiveStream(new File(filePath));
            SevenZArchiveEntry entry;
            while ((entry = sevenZFile.getNextEntry()) != null) {
                if (entry.getName().equals(compressedEntry))
                    return sevenZFile.getCurrentEntryInputStream();
            }
            throw createArchiveFNFE(filePath, compressedEntry);
        }
        // return plain stream if no compressedEntry
        else if (compressedEntry == null) {
            return new FileInputStream(filePath);
        }

        else {
            throw new IOException("Couldn't determine compressed file type for file '" + filePath
                    + "' supposedly containing '" + compressedEntry + "'.");
        }
    }

    //  public static boolean isCompressed(String filePath) {
    //    return isZip(filePath) || isTar(filePath) || isGZip(filePath) || isBZip(filePath);
    //  }

    public static boolean isCompressed(URI uri) {
        String filepath = UriUtil.getFilePath(uri);
        return hasCompressedFileExtension(filepath);
    }

    public static boolean isArchive(URI uri) {
        String filepath = UriUtil.getFilePath(uri);
        return hasArchiveFileExtension(filepath);
    }

    public static boolean isZip(String filePath) {
        return filePath.matches(".*\\.(?i:zip)");
    }

    public static boolean isTar(String filePath) {
        return filePath.matches("(?i).*\\.(tar|(tar\\.|t)(gz|bz2?|xz))");
    }

    public static boolean isGZip(String filePath) {
        return filePath.matches("(?i).*(?!\\.tar)\\.gz");
    }

    public static boolean isBZip(String filePath) {
        return filePath.matches("(?i).*(?!\\.tar)\\.bz2?");
    }

    public static boolean isXZ(String filePath) {
        return filePath.matches("(?i).*(?!\\.tar)\\.(xz)");
    }

    public static boolean isSevenZ(String filePath) {
        return filePath.matches("(?i).*(?!\\.tar)\\.(7z)");
    }

    // archives contain multiple items
    public static String[] getArchiveExtensions() {
        return new String[] { "zip", "tgz", "tar.gz", "tar.bz", "tar.bz2", "tbz", "tbz2", "txz", "tar.xz", "7z" };
    }

    // file is one plainly compressed file
    public static String[] getFileExtensions() {
        return new String[] { "gz", "bz", "bz2", "xz" };
    }

    public static boolean hasCompressedFileExtension(String filename) {
        return Arrays.asList(CompressedFile.getFileExtensions())
                .contains(FileUtil.getExtension(new File(filename)).toLowerCase());
    }

    public static boolean hasArchiveFileExtension(String filename) {
        for (String ext : getArchiveExtensions()) {
            if (filename.toLowerCase().endsWith(ext))
                return true;
        }
        return false;
    }

    public static String getTargetFileWithPath(URI uri) {
        String filepath = UriUtil.getFilePath(uri);
        String entry = UriUtil.getZipEntryName(uri);
        if (hasArchiveFileExtension(filepath)) {
            return entry;
        }
        return filepath;
    }

    public static URI replaceTargetFileWithPath(URI uri, String location) {
        String filepath = UriUtil.getZipFilePath(uri);
        if (hasArchiveFileExtension(filepath)) {
            return UriUtil.createZipUri(filepath, location);
        }
        return UriUtil.createFileUri(location);
    }

    public static URI replaceTargetFileName(URI uri, String filename) {
        String oldpath = UriUtil.getPath(getTargetFileWithPath(uri));
        return replaceTargetFileWithPath(uri, oldpath + filename);
    }

    public static String createLayerName(URI uri) {
        String filename = UriUtil.getFileName(uri);
        String layerName = UriUtil.getFileNameWithoutExtension(uri);
        // layername for archive members is "filename.ext (archive.ext)"
        if (CompressedFile.hasArchiveFileExtension(filename))
            layerName = UriUtil.getZipEntryName(uri) + " (" + filename + ")";
        // remove format extension for compressed files, but hint compressed file in braces
        else if (CompressedFile.hasCompressedFileExtension(filename)) {
            layerName = layerName.substring(0, layerName.lastIndexOf('.')) + " (" + filename + ")";
        }
        return layerName;
    }

    private static FileNotFoundException createArchiveFNFE(String archive, String entry) {
        return new FileNotFoundException("Couldn't find entry '" + entry + "' in compressed file: " + archive);
    }
}