aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: aoqi@0: package javax.activation; aoqi@0: aoqi@0: import java.util.*; aoqi@0: import java.io.*; aoqi@0: import java.net.*; aoqi@0: import com.sun.activation.registries.MailcapFile; aoqi@0: import com.sun.activation.registries.LogSupport; aoqi@0: aoqi@0: /** aoqi@0: * MailcapCommandMap extends the CommandMap aoqi@0: * abstract class. It implements a CommandMap whose configuration aoqi@0: * is based on mailcap files aoqi@0: * (RFC 1524). aoqi@0: * The MailcapCommandMap can be configured both programmatically aoqi@0: * and via configuration files. aoqi@0: *
aoqi@0: * Mailcap file search order:
aoqi@0: * The MailcapCommandMap looks in various places in the user's aoqi@0: * system for mailcap file entries. When requests are made aoqi@0: * to search for commands in the MailcapCommandMap, it searches aoqi@0: * mailcap files in the following order: aoqi@0: *
aoqi@0: *
.mailcap
in the user's home directory.
aoqi@0: * /lib/mailcap
.
aoqi@0: * META-INF/mailcap
.
aoqi@0: * META-INF/mailcap.default
aoqi@0: * (usually found only in the activation.jar
file).
aoqi@0: * aoqi@0: * Mailcap file format:
aoqi@0: * aoqi@0: * Mailcap files must conform to the mailcap aoqi@0: * file specification (RFC 1524, A User Agent Configuration Mechanism aoqi@0: * For Multimedia Mail Format Information). aoqi@0: * The file format consists of entries corresponding to aoqi@0: * particular MIME types. In general, the specification aoqi@0: * specifies applications for clients to use when they aoqi@0: * themselves cannot operate on the specified MIME type. The aoqi@0: * MailcapCommandMap extends this specification by using a parameter mechanism aoqi@0: * in mailcap files that allows JavaBeans(tm) components to be specified as aoqi@0: * corresponding to particular commands for a MIME type.
aoqi@0: *
aoqi@0: * When a mailcap file is
aoqi@0: * parsed, the MailcapCommandMap recognizes certain parameter signatures,
aoqi@0: * specifically those parameter names that begin with x-java-
.
aoqi@0: * The MailcapCommandMap uses this signature to find
aoqi@0: * command entries for inclusion into its registries.
aoqi@0: * Parameter names with the form x-java-<name>
aoqi@0: * are read by the MailcapCommandMap as identifying a command
aoqi@0: * with the name name. When the name is
aoqi@0: * content-handler
the MailcapCommandMap recognizes the class
aoqi@0: * signified by this parameter as a DataContentHandler.
aoqi@0: * All other commands are handled generically regardless of command
aoqi@0: * name. The command implementation is specified by a fully qualified
aoqi@0: * class name of a JavaBean(tm) component. For example; a command for viewing
aoqi@0: * some data can be specified as: x-java-view=com.foo.ViewBean
.
aoqi@0: *
aoqi@0: * When the command name is fallback-entry
, the value of
aoqi@0: * the command may be true
or false
. An
aoqi@0: * entry for a MIME type that includes a parameter of
aoqi@0: * x-java-fallback-entry=true
defines fallback commands
aoqi@0: * for that MIME type that will only be used if no non-fallback entry
aoqi@0: * can be found. For example, an entry of the form text/*; ;
aoqi@0: * x-java-fallback-entry=true; x-java-view=com.sun.TextViewer
aoqi@0: * specifies a view command to be used for any text MIME type. This
aoqi@0: * view command would only be used if a non-fallback view command for
aoqi@0: * the MIME type could not be found.
aoqi@0: * aoqi@0: * MailcapCommandMap aware mailcap files have the aoqi@0: * following general form:
aoqi@0: *
aoqi@0: * # Comments begin with a '#' and continue to the end of the line.
aoqi@0: *
aoqi@0: * <mime type>; ; <parameter list>
aoqi@0: * # Where a parameter list consists of one or more parameters,
aoqi@0: * # where parameters look like: x-java-view=com.sun.TextViewer
aoqi@0: * # and a parameter list looks like:
aoqi@0: * text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit
aoqi@0: *
aoqi@0: * # Note that mailcap entries that do not contain 'x-java' parameters
aoqi@0: * # and comply to RFC 1524 are simply ignored:
aoqi@0: * image/gif; /usr/dt/bin/sdtimage %s
aoqi@0: *
aoqi@0: *
aoqi@0: * aoqi@0: * @author Bart Calder aoqi@0: * @author Bill Shannon aoqi@0: * aoqi@0: * @since 1.6 aoqi@0: */ aoqi@0: aoqi@0: public class MailcapCommandMap extends CommandMap { aoqi@0: /* aoqi@0: * We manage a collection of databases, searched in order. aoqi@0: */ aoqi@0: private MailcapFile[] DB; aoqi@0: private static final int PROG = 0; // programmatically added entries aoqi@0: aoqi@0: /** aoqi@0: * The default Constructor. aoqi@0: */ aoqi@0: public MailcapCommandMap() { aoqi@0: super(); aoqi@0: List dbv = new ArrayList(5); // usually 5 or less databases aoqi@0: MailcapFile mf = null; aoqi@0: dbv.add(null); // place holder for PROG entry aoqi@0: aoqi@0: LogSupport.log("MailcapCommandMap: load HOME"); aoqi@0: try { aoqi@0: String user_home = System.getProperty("user.home"); aoqi@0: aoqi@0: if (user_home != null) { aoqi@0: String path = user_home + File.separator + ".mailcap"; aoqi@0: mf = loadFile(path); aoqi@0: if (mf != null) aoqi@0: dbv.add(mf); aoqi@0: } aoqi@0: } catch (SecurityException ex) {} aoqi@0: aoqi@0: LogSupport.log("MailcapCommandMap: load SYS"); aoqi@0: try { aoqi@0: // check system's home aoqi@0: String system_mailcap = System.getProperty("java.home") + aoqi@0: File.separator + "lib" + File.separator + "mailcap"; aoqi@0: mf = loadFile(system_mailcap); aoqi@0: if (mf != null) aoqi@0: dbv.add(mf); aoqi@0: } catch (SecurityException ex) {} aoqi@0: aoqi@0: LogSupport.log("MailcapCommandMap: load JAR"); aoqi@0: // load from the app's jar file aoqi@0: loadAllResources(dbv, "META-INF/mailcap"); aoqi@0: aoqi@0: LogSupport.log("MailcapCommandMap: load DEF"); aoqi@0: mf = loadResource("/META-INF/mailcap.default"); aoqi@0: aoqi@0: if (mf != null) aoqi@0: dbv.add(mf); aoqi@0: aoqi@0: DB = new MailcapFile[dbv.size()]; aoqi@0: DB = (MailcapFile[])dbv.toArray(DB); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Load from the named resource. aoqi@0: */ aoqi@0: private MailcapFile loadResource(String name) { aoqi@0: InputStream clis = null; aoqi@0: try { aoqi@0: clis = SecuritySupport.getResourceAsStream(this.getClass(), name); aoqi@0: if (clis != null) { aoqi@0: MailcapFile mf = new MailcapFile(clis); aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: successfully loaded " + aoqi@0: "mailcap file: " + name); aoqi@0: return mf; aoqi@0: } else { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: not loading " + aoqi@0: "mailcap file: " + name); aoqi@0: } aoqi@0: } catch (IOException e) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: can't load " + name, e); aoqi@0: } catch (SecurityException sex) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: can't load " + name, sex); aoqi@0: } finally { aoqi@0: try { aoqi@0: if (clis != null) aoqi@0: clis.close(); aoqi@0: } catch (IOException ex) { } // ignore it aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Load all of the named resource. aoqi@0: */ aoqi@0: private void loadAllResources(List v, String name) { aoqi@0: boolean anyLoaded = false; aoqi@0: try { aoqi@0: URL[] urls; aoqi@0: ClassLoader cld = null; aoqi@0: // First try the "application's" class loader. aoqi@0: cld = SecuritySupport.getContextClassLoader(); aoqi@0: if (cld == null) aoqi@0: cld = this.getClass().getClassLoader(); aoqi@0: if (cld != null) aoqi@0: urls = SecuritySupport.getResources(cld, name); aoqi@0: else aoqi@0: urls = SecuritySupport.getSystemResources(name); aoqi@0: if (urls != null) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: getResources"); aoqi@0: for (int i = 0; i < urls.length; i++) { aoqi@0: URL url = urls[i]; aoqi@0: InputStream clis = null; aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: URL " + url); aoqi@0: try { aoqi@0: clis = SecuritySupport.openStream(url); aoqi@0: if (clis != null) { aoqi@0: v.add(new MailcapFile(clis)); aoqi@0: anyLoaded = true; aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: " + aoqi@0: "successfully loaded " + aoqi@0: "mailcap file from URL: " + aoqi@0: url); aoqi@0: } else { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: " + aoqi@0: "not loading mailcap " + aoqi@0: "file from URL: " + url); aoqi@0: } aoqi@0: } catch (IOException ioex) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: can't load " + aoqi@0: url, ioex); aoqi@0: } catch (SecurityException sex) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: can't load " + aoqi@0: url, sex); aoqi@0: } finally { aoqi@0: try { aoqi@0: if (clis != null) aoqi@0: clis.close(); aoqi@0: } catch (IOException cex) { } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } catch (Exception ex) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: can't load " + name, ex); aoqi@0: } aoqi@0: aoqi@0: // if failed to load anything, fall back to old technique, just in case aoqi@0: if (!anyLoaded) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: !anyLoaded"); aoqi@0: MailcapFile mf = loadResource("/" + name); aoqi@0: if (mf != null) aoqi@0: v.add(mf); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Load from the named file. aoqi@0: */ aoqi@0: private MailcapFile loadFile(String name) { aoqi@0: MailcapFile mtf = null; aoqi@0: aoqi@0: try { aoqi@0: mtf = new MailcapFile(name); aoqi@0: } catch (IOException e) { aoqi@0: // e.printStackTrace(); aoqi@0: } aoqi@0: return mtf; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructor that allows the caller to specify the path aoqi@0: * of a mailcap file. aoqi@0: * aoqi@0: * @param fileName The name of the mailcap file to open aoqi@0: * @exception IOException if the file can't be accessed aoqi@0: */ aoqi@0: public MailcapCommandMap(String fileName) throws IOException { aoqi@0: this(); aoqi@0: aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("MailcapCommandMap: load PROG from " + fileName); aoqi@0: if (DB[PROG] == null) { aoqi@0: DB[PROG] = new MailcapFile(fileName); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Constructor that allows the caller to specify an InputStream aoqi@0: * containing a mailcap file. aoqi@0: * aoqi@0: * @param is InputStream of the mailcap file to open aoqi@0: */ aoqi@0: public MailcapCommandMap(InputStream is) { aoqi@0: this(); aoqi@0: aoqi@0: LogSupport.log("MailcapCommandMap: load PROG"); aoqi@0: if (DB[PROG] == null) { aoqi@0: try { aoqi@0: DB[PROG] = new MailcapFile(is); aoqi@0: } catch (IOException ex) { aoqi@0: // XXX - should throw it aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the preferred command list for a MIME Type. The MailcapCommandMap aoqi@0: * searches the mailcap files as described above under aoqi@0: * Mailcap file search order.
aoqi@0: *
aoqi@0: * The result of the search is a proper subset of available
aoqi@0: * commands in all mailcap files known to this instance of
aoqi@0: * MailcapCommandMap. The first entry for a particular command
aoqi@0: * is considered the preferred command.
aoqi@0: *
aoqi@0: * @param mimeType the MIME type
aoqi@0: * @return the CommandInfo objects representing the preferred commands.
aoqi@0: */
aoqi@0: public synchronized CommandInfo[] getPreferredCommands(String mimeType) {
aoqi@0: List cmdList = new ArrayList();
aoqi@0: if (mimeType != null)
aoqi@0: mimeType = mimeType.toLowerCase(Locale.ENGLISH);
aoqi@0:
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapList(mimeType);
aoqi@0: if (cmdMap != null)
aoqi@0: appendPrefCmdsToList(cmdMap, cmdList);
aoqi@0: }
aoqi@0:
aoqi@0: // now add the fallback commands
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
aoqi@0: if (cmdMap != null)
aoqi@0: appendPrefCmdsToList(cmdMap, cmdList);
aoqi@0: }
aoqi@0:
aoqi@0: CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
aoqi@0: cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
aoqi@0:
aoqi@0: return cmdInfos;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Put the commands that are in the hash table, into the list.
aoqi@0: */
aoqi@0: private void appendPrefCmdsToList(Map cmdHash, List cmdList) {
aoqi@0: Iterator verb_enum = cmdHash.keySet().iterator();
aoqi@0:
aoqi@0: while (verb_enum.hasNext()) {
aoqi@0: String verb = (String)verb_enum.next();
aoqi@0: if (!checkForVerb(cmdList, verb)) {
aoqi@0: List cmdList2 = (List)cmdHash.get(verb); // get the list
aoqi@0: String className = (String)cmdList2.get(0);
aoqi@0: cmdList.add(new CommandInfo(verb, className));
aoqi@0: }
aoqi@0: }
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Check the cmdList to see if this command exists, return
aoqi@0: * true if the verb is there.
aoqi@0: */
aoqi@0: private boolean checkForVerb(List cmdList, String verb) {
aoqi@0: Iterator ee = cmdList.iterator();
aoqi@0: while (ee.hasNext()) {
aoqi@0: String enum_verb =
aoqi@0: (String)((CommandInfo)ee.next()).getCommandName();
aoqi@0: if (enum_verb.equals(verb))
aoqi@0: return true;
aoqi@0: }
aoqi@0: return false;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Get all the available commands in all mailcap files known to
aoqi@0: * this instance of MailcapCommandMap for this MIME type.
aoqi@0: *
aoqi@0: * @param mimeType the MIME type
aoqi@0: * @return the CommandInfo objects representing all the commands.
aoqi@0: */
aoqi@0: public synchronized CommandInfo[] getAllCommands(String mimeType) {
aoqi@0: List cmdList = new ArrayList();
aoqi@0: if (mimeType != null)
aoqi@0: mimeType = mimeType.toLowerCase(Locale.ENGLISH);
aoqi@0:
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapList(mimeType);
aoqi@0: if (cmdMap != null)
aoqi@0: appendCmdsToList(cmdMap, cmdList);
aoqi@0: }
aoqi@0:
aoqi@0: // now add the fallback commands
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
aoqi@0: if (cmdMap != null)
aoqi@0: appendCmdsToList(cmdMap, cmdList);
aoqi@0: }
aoqi@0:
aoqi@0: CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
aoqi@0: cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
aoqi@0:
aoqi@0: return cmdInfos;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Put the commands that are in the hash table, into the list.
aoqi@0: */
aoqi@0: private void appendCmdsToList(Map typeHash, List cmdList) {
aoqi@0: Iterator verb_enum = typeHash.keySet().iterator();
aoqi@0:
aoqi@0: while (verb_enum.hasNext()) {
aoqi@0: String verb = (String)verb_enum.next();
aoqi@0: List cmdList2 = (List)typeHash.get(verb);
aoqi@0: Iterator cmd_enum = ((List)cmdList2).iterator();
aoqi@0:
aoqi@0: while (cmd_enum.hasNext()) {
aoqi@0: String cmd = (String)cmd_enum.next();
aoqi@0: cmdList.add(new CommandInfo(verb, cmd));
aoqi@0: // cmdList.add(0, new CommandInfo(verb, cmd));
aoqi@0: }
aoqi@0: }
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Get the command corresponding to cmdName
for the MIME type.
aoqi@0: *
aoqi@0: * @param mimeType the MIME type
aoqi@0: * @param cmdName the command name
aoqi@0: * @return the CommandInfo object corresponding to the command.
aoqi@0: */
aoqi@0: public synchronized CommandInfo getCommand(String mimeType,
aoqi@0: String cmdName) {
aoqi@0: if (mimeType != null)
aoqi@0: mimeType = mimeType.toLowerCase(Locale.ENGLISH);
aoqi@0:
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapList(mimeType);
aoqi@0: if (cmdMap != null) {
aoqi@0: // get the cmd list for the cmd
aoqi@0: List v = (List)cmdMap.get(cmdName);
aoqi@0: if (v != null) {
aoqi@0: String cmdClassName = (String)v.get(0);
aoqi@0:
aoqi@0: if (cmdClassName != null)
aoqi@0: return new CommandInfo(cmdName, cmdClassName);
aoqi@0: }
aoqi@0: }
aoqi@0: }
aoqi@0:
aoqi@0: // now try the fallback list
aoqi@0: for (int i = 0; i < DB.length; i++) {
aoqi@0: if (DB[i] == null)
aoqi@0: continue;
aoqi@0: Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
aoqi@0: if (cmdMap != null) {
aoqi@0: // get the cmd list for the cmd
aoqi@0: List v = (List)cmdMap.get(cmdName);
aoqi@0: if (v != null) {
aoqi@0: String cmdClassName = (String)v.get(0);
aoqi@0:
aoqi@0: if (cmdClassName != null)
aoqi@0: return new CommandInfo(cmdName, cmdClassName);
aoqi@0: }
aoqi@0: }
aoqi@0: }
aoqi@0: return null;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Add entries to the registry. Programmatically
aoqi@0: * added entries are searched before other entries.
aoqi@0: * aoqi@0: * The string that is passed in should be in mailcap aoqi@0: * format. aoqi@0: * aoqi@0: * @param mail_cap a correctly formatted mailcap string aoqi@0: */ aoqi@0: public synchronized void addMailcap(String mail_cap) { aoqi@0: // check to see if one exists aoqi@0: LogSupport.log("MailcapCommandMap: add to PROG"); aoqi@0: if (DB[PROG] == null) aoqi@0: DB[PROG] = new MailcapFile(); aoqi@0: aoqi@0: DB[PROG].appendToMailcap(mail_cap); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Return the DataContentHandler for the specified MIME type. aoqi@0: * aoqi@0: * @param mimeType the MIME type aoqi@0: * @return the DataContentHandler aoqi@0: */ aoqi@0: public synchronized DataContentHandler createDataContentHandler( aoqi@0: String mimeType) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log( aoqi@0: "MailcapCommandMap: createDataContentHandler for " + mimeType); aoqi@0: if (mimeType != null) aoqi@0: mimeType = mimeType.toLowerCase(Locale.ENGLISH); aoqi@0: aoqi@0: for (int i = 0; i < DB.length; i++) { aoqi@0: if (DB[i] == null) aoqi@0: continue; aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log(" search DB #" + i); aoqi@0: Map cmdMap = DB[i].getMailcapList(mimeType); aoqi@0: if (cmdMap != null) { aoqi@0: List v = (List)cmdMap.get("content-handler"); aoqi@0: if (v != null) { aoqi@0: String name = (String)v.get(0); aoqi@0: DataContentHandler dch = getDataContentHandler(name); aoqi@0: if (dch != null) aoqi@0: return dch; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // now try the fallback entries aoqi@0: for (int i = 0; i < DB.length; i++) { aoqi@0: if (DB[i] == null) aoqi@0: continue; aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log(" search fallback DB #" + i); aoqi@0: Map cmdMap = DB[i].getMailcapFallbackList(mimeType); aoqi@0: if (cmdMap != null) { aoqi@0: List v = (List)cmdMap.get("content-handler"); aoqi@0: if (v != null) { aoqi@0: String name = (String)v.get(0); aoqi@0: DataContentHandler dch = getDataContentHandler(name); aoqi@0: if (dch != null) aoqi@0: return dch; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: private DataContentHandler getDataContentHandler(String name) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log(" got content-handler"); aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log(" class " + name); aoqi@0: try { aoqi@0: ClassLoader cld = null; aoqi@0: // First try the "application's" class loader. aoqi@0: cld = SecuritySupport.getContextClassLoader(); aoqi@0: if (cld == null) aoqi@0: cld = this.getClass().getClassLoader(); aoqi@0: Class cl = null; aoqi@0: try { aoqi@0: cl = cld.loadClass(name); aoqi@0: } catch (Exception ex) { aoqi@0: // if anything goes wrong, do it the old way aoqi@0: cl = Class.forName(name); aoqi@0: } aoqi@0: if (cl != null) // XXX - always true? aoqi@0: return (DataContentHandler)cl.newInstance(); aoqi@0: } catch (IllegalAccessException e) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("Can't load DCH " + name, e); aoqi@0: } catch (ClassNotFoundException e) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("Can't load DCH " + name, e); aoqi@0: } catch (InstantiationException e) { aoqi@0: if (LogSupport.isLoggable()) aoqi@0: LogSupport.log("Can't load DCH " + name, e); aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get all the MIME types known to this command map. aoqi@0: * aoqi@0: * @return array of MIME types as strings aoqi@0: * @since JAF 1.1 aoqi@0: */ aoqi@0: public synchronized String[] getMimeTypes() { aoqi@0: List mtList = new ArrayList(); aoqi@0: aoqi@0: for (int i = 0; i < DB.length; i++) { aoqi@0: if (DB[i] == null) aoqi@0: continue; aoqi@0: String[] ts = DB[i].getMimeTypes(); aoqi@0: if (ts != null) { aoqi@0: for (int j = 0; j < ts.length; j++) { aoqi@0: // eliminate duplicates aoqi@0: if (!mtList.contains(ts[j])) aoqi@0: mtList.add(ts[j]); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: String[] mts = new String[mtList.size()]; aoqi@0: mts = (String[])mtList.toArray(mts); aoqi@0: aoqi@0: return mts; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the native commands for the given MIME type. aoqi@0: * Returns an array of strings where each string is aoqi@0: * an entire mailcap file entry. The application aoqi@0: * will need to parse the entry to extract the actual aoqi@0: * command as well as any attributes it needs. See aoqi@0: * RFC 1524 aoqi@0: * for details of the mailcap entry syntax. Only mailcap aoqi@0: * entries that specify a view command for the specified aoqi@0: * MIME type are returned. aoqi@0: * aoqi@0: * @return array of native command entries aoqi@0: * @since JAF 1.1 aoqi@0: */ aoqi@0: public synchronized String[] getNativeCommands(String mimeType) { aoqi@0: List cmdList = new ArrayList(); aoqi@0: if (mimeType != null) aoqi@0: mimeType = mimeType.toLowerCase(Locale.ENGLISH); aoqi@0: aoqi@0: for (int i = 0; i < DB.length; i++) { aoqi@0: if (DB[i] == null) aoqi@0: continue; aoqi@0: String[] cmds = DB[i].getNativeCommands(mimeType); aoqi@0: if (cmds != null) { aoqi@0: for (int j = 0; j < cmds.length; j++) { aoqi@0: // eliminate duplicates aoqi@0: if (!cmdList.contains(cmds[j])) aoqi@0: cmdList.add(cmds[j]); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: String[] cmds = new String[cmdList.size()]; aoqi@0: cmds = (String[])cmdList.toArray(cmds); aoqi@0: aoqi@0: return cmds; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * for debugging... aoqi@0: * aoqi@0: public static void main(String[] argv) throws Exception { aoqi@0: MailcapCommandMap map = new MailcapCommandMap(); aoqi@0: CommandInfo[] cmdInfo; aoqi@0: aoqi@0: cmdInfo = map.getPreferredCommands(argv[0]); aoqi@0: System.out.println("Preferred Commands:"); aoqi@0: for (int i = 0; i < cmdInfo.length; i++) aoqi@0: System.out.println("Command " + cmdInfo[i].getCommandName() + " [" + aoqi@0: cmdInfo[i].getCommandClass() + "]"); aoqi@0: cmdInfo = map.getAllCommands(argv[0]); aoqi@0: System.out.println(); aoqi@0: System.out.println("All Commands:"); aoqi@0: for (int i = 0; i < cmdInfo.length; i++) aoqi@0: System.out.println("Command " + cmdInfo[i].getCommandName() + " [" + aoqi@0: cmdInfo[i].getCommandClass() + "]"); aoqi@0: DataContentHandler dch = map.createDataContentHandler(argv[0]); aoqi@0: if (dch != null) aoqi@0: System.out.println("DataContentHandler " + aoqi@0: dch.getClass().toString()); aoqi@0: System.exit(0); aoqi@0: } aoqi@0: */ aoqi@0: }