/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. 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://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/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 glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [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.
 */

/*
 * @(#)MailcapCommandMap.java	1.42 07/05/14
 */


package javax.activation;

import java.util.*;
import java.io.*;
import java.net.*;
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:
 * <p>
 * <ol>
 * <li> Programatically added entries to the MailcapCommandMap instance.
 * <li> The file <code>.mailcap</code> in the user's home directory.
 * <li> The file &lt;<i>java.home</i>&gt;<code>/lib/mailcap</code>.
 * <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>
 * <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-&lt;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>
 * &lt;mime type>; ; &lt;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

    /**
     * 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
	    String system_mailcap = System.getProperty("java.home") +
		File.separator + "lib" + File.separator + "mailcap";
	    mf = loadFile(system_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.
     *
     * @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);
    }
    */
}
