src/share/jaf_classes/javax/activation/MimeTypeParameterList.java

Wed, 27 Apr 2016 01:27:09 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:27:09 +0800
changeset 0
373ffda63c9a
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17

     1 /*
     2  * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package javax.activation;
    28 import java.util.Hashtable;
    29 import java.util.Enumeration;
    30 import java.util.Locale;
    32 /**
    33  * A parameter list of a MimeType
    34  * as defined in RFC 2045 and 2046. The Primary type of the
    35  * object must already be stripped off.
    36  *
    37  * @see javax.activation.MimeType
    38  *
    39  * @since 1.6
    40  */
    41 public class MimeTypeParameterList {
    42     private Hashtable parameters;
    44     /**
    45      * A string that holds all the special chars.
    46      */
    47     private static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
    50     /**
    51      * Default constructor.
    52      */
    53     public MimeTypeParameterList() {
    54         parameters = new Hashtable();
    55     }
    57     /**
    58      * Constructs a new MimeTypeParameterList with the passed in data.
    59      *
    60      * @param parameterList an RFC 2045, 2046 compliant parameter list.
    61      */
    62     public MimeTypeParameterList(String parameterList)
    63                                         throws MimeTypeParseException {
    64         parameters = new Hashtable();
    66         //    now parse rawdata
    67         parse(parameterList);
    68     }
    70     /**
    71      * A routine for parsing the parameter list out of a String.
    72      *
    73      * @param parameterList an RFC 2045, 2046 compliant parameter list.
    74      */
    75     protected void parse(String parameterList) throws MimeTypeParseException {
    76         if (parameterList == null)
    77             return;
    79         int length = parameterList.length();
    80         if (length <= 0)
    81             return;
    83         int i;
    84         char c;
    85         for (i = skipWhiteSpace(parameterList, 0);
    86                 i < length && (c = parameterList.charAt(i)) == ';';
    87                 i = skipWhiteSpace(parameterList, i)) {
    88             int lastIndex;
    89             String name;
    90             String value;
    92             //    eat the ';'
    93             i++;
    95             //    now parse the parameter name
    97             //    skip whitespace
    98             i = skipWhiteSpace(parameterList, i);
   100             // tolerate trailing semicolon, even though it violates the spec
   101             if (i >= length)
   102                 return;
   104             //    find the end of the token char run
   105             lastIndex = i;
   106             while ((i < length) && isTokenChar(parameterList.charAt(i)))
   107                 i++;
   109             name = parameterList.substring(lastIndex, i).
   110                                                 toLowerCase(Locale.ENGLISH);
   112             //    now parse the '=' that separates the name from the value
   113             i = skipWhiteSpace(parameterList, i);
   115             if (i >= length || parameterList.charAt(i) != '=')
   116                 throw new MimeTypeParseException(
   117                     "Couldn't find the '=' that separates a " +
   118                     "parameter name from its value.");
   120             //    eat it and parse the parameter value
   121             i++;
   122             i = skipWhiteSpace(parameterList, i);
   124             if (i >= length)
   125                 throw new MimeTypeParseException(
   126                         "Couldn't find a value for parameter named " + name);
   128             //    now find out whether or not we have a quoted value
   129             c = parameterList.charAt(i);
   130             if (c == '"') {
   131                 //    yup it's quoted so eat it and capture the quoted string
   132                 i++;
   133                 if (i >= length)
   134                     throw new MimeTypeParseException(
   135                             "Encountered unterminated quoted parameter value.");
   137                 lastIndex = i;
   139                 //    find the next unescaped quote
   140                 while (i < length) {
   141                     c = parameterList.charAt(i);
   142                     if (c == '"')
   143                         break;
   144                     if (c == '\\') {
   145                         //    found an escape sequence
   146                         //    so skip this and the
   147                         //    next character
   148                         i++;
   149                     }
   150                     i++;
   151                 }
   152                 if (c != '"')
   153                     throw new MimeTypeParseException(
   154                         "Encountered unterminated quoted parameter value.");
   156                 value = unquote(parameterList.substring(lastIndex, i));
   157                 //    eat the quote
   158                 i++;
   159             } else if (isTokenChar(c)) {
   160                 //    nope it's an ordinary token so it
   161                 //    ends with a non-token char
   162                 lastIndex = i;
   163                 while (i < length && isTokenChar(parameterList.charAt(i)))
   164                     i++;
   165                 value = parameterList.substring(lastIndex, i);
   166             } else {
   167                 //    it ain't a value
   168                 throw new MimeTypeParseException(
   169                         "Unexpected character encountered at index " + i);
   170             }
   172             //    now put the data into the hashtable
   173             parameters.put(name, value);
   174         }
   175         if (i < length) {
   176             throw new MimeTypeParseException(
   177                 "More characters encountered in input than expected.");
   178         }
   179     }
   181     /**
   182      * Return the number of name-value pairs in this list.
   183      *
   184      * @return  the number of parameters
   185      */
   186     public int size() {
   187         return parameters.size();
   188     }
   190     /**
   191      * Determine whether or not this list is empty.
   192      *
   193      * @return  true if there are no parameters
   194      */
   195     public boolean isEmpty() {
   196         return parameters.isEmpty();
   197     }
   199     /**
   200      * Retrieve the value associated with the given name, or null if there
   201      * is no current association.
   202      *
   203      * @param name      the parameter name
   204      * @return          the parameter's value
   205      */
   206     public String get(String name) {
   207         return (String)parameters.get(name.trim().toLowerCase(Locale.ENGLISH));
   208     }
   210     /**
   211      * Set the value to be associated with the given name, replacing
   212      * any previous association.
   213      *
   214      * @param name      the parameter name
   215      * @param value     the parameter's value
   216      */
   217     public void set(String name, String value) {
   218         parameters.put(name.trim().toLowerCase(Locale.ENGLISH), value);
   219     }
   221     /**
   222      * Remove any value associated with the given name.
   223      *
   224      * @param name      the parameter name
   225      */
   226     public void remove(String name) {
   227         parameters.remove(name.trim().toLowerCase(Locale.ENGLISH));
   228     }
   230     /**
   231      * Retrieve an enumeration of all the names in this list.
   232      *
   233      * @return  an enumeration of all parameter names
   234      */
   235     public Enumeration getNames() {
   236         return parameters.keys();
   237     }
   239     /**
   240      * Return a string representation of this object.
   241      */
   242     public String toString() {
   243         StringBuffer buffer = new StringBuffer();
   244         buffer.ensureCapacity(parameters.size() * 16);
   245                         //    heuristic: 8 characters per field
   247         Enumeration keys = parameters.keys();
   248         while (keys.hasMoreElements()) {
   249             String key = (String)keys.nextElement();
   250             buffer.append("; ");
   251             buffer.append(key);
   252             buffer.append('=');
   253             buffer.append(quote((String)parameters.get(key)));
   254         }
   256         return buffer.toString();
   257     }
   259     //    below here be scary parsing related things
   261     /**
   262      * Determine whether or not a given character belongs to a legal token.
   263      */
   264     private static boolean isTokenChar(char c) {
   265         return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
   266     }
   268     /**
   269      * return the index of the first non white space character in
   270      * rawdata at or after index i.
   271      */
   272     private static int skipWhiteSpace(String rawdata, int i) {
   273         int length = rawdata.length();
   274         while ((i < length) && Character.isWhitespace(rawdata.charAt(i)))
   275             i++;
   276         return i;
   277     }
   279     /**
   280      * A routine that knows how and when to quote and escape the given value.
   281      */
   282     private static String quote(String value) {
   283         boolean needsQuotes = false;
   285         //    check to see if we actually have to quote this thing
   286         int length = value.length();
   287         for (int i = 0; (i < length) && !needsQuotes; i++) {
   288             needsQuotes = !isTokenChar(value.charAt(i));
   289         }
   291         if (needsQuotes) {
   292             StringBuffer buffer = new StringBuffer();
   293             buffer.ensureCapacity((int)(length * 1.5));
   295             //    add the initial quote
   296             buffer.append('"');
   298             //    add the properly escaped text
   299             for (int i = 0; i < length; ++i) {
   300                 char c = value.charAt(i);
   301                 if ((c == '\\') || (c == '"'))
   302                     buffer.append('\\');
   303                 buffer.append(c);
   304             }
   306             //    add the closing quote
   307             buffer.append('"');
   309             return buffer.toString();
   310         } else {
   311             return value;
   312         }
   313     }
   315     /**
   316      * A routine that knows how to strip the quotes and
   317      * escape sequences from the given value.
   318      */
   319     private static String unquote(String value) {
   320         int valueLength = value.length();
   321         StringBuffer buffer = new StringBuffer();
   322         buffer.ensureCapacity(valueLength);
   324         boolean escaped = false;
   325         for (int i = 0; i < valueLength; ++i) {
   326             char currentChar = value.charAt(i);
   327             if (!escaped && (currentChar != '\\')) {
   328                 buffer.append(currentChar);
   329             } else if (escaped) {
   330                 buffer.append(currentChar);
   331                 escaped = false;
   332             } else {
   333                 escaped = true;
   334             }
   335         }
   337         return buffer.toString();
   338     }
   339 }

mercurial