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 org.apache.commons.compress.compressors.brotli.BrotliUtils; 28 import org.apache.commons.compress.compressors.xz.XZUtils; 29 30 import java.util.HashMap; 31 import java.util.Map; 32 33 /** 34 * To query how to generate ArchiveHandle, how to create CompressInputStream and how to create 35 * ArchiveInputStream by using MIME type in ArchiveRegistry. 36 */ 37 final class ArchiveRegistry { 38 static final int COMMON_ARCHIVE_TYPE = 1; 39 static final int ZIP_TYPE = 2; 40 static final int SEVEN_Z_TYPE = 3; 41 42 /** 43 * The mapping between MIME type and how to create ArchiveHandle instance. 44 * key - MIME type 45 * value - the integer value used in ArchiveHandle.create 46 */ 47 private static final Map<String, Integer> sHandleArchiveMap = new HashMap<>(); 48 49 /** 50 * The mapping between MIME type and the archive name that is used by ArchiveStreamFactory. 51 * key - MIME type 52 * value - the archive name is used as the 1st parameter of ArchiveStreamFactory 53 * .createArchiveInputStream 54 */ 55 private static final Map<String, String> sMimeTypeArchiveNameMap = new HashMap<>(); 56 57 /** 58 * The mapping between MIME type and the compress name that is used by CompressorStreamFactory. 59 * key - MIME type 60 * value - the compress name is used as the 1st parameter of CompressorStreamFactory 61 * .createCompressorInputStream 62 */ 63 private static final Map<String, String> sMimeTypeCompressNameMap = new HashMap<>(); 64 65 static { 66 /* initial sHandleArchiveMap */ 67 sHandleArchiveMap.put("application/zip", ZIP_TYPE); 68 sHandleArchiveMap.put("application/x-zip", ZIP_TYPE); 69 sHandleArchiveMap.put("application/x-zip-compressed", ZIP_TYPE); 70 sHandleArchiveMap.put("application/x-7z-compressed", SEVEN_Z_TYPE); 71 sHandleArchiveMap.put("application/x-gtar", COMMON_ARCHIVE_TYPE); 72 sHandleArchiveMap.put("application/x-tar", COMMON_ARCHIVE_TYPE); 73 sHandleArchiveMap.put("application/x-compressed-tar", COMMON_ARCHIVE_TYPE); 74 sHandleArchiveMap.put("application/x-gtar-compressed", COMMON_ARCHIVE_TYPE); 75 sHandleArchiveMap.put("application/x-bzip-compressed-tar", COMMON_ARCHIVE_TYPE); 76 if (BrotliUtils.isBrotliCompressionAvailable()) { 77 sHandleArchiveMap.put("application/x-brotli-compressed-tar", COMMON_ARCHIVE_TYPE); 78 } 79 if (XZUtils.isXZCompressionAvailable()) { 80 sHandleArchiveMap.put("application/x-xz-compressed-tar", COMMON_ARCHIVE_TYPE); 81 } 82 83 /* initial sMimeTypeArchiveNameMap */ 84 sMimeTypeArchiveNameMap.put("application/x-gtar", TAR); 85 sMimeTypeArchiveNameMap.put("application/x-tar", TAR); 86 sMimeTypeArchiveNameMap.put("application/x-compressed-tar", TAR); 87 sMimeTypeArchiveNameMap.put("application/x-gtar-compressed", TAR); 88 sMimeTypeArchiveNameMap.put("application/x-bzip-compressed-tar", TAR); 89 sMimeTypeArchiveNameMap.put("application/x-brotli-compressed-tar", TAR); 90 sMimeTypeArchiveNameMap.put("application/x-xz-compressed-tar", TAR); 91 92 /* initial sMimeTypeCompressNameMap */ 93 sMimeTypeCompressNameMap.put("application/x-compressed-tar", GZIP); 94 sMimeTypeCompressNameMap.put("application/x-gtar-compressed", GZIP); 95 sMimeTypeCompressNameMap.put("application/x-bzip-compressed-tar", BZIP2); 96 if (BrotliUtils.isBrotliCompressionAvailable()) { 97 sMimeTypeCompressNameMap.put("application/x-brotli-compressed-tar", BROTLI); 98 } 99 if (XZUtils.isXZCompressionAvailable()) { 100 sMimeTypeCompressNameMap.put("application/x-xz-compressed-tar", XZ); 101 } 102 } 103 104 /** 105 * To query the archive name by passing MIME type is used by 106 * ArchiveStreamFactory.createArchiveInputStream. 107 * 108 * @param mimeType the MIME type of the archive file 109 * @return the archive name to tell ArchiveStreamFactory how to extract archive 110 */ 111 @Nullable getArchiveName(String mimeType)112 static String getArchiveName(String mimeType) { 113 return sMimeTypeArchiveNameMap.get(mimeType); 114 } 115 116 /** 117 * To query the compress name by passing MIME type is used by 118 * CompressorStreamFactory.createCompressorInputStream. 119 * 120 * @param mimeType the MIME type of the compressed file 121 * @return the compress name to tell CompressorStreamFactory how to uncompress 122 */ 123 @Nullable getCompressName(String mimeType)124 static String getCompressName(String mimeType) { 125 return sMimeTypeCompressNameMap.get(mimeType); 126 } 127 128 /** 129 * To query the method to uncompress the compressed file by MIME type. 130 * 131 * @param mimeType the MIME type of the compressed file 132 * @return the method describe how to uncompress the compressed file 133 */ 134 @Nullable getArchiveType(String mimeType)135 static Integer getArchiveType(String mimeType) { 136 return sHandleArchiveMap.get(mimeType); 137 } 138 } 139