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.nio.charset.StandardCharsets; 011import java.util.zip.GZIPOutputStream; 012import java.util.zip.ZipOutputStream; 013 014import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; 015import org.openstreetmap.josm.tools.Utils; 016 017/** 018 * An enum representing the compression type of a resource. 019 */ 020public enum Compression { 021 /** 022 * no compression 023 */ 024 NONE, 025 /** 026 * bzip2 compression 027 */ 028 BZIP2, 029 /** 030 * gzip compression 031 */ 032 GZIP, 033 /** 034 * zip compression 035 */ 036 ZIP; 037 038 /** 039 * Determines the compression type depending on the suffix of {@code name}. 040 * @param name File name including extension 041 * @return the compression type 042 */ 043 public static Compression byExtension(String name) { 044 return name != null && name.endsWith(".gz") 045 ? GZIP 046 : name != null && (name.endsWith(".bz2") || name.endsWith(".bz")) 047 ? BZIP2 048 : name != null && name.endsWith(".zip") 049 ? ZIP 050 : NONE; 051 } 052 053 /** 054 * Determines the compression type based on the content type (MIME type). 055 * @param contentType the content type 056 * @return the compression type 057 */ 058 public static Compression forContentType(String contentType) { 059 switch (contentType) { 060 case "application/zip": 061 return ZIP; 062 case "application/x-gzip": 063 return GZIP; 064 case "application/x-bzip2": 065 return BZIP2; 066 default: 067 return NONE; 068 } 069 } 070 071 /** 072 * Returns an un-compressing {@link InputStream} for {@code in}. 073 * @param in raw input stream 074 * @return un-compressing input stream 075 * 076 * @throws IOException if any I/O error occurs 077 */ 078 public InputStream getUncompressedInputStream(InputStream in) throws IOException { 079 switch (this) { 080 case BZIP2: 081 return Utils.getBZip2InputStream(in); 082 case GZIP: 083 return Utils.getGZipInputStream(in); 084 case ZIP: 085 return Utils.getZipInputStream(in); 086 case NONE: 087 default: 088 return in; 089 } 090 } 091 092 /** 093 * Returns an un-compressing {@link InputStream} for the {@link File} {@code file}. 094 * @param file file 095 * @return un-compressing input stream 096 * @throws IOException if any I/O error occurs 097 */ 098 public static InputStream getUncompressedFileInputStream(File file) throws IOException { 099 FileInputStream in = new FileInputStream(file); 100 try { 101 return byExtension(file.getName()).getUncompressedInputStream(in); 102 } catch (IOException e) { 103 Utils.close(in); 104 throw e; 105 } 106 } 107 108 /** 109 * Returns a compressing {@link OutputStream} for {@code out}. 110 * @param out raw output stream 111 * @return compressing output stream 112 * 113 * @throws IOException if any I/O error occurs 114 */ 115 public OutputStream getCompressedOutputStream(OutputStream out) throws IOException { 116 switch (this) { 117 case BZIP2: 118 return new BZip2CompressorOutputStream(out); 119 case GZIP: 120 return new GZIPOutputStream(out); 121 case ZIP: 122 return new ZipOutputStream(out, StandardCharsets.UTF_8); 123 case NONE: 124 default: 125 return out; 126 } 127 } 128 129 /** 130 * Returns a compressing {@link OutputStream} for the {@link File} {@code file}. 131 * @param file file 132 * @return compressing output stream 133 * 134 * @throws IOException if any I/O error occurs 135 */ 136 public static OutputStream getCompressedFileOutputStream(File file) throws IOException { 137 FileOutputStream out = new FileOutputStream(file); 138 try { 139 return byExtension(file.getName()).getCompressedOutputStream(out); 140 } catch (IOException e) { 141 Utils.close(out); 142 throw e; 143 } 144 } 145}