| /* |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
| * |
| * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved. |
| * |
| * The contents of this file are subject to the terms of either the GNU |
| * General Public License Version 2 only ("GPL") or the Common Development |
| * and Distribution License("CDDL") (collectively, the "License"). You |
| * may not use this file except in compliance with the License. You can |
| * obtain a copy of the License at |
| * https://oss.oracle.com/licenses/CDDL+GPL-1.1 |
| * or LICENSE.txt. See the License for the specific |
| * language governing permissions and limitations under the License. |
| * |
| * When distributing the software, include this License Header Notice in each |
| * file and include the License file at LICENSE.txt. |
| * |
| * GPL Classpath Exception: |
| * Oracle designates this particular file as subject to the "Classpath" |
| * exception as provided by Oracle in the GPL Version 2 section of the License |
| * file that accompanied this code. |
| * |
| * Modifications: |
| * If applicable, add the following below the License Header, with the fields |
| * enclosed by brackets [] replaced by your own identifying information: |
| * "Portions Copyright [year] [name of copyright owner]" |
| * |
| * Contributor(s): |
| * If you wish your version of this file to be governed by only the CDDL or |
| * only the GPL Version 2, indicate your decision by adding "[Contributor] |
| * elects to include this software in this distribution under the [CDDL or GPL |
| * Version 2] license." If you don't indicate a single choice of license, a |
| * recipient has the option to distribute your version of this file under |
| * either the CDDL, the GPL Version 2 or to extend the choice of license to |
| * its licensees as provided above. However, if you add GPL Version 2 code |
| * and therefore, elected the GPL Version 2 license, then the option applies |
| * only if the new code is made subject to such option by the copyright |
| * holder. |
| */ |
| |
| package javax.activation; |
| |
| import java.util.*; |
| import java.io.*; |
| import java.net.*; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import com.sun.activation.registries.MailcapFile; |
| import com.sun.activation.registries.LogSupport; |
| |
| /** |
| * MailcapCommandMap extends the CommandMap |
| * abstract class. It implements a CommandMap whose configuration |
| * is based on mailcap files |
| * (<A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>). |
| * The MailcapCommandMap can be configured both programmatically |
| * and via configuration files. |
| * <p> |
| * <b>Mailcap file search order:</b><p> |
| * The MailcapCommandMap looks in various places in the user's |
| * system for mailcap file entries. When requests are made |
| * to search for commands in the MailcapCommandMap, it searches |
| * mailcap files in the following order: |
| * <ol> |
| * <li> Programatically added entries to the MailcapCommandMap instance. |
| * <li> The file <code>.mailcap</code> in the user's home directory. |
| * <li> The file <code>mailcap</code> in the Java runtime. |
| * <li> The file or resources named <code>META-INF/mailcap</code>. |
| * <li> The file or resource named <code>META-INF/mailcap.default</code> |
| * (usually found only in the <code>activation.jar</code> file). |
| * </ol> |
| * <p> |
| * (The current implementation looks for the <code>mailcap</code> file |
| * in the Java runtime in the directory <code><i>java.home</i>/conf</code> |
| * if it exists, and otherwise in the directory |
| * <code><i>java.home</i>/lib</code>, where <i>java.home</i> is the value |
| * of the "java.home" System property. Note that the "conf" directory was |
| * introduced in JDK 9.) |
| * <p> |
| * <b>Mailcap file format:</b><p> |
| * |
| * Mailcap files must conform to the mailcap |
| * file specification (RFC 1524, <i>A User Agent Configuration Mechanism |
| * For Multimedia Mail Format Information</i>). |
| * The file format consists of entries corresponding to |
| * particular MIME types. In general, the specification |
| * specifies <i>applications</i> for clients to use when they |
| * themselves cannot operate on the specified MIME type. The |
| * MailcapCommandMap extends this specification by using a parameter mechanism |
| * in mailcap files that allows JavaBeans(tm) components to be specified as |
| * corresponding to particular commands for a MIME type.<p> |
| * |
| * When a mailcap file is |
| * parsed, the MailcapCommandMap recognizes certain parameter signatures, |
| * specifically those parameter names that begin with <code>x-java-</code>. |
| * The MailcapCommandMap uses this signature to find |
| * command entries for inclusion into its registries. |
| * Parameter names with the form <code>x-java-<name></code> |
| * are read by the MailcapCommandMap as identifying a command |
| * with the name <i>name</i>. When the <i>name</i> is <code> |
| * content-handler</code> the MailcapCommandMap recognizes the class |
| * signified by this parameter as a <i>DataContentHandler</i>. |
| * All other commands are handled generically regardless of command |
| * name. The command implementation is specified by a fully qualified |
| * class name of a JavaBean(tm) component. For example; a command for viewing |
| * some data can be specified as: <code>x-java-view=com.foo.ViewBean</code>.<p> |
| * |
| * When the command name is <code>fallback-entry</code>, the value of |
| * the command may be <code>true</code> or <code>false</code>. An |
| * entry for a MIME type that includes a parameter of |
| * <code>x-java-fallback-entry=true</code> defines fallback commands |
| * for that MIME type that will only be used if no non-fallback entry |
| * can be found. For example, an entry of the form <code>text/*; ; |
| * x-java-fallback-entry=true; x-java-view=com.sun.TextViewer</code> |
| * specifies a view command to be used for any text MIME type. This |
| * view command would only be used if a non-fallback view command for |
| * the MIME type could not be found.<p> |
| * |
| * MailcapCommandMap aware mailcap files have the |
| * following general form:<p> |
| * <code> |
| * # Comments begin with a '#' and continue to the end of the line.<br> |
| * <mime type>; ; <parameter list><br> |
| * # Where a parameter list consists of one or more parameters,<br> |
| * # where parameters look like: x-java-view=com.sun.TextViewer<br> |
| * # and a parameter list looks like: <br> |
| * text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit |
| * <br> |
| * # Note that mailcap entries that do not contain 'x-java' parameters<br> |
| * # and comply to RFC 1524 are simply ignored:<br> |
| * image/gif; /usr/dt/bin/sdtimage %s<br> |
| * |
| * </code> |
| * <p> |
| * |
| * @author Bart Calder |
| * @author Bill Shannon |
| */ |
| |
| public class MailcapCommandMap extends CommandMap { |
| /* |
| * We manage a collection of databases, searched in order. |
| */ |
| private MailcapFile[] DB; |
| private static final int PROG = 0; // programmatically added entries |
| |
| private static final String confDir; |
| |
| static { |
| String dir = null; |
| try { |
| dir = (String)AccessController.doPrivileged( |
| new PrivilegedAction() { |
| public Object run() { |
| String home = System.getProperty("java.home"); |
| String newdir = home + File.separator + "conf"; |
| File conf = new File(newdir); |
| if (conf.exists()) |
| return newdir + File.separator; |
| else |
| return home + File.separator + "lib" + File.separator; |
| } |
| }); |
| } catch (Exception ex) { |
| // ignore any exceptions |
| } |
| confDir = dir; |
| } |
| |
| /** |
| * The default Constructor. |
| */ |
| public MailcapCommandMap() { |
| super(); |
| List dbv = new ArrayList(5); // usually 5 or less databases |
| MailcapFile mf = null; |
| dbv.add(null); // place holder for PROG entry |
| |
| LogSupport.log("MailcapCommandMap: load HOME"); |
| try { |
| String user_home = System.getProperty("user.home"); |
| |
| if (user_home != null) { |
| String path = user_home + File.separator + ".mailcap"; |
| mf = loadFile(path); |
| if (mf != null) |
| dbv.add(mf); |
| } |
| } catch (SecurityException ex) {} |
| |
| LogSupport.log("MailcapCommandMap: load SYS"); |
| try { |
| // check system's home |
| if (confDir != null) { |
| mf = loadFile(confDir + "mailcap"); |
| if (mf != null) |
| dbv.add(mf); |
| } |
| } catch (SecurityException ex) {} |
| |
| LogSupport.log("MailcapCommandMap: load JAR"); |
| // load from the app's jar file |
| loadAllResources(dbv, "META-INF/mailcap"); |
| |
| LogSupport.log("MailcapCommandMap: load DEF"); |
| mf = loadResource("/META-INF/mailcap.default"); |
| |
| if (mf != null) |
| dbv.add(mf); |
| |
| DB = new MailcapFile[dbv.size()]; |
| DB = (MailcapFile[])dbv.toArray(DB); |
| } |
| |
| /** |
| * Load from the named resource. |
| */ |
| private MailcapFile loadResource(String name) { |
| InputStream clis = null; |
| try { |
| clis = SecuritySupport.getResourceAsStream(this.getClass(), name); |
| if (clis != null) { |
| MailcapFile mf = new MailcapFile(clis); |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: successfully loaded " + |
| "mailcap file: " + name); |
| return mf; |
| } else { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: not loading " + |
| "mailcap file: " + name); |
| } |
| } catch (IOException e) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: can't load " + name, e); |
| } catch (SecurityException sex) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: can't load " + name, sex); |
| } finally { |
| try { |
| if (clis != null) |
| clis.close(); |
| } catch (IOException ex) { } // ignore it |
| } |
| return null; |
| } |
| |
| /** |
| * Load all of the named resource. |
| */ |
| private void loadAllResources(List v, String name) { |
| boolean anyLoaded = false; |
| try { |
| URL[] urls; |
| ClassLoader cld = null; |
| // First try the "application's" class loader. |
| cld = SecuritySupport.getContextClassLoader(); |
| if (cld == null) |
| cld = this.getClass().getClassLoader(); |
| if (cld != null) |
| urls = SecuritySupport.getResources(cld, name); |
| else |
| urls = SecuritySupport.getSystemResources(name); |
| if (urls != null) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: getResources"); |
| for (int i = 0; i < urls.length; i++) { |
| URL url = urls[i]; |
| InputStream clis = null; |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: URL " + url); |
| try { |
| clis = SecuritySupport.openStream(url); |
| if (clis != null) { |
| v.add(new MailcapFile(clis)); |
| anyLoaded = true; |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: " + |
| "successfully loaded " + |
| "mailcap file from URL: " + |
| url); |
| } else { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: " + |
| "not loading mailcap " + |
| "file from URL: " + url); |
| } |
| } catch (IOException ioex) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: can't load " + |
| url, ioex); |
| } catch (SecurityException sex) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: can't load " + |
| url, sex); |
| } finally { |
| try { |
| if (clis != null) |
| clis.close(); |
| } catch (IOException cex) { } |
| } |
| } |
| } |
| } catch (Exception ex) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: can't load " + name, ex); |
| } |
| |
| // if failed to load anything, fall back to old technique, just in case |
| if (!anyLoaded) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: !anyLoaded"); |
| MailcapFile mf = loadResource("/" + name); |
| if (mf != null) |
| v.add(mf); |
| } |
| } |
| |
| /** |
| * Load from the named file. |
| */ |
| private MailcapFile loadFile(String name) { |
| MailcapFile mtf = null; |
| |
| try { |
| mtf = new MailcapFile(name); |
| } catch (IOException e) { |
| // e.printStackTrace(); |
| } |
| return mtf; |
| } |
| |
| /** |
| * Constructor that allows the caller to specify the path |
| * of a <i>mailcap</i> file. |
| * |
| * @param fileName The name of the <i>mailcap</i> file to open |
| * @exception IOException if the file can't be accessed |
| */ |
| public MailcapCommandMap(String fileName) throws IOException { |
| this(); |
| |
| if (LogSupport.isLoggable()) |
| LogSupport.log("MailcapCommandMap: load PROG from " + fileName); |
| if (DB[PROG] == null) { |
| DB[PROG] = new MailcapFile(fileName); |
| } |
| } |
| |
| |
| /** |
| * Constructor that allows the caller to specify an <i>InputStream</i> |
| * containing a mailcap file. |
| * |
| * @param is InputStream of the <i>mailcap</i> file to open |
| */ |
| public MailcapCommandMap(InputStream is) { |
| this(); |
| |
| LogSupport.log("MailcapCommandMap: load PROG"); |
| if (DB[PROG] == null) { |
| try { |
| DB[PROG] = new MailcapFile(is); |
| } catch (IOException ex) { |
| // XXX - should throw it |
| } |
| } |
| } |
| |
| /** |
| * Get the preferred command list for a MIME Type. The MailcapCommandMap |
| * searches the mailcap files as described above under |
| * <i>Mailcap file search order</i>.<p> |
| * |
| * The result of the search is a proper subset of available |
| * commands in all mailcap files known to this instance of |
| * MailcapCommandMap. The first entry for a particular command |
| * is considered the preferred command. |
| * |
| * @param mimeType the MIME type |
| * @return the CommandInfo objects representing the preferred commands. |
| */ |
| public synchronized CommandInfo[] getPreferredCommands(String mimeType) { |
| List cmdList = new ArrayList(); |
| if (mimeType != null) |
| mimeType = mimeType.toLowerCase(Locale.ENGLISH); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapList(mimeType); |
| if (cmdMap != null) |
| appendPrefCmdsToList(cmdMap, cmdList); |
| } |
| |
| // now add the fallback commands |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapFallbackList(mimeType); |
| if (cmdMap != null) |
| appendPrefCmdsToList(cmdMap, cmdList); |
| } |
| |
| CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()]; |
| cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos); |
| |
| return cmdInfos; |
| } |
| |
| /** |
| * Put the commands that are in the hash table, into the list. |
| */ |
| private void appendPrefCmdsToList(Map cmdHash, List cmdList) { |
| Iterator verb_enum = cmdHash.keySet().iterator(); |
| |
| while (verb_enum.hasNext()) { |
| String verb = (String)verb_enum.next(); |
| if (!checkForVerb(cmdList, verb)) { |
| List cmdList2 = (List)cmdHash.get(verb); // get the list |
| String className = (String)cmdList2.get(0); |
| cmdList.add(new CommandInfo(verb, className)); |
| } |
| } |
| } |
| |
| /** |
| * Check the cmdList to see if this command exists, return |
| * true if the verb is there. |
| */ |
| private boolean checkForVerb(List cmdList, String verb) { |
| Iterator ee = cmdList.iterator(); |
| while (ee.hasNext()) { |
| String enum_verb = |
| (String)((CommandInfo)ee.next()).getCommandName(); |
| if (enum_verb.equals(verb)) |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Get all the available commands in all mailcap files known to |
| * this instance of MailcapCommandMap for this MIME type. |
| * |
| * @param mimeType the MIME type |
| * @return the CommandInfo objects representing all the commands. |
| */ |
| public synchronized CommandInfo[] getAllCommands(String mimeType) { |
| List cmdList = new ArrayList(); |
| if (mimeType != null) |
| mimeType = mimeType.toLowerCase(Locale.ENGLISH); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapList(mimeType); |
| if (cmdMap != null) |
| appendCmdsToList(cmdMap, cmdList); |
| } |
| |
| // now add the fallback commands |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapFallbackList(mimeType); |
| if (cmdMap != null) |
| appendCmdsToList(cmdMap, cmdList); |
| } |
| |
| CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()]; |
| cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos); |
| |
| return cmdInfos; |
| } |
| |
| /** |
| * Put the commands that are in the hash table, into the list. |
| */ |
| private void appendCmdsToList(Map typeHash, List cmdList) { |
| Iterator verb_enum = typeHash.keySet().iterator(); |
| |
| while (verb_enum.hasNext()) { |
| String verb = (String)verb_enum.next(); |
| List cmdList2 = (List)typeHash.get(verb); |
| Iterator cmd_enum = ((List)cmdList2).iterator(); |
| |
| while (cmd_enum.hasNext()) { |
| String cmd = (String)cmd_enum.next(); |
| cmdList.add(new CommandInfo(verb, cmd)); |
| // cmdList.add(0, new CommandInfo(verb, cmd)); |
| } |
| } |
| } |
| |
| /** |
| * Get the command corresponding to <code>cmdName</code> for the MIME type. |
| * |
| * @param mimeType the MIME type |
| * @param cmdName the command name |
| * @return the CommandInfo object corresponding to the command. |
| */ |
| public synchronized CommandInfo getCommand(String mimeType, |
| String cmdName) { |
| if (mimeType != null) |
| mimeType = mimeType.toLowerCase(Locale.ENGLISH); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapList(mimeType); |
| if (cmdMap != null) { |
| // get the cmd list for the cmd |
| List v = (List)cmdMap.get(cmdName); |
| if (v != null) { |
| String cmdClassName = (String)v.get(0); |
| |
| if (cmdClassName != null) |
| return new CommandInfo(cmdName, cmdClassName); |
| } |
| } |
| } |
| |
| // now try the fallback list |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| Map cmdMap = DB[i].getMailcapFallbackList(mimeType); |
| if (cmdMap != null) { |
| // get the cmd list for the cmd |
| List v = (List)cmdMap.get(cmdName); |
| if (v != null) { |
| String cmdClassName = (String)v.get(0); |
| |
| if (cmdClassName != null) |
| return new CommandInfo(cmdName, cmdClassName); |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Add entries to the registry. Programmatically |
| * added entries are searched before other entries.<p> |
| * |
| * The string that is passed in should be in mailcap |
| * format. |
| * |
| * @param mail_cap a correctly formatted mailcap string |
| */ |
| public synchronized void addMailcap(String mail_cap) { |
| // check to see if one exists |
| LogSupport.log("MailcapCommandMap: add to PROG"); |
| if (DB[PROG] == null) |
| DB[PROG] = new MailcapFile(); |
| |
| DB[PROG].appendToMailcap(mail_cap); |
| } |
| |
| /** |
| * Return the DataContentHandler for the specified MIME type. |
| * |
| * @param mimeType the MIME type |
| * @return the DataContentHandler |
| */ |
| public synchronized DataContentHandler createDataContentHandler( |
| String mimeType) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log( |
| "MailcapCommandMap: createDataContentHandler for " + mimeType); |
| if (mimeType != null) |
| mimeType = mimeType.toLowerCase(Locale.ENGLISH); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| if (LogSupport.isLoggable()) |
| LogSupport.log(" search DB #" + i); |
| Map cmdMap = DB[i].getMailcapList(mimeType); |
| if (cmdMap != null) { |
| List v = (List)cmdMap.get("content-handler"); |
| if (v != null) { |
| String name = (String)v.get(0); |
| DataContentHandler dch = getDataContentHandler(name); |
| if (dch != null) |
| return dch; |
| } |
| } |
| } |
| |
| // now try the fallback entries |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| if (LogSupport.isLoggable()) |
| LogSupport.log(" search fallback DB #" + i); |
| Map cmdMap = DB[i].getMailcapFallbackList(mimeType); |
| if (cmdMap != null) { |
| List v = (List)cmdMap.get("content-handler"); |
| if (v != null) { |
| String name = (String)v.get(0); |
| DataContentHandler dch = getDataContentHandler(name); |
| if (dch != null) |
| return dch; |
| } |
| } |
| } |
| return null; |
| } |
| |
| private DataContentHandler getDataContentHandler(String name) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log(" got content-handler"); |
| if (LogSupport.isLoggable()) |
| LogSupport.log(" class " + name); |
| try { |
| ClassLoader cld = null; |
| // First try the "application's" class loader. |
| cld = SecuritySupport.getContextClassLoader(); |
| if (cld == null) |
| cld = this.getClass().getClassLoader(); |
| Class cl = null; |
| try { |
| cl = cld.loadClass(name); |
| } catch (Exception ex) { |
| // if anything goes wrong, do it the old way |
| cl = Class.forName(name); |
| } |
| if (cl != null) // XXX - always true? |
| return (DataContentHandler)cl.newInstance(); |
| } catch (IllegalAccessException e) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("Can't load DCH " + name, e); |
| } catch (ClassNotFoundException e) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("Can't load DCH " + name, e); |
| } catch (InstantiationException e) { |
| if (LogSupport.isLoggable()) |
| LogSupport.log("Can't load DCH " + name, e); |
| } |
| return null; |
| } |
| |
| /** |
| * Get all the MIME types known to this command map. |
| * |
| * @return array of MIME types as strings |
| * @since JAF 1.1 |
| */ |
| public synchronized String[] getMimeTypes() { |
| List mtList = new ArrayList(); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| String[] ts = DB[i].getMimeTypes(); |
| if (ts != null) { |
| for (int j = 0; j < ts.length; j++) { |
| // eliminate duplicates |
| if (!mtList.contains(ts[j])) |
| mtList.add(ts[j]); |
| } |
| } |
| } |
| |
| String[] mts = new String[mtList.size()]; |
| mts = (String[])mtList.toArray(mts); |
| |
| return mts; |
| } |
| |
| /** |
| * Get the native commands for the given MIME type. |
| * Returns an array of strings where each string is |
| * an entire mailcap file entry. The application |
| * will need to parse the entry to extract the actual |
| * command as well as any attributes it needs. See |
| * <A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A> |
| * for details of the mailcap entry syntax. Only mailcap |
| * entries that specify a view command for the specified |
| * MIME type are returned. |
| * |
| * @param mimeType the MIME type |
| * @return array of native command entries |
| * @since JAF 1.1 |
| */ |
| public synchronized String[] getNativeCommands(String mimeType) { |
| List cmdList = new ArrayList(); |
| if (mimeType != null) |
| mimeType = mimeType.toLowerCase(Locale.ENGLISH); |
| |
| for (int i = 0; i < DB.length; i++) { |
| if (DB[i] == null) |
| continue; |
| String[] cmds = DB[i].getNativeCommands(mimeType); |
| if (cmds != null) { |
| for (int j = 0; j < cmds.length; j++) { |
| // eliminate duplicates |
| if (!cmdList.contains(cmds[j])) |
| cmdList.add(cmds[j]); |
| } |
| } |
| } |
| |
| String[] cmds = new String[cmdList.size()]; |
| cmds = (String[])cmdList.toArray(cmds); |
| |
| return cmds; |
| } |
| |
| /** |
| * for debugging... |
| * |
| public static void main(String[] argv) throws Exception { |
| MailcapCommandMap map = new MailcapCommandMap(); |
| CommandInfo[] cmdInfo; |
| |
| cmdInfo = map.getPreferredCommands(argv[0]); |
| System.out.println("Preferred Commands:"); |
| for (int i = 0; i < cmdInfo.length; i++) |
| System.out.println("Command " + cmdInfo[i].getCommandName() + " [" + |
| cmdInfo[i].getCommandClass() + "]"); |
| cmdInfo = map.getAllCommands(argv[0]); |
| System.out.println(); |
| System.out.println("All Commands:"); |
| for (int i = 0; i < cmdInfo.length; i++) |
| System.out.println("Command " + cmdInfo[i].getCommandName() + " [" + |
| cmdInfo[i].getCommandClass() + "]"); |
| DataContentHandler dch = map.createDataContentHandler(argv[0]); |
| if (dch != null) |
| System.out.println("DataContentHandler " + |
| dch.getClass().toString()); |
| System.exit(0); |
| } |
| */ |
| } |