Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/net/www/MimeTable.java
41159 views
1
/*
2
* Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.net.www;
27
import jdk.internal.util.StaticProperty;
28
29
import java.io.*;
30
import java.net.FileNameMap;
31
import java.util.Hashtable;
32
import java.util.Enumeration;
33
import java.util.Properties;
34
import java.util.StringTokenizer;
35
36
@SuppressWarnings("removal")
37
public class MimeTable implements FileNameMap {
38
/** Keyed by content type, returns MimeEntries */
39
private Hashtable<String, MimeEntry> entries
40
= new Hashtable<String, MimeEntry>();
41
42
/** Keyed by file extension (with the .), returns MimeEntries */
43
private Hashtable<String, MimeEntry> extensionMap
44
= new Hashtable<String, MimeEntry>();
45
46
// Will be reset if in the platform-specific data file
47
private static String tempFileTemplate;
48
49
static {
50
java.security.AccessController.doPrivileged(
51
new java.security.PrivilegedAction<Void>() {
52
public Void run() {
53
tempFileTemplate =
54
System.getProperty("content.types.temp.file.template",
55
"/tmp/%s");
56
57
mailcapLocations = new String[] {
58
System.getProperty("user.mailcap"),
59
StaticProperty.userHome() + "/.mailcap",
60
"/etc/mailcap",
61
"/usr/etc/mailcap",
62
"/usr/local/etc/mailcap",
63
};
64
return null;
65
}
66
});
67
}
68
69
70
private static final String filePreamble = "sun.net.www MIME content-types table";
71
private static final String fileMagic = "#" + filePreamble;
72
73
MimeTable() {
74
load();
75
}
76
77
private static class DefaultInstanceHolder {
78
static final MimeTable defaultInstance = getDefaultInstance();
79
80
static MimeTable getDefaultInstance() {
81
return java.security.AccessController.doPrivileged(
82
new java.security.PrivilegedAction<MimeTable>() {
83
public MimeTable run() {
84
MimeTable instance = new MimeTable();
85
URLConnection.setFileNameMap(instance);
86
return instance;
87
}
88
});
89
}
90
}
91
92
/**
93
* Get the single instance of this class. First use will load the
94
* table from a data file.
95
*/
96
public static MimeTable getDefaultTable() {
97
return DefaultInstanceHolder.defaultInstance;
98
}
99
100
/**
101
*
102
*/
103
public static FileNameMap loadTable() {
104
MimeTable mt = getDefaultTable();
105
return (FileNameMap)mt;
106
}
107
108
public synchronized int getSize() {
109
return entries.size();
110
}
111
112
public synchronized String getContentTypeFor(String fileName) {
113
MimeEntry entry = findByFileName(fileName);
114
if (entry != null) {
115
return entry.getType();
116
} else {
117
return null;
118
}
119
}
120
121
public synchronized void add(MimeEntry m) {
122
entries.put(m.getType(), m);
123
124
String exts[] = m.getExtensions();
125
if (exts == null) {
126
return;
127
}
128
129
for (int i = 0; i < exts.length; i++) {
130
extensionMap.put(exts[i], m);
131
}
132
}
133
134
public synchronized MimeEntry remove(String type) {
135
MimeEntry entry = entries.get(type);
136
return remove(entry);
137
}
138
139
public synchronized MimeEntry remove(MimeEntry entry) {
140
String[] extensionKeys = entry.getExtensions();
141
if (extensionKeys != null) {
142
for (int i = 0; i < extensionKeys.length; i++) {
143
extensionMap.remove(extensionKeys[i]);
144
}
145
}
146
147
return entries.remove(entry.getType());
148
}
149
150
public synchronized MimeEntry find(String type) {
151
MimeEntry entry = entries.get(type);
152
if (entry == null) {
153
// try a wildcard lookup
154
Enumeration<MimeEntry> e = entries.elements();
155
while (e.hasMoreElements()) {
156
MimeEntry wild = e.nextElement();
157
if (wild.matches(type)) {
158
return wild;
159
}
160
}
161
}
162
163
return entry;
164
}
165
166
/**
167
* Locate a MimeEntry by the file extension that has been associated
168
* with it. Parses general file names, and URLs.
169
*/
170
public MimeEntry findByFileName(String fname) {
171
String ext = "";
172
173
int i = fname.lastIndexOf('#');
174
175
if (i > 0) {
176
fname = fname.substring(0, i - 1);
177
}
178
179
i = fname.lastIndexOf('.');
180
// REMIND: OS specific delimters appear here
181
i = Math.max(i, fname.lastIndexOf('/'));
182
i = Math.max(i, fname.lastIndexOf('?'));
183
184
if (i != -1 && fname.charAt(i) == '.') {
185
ext = fname.substring(i).toLowerCase();
186
}
187
188
return findByExt(ext);
189
}
190
191
/**
192
* Locate a MimeEntry by the file extension that has been associated
193
* with it.
194
*/
195
public synchronized MimeEntry findByExt(String fileExtension) {
196
return extensionMap.get(fileExtension);
197
}
198
199
public synchronized MimeEntry findByDescription(String description) {
200
Enumeration<MimeEntry> e = elements();
201
while (e.hasMoreElements()) {
202
MimeEntry entry = e.nextElement();
203
if (description.equals(entry.getDescription())) {
204
return entry;
205
}
206
}
207
208
// We failed, now try treating description as type
209
return find(description);
210
}
211
212
String getTempFileTemplate() {
213
return tempFileTemplate;
214
}
215
216
public synchronized Enumeration<MimeEntry> elements() {
217
return entries.elements();
218
}
219
220
// For backward compatibility -- mailcap format files
221
// This is not currently used, but may in the future when we add ability
222
// to read BOTH the properties format and the mailcap format.
223
protected static String[] mailcapLocations;
224
225
public synchronized void load() {
226
Properties entries = new Properties();
227
File file = null;
228
InputStream in;
229
230
// First try to load the user-specific table, if it exists
231
String userTablePath = System.getProperty("content.types.user.table");
232
if (userTablePath != null && (file = new File(userTablePath)).exists()) {
233
try {
234
in = new FileInputStream(file);
235
} catch (FileNotFoundException e) {
236
System.err.println("Warning: " + file.getPath()
237
+ " mime table not found.");
238
return;
239
}
240
} else {
241
in = MimeTable.class.getResourceAsStream("content-types.properties");
242
if (in == null)
243
throw new InternalError("default mime table not found");
244
}
245
246
try (BufferedInputStream bin = new BufferedInputStream(in)) {
247
entries.load(bin);
248
} catch (IOException e) {
249
System.err.println("Warning: " + e.getMessage());
250
}
251
parse(entries);
252
}
253
254
void parse(Properties entries) {
255
// first, strip out the platform-specific temp file template
256
String tempFileTemplate = (String)entries.get("temp.file.template");
257
if (tempFileTemplate != null) {
258
entries.remove("temp.file.template");
259
MimeTable.tempFileTemplate = tempFileTemplate;
260
}
261
262
// now, parse the mime-type spec's
263
Enumeration<?> types = entries.propertyNames();
264
while (types.hasMoreElements()) {
265
String type = (String)types.nextElement();
266
String attrs = entries.getProperty(type);
267
parse(type, attrs);
268
}
269
}
270
271
//
272
// Table format:
273
//
274
// <entry> ::= <table_tag> | <type_entry>
275
//
276
// <table_tag> ::= <table_format_version> | <temp_file_template>
277
//
278
// <type_entry> ::= <type_subtype_pair> '=' <type_attrs_list>
279
//
280
// <type_subtype_pair> ::= <type> '/' <subtype>
281
//
282
// <type_attrs_list> ::= <attr_value_pair> [ ';' <attr_value_pair> ]*
283
// | [ <attr_value_pair> ]+
284
//
285
// <attr_value_pair> ::= <attr_name> '=' <attr_value>
286
//
287
// <attr_name> ::= 'description' | 'action' | 'application'
288
// | 'file_extensions' | 'icon'
289
//
290
// <attr_value> ::= <legal_char>*
291
//
292
// Embedded ';' in an <attr_value> are quoted with leading '\' .
293
//
294
// Interpretation of <attr_value> depends on the <attr_name> it is
295
// associated with.
296
//
297
298
void parse(String type, String attrs) {
299
MimeEntry newEntry = new MimeEntry(type);
300
301
// REMIND handle embedded ';' and '|' and literal '"'
302
StringTokenizer tokenizer = new StringTokenizer(attrs, ";");
303
while (tokenizer.hasMoreTokens()) {
304
String pair = tokenizer.nextToken();
305
parse(pair, newEntry);
306
}
307
308
add(newEntry);
309
}
310
311
void parse(String pair, MimeEntry entry) {
312
// REMIND add exception handling...
313
String name = null;
314
String value = null;
315
316
boolean gotName = false;
317
StringTokenizer tokenizer = new StringTokenizer(pair, "=");
318
while (tokenizer.hasMoreTokens()) {
319
if (gotName) {
320
value = tokenizer.nextToken().trim();
321
}
322
else {
323
name = tokenizer.nextToken().trim();
324
gotName = true;
325
}
326
}
327
328
fill(entry, name, value);
329
}
330
331
void fill(MimeEntry entry, String name, String value) {
332
if ("description".equalsIgnoreCase(name)) {
333
entry.setDescription(value);
334
}
335
else if ("action".equalsIgnoreCase(name)) {
336
entry.setAction(getActionCode(value));
337
}
338
else if ("application".equalsIgnoreCase(name)) {
339
entry.setCommand(value);
340
}
341
else if ("icon".equalsIgnoreCase(name)) {
342
entry.setImageFileName(value);
343
}
344
else if ("file_extensions".equalsIgnoreCase(name)) {
345
entry.setExtensions(value);
346
}
347
348
// else illegal name exception
349
}
350
351
String[] getExtensions(String list) {
352
StringTokenizer tokenizer = new StringTokenizer(list, ",");
353
int n = tokenizer.countTokens();
354
String[] extensions = new String[n];
355
for (int i = 0; i < n; i++) {
356
extensions[i] = tokenizer.nextToken();
357
}
358
359
return extensions;
360
}
361
362
int getActionCode(String action) {
363
for (int i = 0; i < MimeEntry.actionKeywords.length; i++) {
364
if (action.equalsIgnoreCase(MimeEntry.actionKeywords[i])) {
365
return i;
366
}
367
}
368
369
return MimeEntry.UNKNOWN;
370
}
371
372
public Properties getAsProperties() {
373
Properties properties = new Properties();
374
Enumeration<MimeEntry> e = elements();
375
while (e.hasMoreElements()) {
376
MimeEntry entry = e.nextElement();
377
properties.put(entry.getType(), entry.toProperty());
378
}
379
380
return properties;
381
}
382
383
protected boolean saveAsProperties(File file) {
384
FileOutputStream os = null;
385
try {
386
os = new FileOutputStream(file);
387
Properties properties = getAsProperties();
388
properties.put("temp.file.template", tempFileTemplate);
389
String tag;
390
// Perform the property security check for user.name
391
SecurityManager sm = System.getSecurityManager();
392
if (sm != null) {
393
sm.checkPropertyAccess("user.name");
394
}
395
String user = StaticProperty.userName();
396
if (user != null) {
397
tag = "; customized for " + user;
398
properties.store(os, filePreamble + tag);
399
}
400
else {
401
properties.store(os, filePreamble);
402
}
403
}
404
catch (IOException e) {
405
e.printStackTrace();
406
return false;
407
}
408
finally {
409
if (os != null) {
410
try { os.close(); } catch (IOException e) {}
411
}
412
}
413
414
return true;
415
}
416
/*
417
* Debugging utilities
418
*
419
public void list(PrintStream out) {
420
Enumeration keys = entries.keys();
421
while (keys.hasMoreElements()) {
422
String key = (String)keys.nextElement();
423
MimeEntry entry = (MimeEntry)entries.get(key);
424
out.println(key + ": " + entry);
425
}
426
}
427
428
public static void main(String[] args) {
429
MimeTable testTable = MimeTable.getDefaultTable();
430
431
Enumeration e = testTable.elements();
432
while (e.hasMoreElements()) {
433
MimeEntry entry = (MimeEntry)e.nextElement();
434
System.out.println(entry);
435
}
436
437
testTable.save(File.separator + "tmp" +
438
File.separator + "mime_table.save");
439
}
440
*/
441
}
442
443