📄 mimetable.java
字号:
/* * Copyright (c) 2001 Sun Microsystems, Inc. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Sun Microsystems, Inc. for Project JXTA." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact Project JXTA at http://www.jxta.org. * * 5. Products derived from this software may not be called "JXTA", * nor may "JXTA" appear in their name, without prior written * permission of Sun. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of Project JXTA. For more * information on Project JXTA, please see * <http://www.jxta.org/>. * * This license is based on the BSD license adopted by the Apache Foundation. * * $Id: MimeTable.java,v 1.6 2004/06/09 22:44:08 gonzo Exp $ * */package net.jxta.share;import java.io.InputStream;import java.io.BufferedInputStream;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.util.Hashtable;import java.util.Enumeration;import java.util.Properties;import java.util.StringTokenizer;import java.util.Vector;import org.apache.log4j.Logger;/** * This class is used to map file extensions to their corresponding * MimeInfo objects. */public class MimeTable { private Hashtable tmap; // maps major type to MimeInfo object private Hashtable emap; // maps file extension to MimeInfo object private String browser; // browser application command private static final Logger LOG = Logger.getLogger(MimeTable.class); // default mime table private static final String MIME_PROPERTIES = "mime.properties"; private static MimeTable defaultMimeTable; static { defaultMimeTable = new MimeTable(); InputStream is = MimeTable.class.getResourceAsStream(MIME_PROPERTIES); if (is == null) { LOG.error("Cannot load default mime table. " + MIME_PROPERTIES + " file not found."); throw new InternalError("Could not find " + MIME_PROPERTIES); } else { try { defaultMimeTable.load(is); } catch (IOException e) { e.printStackTrace(); throw new InternalError("Could not load default mime table"); } } } /** * Returns default, platform-independent MimeTable. */ public static MimeTable getDefaultMimeTable() { return defaultMimeTable; } /** * Creates a new empty MimeTable. */ public MimeTable() { tmap = new Hashtable(); emap = new Hashtable(); } /** * Returns the MimeInfo object for the specified mime type, or null if not * found. */ public MimeInfo get(String type) { return (MimeInfo)tmap.get(type); } /** * Returns an array of all the MimeInfo objects in this table. */ public MimeInfo[] getAll() { synchronized (this) { MimeInfo[] mis = new MimeInfo[tmap.size()]; Enumeration e = tmap.elements(); for (int i = 0; i < mis.length; i++) { mis[i] = (MimeInfo)e.nextElement(); } return mis; } } /** * Returns true if this mime table contains information for the * specific mime type. */ public boolean contains(String type) { synchronized (this) { return tmap.containsKey(type); } } /** * Adds a new MimeInfo object to the table, replacing any previous mapping * for the mime type. */ public void put(MimeInfo mi) { String type = mi.getType(); synchronized (this) { if (tmap.containsKey(type)) { remove(type); } tmap.put(type, mi); // create mappings for mime type file extensions String[] exts = mi.getFileExtensions(); if (exts != null) { for (int i = 0; i < exts.length; i++) { emap.put(exts[i], mi); } } } } /** * Removes MimeInfo object corresponding to specified mime type. * @throw IllegalArgumentException if mime type not found */ public void remove(String type) { synchronized (this) { MimeInfo mi = (MimeInfo)tmap.remove(type); if (mi == null) { throw new IllegalArgumentException( "Mime type not found in table: " + mi.getType()); } // remove mappings for the mime type file extensions String[] exts = mi.getFileExtensions(); if (exts != null) { for (int i = 0; i < exts.length; i++) { String ext = exts[i]; if (emap.get(ext) == mi) { emap.remove(ext); } } } } } /** * Returns the number of MimeInfo objects stored in this table. */ public int size() { synchronized (this) { return tmap.size(); } } /** * Returns the MimeInfo for the specified file name, or null if not found. */ public MimeInfo getForName(String name) { int i = name.indexOf('.'); synchronized (this) { return i != -1 ? (MimeInfo)emap.get(name.substring(i)) : null; } } /** * Loads mime types from the specified input stream. */ public void load(InputStream is) throws IOException { Properties props = new Properties(); props.load(is); browser = props.getProperty("browser.application"); // parse mime type properties Enumeration e = props.keys(); while (e.hasMoreElements()) { String s = (String)e.nextElement(); if (s.indexOf('/') != -1) { put(parseProperty(s, props.getProperty(s))); } } } // parse mime type information from the specified property value private MimeInfo parseProperty(String type, String value) { MimeInfo mi = new MimeInfo(type); StringTokenizer st = new StringTokenizer(value, ";"); while (st.hasMoreTokens()) { String s = st.nextToken(); parseKeyword(s, mi); } return mi; } // parse keyword and value from property value private void parseKeyword(String s, MimeInfo mi) { int i = s.indexOf('='); if (i == -1) { throw new IllegalArgumentException("Invalid keyword: " + s); } String name = s.substring(0, i); String value = s.substring(i + 1); if (value.length() > 0) { if (name.equals("description")) { mi.setDescription(value); } else if (name.equals("file_extensions")) { mi.setFileExtensions(parseList(value)); } else if (name.equals("icon")) { mi.setIcon(value); } else if (name.equals("action")) { mi.setAction(value); } else if (name.equals("application")) { mi.setApplication(value); } else { // ignore unrecognized keywords } } } // parse comma separated list of strings private String[] parseList(String s) { StringTokenizer st = new StringTokenizer(s, ","); String[] strs = new String[st.countTokens()]; for (int i = 0; i < strs.length; i++) { strs[i] = st.nextToken(); } return strs; } /** * Saves this MimeTable to the specified output stream. */ public void save(OutputStream os) throws IOException { Properties props = new Properties(); synchronized (this) { if (browser != null) { props.put("browser.application", browser); } StringBuffer sb = new StringBuffer(); Enumeration e = tmap.keys(); while (e.hasMoreElements()) { String type = (String)e.nextElement(); MimeInfo mi = (MimeInfo)tmap.get(type); sb.append("description="); if (mi.getDescription() != null) { sb.append(mi.getDescription()); } if (mi.getFileExtensions() != null) { sb.append(";file_extensions="); String[] exts = mi.getFileExtensions(); if (exts.length > 0) { sb.append(exts[0]); for (int i = 1; i < exts.length; i++) { sb.append(','); sb.append(exts[i]); } } } if (mi.getIcon() != null) { sb.append(";icon="); sb.append(mi.getIcon()); } if (mi.getAction() != null) { sb.append(";action="); sb.append(mi.getAction()); } if (mi.getApplication() != null) { sb.append(";application="); sb.append(mi.getApplication()); } props.put(type, sb.toString()); sb.setLength(0); } } props.store(os, "Mime properties"); } /** * Returns the browser application launch string or null if none. */ public String getBrowserApplication() { synchronized (this) { return browser; } } /** * Sets the browser application launch string. */ public void setBrowserApplication(String browser) { synchronized (this) { this.browser = browser; } } /** * Returns an array of strings that can be used to launch * the browser for the specified argument using Runtime.exec(). */ public String[] getBrowserCmdArray(String arg) { synchronized (this) { if (browser != null) { return getCommandArray(browser, arg); } } return null; } /** * Parses the specified command string into an array of strings * appropriate for use with Runtime.exec(). Arguments containing * single and double quotes are properly handled. The special * token '%s' if not contained in quotes will be substituted with * the specified optional argument if not null. */ public static String[] getCommandArray(String cmd, String arg) { Vector v = new Vector(); StringBuffer sb = new StringBuffer(); boolean inToken = false; boolean quoted = false; char quoteChar = 0; char[] cs = new char[cmd.length()]; cmd.getChars(0, cs.length, cs, 0); for (int i = 0; i < cs.length; i++) { char c = cs[i]; switch (c) { case ' ': case '\t': case '\n': case '\r': case '\f': if (inToken) { if (quoted) { sb.append(c); } else { v.addElement(sb.toString()); sb.setLength(0); inToken = false; } } continue; case '\'': case '"': if (inToken) { if (quoted) { if (c == quoteChar) { quoted = false; } else { sb.append(c); } } else { quoted = true; quoteChar = c; } } else { inToken = quoted = true; quoteChar = c; } continue; case '%': if (!inToken) { int j = i + 1; if (j < cs.length && cs[j++] == 's') { if (j >= cs.length || isSpaceChar(cs[j])) { if (arg != null) { v.addElement(arg); } i++; continue; } } } default: if (!inToken) { inToken = true; quoted = false; } sb.append(c); continue; } } if (inToken) { if (quoted) { throw new IllegalArgumentException( "Unmatched quote in command string: " + cmd); } v.addElement(sb.toString()); } String[] cmdArray = new String[v.size()]; v.copyInto(cmdArray); return cmdArray; } private static boolean isSpaceChar(char c) { switch (c) { case ' ': case '\t': case '\n': case '\r': case '\f': return true; default: return false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -