⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parameterlist.java

📁 java Email you can use it to send email to others
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * 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. *//* * @(#)ParameterList.java	1.17 07/05/04 */package javax.mail.internet;import java.util.*;import java.io.*;/** * This class holds MIME parameters (attribute-value pairs). * The <code>mail.mime.encodeparameters</code> and * <code>mail.mime.decodeparameters</code> System properties * control whether encoded parameters, as specified by  * <a href="http://www.ietf.org/rfc/rfc2231.txt">RFC 2231</a>, * are supported.  By default, such encoded parameters are not * supported. <p> * * Also, in the current implementation, setting the System property * <code>mail.mime.decodeparameters.strict</code> to <code>"true"</code> * will cause a <code>ParseException</code> to be thrown for errors * detected while decoding encoded parameters.  By default, if any * decoding errors occur, the original (undecoded) string is used. * * @version 1.17, 07/05/04 * @author  John Mani * @author  Bill Shannon */public class ParameterList {    /**     * The map of name, value pairs.     * The value object is either a String, for unencoded     * values, or a Value object, for encoded values,     * or a MultiValue object, for multi-segment parameters.     *     * We use a LinkedHashMap so that parameters are (as much as     * possible) kept in the original order.  Note however that     * multi-segment parameters (see below) will appear in the     * position of the first seen segment and orphan segments     * will all move to the end.     */    private Map list = new LinkedHashMap();	// keep parameters in order    /**     * A set of names for multi-segment parameters that we     * haven't processed yet.  Normally such names are accumulated     * during the inital parse and processed at the end of the parse,     * but such names can also be set via the set method when the     * IMAP provider accumulates pre-parsed pieces of a parameter list.     * (A special call to the set method tells us when the IMAP provider     * is done setting parameters.)     *     * A multi-segment parameter is defined by RFC 2231.  For example,     * "title*0=part1; title*1=part2", which represents a parameter     * named "title" with value "part1part2".     *     * Note also that each segment of the value might or might not be     * encoded, indicated by a trailing "*" on the parameter name.     * If any segment is encoded, the first segment must be encoded.     * Only the first segment contains the charset and language     * information needed to decode any encoded segments.     *     * RFC 2231 introduces many possible failure modes, which we try     * to handle as gracefully as possible.  Generally, a failure to     * decode a parameter value causes the non-decoded parameter value     * to be used instead.  Missing segments cause all later segments     * to be appear as independent parameters with names that include     * the segment number.  For example, "title*0=part1; title*1=part2;     * title*3=part4" appears as two parameters named "title" and "title*3".     */    private Set multisegmentNames;    /**     * A map containing the segments for all not-yet-processed     * multi-segment parameters.  The map is indexed by "name*seg".     * The value object is either a String or a Value object.     * The Value object is not decoded during the initial parse     * because the segments may appear in any order and until the     * first segment appears we don't know what charset to use to     * decode any encoded segments.  The segments are decoded in     * order in the combineMultisegmentNames method.     */    private Map slist;    /**     * MWB 3BView: The name of the last parameter added to the map.     * Used for the AppleMail hack.     */    private String lastName = null;    private static boolean encodeParameters = false;    private static boolean decodeParameters = false;    private static boolean decodeParametersStrict = false;    private static boolean applehack = false;    static {	try {	    String s = System.getProperty("mail.mime.encodeparameters");	    // default to false	    encodeParameters = s != null && s.equalsIgnoreCase("true");	    s = System.getProperty("mail.mime.decodeparameters");	    // default to false	    decodeParameters = s != null && s.equalsIgnoreCase("true");	    s = System.getProperty("mail.mime.decodeparameters.strict");	    // default to false	    decodeParametersStrict = s != null && s.equalsIgnoreCase("true");	    s = System.getProperty("mail.mime.applefilenames");	    // default to false	    applehack = s != null && s.equalsIgnoreCase("true");	} catch (SecurityException sex) {	    // ignore it	}    }    /**     * A struct to hold an encoded value.     * A parsed encoded value is stored as both the     * decoded value and the original encoded value     * (so that toString will produce the same result).     * An encoded value that is set explicitly is stored     * as the original value and the encoded value, to     * ensure that get will return the same value that     * was set.     */    private static class Value {	String value;	String charset;	String encodedValue;    }    /**     * A struct for a multi-segment parameter.  Each entry in the     * List is either a String or a Value object.  When all the     * segments are present and combined in the combineMultisegmentNames     * method, the value field contains the combined and decoded value.     * Until then the value field contains an empty string as a placeholder.     */    private static class MultiValue extends ArrayList {	String value;    }    /**     * Map the LinkedHashMap's keySet iterator to an Enumeration.     */    private static class ParamEnum implements Enumeration {	private Iterator it;	ParamEnum(Iterator it) {	    this.it = it;	}	public boolean hasMoreElements() {	    return it.hasNext();	}	public Object nextElement() {	    return it.next();	}    }    /**     * No-arg Constructor.     */    public ParameterList() { 	// initialize other collections only if they'll be needed	if (decodeParameters) {	    multisegmentNames = new HashSet();	    slist = new HashMap();	}    }    /**     * Constructor that takes a parameter-list string. The String     * is parsed and the parameters are collected and stored internally.     * A ParseException is thrown if the parse fails.      * Note that an empty parameter-list string is valid and will be      * parsed into an empty ParameterList.     *     * @param	s	the parameter-list string.     * @exception	ParseException if the parse fails.     */    public ParameterList(String s) throws ParseException {	this();	HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);	for (;;) {	    HeaderTokenizer.Token tk = h.next();	    int type = tk.getType();	    String name, value;	    if (type == HeaderTokenizer.Token.EOF) // done		break;	    if ((char)type == ';') {		// expect parameter name		tk = h.next();		// tolerate trailing semicolon, even though it violates the spec		if (tk.getType() == HeaderTokenizer.Token.EOF)		    break;		// parameter name must be a MIME Atom		if (tk.getType() != HeaderTokenizer.Token.ATOM)		    throw new ParseException("Expected parameter name, " +					    "got \"" + tk.getValue() + "\"");		name = tk.getValue().toLowerCase(Locale.ENGLISH);		// expect '='		tk = h.next();		if ((char)tk.getType() != '=')		    throw new ParseException("Expected '=', " +					    "got \"" + tk.getValue() + "\"");		// expect parameter value		tk = h.next();		type = tk.getType();		// parameter value must be a MIME Atom or Quoted String		if (type != HeaderTokenizer.Token.ATOM &&		    type != HeaderTokenizer.Token.QUOTEDSTRING)		    throw new ParseException("Expected parameter value, " +					    "got \"" + tk.getValue() + "\"");		value = tk.getValue();		lastName = name;		if (decodeParameters)		    putEncodedName(name, value);		else		    list.put(name, value);            } else {		// MWB 3BView new code to add in filenames generated by 		// AppleMail.		// Note - one space is assumed between name elements.		// This may not be correct but it shouldn't matter too much.		// Note: AppleMail encodes filenames with non-ascii characters 		// correctly, so we don't need to worry about the name* subkeys.		if (applehack && type == HeaderTokenizer.Token.ATOM &&			lastName != null &&			(lastName.equals("name") ||			 lastName.equals("filename"))) {		    // Add value to previous value		    String lastValue = (String)list.get(lastName);		    value = lastValue + " " + tk.getValue();		    list.put(lastName, value);                } else {		    throw new ParseException("Expected ';', " +					    "got \"" + tk.getValue() + "\"");		}	    }        }	if (decodeParameters) {	    /*	     * After parsing all the parameters, combine all the	     * multi-segment parameter values together.	     */	    combineMultisegmentNames(false);	}    }    /**     * If the name is an encoded or multi-segment name (or both)     * handle it appropriately, storing the appropriate String     * or Value object.  Multi-segment names are stored in the     * main parameter list as an emtpy string as a placeholder,     * replaced later in combineMultisegmentNames with a MultiValue     * object.  This causes all pieces of the multi-segment parameter     * to appear in the position of the first seen segment of the     * parameter.     */    private void putEncodedName(String name, String value)				throws ParseException {	int star = name.indexOf('*');	if (star < 0) {	    // single parameter, unencoded value	    list.put(name, value);	} else if (star == name.length() - 1) {	    // single parameter, encoded value	    name = name.substring(0, star);	    list.put(name, decodeValue(value));	} else {	    // multiple segments	    String rname = name.substring(0, star);	    multisegmentNames.add(rname);	    list.put(rname, "");	    Object v;	    if (name.endsWith("*")) {		// encoded value		v = new Value();		((Value)v).encodedValue = value;		((Value)v).value = value;	// default; decoded later		name = name.substring(0, name.length() - 1);	    } else {		// unencoded value		v = value;	    }	    slist.put(name, v);	}    }    /**     * Iterate through the saved set of names of multi-segment parameters,     * for each parameter find all segments stored in the slist map,     * decode each segment as needed, combine the segments together into     * a single decoded value, and save all segments in a MultiValue object     * in the main list indexed by the parameter name.     */    private void combineMultisegmentNames(boolean keepConsistentOnFailure)				throws ParseException {	boolean success = false;	try {	    Iterator it = multisegmentNames.iterator();	    while (it.hasNext()) {		String name = (String)it.next();		StringBuffer sb = new StringBuffer();		MultiValue mv = new MultiValue();		/*		 * Now find all the segments for this name and		 * decode each segment as needed.		 */		String charset = null;		int segment;		for (segment = 0; ; segment++) {		    String sname = name + "*" + segment;		    Object v = slist.get(sname);		    if (v == null)	// out of segments			break;		    mv.add(v);		    String value = null;		    if (v instanceof Value) {			try {			    Value vv = (Value)v;			    String evalue = vv.encodedValue;			    value = evalue;		// in case of exception			    if (segment == 0) {				// the first segment specified the charset				// for all other encoded segments				Value vnew = decodeValue(evalue);				charset = vv.charset = vnew.charset;				value = vv.value = vnew.value;			    } else {				if (charset == null) {				    // should never happen				    multisegmentNames.remove(name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -