[6716] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.io;
|
---|
| 3 |
|
---|
| 4 | import java.io.File;
|
---|
| 5 | import java.io.FileInputStream;
|
---|
| 6 | import java.io.FileOutputStream;
|
---|
| 7 | import java.io.IOException;
|
---|
| 8 | import java.io.InputStream;
|
---|
| 9 | import java.io.OutputStream;
|
---|
[7089] | 10 | import java.nio.charset.StandardCharsets;
|
---|
[12772] | 11 | import java.util.zip.GZIPInputStream;
|
---|
[6716] | 12 | import java.util.zip.GZIPOutputStream;
|
---|
[12772] | 13 | import java.util.zip.ZipEntry;
|
---|
| 14 | import java.util.zip.ZipInputStream;
|
---|
[6882] | 15 | import java.util.zip.ZipOutputStream;
|
---|
[6716] | 16 |
|
---|
[12772] | 17 | import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
---|
[7867] | 18 | import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
|
---|
[12772] | 19 | import org.openstreetmap.josm.tools.Logging;
|
---|
[7089] | 20 | import org.openstreetmap.josm.tools.Utils;
|
---|
| 21 |
|
---|
[6716] | 22 | /**
|
---|
| 23 | * An enum representing the compression type of a resource.
|
---|
| 24 | */
|
---|
| 25 | public enum Compression {
|
---|
| 26 | /**
|
---|
| 27 | * no compression
|
---|
| 28 | */
|
---|
| 29 | NONE,
|
---|
| 30 | /**
|
---|
| 31 | * bzip2 compression
|
---|
| 32 | */
|
---|
| 33 | BZIP2,
|
---|
| 34 | /**
|
---|
| 35 | * gzip compression
|
---|
| 36 | */
|
---|
[6882] | 37 | GZIP,
|
---|
| 38 | /**
|
---|
| 39 | * zip compression
|
---|
| 40 | */
|
---|
| 41 | ZIP;
|
---|
[6716] | 42 |
|
---|
| 43 | /**
|
---|
| 44 | * Determines the compression type depending on the suffix of {@code name}.
|
---|
[6882] | 45 | * @param name File name including extension
|
---|
| 46 | * @return the compression type
|
---|
[6716] | 47 | */
|
---|
| 48 | public static Compression byExtension(String name) {
|
---|
| 49 | return name != null && name.endsWith(".gz")
|
---|
| 50 | ? GZIP
|
---|
| 51 | : name != null && (name.endsWith(".bz2") || name.endsWith(".bz"))
|
---|
| 52 | ? BZIP2
|
---|
[6882] | 53 | : name != null && name.endsWith(".zip")
|
---|
| 54 | ? ZIP
|
---|
[6716] | 55 | : NONE;
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | /**
|
---|
[9169] | 59 | * Determines the compression type based on the content type (MIME type).
|
---|
| 60 | * @param contentType the content type
|
---|
| 61 | * @return the compression type
|
---|
| 62 | */
|
---|
| 63 | public static Compression forContentType(String contentType) {
|
---|
| 64 | switch (contentType) {
|
---|
| 65 | case "application/zip":
|
---|
| 66 | return ZIP;
|
---|
| 67 | case "application/x-gzip":
|
---|
| 68 | return GZIP;
|
---|
| 69 | case "application/x-bzip2":
|
---|
| 70 | return BZIP2;
|
---|
| 71 | default:
|
---|
| 72 | return NONE;
|
---|
| 73 | }
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | /**
|
---|
[6716] | 77 | * Returns an un-compressing {@link InputStream} for {@code in}.
|
---|
[8929] | 78 | * @param in raw input stream
|
---|
| 79 | * @return un-compressing input stream
|
---|
[6716] | 80 | *
|
---|
[8470] | 81 | * @throws IOException if any I/O error occurs
|
---|
[6716] | 82 | */
|
---|
| 83 | public InputStream getUncompressedInputStream(InputStream in) throws IOException {
|
---|
| 84 | switch (this) {
|
---|
| 85 | case BZIP2:
|
---|
[12772] | 86 | return getBZip2InputStream(in);
|
---|
[6716] | 87 | case GZIP:
|
---|
[12772] | 88 | return getGZipInputStream(in);
|
---|
[6882] | 89 | case ZIP:
|
---|
[12772] | 90 | return getZipInputStream(in);
|
---|
[6716] | 91 | case NONE:
|
---|
| 92 | default:
|
---|
| 93 | return in;
|
---|
| 94 | }
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | /**
|
---|
[12772] | 98 | * Returns a Bzip2 input stream wrapping given input stream.
|
---|
| 99 | * @param in The raw input stream
|
---|
| 100 | * @return a Bzip2 input stream wrapping given input stream, or {@code null} if {@code in} is {@code null}
|
---|
| 101 | * @throws IOException if the given input stream does not contain valid BZ2 header
|
---|
| 102 | * @since 12772 (moved from {@link Utils}, there since 7867)
|
---|
| 103 | */
|
---|
| 104 | public static BZip2CompressorInputStream getBZip2InputStream(InputStream in) throws IOException {
|
---|
| 105 | if (in == null) {
|
---|
| 106 | return null;
|
---|
| 107 | }
|
---|
| 108 | return new BZip2CompressorInputStream(in, /* see #9537 */ true);
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | /**
|
---|
| 112 | * Returns a Gzip input stream wrapping given input stream.
|
---|
| 113 | * @param in The raw input stream
|
---|
| 114 | * @return a Gzip input stream wrapping given input stream, or {@code null} if {@code in} is {@code null}
|
---|
| 115 | * @throws IOException if an I/O error has occurred
|
---|
| 116 | * @since 12772 (moved from {@link Utils}, there since 7119)
|
---|
| 117 | */
|
---|
| 118 | public static GZIPInputStream getGZipInputStream(InputStream in) throws IOException {
|
---|
| 119 | if (in == null) {
|
---|
| 120 | return null;
|
---|
| 121 | }
|
---|
| 122 | return new GZIPInputStream(in);
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | /**
|
---|
| 126 | * Returns a Zip input stream wrapping given input stream.
|
---|
| 127 | * @param in The raw input stream
|
---|
| 128 | * @return a Zip input stream wrapping given input stream, or {@code null} if {@code in} is {@code null}
|
---|
| 129 | * @throws IOException if an I/O error has occurred
|
---|
| 130 | * @since 12772 (moved from {@link Utils}, there since 7119)
|
---|
| 131 | */
|
---|
| 132 | public static ZipInputStream getZipInputStream(InputStream in) throws IOException {
|
---|
| 133 | if (in == null) {
|
---|
| 134 | return null;
|
---|
| 135 | }
|
---|
| 136 | ZipInputStream zis = new ZipInputStream(in, StandardCharsets.UTF_8);
|
---|
| 137 | // Positions the stream at the beginning of first entry
|
---|
| 138 | ZipEntry ze = zis.getNextEntry();
|
---|
| 139 | if (ze != null && Logging.isDebugEnabled()) {
|
---|
| 140 | Logging.debug("Zip entry: {0}", ze.getName());
|
---|
| 141 | }
|
---|
| 142 | return zis;
|
---|
| 143 | }
|
---|
| 144 |
|
---|
| 145 | /**
|
---|
[6716] | 146 | * Returns an un-compressing {@link InputStream} for the {@link File} {@code file}.
|
---|
[8929] | 147 | * @param file file
|
---|
| 148 | * @return un-compressing input stream
|
---|
[8470] | 149 | * @throws IOException if any I/O error occurs
|
---|
[6716] | 150 | */
|
---|
| 151 | public static InputStream getUncompressedFileInputStream(File file) throws IOException {
|
---|
[10223] | 152 | FileInputStream in = new FileInputStream(file);
|
---|
| 153 | try {
|
---|
| 154 | return byExtension(file.getName()).getUncompressedInputStream(in);
|
---|
| 155 | } catch (IOException e) {
|
---|
| 156 | Utils.close(in);
|
---|
| 157 | throw e;
|
---|
| 158 | }
|
---|
[6716] | 159 | }
|
---|
| 160 |
|
---|
| 161 | /**
|
---|
| 162 | * Returns a compressing {@link OutputStream} for {@code out}.
|
---|
[8929] | 163 | * @param out raw output stream
|
---|
| 164 | * @return compressing output stream
|
---|
[6716] | 165 | *
|
---|
[8470] | 166 | * @throws IOException if any I/O error occurs
|
---|
[6716] | 167 | */
|
---|
| 168 | public OutputStream getCompressedOutputStream(OutputStream out) throws IOException {
|
---|
| 169 | switch (this) {
|
---|
| 170 | case BZIP2:
|
---|
[7867] | 171 | return new BZip2CompressorOutputStream(out);
|
---|
[6716] | 172 | case GZIP:
|
---|
| 173 | return new GZIPOutputStream(out);
|
---|
[6882] | 174 | case ZIP:
|
---|
[7089] | 175 | return new ZipOutputStream(out, StandardCharsets.UTF_8);
|
---|
[6716] | 176 | case NONE:
|
---|
| 177 | default:
|
---|
| 178 | return out;
|
---|
| 179 | }
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 | /**
|
---|
| 183 | * Returns a compressing {@link OutputStream} for the {@link File} {@code file}.
|
---|
[8929] | 184 | * @param file file
|
---|
| 185 | * @return compressing output stream
|
---|
[6716] | 186 | *
|
---|
[8470] | 187 | * @throws IOException if any I/O error occurs
|
---|
[6716] | 188 | */
|
---|
| 189 | public static OutputStream getCompressedFileOutputStream(File file) throws IOException {
|
---|
[10223] | 190 | FileOutputStream out = new FileOutputStream(file);
|
---|
| 191 | try {
|
---|
| 192 | return byExtension(file.getName()).getCompressedOutputStream(out);
|
---|
| 193 | } catch (IOException e) {
|
---|
| 194 | Utils.close(out);
|
---|
| 195 | throw e;
|
---|
| 196 | }
|
---|
[6716] | 197 | }
|
---|
| 198 | }
|
---|