1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui.archives; 18 19 import static org.apache.commons.compress.archivers.ArchiveStreamFactory.TAR; 20 import static org.apache.commons.compress.compressors.CompressorStreamFactory.BROTLI; 21 import static org.apache.commons.compress.compressors.CompressorStreamFactory.BZIP2; 22 import static org.apache.commons.compress.compressors.CompressorStreamFactory.GZIP; 23 import static org.apache.commons.compress.compressors.CompressorStreamFactory.XZ; 24 25 import androidx.annotation.Nullable; 26 27 import java.util.HashMap; 28 import java.util.Map; 29 import java.util.Set; 30 31 import org.apache.commons.compress.compressors.brotli.BrotliUtils; 32 import org.apache.commons.compress.compressors.xz.XZUtils; 33 34 /** 35 * To query how to generate ArchiveHandle, how to create CompressInputStream and how to create 36 * ArchiveInputStream by using MIME type in ArchiveRegistry. 37 */ 38 final class ArchiveRegistry { 39 static final int COMMON_ARCHIVE_TYPE = 1; 40 static final int ZIP_TYPE = 2; 41 static final int SEVEN_Z_TYPE = 3; 42 43 /** 44 * The mapping between MIME type and how to create ArchiveHandle instance. 45 * key - MIME type 46 * value - the integer value used in ArchiveHandle.create 47 */ 48 private static final Map<String, Integer> sHandleArchiveMap = new HashMap<>(); 49 50 /** 51 * The mapping between MIME type and the archive name that is used by ArchiveStreamFactory. 52 * key - MIME type 53 * value - the archive name is used as the 1st parameter of ArchiveStreamFactory 54 * .createArchiveInputStream 55 */ 56 private static final Map<String, String> sMimeTypeArchiveNameMap = new HashMap<>(); 57 58 /** 59 * The mapping between MIME type and the compress name that is used by CompressorStreamFactory. 60 * key - MIME type 61 * value - the compress name is used as the 1st parameter of CompressorStreamFactory 62 * .createCompressorInputStream 63 */ 64 private static final Map<String, String> sMimeTypeCompressNameMap = new HashMap<>(); 65 66 static { 67 /* initial sHandleArchiveMap */ 68 sHandleArchiveMap.put("application/zip", ZIP_TYPE); 69 sHandleArchiveMap.put("application/x-zip", ZIP_TYPE); 70 sHandleArchiveMap.put("application/x-zip-compressed", ZIP_TYPE); 71 sHandleArchiveMap.put("application/x-7z-compressed", SEVEN_Z_TYPE); 72 sHandleArchiveMap.put("application/x-gtar", COMMON_ARCHIVE_TYPE); 73 sHandleArchiveMap.put("application/x-tar", COMMON_ARCHIVE_TYPE); 74 sHandleArchiveMap.put("application/x-compressed-tar", COMMON_ARCHIVE_TYPE); 75 sHandleArchiveMap.put("application/x-gtar-compressed", COMMON_ARCHIVE_TYPE); 76 sHandleArchiveMap.put("application/x-bzip-compressed-tar", COMMON_ARCHIVE_TYPE); 77 if (BrotliUtils.isBrotliCompressionAvailable()) { 78 sHandleArchiveMap.put("application/x-brotli-compressed-tar", COMMON_ARCHIVE_TYPE); 79 } 80 if (XZUtils.isXZCompressionAvailable()) { 81 sHandleArchiveMap.put("application/x-xz-compressed-tar", COMMON_ARCHIVE_TYPE); 82 } 83 84 /* initial sMimeTypeArchiveNameMap */ 85 sMimeTypeArchiveNameMap.put("application/x-gtar", TAR); 86 sMimeTypeArchiveNameMap.put("application/x-tar", TAR); 87 sMimeTypeArchiveNameMap.put("application/x-compressed-tar", TAR); 88 sMimeTypeArchiveNameMap.put("application/x-gtar-compressed", TAR); 89 sMimeTypeArchiveNameMap.put("application/x-bzip-compressed-tar", TAR); 90 sMimeTypeArchiveNameMap.put("application/x-brotli-compressed-tar", TAR); 91 sMimeTypeArchiveNameMap.put("application/x-xz-compressed-tar", TAR); 92 93 /* initial sMimeTypeCompressNameMap */ 94 sMimeTypeCompressNameMap.put("application/x-compressed-tar", GZIP); 95 sMimeTypeCompressNameMap.put("application/x-gtar-compressed", GZIP); 96 sMimeTypeCompressNameMap.put("application/x-bzip-compressed-tar", BZIP2); 97 if (BrotliUtils.isBrotliCompressionAvailable()) { 98 sMimeTypeCompressNameMap.put("application/x-brotli-compressed-tar", BROTLI); 99 } 100 if (XZUtils.isXZCompressionAvailable()) { 101 sMimeTypeCompressNameMap.put("application/x-xz-compressed-tar", XZ); 102 } 103 } 104 105 /** 106 * To query the archive name by passing MIME type is used by 107 * ArchiveStreamFactory.createArchiveInputStream. 108 * 109 * @param mimeType the MIME type of the archive file 110 * @return the archive name to tell ArchiveStreamFactory how to extract archive 111 */ 112 @Nullable getArchiveName(String mimeType)113 static String getArchiveName(String mimeType) { 114 return sMimeTypeArchiveNameMap.get(mimeType); 115 } 116 117 /** 118 * To query the compress name by passing MIME type is used by 119 * CompressorStreamFactory.createCompressorInputStream. 120 * 121 * @param mimeType the MIME type of the compressed file 122 * @return the compress name to tell CompressorStreamFactory how to uncompress 123 */ 124 @Nullable getCompressName(String mimeType)125 static String getCompressName(String mimeType) { 126 return sMimeTypeCompressNameMap.get(mimeType); 127 } 128 129 /** 130 * To query the method to uncompress the compressed file by MIME type. 131 * 132 * @param mimeType the MIME type of the compressed file 133 * @return the method describe how to uncompress the compressed file 134 */ 135 @Nullable getArchiveType(String mimeType)136 static Integer getArchiveType(String mimeType) { 137 return sHandleArchiveMap.get(mimeType); 138 } 139 getSupportList()140 static Set<String> getSupportList() { 141 return sHandleArchiveMap.keySet(); 142 } 143 } 144