463 lines · 14.6 KB · Java
RawDownload
/* * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.net.www;import java.io.*;import java.util.Calendar;import java.util.Date;import java.text.SimpleDateFormat;import java.net.URL;import java.net.FileNameMap;import java.util.Hashtable;import java.util.Enumeration;import java.util.Properties;import java.util.StringTokenizer; public class MimeTable implements FileNameMap {    /** Keyed by content type, returns MimeEntries */    private Hashtable<String, MimeEntry> entries        = new Hashtable<String, MimeEntry>();     /** Keyed by file extension (with the .), returns MimeEntries */    private Hashtable<String, MimeEntry> extensionMap        = new Hashtable<String, MimeEntry>();     // Will be reset if in the platform-specific data file    private static String tempFileTemplate;     static {        java.security.AccessController.doPrivileged(            new java.security.PrivilegedAction<Void>() {                public Void run() {                tempFileTemplate =                    System.getProperty("content.types.temp.file.template",                                       "/tmp/%s");                 mailcapLocations = new String[] {                    System.getProperty("user.mailcap"),                    System.getProperty("user.home") + "/.mailcap",                    "/etc/mailcap",                    "/usr/etc/mailcap",                    "/usr/local/etc/mailcap",                    System.getProperty("hotjava.home",                                           "/usr/local/hotjava")                        + "/lib/mailcap",                };                return null;            }        });    }      private static final String filePreamble = "sun.net.www MIME content-types table";    private static final String fileMagic = "#" + filePreamble;     MimeTable() {        load();    }     private static class DefaultInstanceHolder {        static final MimeTable defaultInstance = getDefaultInstance();         static MimeTable getDefaultInstance() {            return java.security.AccessController.doPrivileged(                new java.security.PrivilegedAction<MimeTable>() {                public MimeTable run() {                    MimeTable instance = new MimeTable();                    URLConnection.setFileNameMap(instance);                    return instance;                }            });        }    }     /**     * Get the single instance of this class.  First use will load the     * table from a data file.     */    public static MimeTable getDefaultTable() {        return DefaultInstanceHolder.defaultInstance;    }     /**     *     */    public static FileNameMap loadTable() {        MimeTable mt = getDefaultTable();        return (FileNameMap)mt;    }     public synchronized int getSize() {        return entries.size();    }     public synchronized String getContentTypeFor(String fileName) {        MimeEntry entry = findByFileName(fileName);        if (entry != null) {            return entry.getType();        } else {            return null;        }    }     public synchronized void add(MimeEntry m) {        entries.put(m.getType(), m);         String exts[] = m.getExtensions();        if (exts == null) {            return;        }         for (int i = 0; i < exts.length; i++) {            extensionMap.put(exts[i], m);        }    }     public synchronized MimeEntry remove(String type) {        MimeEntry entry = entries.get(type);        return remove(entry);    }     public synchronized MimeEntry remove(MimeEntry entry) {        String[] extensionKeys = entry.getExtensions();        if (extensionKeys != null) {            for (int i = 0; i < extensionKeys.length; i++) {                extensionMap.remove(extensionKeys[i]);            }        }         return entries.remove(entry.getType());    }     public synchronized MimeEntry find(String type) {        MimeEntry entry = entries.get(type);        if (entry == null) {            // try a wildcard lookup            Enumeration<MimeEntry> e = entries.elements();            while (e.hasMoreElements()) {                MimeEntry wild = e.nextElement();                if (wild.matches(type)) {                    return wild;                }            }        }         return entry;    }     /**     * Locate a MimeEntry by the file extension that has been associated     * with it. Parses general file names, and URLs.     */    public MimeEntry findByFileName(String fname) {        String ext = "";         int i = fname.lastIndexOf('#');         if (i > 0) {            fname = fname.substring(0, i - 1);        }         i = fname.lastIndexOf('.');        // REMIND: OS specific delimters appear here        i = Math.max(i, fname.lastIndexOf('/'));        i = Math.max(i, fname.lastIndexOf('?'));         if (i != -1 && fname.charAt(i) == '.') {            ext = fname.substring(i).toLowerCase();        }         return findByExt(ext);    }     /**     * Locate a MimeEntry by the file extension that has been associated     * with it.     */    public synchronized MimeEntry findByExt(String fileExtension) {        return extensionMap.get(fileExtension);    }     public synchronized MimeEntry findByDescription(String description) {        Enumeration<MimeEntry> e = elements();        while (e.hasMoreElements()) {            MimeEntry entry = e.nextElement();            if (description.equals(entry.getDescription())) {                return entry;            }        }         // We failed, now try treating description as type        return find(description);    }     String getTempFileTemplate() {        return tempFileTemplate;    }     public synchronized Enumeration<MimeEntry> elements() {        return entries.elements();    }     // For backward compatibility -- mailcap format files    // This is not currently used, but may in the future when we add ability    // to read BOTH the properties format and the mailcap format.    protected static String[] mailcapLocations;     public synchronized void load() {        Properties entries = new Properties();        File file = null;        try {            InputStream is;            // First try to load the user-specific table, if it exists            String userTablePath =                System.getProperty("content.types.user.table");            if (userTablePath != null) {                file = new File(userTablePath);                if (!file.exists()) {                    // No user-table, try to load the default built-in table.                    file = new File(System.getProperty("java.home") +                                    File.separator +                                    "lib" +                                    File.separator +                                    "content-types.properties");                }            }            else {                // No user table, try to load the default built-in table.                file = new File(System.getProperty("java.home") +                                File.separator +                                "lib" +                                File.separator +                                "content-types.properties");            }             is = new BufferedInputStream(new FileInputStream(file));            entries.load(is);            is.close();        }        catch (IOException e) {            System.err.println("Warning: default mime table not found: " +                               file.getPath());            return;        }        parse(entries);    }     void parse(Properties entries) {        // first, strip out the platform-specific temp file template        String tempFileTemplate = (String)entries.get("temp.file.template");        if (tempFileTemplate != null) {            entries.remove("temp.file.template");            this.tempFileTemplate = tempFileTemplate;        }         // now, parse the mime-type spec's        Enumeration<?> types = entries.propertyNames();        while (types.hasMoreElements()) {            String type = (String)types.nextElement();            String attrs = entries.getProperty(type);            parse(type, attrs);        }    }     //    // Table format:    //    // <entry> ::= <table_tag> | <type_entry>    //    // <table_tag> ::= <table_format_version> | <temp_file_template>    //    // <type_entry> ::= <type_subtype_pair> '=' <type_attrs_list>    //    // <type_subtype_pair> ::= <type> '/' <subtype>    //    // <type_attrs_list> ::= <attr_value_pair> [ ';' <attr_value_pair> ]*    //                       | [ <attr_value_pair> ]+    //    // <attr_value_pair> ::= <attr_name> '=' <attr_value>    //    // <attr_name> ::= 'description' | 'action' | 'application'    //                 | 'file_extensions' | 'icon'    //    // <attr_value> ::= <legal_char>*    //    // Embedded ';' in an <attr_value> are quoted with leading '\' .    //    // Interpretation of <attr_value> depends on the <attr_name> it is    // associated with.    //     void parse(String type, String attrs) {        MimeEntry newEntry = new MimeEntry(type);         // REMIND handle embedded ';' and '|' and literal '"'        StringTokenizer tokenizer = new StringTokenizer(attrs, ";");        while (tokenizer.hasMoreTokens()) {            String pair = tokenizer.nextToken();            parse(pair, newEntry);        }         add(newEntry);    }     void parse(String pair, MimeEntry entry) {        // REMIND add exception handling...        String name = null;        String value = null;         boolean gotName = false;        StringTokenizer tokenizer = new StringTokenizer(pair, "=");        while (tokenizer.hasMoreTokens()) {            if (gotName) {                value = tokenizer.nextToken().trim();            }            else {                name = tokenizer.nextToken().trim();                gotName = true;            }        }         fill(entry, name, value);    }     void fill(MimeEntry entry, String name, String value) {        if ("description".equalsIgnoreCase(name)) {            entry.setDescription(value);        }        else if ("action".equalsIgnoreCase(name)) {            entry.setAction(getActionCode(value));        }        else if ("application".equalsIgnoreCase(name)) {            entry.setCommand(value);        }        else if ("icon".equalsIgnoreCase(name)) {            entry.setImageFileName(value);        }        else if ("file_extensions".equalsIgnoreCase(name)) {            entry.setExtensions(value);        }         // else illegal name exception    }     String[] getExtensions(String list) {        StringTokenizer tokenizer = new StringTokenizer(list, ",");        int n = tokenizer.countTokens();        String[] extensions = new String[n];        for (int i = 0; i < n; i++) {            extensions[i] = tokenizer.nextToken();        }         return extensions;    }     int getActionCode(String action) {        for (int i = 0; i < MimeEntry.actionKeywords.length; i++) {            if (action.equalsIgnoreCase(MimeEntry.actionKeywords[i])) {                return i;            }        }         return MimeEntry.UNKNOWN;    }     public synchronized boolean save(String filename) {        if (filename == null) {            filename = System.getProperty("user.home" +                                          File.separator +                                          "lib" +                                          File.separator +                                          "content-types.properties");        }         return saveAsProperties(new File(filename));    }     public Properties getAsProperties() {        Properties properties = new Properties();        Enumeration<MimeEntry> e = elements();        while (e.hasMoreElements()) {            MimeEntry entry = e.nextElement();            properties.put(entry.getType(), entry.toProperty());        }         return properties;    }     protected boolean saveAsProperties(File file) {        FileOutputStream os = null;        try {            os = new FileOutputStream(file);            Properties properties = getAsProperties();            properties.put("temp.file.template", tempFileTemplate);            String tag;            String user = System.getProperty("user.name");            if (user != null) {                tag = "; customized for " + user;                properties.save(os, filePreamble + tag);            }            else {                properties.save(os, filePreamble);            }        }        catch (IOException e) {            e.printStackTrace();            return false;        }        finally {            if (os != null) {                try { os.close(); } catch (IOException e) {}            }        }         return true;    }    /*     * Debugging utilities     *    public void list(PrintStream out) {        Enumeration keys = entries.keys();        while (keys.hasMoreElements()) {            String key = (String)keys.nextElement();            MimeEntry entry = (MimeEntry)entries.get(key);            out.println(key + ": " + entry);        }    }     public static void main(String[] args) {        MimeTable testTable = MimeTable.getDefaultTable();         Enumeration e = testTable.elements();        while (e.hasMoreElements()) {            MimeEntry entry = (MimeEntry)e.nextElement();            System.out.println(entry);        }         testTable.save(File.separator + "tmp" +                       File.separator + "mime_table.save");    }    */}