blob: 367160367cc049bd61af6ec4d0167d9327f0458c [file] [log] [blame]
Tobias Thierer878c77b2019-08-18 15:19:45 +01001/*
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
17package android.content.type;
18
19import libcore.net.MimeMap;
20
21import java.io.BufferedReader;
22import java.io.IOException;
23import java.io.InputStreamReader;
Tobias Thiererfd9657d2019-08-20 15:23:34 +010024import java.util.Arrays;
Tobias Thierer878c77b2019-08-18 15:19:45 +010025import java.util.List;
Tobias Thierer878c77b2019-08-18 15:19:45 +010026import java.util.regex.Pattern;
27
28/**
29 * Default implementation of {@link MimeMap}, a bidirectional mapping between
30 * MIME types and file extensions.
31 *
32 * This default mapping is loaded from data files that start with some mappings
33 * recognized by IANA plus some custom extensions and overrides.
34 *
35 * @hide
36 */
Tobias Thiererfd9657d2019-08-20 15:23:34 +010037public class MimeMapImpl {
Tobias Thierer878c77b2019-08-18 15:19:45 +010038
39 /**
40 * Creates and returns a new {@link MimeMapImpl} instance that implements.
41 * Android's default mapping between MIME types and extensions.
42 */
Tobias Thiererfd9657d2019-08-20 15:23:34 +010043 public static MimeMap createDefaultInstance() {
Tobias Thierer878c77b2019-08-18 15:19:45 +010044 return parseFromResources("/mime.types", "/android.mime.types");
45 }
46
47 private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+");
48
Tobias Thiererfd9657d2019-08-20 15:23:34 +010049 static MimeMap parseFromResources(String... resourceNames) {
50 MimeMap.Builder builder = MimeMap.builder();
Tobias Thierer878c77b2019-08-18 15:19:45 +010051 for (String resourceName : resourceNames) {
Tobias Thiererfd9657d2019-08-20 15:23:34 +010052 parseTypes(builder, resourceName);
Tobias Thierer878c77b2019-08-18 15:19:45 +010053 }
Tobias Thiererfd9657d2019-08-20 15:23:34 +010054 return builder.build();
Tobias Thierer878c77b2019-08-18 15:19:45 +010055 }
56
Tobias Thiererfd9657d2019-08-20 15:23:34 +010057 private static void parseTypes(MimeMap.Builder builder, String resource) {
Tobias Thierer878c77b2019-08-18 15:19:45 +010058 try (BufferedReader r = new BufferedReader(
59 new InputStreamReader(MimeMapImpl.class.getResourceAsStream(resource)))) {
60 String line;
61 while ((line = r.readLine()) != null) {
62 int commentPos = line.indexOf('#');
63 if (commentPos >= 0) {
64 line = line.substring(0, commentPos);
65 }
66 line = line.trim();
Tobias Thiererfd9657d2019-08-20 15:23:34 +010067 if (line.isEmpty()) {
Tobias Thierer878c77b2019-08-18 15:19:45 +010068 continue;
69 }
Tobias Thiererfd9657d2019-08-20 15:23:34 +010070 List<String> specs = Arrays.asList(SPLIT_PATTERN.split(line));
71 builder.put(specs.get(0), specs.subList(1, specs.size()));
Tobias Thierer878c77b2019-08-18 15:19:45 +010072 }
73 } catch (IOException | RuntimeException e) {
74 throw new RuntimeException("Failed to parse " + resource, e);
75 }
76 }
77
Tobias Thierer878c77b2019-08-18 15:19:45 +010078}