001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io;
003
004import java.io.File;
005import java.io.FileInputStream;
006import java.io.FileOutputStream;
007import java.io.IOException;
008import java.io.InputStream;
009import java.io.OutputStream;
010import java.net.URL;
011import java.nio.charset.StandardCharsets;
012import java.util.zip.GZIPOutputStream;
013import java.util.zip.ZipOutputStream;
014
015import org.apache.tools.bzip2.CBZip2OutputStream;
016import org.openstreetmap.josm.tools.Utils;
017
018/**
019 * An enum representing the compression type of a resource.
020 */
021public enum Compression {
022    /**
023     * no compression
024     */
025    NONE,
026    /**
027     * bzip2 compression
028     */
029    BZIP2,
030    /**
031     * gzip compression
032     */
033    GZIP,
034    /**
035     * zip compression
036     */
037    ZIP;
038
039    /**
040     * Determines the compression type depending on the suffix of {@code name}.
041     * @param name File name including extension
042     * @return the compression type
043     */
044    public static Compression byExtension(String name) {
045        return name != null && name.endsWith(".gz")
046                ? GZIP
047                : name != null && (name.endsWith(".bz2") || name.endsWith(".bz"))
048                ? BZIP2
049                : name != null && name.endsWith(".zip")
050                ? ZIP
051                : NONE;
052    }
053
054    /**
055     * Returns an un-compressing {@link InputStream} for {@code in}.
056     *
057     * @throws IOException
058     */
059    public InputStream getUncompressedInputStream(InputStream in) throws IOException {
060        switch (this) {
061            case BZIP2:
062                return Utils.getBZip2InputStream(in);
063            case GZIP:
064                return Utils.getGZipInputStream(in);
065            case ZIP:
066                return Utils.getZipInputStream(in);
067            case NONE:
068            default:
069                return in;
070        }
071    }
072
073    /**
074     * Returns an un-compressing {@link InputStream} for the {@link File} {@code file}.
075     *
076     * @throws IOException
077     */
078    @SuppressWarnings("resource")
079    public static InputStream getUncompressedFileInputStream(File file) throws IOException {
080        return byExtension(file.getName()).getUncompressedInputStream(new FileInputStream(file));
081    }
082
083    /**
084     * Returns an un-compressing {@link InputStream} for the {@link URL} {@code url}.
085     *
086     * @throws IOException
087     */
088    public static InputStream getUncompressedURLInputStream(URL url) throws IOException {
089        return Utils.openURLAndDecompress(url, true);
090    }
091
092    /**
093     * Returns a compressing {@link OutputStream} for {@code out}.
094     *
095     * @throws IOException
096     */
097    public OutputStream getCompressedOutputStream(OutputStream out) throws IOException {
098        switch (this) {
099            case BZIP2:
100                out.write('B');
101                out.write('Z');
102                return new CBZip2OutputStream(out);
103            case GZIP:
104                return new GZIPOutputStream(out);
105            case ZIP:
106                return new ZipOutputStream(out, StandardCharsets.UTF_8);
107            case NONE:
108            default:
109                return out;
110        }
111    }
112
113    /**
114     * Returns a compressing {@link OutputStream} for the {@link File} {@code file}.
115     *
116     * @throws IOException
117     */
118    @SuppressWarnings("resource")
119    public static OutputStream getCompressedFileOutputStream(File file) throws IOException {
120        return byExtension(file.getName()).getCompressedOutputStream(new FileOutputStream(file));
121    }
122}