mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			804 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			804 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Java
		
	
	
	
/* MailcapCommandMap.java -- Command map implementation using a mailcap file.
 | 
						|
   Copyright (C) 2004 Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
package javax.activation;
 | 
						|
 | 
						|
import gnu.java.lang.CPStringBuilder;
 | 
						|
 | 
						|
import java.io.BufferedReader;
 | 
						|
import java.io.File;
 | 
						|
import java.io.FileReader;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.InputStreamReader;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.Reader;
 | 
						|
import java.io.StringReader;
 | 
						|
import java.net.URL;
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Enumeration;
 | 
						|
import java.util.LinkedHashMap;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
 | 
						|
/**
 | 
						|
 * Implementation of a command map using a <code>mailcap</code> file (RFC
 | 
						|
 * 1524). Mailcap files are searched for in the following places:
 | 
						|
 * <ol>
 | 
						|
 * <li>Programmatically added entries to this interface</li>
 | 
						|
 * <li>the file <tt>.mailcap</tt> in the user's home directory</li>
 | 
						|
 * <li>the file <i><java.home></i><tt>/lib/mailcap</tt></li>
 | 
						|
 * <li>the resource <tt>META-INF/mailcap</tt></li>
 | 
						|
 * <li>the resource <tt>META-INF/mailcap.default</tt> in the JAF
 | 
						|
 * distribution</li>
 | 
						|
 * </ol>
 | 
						|
 *
 | 
						|
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 | 
						|
 * @version 1.1
 | 
						|
 */
 | 
						|
