Java tutorial
/* * * 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; } }