001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.safehaus.asyncweb.common;
021:
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Collections;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.TreeMap;
029: import java.util.TreeSet;
030:
031: import org.safehaus.asyncweb.codec.HttpCodecUtils;
032: import org.safehaus.asyncweb.common.content.EmptyContent;
033: import org.safehaus.asyncweb.util.HttpHeaderConstants;
034:
035: /**
036: * A default implementation of {@link MutableHttpMessage}.
037: *
038: * @author trustin
039: * @version $Rev: 240 $, $Date: 2007-09-26 14:53:47 -0700 (Wed, 26 Sep 2007) $
040: */
041: public class DefaultHttpMessage implements MutableHttpMessage {
042:
043: private static final long serialVersionUID = -7559479748566065541L;
044:
045: private HttpVersion protocolVersion = HttpVersion.HTTP_1_1;
046: private final Map<String, List<String>> headers = new TreeMap<String, List<String>>(
047: HeaderNameComparator.INSTANCE);
048: private final Set<Cookie> cookies = new TreeSet<Cookie>(
049: CookieComparator.INSTANCE);
050: private Content content = EmptyContent.INSTANCE;
051:
052: public HttpVersion getProtocolVersion() {
053: return protocolVersion;
054: }
055:
056: public void setProtocolVersion(HttpVersion protocolVersion) {
057: if (protocolVersion == null) {
058: throw new NullPointerException("protocolVersion");
059: }
060: this .protocolVersion = protocolVersion;
061: }
062:
063: public boolean containsHeader(String name) {
064: return headers.containsKey(name);
065: }
066:
067: public String getHeader(String name) {
068: List<String> values = headers.get(name);
069: if (values == null) {
070: return null;
071: }
072:
073: return values.get(0);
074: }
075:
076: public Map<String, List<String>> getHeaders() {
077: return Collections.unmodifiableMap(headers);
078: }
079:
080: public void addHeader(String name, String value) {
081: validateHeaderName(name);
082: if (value == null) {
083: throw new NullPointerException("value");
084: }
085:
086: List<String> values = headers.get(name);
087: if (values == null) {
088: values = new ArrayList<String>();
089: headers.put(name, values);
090: }
091: values.add(value);
092: }
093:
094: public boolean removeHeader(String name) {
095: return headers.remove(name) != null;
096: }
097:
098: public void setHeader(String name, String value) {
099: validateHeaderName(name);
100: if (value == null) {
101: throw new NullPointerException("value");
102: }
103:
104: List<String> values = new ArrayList<String>();
105: values.add(value);
106: headers.put(name, values);
107: }
108:
109: public void setHeaders(Map<String, List<String>> headers) {
110: clearHeaders();
111:
112: for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
113: validateHeaderName(entry.getKey());
114: for (String value : entry.getValue()) {
115: if (value == null) {
116: throw new NullPointerException("Header '"
117: + entry.getKey() + "' contains null.");
118: }
119: }
120: if (entry.getValue().size() > 0) {
121: this .headers.put(entry.getKey(), entry.getValue());
122: }
123: }
124: }
125:
126: public void clearHeaders() {
127: this .headers.clear();
128: }
129:
130: public String getContentType() {
131: return getHeader("Content-Type");
132: }
133:
134: public void setContentType(String type) {
135: setHeader("Content-Type", type);
136: }
137:
138: public boolean isKeepAlive() {
139: String connection = getHeader(HttpHeaderConstants.KEY_CONNECTION);
140: if (getProtocolVersion() == HttpVersion.HTTP_1_1) {
141: return !HttpHeaderConstants.VALUE_CLOSE
142: .equalsIgnoreCase(connection);
143: } else {
144: return HttpHeaderConstants.VALUE_KEEP_ALIVE
145: .equalsIgnoreCase(connection);
146: }
147: }
148:
149: public void setKeepAlive(boolean keepAlive) {
150: setHeader(HttpHeaderConstants.KEY_CONNECTION,
151: keepAlive ? HttpHeaderConstants.VALUE_KEEP_ALIVE
152: : HttpHeaderConstants.VALUE_CLOSE);
153: }
154:
155: public Content getContent() {
156: return content;
157: }
158:
159: public void setContent(Content content) {
160: if (content == null) {
161: this .content = EmptyContent.INSTANCE;
162: } else {
163: this .content = content;
164: }
165: }
166:
167: public void removeCookie(String name) {
168: cookies.remove(name);
169: }
170:
171: public void addCookie(Cookie cookie) {
172: cookies.add(cookie);
173: }
174:
175: public boolean removeCookie(Cookie cookie) {
176: return cookies.remove(cookie);
177: }
178:
179: public void setCookies(Collection<Cookie> cookies) {
180: clearCookies();
181:
182: for (Cookie c : cookies) {
183: if (c == null) {
184: throw new NullPointerException("cookies contains null.");
185: }
186: this .cookies.add(c);
187: }
188: }
189:
190: public void clearCookies() {
191: this .cookies.clear();
192: }
193:
194: public Set<Cookie> getCookies() {
195: return Collections.unmodifiableSet(cookies);
196: }
197:
198: private static void validateHeaderName(String name) {
199: if (name == null) {
200: throw new NullPointerException("name");
201: }
202:
203: for (int i = 0; i < name.length(); i++) {
204: char c = name.charAt(i);
205: if (c > 127) {
206: throw new IllegalArgumentException(
207: "Name contains an illegal character: " + name);
208: }
209:
210: byte b = (byte) c;
211: if (HttpCodecUtils.isHttpControl(b)
212: || HttpCodecUtils.isHttpSeparator(b)) {
213: throw new IllegalArgumentException(
214: "Name contains an illegal character: " + name);
215: }
216: }
217: }
218: }
|