public class MailcapCommandMap
 | 
						|
    extends CommandMap
 | 
						|
{
 | 
						|
 | 
						|
  private static final int PROG = 0;
 | 
						|
  private static final int HOME = 1;
 | 
						|
  private static final int SYS = 2;
 | 
						|
  private static final int JAR = 3;
 | 
						|
  private static final int DEF = 4;
 | 
						|
  private static boolean debug = false;
 | 
						|
  private static final int NORMAL = 0;
 | 
						|
  private static final int FALLBACK = 1;
 | 
						|
 | 
						|
  static
 | 
						|
  {
 | 
						|
    try
 | 
						|
      {
 | 
						|
        String d = System.getProperty("javax.activation.debug");
 | 
						|
        debug = Boolean.valueOf(d).booleanValue();
 | 
						|
      }
 | 
						|
    catch (SecurityException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private Map<String,Map<String,List<String>>>[][] mailcaps;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Default constructor.
 | 
						|
   */
 | 
						|
  public MailcapCommandMap()
 | 
						|
  {
 | 
						|
    init(null);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constructor specifying a filename.
 | 
						|
   * @param fileName the name of the file to read mailcap entries from
 | 
						|
   */
 | 
						|
  public MailcapCommandMap(String fileName)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    Reader in = null;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        in = new FileReader(fileName);
 | 
						|
      }
 | 
						|
    catch (IOException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
    init(in);
 | 
						|
    if (in != null)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            in.close();
 | 
						|
          }
 | 
						|
        catch (IOException e)
 | 
						|
          {
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constructor specifying an input stream.
 | 
						|
   * @param is the input stream to read mailcap entries from
 | 
						|
   */
 | 
						|
  public MailcapCommandMap(InputStream is)
 | 
						|
  {
 | 
						|
    init(new InputStreamReader(is));
 | 
						|
  }
 | 
						|
 | 
						|
  private void init(Reader in)
 | 
						|
  {
 | 
						|
    mailcaps = new Map[5][2];
 | 
						|
    for (int i = 0; i < 5; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 2; j++)
 | 
						|
          {
 | 
						|
            mailcaps[i][j] =
 | 
						|
              new LinkedHashMap<String,Map<String,List<String>>>();
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (in != null)
 | 
						|
      {
 | 
						|
        if (debug)
 | 
						|
          {
 | 
						|
            System.out.println("MailcapCommandMap: load PROG");
 | 
						|
          }
 | 
						|
        try
 | 
						|
          {
 | 
						|
            parse(PROG, in);
 | 
						|
          }
 | 
						|
        catch (IOException e)
 | 
						|
          {
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: load HOME");
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        String home = System.getProperty("user.home");
 | 
						|
        if (home != null)
 | 
						|
          {
 | 
						|
            parseFile(HOME, new CPStringBuilder(home)
 | 
						|
                      .append(File.separatorChar)
 | 
						|
                      .append(".mailcap")
 | 
						|
                      .toString());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (SecurityException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: load SYS");
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        parseFile(SYS,
 | 
						|
                  new CPStringBuilder(System.getProperty("java.home"))
 | 
						|
                  .append(File.separatorChar)
 | 
						|
                  .append("lib")
 | 
						|
                  .append(File.separatorChar)
 | 
						|
                  .append("mailcap")
 | 
						|
                  .toString());
 | 
						|
      }
 | 
						|
    catch (SecurityException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: load JAR");
 | 
						|
      }
 | 
						|
    List<URL> systemResources = getSystemResources("META-INF/mailcap");
 | 
						|
    int len = systemResources.size();
 | 
						|
    if (len > 0)
 | 
						|
      {
 | 
						|
        for (int i = 0; i < len ; i++)
 | 
						|
          {
 | 
						|
            Reader urlIn = null;
 | 
						|
            URL url = systemResources.get(i);
 | 
						|
            try
 | 
						|
              {
 | 
						|
                if (debug)
 | 
						|
                  {
 | 
						|
                    System.out.println("\t" + url.toString());
 | 
						|
                  }
 | 
						|
                urlIn = new InputStreamReader(url.openStream());
 | 
						|
                parse(JAR, urlIn);
 | 
						|
              }
 | 
						|
            catch (IOException e)
 | 
						|
              {
 | 
						|
                if (debug)
 | 
						|
                  {
 | 
						|
                    System.out.println(e.getClass().getName() + ": " +
 | 
						|
                                       e.getMessage());
 | 
						|
                  }
 | 
						|
              }
 | 
						|
            finally
 | 
						|
              {
 | 
						|
                if (urlIn != null)
 | 
						|
                  {
 | 
						|
                    try
 | 
						|
                      {
 | 
						|
                        urlIn.close();
 | 
						|
                      }
 | 
						|
                    catch (IOException e)
 | 
						|
                      {
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        parseResource(JAR, "/META-INF/mailcap");
 | 
						|
      }
 | 
						|
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: load DEF");
 | 
						|
      }
 | 
						|
    parseResource(DEF, "/META-INF/mailcap.default");
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the list of preferred commands for a given MIME type.
 | 
						|
   * @param mimeType the MIME type
 | 
						|
   */
 | 
						|
  public synchronized CommandInfo[] getPreferredCommands(String mimeType)
 | 
						|
  {
 | 
						|
    List<CommandInfo> cmdList = new ArrayList<CommandInfo>();
 | 
						|
    List<String> verbList = new ArrayList<String>();
 | 
						|
    for (int i = 0; i < 2; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 5; j++)
 | 
						|
          {
 | 
						|
            Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
 | 
						|
            if (map != null)
 | 
						|
              {
 | 
						|
                for (Map.Entry<String,List<String>> entry : map.entrySet())
 | 
						|
                  {
 | 
						|
                    String verb = entry.getKey();
 | 
						|
                    if (!verbList.contains(verb))
 | 
						|
                      {
 | 
						|
                        List<String> classNames = entry.getValue();
 | 
						|
                        String className = classNames.get(0);
 | 
						|
                        CommandInfo cmd = new CommandInfo(verb, className);
 | 
						|
                        cmdList.add(cmd);
 | 
						|
                        verbList.add(verb);
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    CommandInfo[] cmds = new CommandInfo[cmdList.size()];
 | 
						|
    cmdList.toArray(cmds);
 | 
						|
    return cmds;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns all commands for the given MIME type.
 | 
						|
   * @param mimeType the MIME type
 | 
						|
   */
 | 
						|
  public synchronized CommandInfo[] getAllCommands(String mimeType)
 | 
						|
  {
 | 
						|
    List<CommandInfo> cmdList = new ArrayList<CommandInfo>();
 | 
						|
    for (int i = 0; i < 2; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 5; j++)
 | 
						|
          {
 | 
						|
            Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
 | 
						|
            if (map != null)
 | 
						|
              {
 | 
						|
                for (Map.Entry<String,List<String>> entry : map.entrySet())
 | 
						|
                  {
 | 
						|
                    String verb = entry.getKey();
 | 
						|
                    List<String> classNames = entry.getValue();
 | 
						|
                    int len = classNames.size();
 | 
						|
                    for (int l = 0; l < len; l++)
 | 
						|
                      {
 | 
						|
                        String className = classNames.get(l);
 | 
						|
                        CommandInfo cmd = new CommandInfo(verb, className);
 | 
						|
                        cmdList.add(cmd);
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    CommandInfo[] cmds = new CommandInfo[cmdList.size()];
 | 
						|
    cmdList.toArray(cmds);
 | 
						|
    return cmds;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the command with the specified name for the given MIME type.
 | 
						|
   * @param mimeType the MIME type
 | 
						|
   * @param cmdName the command verb
 | 
						|
   */
 | 
						|
  public synchronized CommandInfo getCommand(String mimeType,
 | 
						|
                                             String cmdName)
 | 
						|
  {
 | 
						|
    for (int i = 0; i < 2; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 5; j++)
 | 
						|
          {
 | 
						|
            Map<String,List<String>> map =
 | 
						|
              getCommands(mailcaps[j][i], mimeType);
 | 
						|
            if (map != null)
 | 
						|
              {
 | 
						|
                List<String> classNames = map.get(cmdName);
 | 
						|
                if (classNames == null)
 | 
						|
                  {
 | 
						|
                    classNames = map.get("x-java-" + cmdName);
 | 
						|
                  }
 | 
						|
                if (classNames != null)
 | 
						|
                  {
 | 
						|
                    String className = classNames.get(0);
 | 
						|
                    return new CommandInfo(cmdName, className);
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds entries programmatically to the registry.
 | 
						|
   * @param mailcap a mailcap string
 | 
						|
   */
 | 
						|
  public synchronized void addMailcap(String mailcap)
 | 
						|
  {
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: add to PROG");
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        parse(PROG, new StringReader(mailcap));
 | 
						|
      }
 | 
						|
    catch (IOException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the DCH for the specified MIME type.
 | 
						|
   * @param mimeType the MIME type
 | 
						|
   */
 | 
						|
  public synchronized DataContentHandler
 | 
						|
    createDataContentHandler(String mimeType)
 | 
						|
  {
 | 
						|
    if (debug)
 | 
						|
      {
 | 
						|
        System.out.println("MailcapCommandMap: " +
 | 
						|
                           "createDataContentHandler for " + mimeType);
 | 
						|
      }
 | 
						|
    for (int i = 0; i < 2; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 5; j++)
 | 
						|
          {
 | 
						|
            if (debug)
 | 
						|
              {
 | 
						|
                System.out.println("  search DB #" + i);
 | 
						|
              }
 | 
						|
            Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
 | 
						|
            if (map != null)
 | 
						|
              {
 | 
						|
                List<String> classNames = map.get("content-handler");
 | 
						|
                if (classNames == null)
 | 
						|
                  {
 | 
						|
                    classNames = map.get("x-java-content-handler");
 | 
						|
                  }
 | 
						|
                if (classNames != null)
 | 
						|
                  {
 | 
						|
                    String className = classNames.get(0);
 | 
						|
                    if (debug)
 | 
						|
                      {
 | 
						|
                        System.out.println("  In " + nameOf(j) +
 | 
						|
                                           ", content-handler=" + className);
 | 
						|
                      }
 | 
						|
                    try
 | 
						|
                      {
 | 
						|
                        Class<?> clazz = Class.forName(className);
 | 
						|
                        return (DataContentHandler)clazz.newInstance();
 | 
						|
                      }
 | 
						|
                    catch (IllegalAccessException e)
 | 
						|
                      {
 | 
						|
                        if (debug)
 | 
						|
                          {
 | 
						|
                            e.printStackTrace();
 | 
						|
                          }
 | 
						|
                      }
 | 
						|
                    catch (ClassNotFoundException e)
 | 
						|
                      {
 | 
						|
                        if (debug)
 | 
						|
                      {
 | 
						|
                        e.printStackTrace();
 | 
						|
                      }
 | 
						|
                      }
 | 
						|
                    catch (InstantiationException e)
 | 
						|
                      {
 | 
						|
                        if (debug)
 | 
						|
                          {
 | 
						|
                            e.printStackTrace();
 | 
						|
                          }
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * 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 String[] getNativeCommands(String mimeType)
 | 
						|
  {
 | 
						|
    List<String> acc = new ArrayList<String>();
 | 
						|
    for (int i = 0; i < 2; i++)
 | 
						|
      {
 | 
						|
        for (int j = 0; j < 5; j++)
 | 
						|
          {
 | 
						|
            addNativeCommands(acc, mailcaps[j][i], mimeType);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    String[] ret = new String[acc.size()];
 | 
						|
    acc.toArray(ret);
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  private void addNativeCommands(List<String> acc,
 | 
						|
                                 Map<String,Map<String,List<String>>> mailcap,
 | 
						|
                                 String mimeType)
 | 
						|
  {
 | 
						|
    for (Map.Entry<String,Map<String,List<String>>> mEntry : mailcap.entrySet())
 | 
						|
      {
 | 
						|
        String entryMimeType = mEntry.getKey();
 | 
						|
        if (!entryMimeType.equals(mimeType))
 | 
						|
          {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
        Map<String,List<String>> commands = mEntry.getValue();
 | 
						|
        String viewCommand = commands.get("view-command").get(0);
 | 
						|
        if (viewCommand == null)
 | 
						|
          {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
        CPStringBuilder buf = new CPStringBuilder();
 | 
						|
        buf.append(mimeType);
 | 
						|
        buf.append(';');
 | 
						|
        buf.append(' ');
 | 
						|
        buf.append(viewCommand);
 | 
						|
        for (Map.Entry<String,List<String>> cEntry : commands.entrySet())
 | 
						|
          {
 | 
						|
            String verb = cEntry.getKey();
 | 
						|
            List<String> classNames = cEntry.getValue();
 | 
						|
            if (!"view-command".equals(verb))
 | 
						|
              {
 | 
						|
                for (String command : classNames)
 | 
						|
                  {
 | 
						|
                    buf.append(';');
 | 
						|
                    buf.append(' ');
 | 
						|
                    buf.append(verb);
 | 
						|
                    buf.append('=');
 | 
						|
                    buf.append(command);
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
        if (buf.length() > 0)
 | 
						|
          {
 | 
						|
            acc.add(buf.toString());
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private static String nameOf(int mailcap)
 | 
						|
  {
 | 
						|
    switch (mailcap)
 | 
						|
      {
 | 
						|
      case PROG:
 | 
						|
        return "PROG";
 | 
						|
      case HOME:
 | 
						|
        return "HOME";
 | 
						|
      case SYS:
 | 
						|
        return "SYS";
 | 
						|
      case JAR:
 | 
						|
        return "JAR";
 | 
						|
      case DEF:
 | 
						|
        return "DEF";
 | 
						|
      default:
 | 
						|
        return "ERR";
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private void parseFile(int index, String filename)
 | 
						|
  {
 | 
						|
    Reader in = null;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        if (debug)
 | 
						|
          {
 | 
						|
            System.out.println("\t" + filename);
 | 
						|
          }
 | 
						|
        in = new FileReader(filename);
 | 
						|
        parse(index, in);
 | 
						|
      }
 | 
						|
    catch (IOException e)
 | 
						|
      {
 | 
						|
        if (debug)
 | 
						|
          {
 | 
						|
            System.out.println(e.getClass().getName() + ": " +
 | 
						|
                               e.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    finally
 | 
						|
      {
 | 
						|
        if (in != null)
 | 
						|
          {
 | 
						|
            try
 | 
						|
              {
 | 
						|
                in.close();
 | 
						|
              }
 | 
						|
            catch (IOException e)
 | 
						|
              {
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private void parseResource(int index, String name)
 | 
						|
  {
 | 
						|
    Reader in = null;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        InputStream is = getClass().getResourceAsStream(name);
 | 
						|
        if (is != null)
 | 
						|
          {
 | 
						|
            if (debug)
 | 
						|
              {
 | 
						|
                System.out.println("\t" + name);
 | 
						|
              }
 | 
						|
            in = new InputStreamReader(is);
 | 
						|
            parse(index, in);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (IOException e)
 | 
						|
      {
 | 
						|
        if (debug)
 | 
						|
          {
 | 
						|
            System.out.println(e.getClass().getName() + ": " +
 | 
						|
                               e.getMessage());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    finally
 | 
						|
      {
 | 
						|
        if (in != null)
 | 
						|
          {
 | 
						|
            try
 | 
						|
              {
 | 
						|
                in.close();
 | 
						|
              }
 | 
						|
            catch (IOException e)
 | 
						|
              {
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private void parse(int index, Reader in)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    BufferedReader br = new BufferedReader(in);
 | 
						|
    CPStringBuilder buf = null;
 | 
						|
    for (String line = br.readLine(); line != null; line = br.readLine())
 | 
						|
      {
 | 
						|
        line = line.trim();
 | 
						|
        int len = line.length();
 | 
						|
        if (len == 0 || line.charAt(0) == '#')
 | 
						|
          {
 | 
						|
            continue; // Comment
 | 
						|
          }
 | 
						|
        if (line.charAt(len - 1) == '\\')
 | 
						|
          {
 | 
						|
            if (buf == null)
 | 
						|
              {
 | 
						|
                buf = new CPStringBuilder();
 | 
						|
              }
 | 
						|
            buf.append(line.substring(0, len - 1));
 | 
						|
          }
 | 
						|
        else if (buf != null)
 | 
						|
          {
 | 
						|
            buf.append(line);
 | 
						|
            parseEntry(index, buf.toString());
 | 
						|
            buf = null;
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            parseEntry(index, line);
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private void parseEntry(int index, String line)
 | 
						|
  {
 | 
						|
    // Tokenize entry into fields
 | 
						|
    char[] chars = line.toCharArray();
 | 
						|
    int len = chars.length;
 | 
						|
    boolean inQuotedString = false;
 | 
						|
    boolean fallback = false;
 | 
						|
    CPStringBuilder buffer = new CPStringBuilder();
 | 
						|
    List<String> fields = new ArrayList<String>();
 | 
						|
    for (int i = 0; i < len; i++)
 | 
						|
      {
 | 
						|
        char c = chars[i];
 | 
						|
        if (c == '\\')
 | 
						|
          {
 | 
						|
            c = chars[++i]; // qchar
 | 
						|
          }
 | 
						|
        if (c == ';' && !inQuotedString)
 | 
						|
          {
 | 
						|
            String field = buffer.toString().trim();
 | 
						|
            if ("x-java-fallback-entry".equals(field))
 | 
						|
              {
 | 
						|
                fallback = true;
 | 
						|
              }
 | 
						|
            fields.add(field);
 | 
						|
            buffer.setLength(0);
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            if (c == '"')
 | 
						|
              {
 | 
						|
                inQuotedString = !inQuotedString;
 | 
						|
              }
 | 
						|
            buffer.append(c);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    String field = buffer.toString().trim();
 | 
						|
    if ("x-java-fallback-entry".equals(field))
 | 
						|
      {
 | 
						|
        fallback = true;
 | 
						|
      }
 | 
						|
    fields.add(field);
 | 
						|
 | 
						|
    len = fields.size();
 | 
						|
    if (len < 2)
 | 
						|
      {
 | 
						|
        if (debug)
 | 
						|
          {
 | 
						|
            System.err.println("Invalid mailcap entry: " + line);
 | 
						|
          }
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
    Map<String,Map<String,List<String>>> mailcap =
 | 
						|
      fallback ? mailcaps[index][FALLBACK] : mailcaps[index][NORMAL];
 | 
						|
    String mimeType = fields.get(0);
 | 
						|
    addField(mailcap, mimeType, "view-command", (String) fields.get(1));
 | 
						|
    for (int i = 2; i < len; i++)
 | 
						|
      {
 | 
						|
        addField(mailcap, mimeType, null, (String) fields.get(i));
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  private void addField(Map<String,Map<String,List<String>>> mailcap,
 | 
						|
                        String mimeType, String verb, String command)
 | 
						|
  {
 | 
						|
    if (verb == null)
 | 
						|
      {
 | 
						|
        int ei = command.indexOf('=');
 | 
						|
        if (ei != -1)
 | 
						|
          {
 | 
						|
            verb = command.substring(0, ei);
 | 
						|
            command = command.substring(ei + 1);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (command.length() == 0 || verb == null || verb.length() == 0)
 | 
						|
      {
 | 
						|
        return; // Invalid field or flag
 | 
						|
      }
 | 
						|
 | 
						|
    Map<String,List<String>> commands = mailcap.get(mimeType);
 | 
						|
    if (commands == null)
 | 
						|
      {
 | 
						|
        commands = new LinkedHashMap<String,List<String>>();
 | 
						|
        mailcap.put(mimeType, commands);
 | 
						|
      }
 | 
						|
    List<String> classNames = commands.get(verb);
 | 
						|
    if (classNames == null)
 | 
						|
      {
 | 
						|
        classNames = new ArrayList<String>();
 | 
						|
        commands.put(verb, classNames);
 | 
						|
      }
 | 
						|
    classNames.add(command);
 | 
						|
  }
 | 
						|
 | 
						|
  private Map<String,List<String>>
 | 
						|
    getCommands(Map<String,Map<String,List<String>>> mailcap,
 | 
						|
                String mimeType)
 | 
						|
  {
 | 
						|
    int si = mimeType.indexOf('/');
 | 
						|
    String genericMimeType = new CPStringBuilder(mimeType.substring(0, si))
 | 
						|
      .append('/')
 | 
						|
      .append('*')
 | 
						|
      .toString();
 | 
						|
    Map<String,List<String>> specific = mailcap.get(mimeType);
 | 
						|
    Map<String,List<String>> generic = mailcap.get(genericMimeType);
 | 
						|
    if (generic == null)
 | 
						|
      {
 | 
						|
        return specific;
 | 
						|
      }
 | 
						|
    if (specific == null)
 | 
						|
      {
 | 
						|
        return generic;
 | 
						|
      }
 | 
						|
    Map<String,List<String>> combined = new LinkedHashMap<String,List<String>>();
 | 
						|
    combined.putAll(specific);
 | 
						|
    for (String verb : generic.keySet())
 | 
						|
      {
 | 
						|
        List<String> genericClassNames = generic.get(verb);
 | 
						|
        List<String> classNames = combined.get(verb);
 | 
						|
        if (classNames == null)
 | 
						|
          {
 | 
						|
            combined.put(verb, genericClassNames);
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            classNames.addAll(genericClassNames);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return combined;
 | 
						|
  }
 | 
						|
 | 
						|
  // -- Utility methods --
 | 
						|
 | 
						|
  private List<URL> getSystemResources(String name)
 | 
						|
  {
 | 
						|
    List<URL> acc = new ArrayList<URL>();
 | 
						|
    try
 | 
						|
      {
 | 
						|
        for (Enumeration<URL> i = ClassLoader.getSystemResources(name);
 | 
						|
             i.hasMoreElements(); )
 | 
						|
          {
 | 
						|
            acc.add(i.nextElement());
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (IOException e)
 | 
						|
      {
 | 
						|
      }
 | 
						|
    return acc;
 | 
						|
  }
 | 
						|
 | 
						|
}
 |