001: /* ====================================================================
002: The Jicarilla Software License
003:
004: Copyright (c) 2003 Leo Simons.
005: All rights reserved.
006:
007: Permission is hereby granted, free of charge, to any person obtaining
008: a copy of this software and associated documentation files (the
009: "Software"), to deal in the Software without restriction, including
010: without limitation the rights to use, copy, modify, merge, publish,
011: distribute, sublicense, and/or sell copies of the Software, and to
012: permit persons to whom the Software is furnished to do so, subject to
013: the following conditions:
014:
015: The above copyright notice and this permission notice shall be
016: included in all copies or substantial portions of the Software.
017:
018: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
020: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
021: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
022: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
023: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
024: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
025: ==================================================================== */
026: package org.jicarilla.http;
027:
028: import org.jicarilla.lang.Recyclable;
029: import org.jicarilla.http.util.NioUtil;
030:
031: import java.nio.ByteBuffer;
032: import java.util.ArrayList;
033: import java.util.Collections;
034: import java.util.LinkedList;
035: import java.util.List;
036:
037: /**
038: * JavaBean modelling an HTTP protocol message. Doesn't provide
039: * argument verification.
040: *
041: * Can be used either to model a request or a response.
042: *
043: * @author <a href="mailto: lsimons at jicarilla dot org">Leo Simons</a>
044: * @version $Id: HTTPMessage.java,v 1.6 2004/03/23 13:37:48 lsimons Exp $
045: */
046: public class HTTPMessage implements Recyclable {
047: // ----------------------------------------------------------------------
048: // Properties
049: // ----------------------------------------------------------------------
050: public final static boolean TYPE_REQUEST = true;
051: public final static boolean TYPE_RESPONSE = false;
052:
053: protected boolean m_isRequest = true;
054: protected boolean m_isComplete = false;
055:
056: protected ByteBuffer m_field1;
057: protected ByteBuffer m_field2;
058: protected ByteBuffer m_field3;
059:
060: protected List m_headers;
061: protected List m_bodyParts;
062:
063: // ----------------------------------------------------------------------
064: // Constructors
065: // ----------------------------------------------------------------------
066: /**
067: * Default constructor.
068: */
069: public HTTPMessage() {
070: m_field1 = null;
071: m_field2 = null;
072: m_field3 = null;
073:
074: m_headers = new ArrayList();
075: m_bodyParts = new LinkedList();
076: }
077:
078: // ----------------------------------------------------------------------
079: // Getters/Setters
080: // ----------------------------------------------------------------------
081: /**
082: * Mark whether this message models a request or a response.
083: *
084: * @param isRequest true if the message should behave like a
085: * request, false if it should behave like a response
086: */
087: public void setMessageType(final boolean isRequest) {
088: m_isRequest = isRequest;
089: }
090:
091: /**
092: * Determine whether this message represents a request or a
093: * response.
094: *
095: * @return true if the message represents a
096: * request, false if it represents a response
097: *
098: * @return
099: */
100: public boolean getMessageType() {
101: return m_isRequest;
102: }
103:
104: public boolean isComplete() {
105: return m_isComplete;
106: }
107:
108: public void setComplete(final boolean complete) {
109: m_isComplete = complete;
110: }
111:
112: /**
113: * Set the first HTTP header line field.
114: *
115: * @param field the first HTTP header line field
116: */
117: public void setField1(final ByteBuffer field) {
118: m_field1 = field;
119: }
120:
121: /**
122: * Get the first HTTP header line field.
123: *
124: * @return the field, or null if it hasn't been set
125: */
126: public ByteBuffer getField1() {
127: return m_field1;
128: }
129:
130: /**
131: * Get the first HTTP header line field as a string.
132: *
133: * @return the field, or null if it hasn't been set
134: */
135: public String getField1String() {
136: getField1().rewind();
137: return NioUtil.toString(getField1());
138: }
139:
140: public void setField1(final String field) {
141: setField1(NioUtil.toByteBuffer(field));
142: }
143:
144: /**
145: * Set the second HTTP header line field.
146: *
147: * @param field2 the second HTTP header line field
148: */
149: public void setField2(final ByteBuffer field2) {
150: m_field2 = field2;
151: }
152:
153: /**
154: * Get the second HTTP header line field.
155: *
156: * @return the field, or null if it hasn't been set
157: */
158: public ByteBuffer getField2() {
159: return m_field2;
160: }
161:
162: /**
163: * Get the second HTTP header line field as a string.
164: *
165: * @return the field, or null if it hasn't been set
166: */
167: public String getField2String() {
168: getField2().rewind();
169: return NioUtil.toString(getField2());
170: }
171:
172: public void setField2(final String field) {
173: setField2(NioUtil.toByteBuffer(field));
174: }
175:
176: /**
177: * Set the third HTTP header line field.
178: *
179: * @param field the third HTTP header line field
180: */
181: public void setField3(final ByteBuffer field) {
182: m_field3 = field;
183: }
184:
185: /**
186: * Get the third HTTP header line field.
187: *
188: * @return the field, or null if it hasn't been set
189: */
190: public ByteBuffer getField3() {
191: return m_field3;
192: }
193:
194: /**
195: * Get the third HTTP header line field as a string.
196: *
197: * @return the field, or null if it hasn't been set
198: */
199: public String getField3String() {
200: getField3().rewind();
201: return NioUtil.toString(getField3());
202: }
203:
204: public void setField3(final String field) {
205: setField3(NioUtil.toByteBuffer(field));
206: }
207:
208: /**
209: * Add a parsed HTTP header to the set of headers associated with this message.
210: * No verification of the arguments is done.
211: *
212: * @param name The new header name
213: * @param value The new header value
214: */
215: public void addHeader(final ByteBuffer name, final ByteBuffer value) {
216: m_headers.add(new HTTPField(name, value));
217: }
218:
219: public void addHeader(final String name, final String value) {
220: addHeader(NioUtil.toByteBuffer(name), NioUtil
221: .toByteBuffer(value));
222: }
223:
224: /**
225: * Get an unmodifiable map of the HTTP headers associated with this message.
226: * No verification of the headers is done.
227: *
228: * @return an unmodifiable {@link List} of the HTTP headers, which might
229: * be empty
230: */
231: public List getHeaders() {
232: return Collections.unmodifiableList(m_headers);
233: }
234:
235: /**
236: * Add a piece of the body associated with this message.
237: * No verification of the buffer is done.
238: *
239: * @param buffer the body part to append
240: */
241: public void addBodyPart(final ByteBuffer buffer) {
242: m_bodyParts.add(buffer);
243: }
244:
245: public void addBodyPart(final String string) {
246: m_bodyParts.add(NioUtil.toByteBuffer(string));
247: }
248:
249: public void addBodyParts(final ByteBuffer[] buffers) {
250: for (int i = 0; i < buffers.length; i++)
251: addBodyPart(buffers[i]);
252: }
253:
254: /**
255: * Get an ordered array of the body parts associated
256: * with this message.
257: *
258: * @return the body parts of this message
259: */
260: public ByteBuffer[] getBodyParts() {
261: return (ByteBuffer[]) m_bodyParts.toArray(new ByteBuffer[0]);
262: }
263:
264: public String getBodyAsString() {
265: final ByteBuffer[] buf = getBodyParts();
266: final String body = NioUtil.toString(buf); // ouch!
267: return body;
268: }
269:
270: // ----------------------------------------------------------------------
271: // Convenience response methods
272: // ----------------------------------------------------------------------
273:
274: public int getStatusCode() {
275: //if( m_isRequest )
276: // throw new IllegalStateException( "We're not a response!" );
277:
278: // status code is the second field
279: final String val = getField2String();
280: return new Integer(val).intValue();
281: }
282:
283: public void setStatusCode(final ByteBuffer statusCode) {
284: setField2(statusCode);
285: }
286:
287: public void setStatusCode(final int code) {
288: setStatusCode(NioUtil.toByteBuffer(code));
289: }
290:
291: // ----------------------------------------------------------------------
292: // Work Interface: Recyclable
293: // ----------------------------------------------------------------------
294: public void recycle() {
295: m_field1 = null;
296: m_field2 = null;
297: m_field3 = null;
298:
299: m_headers.clear();
300: m_bodyParts.clear();
301: }
302: }
|