PageRenderTime 60ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/momock-ext-email/src/javax/activation/MimeTypeParameterList.java

https://github.com/midnightjuly/momock-android
Java | 352 lines | 246 code | 28 blank | 78 comment | 32 complexity | e94f77b8152b135bccc6ef8641e089bf MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
  5. *
  6. * The contents of this file are subject to the terms of either the GNU
  7. * General Public License Version 2 only ("GPL") or the Common Development
  8. * and Distribution License("CDDL") (collectively, the "License"). You
  9. * may not use this file except in compliance with the License. You can obtain
  10. * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
  11. * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
  12. * language governing permissions and limitations under the License.
  13. *
  14. * When distributing the software, include this License Header Notice in each
  15. * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
  16. * Sun designates this particular file as subject to the "Classpath" exception
  17. * as provided by Sun in the GPL Version 2 section of the License file that
  18. * accompanied this code. If applicable, add the following below the License
  19. * Header, with the fields enclosed by brackets [] replaced by your own
  20. * identifying information: "Portions Copyrighted [year]
  21. * [name of copyright owner]"
  22. *
  23. * Contributor(s):
  24. *
  25. * If you wish your version of this file to be governed by only the CDDL or
  26. * only the GPL Version 2, indicate your decision by adding "[Contributor]
  27. * elects to include this software in this distribution under the [CDDL or GPL
  28. * Version 2] license." If you don't indicate a single choice of license, a
  29. * recipient has the option to distribute your version of this file under
  30. * either the CDDL, the GPL Version 2 or to extend the choice of license to
  31. * its licensees as provided above. However, if you add GPL Version 2 code
  32. * and therefore, elected the GPL Version 2 license, then the option applies
  33. * only if the new code is made subject to such option by the copyright
  34. * holder.
  35. */
  36. /*
  37. * @(#)MimeTypeParameterList.java 1.13 07/05/14
  38. */
  39. package javax.activation;
  40. import java.util.Hashtable;
  41. import java.util.Enumeration;
  42. import java.util.Locale;
  43. /**
  44. * A parameter list of a MimeType
  45. * as defined in RFC 2045 and 2046. The Primary type of the
  46. * object must already be stripped off.
  47. *
  48. * @see javax.activation.MimeType
  49. */
  50. public class MimeTypeParameterList {
  51. private Hashtable parameters;
  52. /**
  53. * A string that holds all the special chars.
  54. */
  55. private static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
  56. /**
  57. * Default constructor.
  58. */
  59. public MimeTypeParameterList() {
  60. parameters = new Hashtable();
  61. }
  62. /**
  63. * Constructs a new MimeTypeParameterList with the passed in data.
  64. *
  65. * @param parameterList an RFC 2045, 2046 compliant parameter list.
  66. */
  67. public MimeTypeParameterList(String parameterList)
  68. throws MimeTypeParseException {
  69. parameters = new Hashtable();
  70. // now parse rawdata
  71. parse(parameterList);
  72. }
  73. /**
  74. * A routine for parsing the parameter list out of a String.
  75. *
  76. * @param parameterList an RFC 2045, 2046 compliant parameter list.
  77. */
  78. protected void parse(String parameterList) throws MimeTypeParseException {
  79. if (parameterList == null)
  80. return;
  81. int length = parameterList.length();
  82. if (length <= 0)
  83. return;
  84. int i;
  85. char c;
  86. for (i = skipWhiteSpace(parameterList, 0);
  87. i < length && (c = parameterList.charAt(i)) == ';';
  88. i = skipWhiteSpace(parameterList, i)) {
  89. int lastIndex;
  90. String name;
  91. String value;
  92. // eat the ';'
  93. i++;
  94. // now parse the parameter name
  95. // skip whitespace
  96. i = skipWhiteSpace(parameterList, i);
  97. // tolerate trailing semicolon, even though it violates the spec
  98. if (i >= length)
  99. return;
  100. // find the end of the token char run
  101. lastIndex = i;
  102. while ((i < length) && isTokenChar(parameterList.charAt(i)))
  103. i++;
  104. name = parameterList.substring(lastIndex, i).
  105. toLowerCase(Locale.ENGLISH);
  106. // now parse the '=' that separates the name from the value
  107. i = skipWhiteSpace(parameterList, i);
  108. if (i >= length || parameterList.charAt(i) != '=')
  109. throw new MimeTypeParseException(
  110. "Couldn't find the '=' that separates a " +
  111. "parameter name from its value.");
  112. // eat it and parse the parameter value
  113. i++;
  114. i = skipWhiteSpace(parameterList, i);
  115. if (i >= length)
  116. throw new MimeTypeParseException(
  117. "Couldn't find a value for parameter named " + name);
  118. // now find out whether or not we have a quoted value
  119. c = parameterList.charAt(i);
  120. if (c == '"') {
  121. // yup it's quoted so eat it and capture the quoted string
  122. i++;
  123. if (i >= length)
  124. throw new MimeTypeParseException(
  125. "Encountered unterminated quoted parameter value.");
  126. lastIndex = i;
  127. // find the next unescaped quote
  128. while (i < length) {
  129. c = parameterList.charAt(i);
  130. if (c == '"')
  131. break;
  132. if (c == '\\') {
  133. // found an escape sequence
  134. // so skip this and the
  135. // next character
  136. i++;
  137. }
  138. i++;
  139. }
  140. if (c != '"')
  141. throw new MimeTypeParseException(
  142. "Encountered unterminated quoted parameter value.");
  143. value = unquote(parameterList.substring(lastIndex, i));
  144. // eat the quote
  145. i++;
  146. } else if (isTokenChar(c)) {
  147. // nope it's an ordinary token so it
  148. // ends with a non-token char
  149. lastIndex = i;
  150. while (i < length && isTokenChar(parameterList.charAt(i)))
  151. i++;
  152. value = parameterList.substring(lastIndex, i);
  153. } else {
  154. // it ain't a value
  155. throw new MimeTypeParseException(
  156. "Unexpected character encountered at index " + i);
  157. }
  158. // now put the data into the hashtable
  159. parameters.put(name, value);
  160. }
  161. if (i < length) {
  162. throw new MimeTypeParseException(
  163. "More characters encountered in input than expected.");
  164. }
  165. }
  166. /**
  167. * Return the number of name-value pairs in this list.
  168. *
  169. * @return the number of parameters
  170. */
  171. public int size() {
  172. return parameters.size();
  173. }
  174. /**
  175. * Determine whether or not this list is empty.
  176. *
  177. * @return true if there are no parameters
  178. */
  179. public boolean isEmpty() {
  180. return parameters.isEmpty();
  181. }
  182. /**
  183. * Retrieve the value associated with the given name, or null if there
  184. * is no current association.
  185. *
  186. * @param name the parameter name
  187. * @return the parameter's value
  188. */
  189. public String get(String name) {
  190. return (String)parameters.get(name.trim().toLowerCase(Locale.ENGLISH));
  191. }
  192. /**
  193. * Set the value to be associated with the given name, replacing
  194. * any previous association.
  195. *
  196. * @param name the parameter name
  197. * @param value the parameter's value
  198. */
  199. public void set(String name, String value) {
  200. parameters.put(name.trim().toLowerCase(Locale.ENGLISH), value);
  201. }
  202. /**
  203. * Remove any value associated with the given name.
  204. *
  205. * @param name the parameter name
  206. */
  207. public void remove(String name) {
  208. parameters.remove(name.trim().toLowerCase(Locale.ENGLISH));
  209. }
  210. /**
  211. * Retrieve an enumeration of all the names in this list.
  212. *
  213. * @return an enumeration of all parameter names
  214. */
  215. public Enumeration getNames() {
  216. return parameters.keys();
  217. }
  218. /**
  219. * Return a string representation of this object.
  220. */
  221. public String toString() {
  222. StringBuffer buffer = new StringBuffer();
  223. buffer.ensureCapacity(parameters.size() * 16);
  224. // heuristic: 8 characters per field
  225. Enumeration keys = parameters.keys();
  226. while (keys.hasMoreElements()) {
  227. String key = (String)keys.nextElement();
  228. buffer.append("; ");
  229. buffer.append(key);
  230. buffer.append('=');
  231. buffer.append(quote((String)parameters.get(key)));
  232. }
  233. return buffer.toString();
  234. }
  235. // below here be scary parsing related things
  236. /**
  237. * Determine whether or not a given character belongs to a legal token.
  238. */
  239. private static boolean isTokenChar(char c) {
  240. return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
  241. }
  242. /**
  243. * return the index of the first non white space character in
  244. * rawdata at or after index i.
  245. */
  246. private static int skipWhiteSpace(String rawdata, int i) {
  247. int length = rawdata.length();
  248. while ((i < length) && Character.isWhitespace(rawdata.charAt(i)))
  249. i++;
  250. return i;
  251. }
  252. /**
  253. * A routine that knows how and when to quote and escape the given value.
  254. */
  255. private static String quote(String value) {
  256. boolean needsQuotes = false;
  257. // check to see if we actually have to quote this thing
  258. int length = value.length();
  259. for (int i = 0; (i < length) && !needsQuotes; i++) {
  260. needsQuotes = !isTokenChar(value.charAt(i));
  261. }
  262. if (needsQuotes) {
  263. StringBuffer buffer = new StringBuffer();
  264. buffer.ensureCapacity((int)(length * 1.5));
  265. // add the initial quote
  266. buffer.append('"');
  267. // add the properly escaped text
  268. for (int i = 0; i < length; ++i) {
  269. char c = value.charAt(i);
  270. if ((c == '\\') || (c == '"'))
  271. buffer.append('\\');
  272. buffer.append(c);
  273. }
  274. // add the closing quote
  275. buffer.append('"');
  276. return buffer.toString();
  277. } else {
  278. return value;
  279. }
  280. }
  281. /**
  282. * A routine that knows how to strip the quotes and
  283. * escape sequences from the given value.
  284. */
  285. private static String unquote(String value) {
  286. int valueLength = value.length();
  287. StringBuffer buffer = new StringBuffer();
  288. buffer.ensureCapacity(valueLength);
  289. boolean escaped = false;
  290. for (int i = 0; i < valueLength; ++i) {
  291. char currentChar = value.charAt(i);
  292. if (!escaped && (currentChar != '\\')) {
  293. buffer.append(currentChar);
  294. } else if (escaped) {
  295. buffer.append(currentChar);
  296. escaped = false;
  297. } else {
  298. escaped = true;
  299. }
  300. }
  301. return buffer.toString();
  302. }
  303. }