/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.eclipse.webdav.http.client; import java.util.Enumeration; import java.util.Hashtable; import org.eclipse.webdav.client.Policy; import org.eclipse.webdav.internal.kernel.utils.Assert; /** * Parses an HTTP Content-Type entity-header field. See section 14.18 of * RFC2068 for more information on this field. * <p> * <b>Note:</b> This class/interface is part of an interim API that is still under * development and expected to change significantly before reaching stability. * It is being made available at this early stage to solicit feedback from pioneering * adopters on the understanding that any code that uses this API will almost * certainly be broken (repeatedly) as the API evolves. * </p> */ public class ContentType { private String contentType; private int position; private boolean foundDelim; private String type; private String subtype; private Hashtable parameters = new Hashtable(5); /** * Parses the given HTTP Content-Type entity-header field. For example, * if the content type is "text/xml; charset="ISO-8859-4"" the type is * "text", the subtype is "xml", and the value of the attribute "charset" * is "ISO-8859-4". * * @param contentType the value of the content type field to parse * @throws IllegalArgumentException if the content type is * malformed */ public ContentType(String contentType) throws IllegalArgumentException { Assert.isNotNull(contentType); this.contentType = contentType; position = 0; parse(); } private void checkPosition() throws IllegalArgumentException { if (position >= contentType.length()) illegalArgument(); } /** * Returns an <code>Enumeration</code> of this content type's attributes. * For example, if the content type is "text/xml; charset="ISO-8859-4"", * it has one attribute namely, "charset". * * @return an <code>Enumeration</code> of <code>String</code>s */ public Enumeration getAttributes() { return parameters.keys(); } /** * Returns this content type's subtype. For example, if the content type * is "text/xml; charset="ISO-8859-4"", the the subtype is "xml". * * @return this content type's subtype */ public String getSubtype() { return subtype; } /** * Returns this content type's type. For example, if the content type is * "text/xml; charset="ISO-8859-4"", the the type is "text". * * @return this content type's type */ public String getType() { return type; } /** * Returns the value of the given attribute for this content type. For * example, if the content type is "text/xml; charset="ISO-8859-4"", then * the value for the attribute "charset" is "IS-8859-4". * * @return the value of the given attribute for this content type */ public String getValue(String attribute) { return (String) parameters.get(attribute); } private void illegalArgument() throws IllegalArgumentException { throw new IllegalArgumentException(Policy.bind("exception.malformedContentType", contentType)); //$NON-NLS-1$ } private String nextToken(char delim, boolean trim) throws IllegalArgumentException { int start = position; int end = start; boolean done = false; boolean trimming = false; while (!done) { if (position == contentType.length()) { done = true; foundDelim = false; } else { char c = contentType.charAt(position); if (Character.isWhitespace(c)) { if (trim) { trimming = true; } else { illegalArgument(); } } else { if (c == delim) { done = true; foundDelim = true; } else { if (trimming) { illegalArgument(); } end = position + 1; } } ++position; } } return contentType.substring(start, end); } private void parse() throws IllegalArgumentException { checkPosition(); skipWhiteSpace(); checkPosition(); type = nextToken('/', false); checkPosition(); subtype = nextToken(';', true); skipWhiteSpace(); if (foundDelim) { checkPosition(); } while (position < contentType.length()) { String attribute = nextToken('=', false); checkPosition(); String value = nextToken(';', true); if (value.startsWith("\"") && value.endsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$ value = value.substring(1, value.length() - 1); } skipWhiteSpace(); if (foundDelim) { checkPosition(); } parameters.put(attribute, value); } } private void skipWhiteSpace() { while (position < contentType.length() && Character.isWhitespace(contentType.charAt(position))) { ++position; } } }