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: *

    aoqi@0: *
  1. Programatically added entries to the MailcapCommandMap instance. aoqi@0: *
  2. The file .mailcap in the user's home directory. aoqi@0: *
  3. The file <java.home>/lib/mailcap. aoqi@0: *
  4. The file or resources named META-INF/mailcap. aoqi@0: *
  5. The file or resource named META-INF/mailcap.default aoqi@0: * (usually found only in the activation.jar file). aoqi@0: *
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: * <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: * 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: }