blob: da8901a0e633bbdbbd1974aa8cf2177ab7b33da1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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.webkit;
18
Elliott Hughes0f1169612010-08-02 13:37:48 -070019import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import java.util.regex.Pattern;
Elliott Hughes0f1169612010-08-02 13:37:48 -070021import libcore.net.MimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
23/**
24 * Two-way map that maps MIME-types to file extensions and vice versa.
Elliott Hughes0f1169612010-08-02 13:37:48 -070025 *
26 * <p>See also {@link java.net.URLConnection#guessContentTypeFromName}
27 * and {@link java.net.URLConnection#guessContentTypeFromStream}. This
28 * class and {@code URLConnection} share the same MIME-type database.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029 */
Patrick Scott9f617322009-07-21 13:39:45 -040030public class MimeTypeMap {
Elliott Hughes0f1169612010-08-02 13:37:48 -070031 private static final MimeTypeMap sMimeTypeMap = new MimeTypeMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 private MimeTypeMap() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034 }
35
36 /**
37 * Returns the file extension or an empty string iff there is no
Patrick Scott9f617322009-07-21 13:39:45 -040038 * extension. This method is a convenience method for obtaining the
39 * extension of a url and has undefined results for other Strings.
40 * @param url
41 * @return The file extension of the given url.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042 */
43 public static String getFileExtensionFromUrl(String url) {
Elliott Hughes0f1169612010-08-02 13:37:48 -070044 if (!TextUtils.isEmpty(url)) {
Ben Murdoch18700152010-12-14 16:36:03 +000045 int fragment = url.lastIndexOf('#');
46 if (fragment > 0) {
47 url = url.substring(0, fragment);
48 }
49
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 int query = url.lastIndexOf('?');
51 if (query > 0) {
52 url = url.substring(0, query);
53 }
Ben Murdoch18700152010-12-14 16:36:03 +000054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 int filenamePos = url.lastIndexOf('/');
56 String filename =
57 0 <= filenamePos ? url.substring(filenamePos + 1) : url;
58
59 // if the filename contains special characters, we don't
60 // consider it valid for our matching purposes:
Elliott Hughes0f1169612010-08-02 13:37:48 -070061 if (!filename.isEmpty() &&
Melanie Clementsf19670a2010-05-01 22:48:20 -040062 Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 int dotPos = filename.lastIndexOf('.');
64 if (0 <= dotPos) {
65 return filename.substring(dotPos + 1);
66 }
67 }
68 }
69
70 return "";
71 }
72
73 /**
Patrick Scott9f617322009-07-21 13:39:45 -040074 * Return true if the given MIME type has an entry in the map.
75 * @param mimeType A MIME type (i.e. text/plain)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 * @return True iff there is a mimeType entry in the map.
77 */
78 public boolean hasMimeType(String mimeType) {
Elliott Hughes0f1169612010-08-02 13:37:48 -070079 return MimeUtils.hasMimeType(mimeType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 }
81
82 /**
Patrick Scott9f617322009-07-21 13:39:45 -040083 * Return the MIME type for the given extension.
84 * @param extension A file extension without the leading '.'
85 * @return The MIME type for the given extension or null iff there is none.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 */
87 public String getMimeTypeFromExtension(String extension) {
Elliott Hughes0f1169612010-08-02 13:37:48 -070088 return MimeUtils.guessMimeTypeFromExtension(extension);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 }
90
Patrick Scott021b7b42010-01-13 14:12:43 -050091 // Static method called by jni.
92 private static String mimeTypeFromExtension(String extension) {
Elliott Hughes0f1169612010-08-02 13:37:48 -070093 return MimeUtils.guessMimeTypeFromExtension(extension);
Patrick Scott021b7b42010-01-13 14:12:43 -050094 }
95
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 /**
Patrick Scott9f617322009-07-21 13:39:45 -040097 * Return true if the given extension has a registered MIME type.
98 * @param extension A file extension without the leading '.'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 * @return True iff there is an extension entry in the map.
100 */
101 public boolean hasExtension(String extension) {
Elliott Hughes0f1169612010-08-02 13:37:48 -0700102 return MimeUtils.hasExtension(extension);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 }
104
105 /**
Patrick Scott9f617322009-07-21 13:39:45 -0400106 * Return the registered extension for the given MIME type. Note that some
107 * MIME types map to multiple extensions. This call will return the most
108 * common extension for the given MIME type.
109 * @param mimeType A MIME type (i.e. text/plain)
110 * @return The extension for the given MIME type or null iff there is none.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 */
112 public String getExtensionFromMimeType(String mimeType) {
Elliott Hughes0f1169612010-08-02 13:37:48 -0700113 return MimeUtils.guessExtensionFromMimeType(mimeType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 }
115
116 /**
Iain Merrickd77f9b72010-10-18 18:22:25 +0100117 * If the given MIME type is null, or one of the "generic" types (text/plain
118 * or application/octet-stream) map it to a type that Android can deal with.
119 * If the given type is not generic, return it unchanged.
120 *
121 * @param mimeType MIME type provided by the server.
122 * @param url URL of the data being loaded.
123 * @param contentDisposition Content-disposition header given by the server.
124 * @return The MIME type that should be used for this data.
125 */
126 /* package */ String remapGenericMimeType(String mimeType, String url,
127 String contentDisposition) {
128 // If we have one of "generic" MIME types, try to deduce
129 // the right MIME type from the file extension (if any):
130 if ("text/plain".equals(mimeType) ||
131 "application/octet-stream".equals(mimeType)) {
132
133 // for attachment, use the filename in the Content-Disposition
134 // to guess the mimetype
135 String filename = null;
136 if (contentDisposition != null) {
137 filename = URLUtil.parseContentDisposition(contentDisposition);
138 }
139 if (filename != null) {
140 url = filename;
141 }
142 String extension = getFileExtensionFromUrl(url);
143 String newMimeType = getMimeTypeFromExtension(extension);
144 if (newMimeType != null) {
145 mimeType = newMimeType;
146 }
147 } else if ("text/vnd.wap.wml".equals(mimeType)) {
148 // As we don't support wml, render it as plain text
149 mimeType = "text/plain";
150 } else {
151 // It seems that xhtml+xml and vnd.wap.xhtml+xml mime
152 // subtypes are used interchangeably. So treat them the same.
153 if ("application/vnd.wap.xhtml+xml".equals(mimeType)) {
154 mimeType = "application/xhtml+xml";
155 }
156 }
157 return mimeType;
158 }
159
160 /**
Patrick Scott9f617322009-07-21 13:39:45 -0400161 * Get the singleton instance of MimeTypeMap.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 * @return The singleton instance of the MIME-type map.
163 */
164 public static MimeTypeMap getSingleton() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 return sMimeTypeMap;
166 }
167}