com.hpl.erk.files.StreamDecompressor.java Source code

Java tutorial

Introduction

Here is the source code for com.hpl.erk.files.StreamDecompressor.java

Source

/*
 *
 *  Managed Data Structures
 *  Copyright  2016 Hewlett Packard Enterprise Development Company LP.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  As an exception, the copyright holders of this Library grant you permission
 *  to (i) compile an Application with the Library, and (ii) distribute the 
 *  Application containing code generated by the Library and added to the 
 *  Application during this compilation process under terms of your choice, 
 *  provided you also meet the terms and conditions of the Application license.
 *
 */

package com.hpl.erk.files;

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.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;

import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;

public abstract class StreamDecompressor {

    private static Map<String, StreamDecompressor> decompressors = new HashMap<>();

    public static final StreamDecompressor UNCOMPRESSED = new StreamDecompressor() {
        @Override
        public InputStream decompress(InputStream s) {
            return s;
        }
    };

    public static final StreamDecompressor GZIP = register(GZIPInputStream.class, "gz", "GZ", "gzip", "GZIP");
    public static final StreamDecompressor ZIP = register(ZipInputStream.class, "zip", "ZIP");
    public static final StreamDecompressor BZIP2 = register(BZip2CompressorInputStream.class, "bz2", "BZ2");

    private static class Providing<T extends InputStream> extends StreamDecompressor {
        final Class<T> clss;
        Constructor<T> ctor;

        public Providing(Class<T> clss) {
            this.clss = clss;
        }

        @Override
        public InputStream decompress(InputStream s) throws IOException {
            try {
                if (ctor == null) {
                    ctor = clss.getConstructor(InputStream.class);
                }
                s = ctor.newInstance(s);
                s = new BufferedInputStream(s);// makes it *WAY* faster
                return s;
            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                throw new IOException(String.format("Error trying to create decompress stream for class %s", clss));
            }
        }

    }

    public abstract InputStream decompress(InputStream s) throws IOException;

    public StreamDecompressor register(String... exts) {
        for (String ext : exts) {
            decompressors.put("." + ext, this);
        }
        return this;
    }

    public static <T extends InputStream> StreamDecompressor register(Class<T> clss, String... exts) {
        return new Providing<>(clss).register(exts);
    }

    @SuppressWarnings("resource")
    public static InputStream decompress(File file) throws IOException {
        StreamDecompressor decompressor = null;
        final String infileName = file.getName();
        if (file.exists()) {
            int longestLength = 0;
            for (String ext : decompressors.keySet()) {
                final int len = ext.length();
                if (len > longestLength && infileName.endsWith(ext)) {
                    decompressor = decompressors.get(ext);
                    longestLength = len;
                }
            }
            if (decompressor == null) {
                decompressor = UNCOMPRESSED;
            }
        } else {
            final File infileParent = file.getParentFile();
            for (String ext : decompressors.keySet()) {
                File f = new File(infileParent, infileName + ext);
                if (f.exists()) {
                    decompressor = decompressors.get(ext);
                    file = f;
                    break;
                }
            }
            if (decompressor == null) {
                throw new FileNotFoundException(String.format(
                        "File not found: %s (or with any of %s). Use %s.register() to add more compression schemes.",
                        file, decompressors.keySet(), StreamDecompressor.class.getSimpleName()));
            }
        }
        InputStream s = new FileInputStream(file);
        s = decompressor.decompress(s);
        return s;
    }

}