001: // Copyright 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.util;
016:
017: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
018:
019: import java.util.List;
020: import java.util.Map;
021: import java.util.StringTokenizer;
022:
023: import org.apache.tapestry.ioc.internal.util.Defense;
024: import org.apache.tapestry.ioc.internal.util.InternalUtils;
025:
026: /**
027: * Represents an HTTP content type. Allows to set various elements like the mime type, the character
028: * set, and other parameters. This is similar to a number of other implementations of the same
029: * concept in JAF, etc. We have created this simple implementation to avoid including the whole
030: * libraries.
031: */
032: public final class ContentType {
033: private String _baseType = "";
034:
035: private String _subType = "";
036:
037: private final Map<String, String> _parameters = newCaseInsensitiveMap();
038:
039: /**
040: * Creates a new empty content type.
041: */
042: public ContentType() {
043: }
044:
045: /**
046: * Creates a new content type from the argument. The format of the argument has to be
047: * basetype/subtype(;key=value)*
048: *
049: * @param contentType
050: * the content type that needs to be represented
051: */
052: public ContentType(String contentType) {
053: this ();
054: parse(contentType);
055: }
056:
057: /**
058: * Returns true only if the other object is another instance of ContentType, and has the ssame
059: * baseType, subType and set of parameters.
060: */
061: @Override
062: public boolean equals(Object o) {
063: if (o == null)
064: return false;
065:
066: if (o.getClass() != this .getClass())
067: return false;
068:
069: ContentType ct = (ContentType) o;
070:
071: return _baseType.equals(ct._baseType)
072: && _subType.equals(ct._subType)
073: && _parameters.equals(ct._parameters);
074: }
075:
076: /**
077: * @return the base type of the content type
078: */
079: public String getBaseType() {
080: return _baseType;
081: }
082:
083: /**
084: * @param baseType
085: */
086: public void setBaseType(String baseType) {
087: Defense.notNull(baseType, "baseType");
088:
089: _baseType = baseType;
090: }
091:
092: /**
093: * @return the sub-type of the content type
094: */
095: public String getSubType() {
096: return _subType;
097: }
098:
099: /**
100: * @param subType
101: */
102: public void setSubType(String subType) {
103: Defense.notNull(subType, "subType");
104:
105: _subType = subType;
106: }
107:
108: /**
109: * @return the MIME type of the content type
110: */
111: public String getMimeType() {
112: return _baseType + "/" + _subType;
113: }
114:
115: /**
116: * @return the list of names of parameters in this content type, in alphabetical order.
117: */
118: public List<String> getParameterNames() {
119: return InternalUtils.sortedKeys(_parameters);
120: }
121:
122: /**
123: * @param key
124: * the name of the content type parameter
125: * @return the value of the content type parameter
126: */
127: public String getParameter(String key) {
128: Defense.notNull(key, "key");
129:
130: return _parameters.get(key);
131: }
132:
133: /**
134: * @param key
135: * the name of the content type parameter
136: * @param value
137: * the value of the content type parameter
138: */
139: public void setParameter(String key, String value) {
140: Defense.notNull(key, "key");
141: Defense.notNull(value, "value");
142:
143: _parameters.put(key, value);
144: }
145:
146: /**
147: * Parses the argument and configures the content type accordingly. The format of the argument
148: * has to be type/subtype(;key=value)*
149: *
150: * @param contentType
151: * the content type that needs to be represented
152: */
153: public void parse(String contentType) {
154: _baseType = "";
155: _subType = "";
156: _parameters.clear();
157:
158: StringTokenizer tokens = new StringTokenizer(contentType, ";");
159: if (!tokens.hasMoreTokens())
160: return;
161:
162: String mimeType = tokens.nextToken();
163: StringTokenizer mimeTokens = new StringTokenizer(mimeType, "/");
164: setBaseType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken()
165: : "");
166: setSubType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken()
167: : "");
168:
169: while (tokens.hasMoreTokens()) {
170: String parameter = tokens.nextToken();
171:
172: StringTokenizer parameterTokens = new StringTokenizer(
173: parameter, "=");
174: String key = parameterTokens.hasMoreTokens() ? parameterTokens
175: .nextToken()
176: : "";
177: String value = parameterTokens.hasMoreTokens() ? parameterTokens
178: .nextToken()
179: : "";
180: setParameter(key, value);
181: }
182: }
183:
184: /**
185: * @return the string representation of this content type
186: */
187: public String unparse() {
188: StringBuilder buffer = new StringBuilder(getMimeType());
189:
190: for (String parameterName : getParameterNames()) {
191: buffer.append(";");
192: buffer.append(parameterName);
193: buffer.append("=");
194: buffer.append(_parameters.get(parameterName));
195: }
196:
197: return buffer.toString();
198: }
199:
200: /**
201: * @return the string representation of this content type. Same as unparse().
202: */
203: @Override
204: public String toString() {
205: return unparse();
206: }
207:
208: }
|