Class ParameterList


  • public class ParameterList
    extends java.lang.Object
    This class holds MIME parameters (attribute-value pairs). The mail.mime.encodeparameters and mail.mime.decodeparameters System properties control whether encoded parameters, as specified by RFC 2231, are supported. By default, such encoded parameters are supported.

    Also, in the current implementation, setting the System property mail.mime.decodeparameters.strict to "true" will cause a ParseException to be thrown for errors detected while decoding encoded parameters. By default, if any decoding errors occur, the original (undecoded) string is used.

    The current implementation supports the System property mail.mime.parameters.strict, which if set to false when parsing a parameter list allows parameter values to contain whitespace and other special characters without being quoted; the parameter value ends at the next semicolon. If set to true (the default), parameter values are required to conform to the MIME specification and must be quoted if they contain whitespace or special characters.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  ParameterList.LiteralValue
      A struct to hold a literal value that shouldn't be further encoded.
      private static class  ParameterList.MultiValue
      A struct for a multi-segment parameter.
      private static class  ParameterList.ParamEnum
      Map the LinkedHashMap's keySet iterator to an Enumeration.
      private static class  ParameterList.ToStringBuffer
      A special wrapper for a StringBuffer that keeps track of the number of characters used in a line, wrapping to a new line as necessary; for use by the toString method.
      private static class  ParameterList.Value
      A struct to hold an encoded value.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static boolean applehack  
      private static boolean decodeParameters  
      private static boolean decodeParametersStrict  
      private static boolean encodeParameters  
      private static char[] hex  
      private java.lang.String lastName
      MWB 3BView: The name of the last parameter added to the map.
      private java.util.Map<java.lang.String,​java.lang.Object> list
      The map of name, value pairs.
      private java.util.Set<java.lang.String> multisegmentNames
      A set of names for multi-segment parameters that we haven't processed yet.
      private static boolean parametersStrict  
      private java.util.Map<java.lang.String,​java.lang.Object> slist
      A map containing the segments for all not-yet-processed multi-segment parameters.
      private static boolean splitLongParameters  
      private static boolean windowshack  
    • Constructor Summary

      Constructors 
      Constructor Description
      ParameterList()
      No-arg Constructor.
      ParameterList​(java.lang.String s)
      Constructor that takes a parameter-list string.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private void combineMultisegmentNames​(boolean keepConsistentOnFailure)
      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.
      void combineSegments()
      Normal users of this class will use simple parameter names.
      private static void decodeBytes​(java.lang.String value, java.io.OutputStream os)
      Decode the encoded bytes in value and write them to the OutputStream.
      private static java.lang.String decodeBytes​(java.lang.String value, java.lang.String charset)
      Decode the encoded bytes in value using the specified charset.
      private static ParameterList.Value encodeValue​(java.lang.String value, java.lang.String charset)
      Encode a parameter value, if necessary.
      private static ParameterList.Value extractCharset​(java.lang.String value)
      Extract charset and encoded value.
      java.lang.String get​(java.lang.String name)
      Returns the value of the specified parameter.
      java.util.Enumeration<java.lang.String> getNames()
      Return an enumeration of the names of all parameters in this list.
      private void putEncodedName​(java.lang.String name, java.lang.String value)
      If the name is an encoded or multi-segment name (or both) handle it appropriately, storing the appropriate String or Value object.
      private static java.lang.String quote​(java.lang.String value)  
      void remove​(java.lang.String name)
      Removes the specified parameter from this ParameterList.
      void set​(java.lang.String name, java.lang.String value)
      Set a parameter.
      void set​(java.lang.String name, java.lang.String value, java.lang.String charset)
      Set a parameter.
      (package private) void setLiteral​(java.lang.String name, java.lang.String value)
      Package-private method to set a literal value that won't be further encoded.
      int size()
      Return the number of parameters in this list.
      java.lang.String toString()
      Convert this ParameterList into a MIME String.
      java.lang.String toString​(int used)
      Convert this ParameterList into a MIME String.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • list

        private java.util.Map<java.lang.String,​java.lang.Object> list
        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, or a LiteralValue object for strings that should not be encoded. 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.
      • multisegmentNames

        private java.util.Set<java.lang.String> multisegmentNames
        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".
      • slist

        private java.util.Map<java.lang.String,​java.lang.Object> slist
        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 the encoded segments. The segments are hex decoded in order, combined into a single byte array, and converted to a String using the specified charset in the combineMultisegmentNames method.
      • lastName

        private java.lang.String lastName
        MWB 3BView: The name of the last parameter added to the map. Used for the AppleMail hack.
      • encodeParameters

        private static final boolean encodeParameters
      • decodeParameters

        private static final boolean decodeParameters
      • decodeParametersStrict

        private static final boolean decodeParametersStrict
      • applehack

        private static final boolean applehack
      • windowshack

        private static final boolean windowshack
      • parametersStrict

        private static final boolean parametersStrict
      • splitLongParameters

        private static final boolean splitLongParameters
      • hex

        private static final char[] hex
    • Constructor Detail

      • ParameterList

        public ParameterList()
        No-arg Constructor.
      • ParameterList

        public ParameterList​(java.lang.String s)
                      throws ParseException
        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.
        Parameters:
        s - the parameter-list string.
        Throws:
        ParseException - if the parse fails.
    • Method Detail

      • combineSegments

        public void combineSegments()
        Normal users of this class will use simple parameter names. In some cases, for example, when processing IMAP protocol messages, individual segments of a multi-segment name (specified by RFC 2231) will be encountered and passed to the set(java.lang.String, java.lang.String) method. After all these segments are added to this ParameterList, they need to be combined to represent the logical parameter name and value. This method will combine all segments of multi-segment names.

        Normal users should never need to call this method.

        Since:
        JavaMail 1.5
      • putEncodedName

        private void putEncodedName​(java.lang.String name,
                                    java.lang.String value)
                             throws ParseException
        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.
        Throws:
        ParseException
      • combineMultisegmentNames

        private void combineMultisegmentNames​(boolean keepConsistentOnFailure)
                                       throws ParseException
        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.
        Throws:
        ParseException
      • size

        public int size()
        Return the number of parameters in this list.
        Returns:
        number of parameters.
      • get

        public java.lang.String get​(java.lang.String name)
        Returns the value of the specified parameter. Note that parameter names are case-insensitive.
        Parameters:
        name - parameter name.
        Returns:
        Value of the parameter. Returns null if the parameter is not present.
      • set

        public void set​(java.lang.String name,
                        java.lang.String value)
        Set a parameter. If this parameter already exists, it is replaced by this new value.
        Parameters:
        name - name of the parameter.
        value - value of the parameter.
      • set

        public void set​(java.lang.String name,
                        java.lang.String value,
                        java.lang.String charset)
        Set a parameter. If this parameter already exists, it is replaced by this new value. If the mail.mime.encodeparameters System property is true, and the parameter value is non-ASCII, it will be encoded with the specified charset, as specified by RFC 2231.
        Parameters:
        name - name of the parameter.
        value - value of the parameter.
        charset - charset of the parameter value.
        Since:
        JavaMail 1.4
      • setLiteral

        void setLiteral​(java.lang.String name,
                        java.lang.String value)
        Package-private method to set a literal value that won't be further encoded. Used to set the filename parameter when "mail.mime.encodefilename" is true.
        Parameters:
        name - name of the parameter.
        value - value of the parameter.
      • remove

        public void remove​(java.lang.String name)
        Removes the specified parameter from this ParameterList. This method does nothing if the parameter is not present.
        Parameters:
        name - name of the parameter.
      • getNames

        public java.util.Enumeration<java.lang.String> getNames()
        Return an enumeration of the names of all parameters in this list.
        Returns:
        Enumeration of all parameter names in this list.
      • toString

        public java.lang.String toString()
        Convert this ParameterList into a MIME String. If this is an empty list, an empty string is returned.
        Overrides:
        toString in class java.lang.Object
        Returns:
        String
      • toString

        public java.lang.String toString​(int used)
        Convert this ParameterList into a MIME String. If this is an empty list, an empty string is returned. The 'used' parameter specifies the number of character positions already taken up in the field into which the resulting parameter list is to be inserted. It's used to determine where to fold the resulting parameter list.
        Parameters:
        used - number of character positions already used, in the field into which the parameter list is to be inserted.
        Returns:
        String
      • quote

        private static java.lang.String quote​(java.lang.String value)
      • encodeValue

        private static ParameterList.Value encodeValue​(java.lang.String value,
                                                       java.lang.String charset)
        Encode a parameter value, if necessary. If the value is encoded, a Value object is returned. Otherwise, null is returned. XXX - Could return a MultiValue object if parameter value is too long.
      • decodeBytes

        private static java.lang.String decodeBytes​(java.lang.String value,
                                                    java.lang.String charset)
                                             throws ParseException,
                                                    java.io.UnsupportedEncodingException
        Decode the encoded bytes in value using the specified charset.
        Throws:
        ParseException
        java.io.UnsupportedEncodingException
      • decodeBytes

        private static void decodeBytes​(java.lang.String value,
                                        java.io.OutputStream os)
                                 throws ParseException,
                                        java.io.IOException
        Decode the encoded bytes in value and write them to the OutputStream.
        Throws:
        ParseException
        java.io.IOException