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

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

mercurial