Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java
38877 views
1
/*
2
* Copyright (c) 1997, 2013, 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
27
package javax.activation;
28
29
import java.util.*;
30
import java.io.*;
31
import java.net.*;
32
import com.sun.activation.registries.MailcapFile;
33
import com.sun.activation.registries.LogSupport;
34
35
/**
36
* MailcapCommandMap extends the CommandMap
37
* abstract class. It implements a CommandMap whose configuration
38
* is based on mailcap files
39
* (<A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>).
40
* The MailcapCommandMap can be configured both programmatically
41
* and via configuration files.
42
* <p>
43
* <b>Mailcap file search order:</b><p>
44
* The MailcapCommandMap looks in various places in the user's
45
* system for mailcap file entries. When requests are made
46
* to search for commands in the MailcapCommandMap, it searches
47
* mailcap files in the following order:
48
* <p>
49
* <ol>
50
* <li> Programatically added entries to the MailcapCommandMap instance.
51
* <li> The file <code>.mailcap</code> in the user's home directory.
52
* <li> The file &lt;<i>java.home</i>&gt;<code>/lib/mailcap</code>.
53
* <li> The file or resources named <code>META-INF/mailcap</code>.
54
* <li> The file or resource named <code>META-INF/mailcap.default</code>
55
* (usually found only in the <code>activation.jar</code> file).
56
* </ol>
57
* <p>
58
* <b>Mailcap file format:</b><p>
59
*
60
* Mailcap files must conform to the mailcap
61
* file specification (RFC 1524, <i>A User Agent Configuration Mechanism
62
* For Multimedia Mail Format Information</i>).
63
* The file format consists of entries corresponding to
64
* particular MIME types. In general, the specification
65
* specifies <i>applications</i> for clients to use when they
66
* themselves cannot operate on the specified MIME type. The
67
* MailcapCommandMap extends this specification by using a parameter mechanism
68
* in mailcap files that allows JavaBeans(tm) components to be specified as
69
* corresponding to particular commands for a MIME type.<p>
70
*
71
* When a mailcap file is
72
* parsed, the MailcapCommandMap recognizes certain parameter signatures,
73
* specifically those parameter names that begin with <code>x-java-</code>.
74
* The MailcapCommandMap uses this signature to find
75
* command entries for inclusion into its registries.
76
* Parameter names with the form <code>x-java-&lt;name></code>
77
* are read by the MailcapCommandMap as identifying a command
78
* with the name <i>name</i>. When the <i>name</i> is <code>
79
* content-handler</code> the MailcapCommandMap recognizes the class
80
* signified by this parameter as a <i>DataContentHandler</i>.
81
* All other commands are handled generically regardless of command
82
* name. The command implementation is specified by a fully qualified
83
* class name of a JavaBean(tm) component. For example; a command for viewing
84
* some data can be specified as: <code>x-java-view=com.foo.ViewBean</code>.<p>
85
*
86
* When the command name is <code>fallback-entry</code>, the value of
87
* the command may be <code>true</code> or <code>false</code>. An
88
* entry for a MIME type that includes a parameter of
89
* <code>x-java-fallback-entry=true</code> defines fallback commands
90
* for that MIME type that will only be used if no non-fallback entry
91
* can be found. For example, an entry of the form <code>text/*; ;
92
* x-java-fallback-entry=true; x-java-view=com.sun.TextViewer</code>
93
* specifies a view command to be used for any text MIME type. This
94
* view command would only be used if a non-fallback view command for
95
* the MIME type could not be found.<p>
96
*
97
* MailcapCommandMap aware mailcap files have the
98
* following general form:<p>
99
* <code>
100
* # Comments begin with a '#' and continue to the end of the line.<br>
101
* &lt;mime type>; ; &lt;parameter list><br>
102
* # Where a parameter list consists of one or more parameters,<br>
103
* # where parameters look like: x-java-view=com.sun.TextViewer<br>
104
* # and a parameter list looks like: <br>
105
* text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit
106
* <br>
107
* # Note that mailcap entries that do not contain 'x-java' parameters<br>
108
* # and comply to RFC 1524 are simply ignored:<br>
109
* image/gif; /usr/dt/bin/sdtimage %s<br>
110
*
111
* </code>
112
* <p>
113
*
114
* @author Bart Calder
115
* @author Bill Shannon
116
*
117
* @since 1.6
118
*/
119
120
public class MailcapCommandMap extends CommandMap {
121
/*
122
* We manage a collection of databases, searched in order.
123
*/
124
private MailcapFile[] DB;
125
private static final int PROG = 0; // programmatically added entries
126
127
/**
128
* The default Constructor.
129
*/
130
public MailcapCommandMap() {
131
super();
132
List dbv = new ArrayList(5); // usually 5 or less databases
133
MailcapFile mf = null;
134
dbv.add(null); // place holder for PROG entry
135
136
LogSupport.log("MailcapCommandMap: load HOME");
137
try {
138
String user_home = System.getProperty("user.home");
139
140
if (user_home != null) {
141
String path = user_home + File.separator + ".mailcap";
142
mf = loadFile(path);
143
if (mf != null)
144
dbv.add(mf);
145
}
146
} catch (SecurityException ex) {}
147
148
LogSupport.log("MailcapCommandMap: load SYS");
149
try {
150
// check system's home
151
String system_mailcap = System.getProperty("java.home") +
152
File.separator + "lib" + File.separator + "mailcap";
153
mf = loadFile(system_mailcap);
154
if (mf != null)
155
dbv.add(mf);
156
} catch (SecurityException ex) {}
157
158
LogSupport.log("MailcapCommandMap: load JAR");
159
// load from the app's jar file
160
loadAllResources(dbv, "META-INF/mailcap");
161
162
LogSupport.log("MailcapCommandMap: load DEF");
163
mf = loadResource("/META-INF/mailcap.default");
164
165
if (mf != null)
166
dbv.add(mf);
167
168
DB = new MailcapFile[dbv.size()];
169
DB = (MailcapFile[])dbv.toArray(DB);
170
}
171
172
/**
173
* Load from the named resource.
174
*/
175
private MailcapFile loadResource(String name) {
176
InputStream clis = null;
177
try {
178
clis = SecuritySupport.getResourceAsStream(this.getClass(), name);
179
if (clis != null) {
180
MailcapFile mf = new MailcapFile(clis);
181
if (LogSupport.isLoggable())
182
LogSupport.log("MailcapCommandMap: successfully loaded " +
183
"mailcap file: " + name);
184
return mf;
185
} else {
186
if (LogSupport.isLoggable())
187
LogSupport.log("MailcapCommandMap: not loading " +
188
"mailcap file: " + name);
189
}
190
} catch (IOException e) {
191
if (LogSupport.isLoggable())
192
LogSupport.log("MailcapCommandMap: can't load " + name, e);
193
} catch (SecurityException sex) {
194
if (LogSupport.isLoggable())
195
LogSupport.log("MailcapCommandMap: can't load " + name, sex);
196
} finally {
197
try {
198
if (clis != null)
199
clis.close();
200
} catch (IOException ex) { } // ignore it
201
}
202
return null;
203
}
204
205
/**
206
* Load all of the named resource.
207
*/
208
private void loadAllResources(List v, String name) {
209
boolean anyLoaded = false;
210
try {
211
URL[] urls;
212
ClassLoader cld = null;
213
// First try the "application's" class loader.
214
cld = SecuritySupport.getContextClassLoader();
215
if (cld == null)
216
cld = this.getClass().getClassLoader();
217
if (cld != null)
218
urls = SecuritySupport.getResources(cld, name);
219
else
220
urls = SecuritySupport.getSystemResources(name);
221
if (urls != null) {
222
if (LogSupport.isLoggable())
223
LogSupport.log("MailcapCommandMap: getResources");
224
for (int i = 0; i < urls.length; i++) {
225
URL url = urls[i];
226
InputStream clis = null;
227
if (LogSupport.isLoggable())
228
LogSupport.log("MailcapCommandMap: URL " + url);
229
try {
230
clis = SecuritySupport.openStream(url);
231
if (clis != null) {
232
v.add(new MailcapFile(clis));
233
anyLoaded = true;
234
if (LogSupport.isLoggable())
235
LogSupport.log("MailcapCommandMap: " +
236
"successfully loaded " +
237
"mailcap file from URL: " +
238
url);
239
} else {
240
if (LogSupport.isLoggable())
241
LogSupport.log("MailcapCommandMap: " +
242
"not loading mailcap " +
243
"file from URL: " + url);
244
}
245
} catch (IOException ioex) {
246
if (LogSupport.isLoggable())
247
LogSupport.log("MailcapCommandMap: can't load " +
248
url, ioex);
249
} catch (SecurityException sex) {
250
if (LogSupport.isLoggable())
251
LogSupport.log("MailcapCommandMap: can't load " +
252
url, sex);
253
} finally {
254
try {
255
if (clis != null)
256
clis.close();
257
} catch (IOException cex) { }
258
}
259
}
260
}
261
} catch (Exception ex) {
262
if (LogSupport.isLoggable())
263
LogSupport.log("MailcapCommandMap: can't load " + name, ex);
264
}
265
266
// if failed to load anything, fall back to old technique, just in case
267
if (!anyLoaded) {
268
if (LogSupport.isLoggable())
269
LogSupport.log("MailcapCommandMap: !anyLoaded");
270
MailcapFile mf = loadResource("/" + name);
271
if (mf != null)
272
v.add(mf);
273
}
274
}
275
276
/**
277
* Load from the named file.
278
*/
279
private MailcapFile loadFile(String name) {
280
MailcapFile mtf = null;
281
282
try {
283
mtf = new MailcapFile(name);
284
} catch (IOException e) {
285
// e.printStackTrace();
286
}
287
return mtf;
288
}
289
290
/**
291
* Constructor that allows the caller to specify the path
292
* of a <i>mailcap</i> file.
293
*
294
* @param fileName The name of the <i>mailcap</i> file to open
295
* @exception IOException if the file can't be accessed
296
*/
297
public MailcapCommandMap(String fileName) throws IOException {
298
this();
299
300
if (LogSupport.isLoggable())
301
LogSupport.log("MailcapCommandMap: load PROG from " + fileName);
302
if (DB[PROG] == null) {
303
DB[PROG] = new MailcapFile(fileName);
304
}
305
}
306
307
308
/**
309
* Constructor that allows the caller to specify an <i>InputStream</i>
310
* containing a mailcap file.
311
*
312
* @param is InputStream of the <i>mailcap</i> file to open
313
*/
314
public MailcapCommandMap(InputStream is) {
315
this();
316
317
LogSupport.log("MailcapCommandMap: load PROG");
318
if (DB[PROG] == null) {
319
try {
320
DB[PROG] = new MailcapFile(is);
321
} catch (IOException ex) {
322
// XXX - should throw it
323
}
324
}
325
}
326
327
/**
328
* Get the preferred command list for a MIME Type. The MailcapCommandMap
329
* searches the mailcap files as described above under
330
* <i>Mailcap file search order</i>.<p>
331
*
332
* The result of the search is a proper subset of available
333
* commands in all mailcap files known to this instance of
334
* MailcapCommandMap. The first entry for a particular command
335
* is considered the preferred command.
336
*
337
* @param mimeType the MIME type
338
* @return the CommandInfo objects representing the preferred commands.
339
*/
340
public synchronized CommandInfo[] getPreferredCommands(String mimeType) {
341
List cmdList = new ArrayList();
342
if (mimeType != null)
343
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
344
345
for (int i = 0; i < DB.length; i++) {
346
if (DB[i] == null)
347
continue;
348
Map cmdMap = DB[i].getMailcapList(mimeType);
349
if (cmdMap != null)
350
appendPrefCmdsToList(cmdMap, cmdList);
351
}
352
353
// now add the fallback commands
354
for (int i = 0; i < DB.length; i++) {
355
if (DB[i] == null)
356
continue;
357
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
358
if (cmdMap != null)
359
appendPrefCmdsToList(cmdMap, cmdList);
360
}
361
362
CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
363
cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
364
365
return cmdInfos;
366
}
367
368
/**
369
* Put the commands that are in the hash table, into the list.
370
*/
371
private void appendPrefCmdsToList(Map cmdHash, List cmdList) {
372
Iterator verb_enum = cmdHash.keySet().iterator();
373
374
while (verb_enum.hasNext()) {
375
String verb = (String)verb_enum.next();
376
if (!checkForVerb(cmdList, verb)) {
377
List cmdList2 = (List)cmdHash.get(verb); // get the list
378
String className = (String)cmdList2.get(0);
379
cmdList.add(new CommandInfo(verb, className));
380
}
381
}
382
}
383
384
/**
385
* Check the cmdList to see if this command exists, return
386
* true if the verb is there.
387
*/
388
private boolean checkForVerb(List cmdList, String verb) {
389
Iterator ee = cmdList.iterator();
390
while (ee.hasNext()) {
391
String enum_verb =
392
(String)((CommandInfo)ee.next()).getCommandName();
393
if (enum_verb.equals(verb))
394
return true;
395
}
396
return false;
397
}
398
399
/**
400
* Get all the available commands in all mailcap files known to
401
* this instance of MailcapCommandMap for this MIME type.
402
*
403
* @param mimeType the MIME type
404
* @return the CommandInfo objects representing all the commands.
405
*/
406
public synchronized CommandInfo[] getAllCommands(String mimeType) {
407
List cmdList = new ArrayList();
408
if (mimeType != null)
409
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
410
411
for (int i = 0; i < DB.length; i++) {
412
if (DB[i] == null)
413
continue;
414
Map cmdMap = DB[i].getMailcapList(mimeType);
415
if (cmdMap != null)
416
appendCmdsToList(cmdMap, cmdList);
417
}
418
419
// now add the fallback commands
420
for (int i = 0; i < DB.length; i++) {
421
if (DB[i] == null)
422
continue;
423
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
424
if (cmdMap != null)
425
appendCmdsToList(cmdMap, cmdList);
426
}
427
428
CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
429
cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
430
431
return cmdInfos;
432
}
433
434
/**
435
* Put the commands that are in the hash table, into the list.
436
*/
437
private void appendCmdsToList(Map typeHash, List cmdList) {
438
Iterator verb_enum = typeHash.keySet().iterator();
439
440
while (verb_enum.hasNext()) {
441
String verb = (String)verb_enum.next();
442
List cmdList2 = (List)typeHash.get(verb);
443
Iterator cmd_enum = ((List)cmdList2).iterator();
444
445
while (cmd_enum.hasNext()) {
446
String cmd = (String)cmd_enum.next();
447
cmdList.add(new CommandInfo(verb, cmd));
448
// cmdList.add(0, new CommandInfo(verb, cmd));
449
}
450
}
451
}
452
453
/**
454
* Get the command corresponding to <code>cmdName</code> for the MIME type.
455
*
456
* @param mimeType the MIME type
457
* @param cmdName the command name
458
* @return the CommandInfo object corresponding to the command.
459
*/
460
public synchronized CommandInfo getCommand(String mimeType,
461
String cmdName) {
462
if (mimeType != null)
463
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
464
465
for (int i = 0; i < DB.length; i++) {
466
if (DB[i] == null)
467
continue;
468
Map cmdMap = DB[i].getMailcapList(mimeType);
469
if (cmdMap != null) {
470
// get the cmd list for the cmd
471
List v = (List)cmdMap.get(cmdName);
472
if (v != null) {
473
String cmdClassName = (String)v.get(0);
474
475
if (cmdClassName != null)
476
return new CommandInfo(cmdName, cmdClassName);
477
}
478
}
479
}
480
481
// now try the fallback list
482
for (int i = 0; i < DB.length; i++) {
483
if (DB[i] == null)
484
continue;
485
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
486
if (cmdMap != null) {
487
// get the cmd list for the cmd
488
List v = (List)cmdMap.get(cmdName);
489
if (v != null) {
490
String cmdClassName = (String)v.get(0);
491
492
if (cmdClassName != null)
493
return new CommandInfo(cmdName, cmdClassName);
494
}
495
}
496
}
497
return null;
498
}
499
500
/**
501
* Add entries to the registry. Programmatically
502
* added entries are searched before other entries.<p>
503
*
504
* The string that is passed in should be in mailcap
505
* format.
506
*
507
* @param mail_cap a correctly formatted mailcap string
508
*/
509
public synchronized void addMailcap(String mail_cap) {
510
// check to see if one exists
511
LogSupport.log("MailcapCommandMap: add to PROG");
512
if (DB[PROG] == null)
513
DB[PROG] = new MailcapFile();
514
515
DB[PROG].appendToMailcap(mail_cap);
516
}
517
518
/**
519
* Return the DataContentHandler for the specified MIME type.
520
*
521
* @param mimeType the MIME type
522
* @return the DataContentHandler
523
*/
524
public synchronized DataContentHandler createDataContentHandler(
525
String mimeType) {
526
if (LogSupport.isLoggable())
527
LogSupport.log(
528
"MailcapCommandMap: createDataContentHandler for " + mimeType);
529
if (mimeType != null)
530
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
531
532
for (int i = 0; i < DB.length; i++) {
533
if (DB[i] == null)
534
continue;
535
if (LogSupport.isLoggable())
536
LogSupport.log(" search DB #" + i);
537
Map cmdMap = DB[i].getMailcapList(mimeType);
538
if (cmdMap != null) {
539
List v = (List)cmdMap.get("content-handler");
540
if (v != null) {
541
String name = (String)v.get(0);
542
DataContentHandler dch = getDataContentHandler(name);
543
if (dch != null)
544
return dch;
545
}
546
}
547
}
548
549
// now try the fallback entries
550
for (int i = 0; i < DB.length; i++) {
551
if (DB[i] == null)
552
continue;
553
if (LogSupport.isLoggable())
554
LogSupport.log(" search fallback DB #" + i);
555
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
556
if (cmdMap != null) {
557
List v = (List)cmdMap.get("content-handler");
558
if (v != null) {
559
String name = (String)v.get(0);
560
DataContentHandler dch = getDataContentHandler(name);
561
if (dch != null)
562
return dch;
563
}
564
}
565
}
566
return null;
567
}
568
569
private DataContentHandler getDataContentHandler(String name) {
570
if (LogSupport.isLoggable())
571
LogSupport.log(" got content-handler");
572
if (LogSupport.isLoggable())
573
LogSupport.log(" class " + name);
574
try {
575
ClassLoader cld = null;
576
// First try the "application's" class loader.
577
cld = SecuritySupport.getContextClassLoader();
578
if (cld == null)
579
cld = this.getClass().getClassLoader();
580
Class cl = null;
581
try {
582
cl = cld.loadClass(name);
583
} catch (Exception ex) {
584
// if anything goes wrong, do it the old way
585
cl = Class.forName(name);
586
}
587
if (cl != null) // XXX - always true?
588
return (DataContentHandler)cl.newInstance();
589
} catch (IllegalAccessException e) {
590
if (LogSupport.isLoggable())
591
LogSupport.log("Can't load DCH " + name, e);
592
} catch (ClassNotFoundException e) {
593
if (LogSupport.isLoggable())
594
LogSupport.log("Can't load DCH " + name, e);
595
} catch (InstantiationException e) {
596
if (LogSupport.isLoggable())
597
LogSupport.log("Can't load DCH " + name, e);
598
}
599
return null;
600
}
601
602
/**
603
* Get all the MIME types known to this command map.
604
*
605
* @return array of MIME types as strings
606
* @since JAF 1.1
607
*/
608
public synchronized String[] getMimeTypes() {
609
List mtList = new ArrayList();
610
611
for (int i = 0; i < DB.length; i++) {
612
if (DB[i] == null)
613
continue;
614
String[] ts = DB[i].getMimeTypes();
615
if (ts != null) {
616
for (int j = 0; j < ts.length; j++) {
617
// eliminate duplicates
618
if (!mtList.contains(ts[j]))
619
mtList.add(ts[j]);
620
}
621
}
622
}
623
624
String[] mts = new String[mtList.size()];
625
mts = (String[])mtList.toArray(mts);
626
627
return mts;
628
}
629
630
/**
631
* Get the native commands for the given MIME type.
632
* Returns an array of strings where each string is
633
* an entire mailcap file entry. The application
634
* will need to parse the entry to extract the actual
635
* command as well as any attributes it needs. See
636
* <A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>
637
* for details of the mailcap entry syntax. Only mailcap
638
* entries that specify a view command for the specified
639
* MIME type are returned.
640
*
641
* @return array of native command entries
642
* @since JAF 1.1
643
*/
644
public synchronized String[] getNativeCommands(String mimeType) {
645
List cmdList = new ArrayList();
646
if (mimeType != null)
647
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
648
649
for (int i = 0; i < DB.length; i++) {
650
if (DB[i] == null)
651
continue;
652
String[] cmds = DB[i].getNativeCommands(mimeType);
653
if (cmds != null) {
654
for (int j = 0; j < cmds.length; j++) {
655
// eliminate duplicates
656
if (!cmdList.contains(cmds[j]))
657
cmdList.add(cmds[j]);
658
}
659
}
660
}
661
662
String[] cmds = new String[cmdList.size()];
663
cmds = (String[])cmdList.toArray(cmds);
664
665
return cmds;
666
}
667
668
/**
669
* for debugging...
670
*
671
public static void main(String[] argv) throws Exception {
672
MailcapCommandMap map = new MailcapCommandMap();
673
CommandInfo[] cmdInfo;
674
675
cmdInfo = map.getPreferredCommands(argv[0]);
676
System.out.println("Preferred Commands:");
677
for (int i = 0; i < cmdInfo.length; i++)
678
System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
679
cmdInfo[i].getCommandClass() + "]");
680
cmdInfo = map.getAllCommands(argv[0]);
681
System.out.println();
682
System.out.println("All Commands:");
683
for (int i = 0; i < cmdInfo.length; i++)
684
System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
685
cmdInfo[i].getCommandClass() + "]");
686
DataContentHandler dch = map.createDataContentHandler(argv[0]);
687
if (dch != null)
688
System.out.println("DataContentHandler " +
689
dch.getClass().toString());
690
System.exit(0);
691
}
692
*/
693
}
694
695