001: /**
002: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
003: * Unpublished - rights reserved under the Copyright Laws of the United States.
004: * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
005: * Copyright © 2005 BEA Systems, Inc. All rights reserved.
006: *
007: * Use is subject to license terms.
008: *
009: * This distribution may include materials developed by third parties.
010: *
011: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
012: *
013: * Module Name : JSIP Specification
014: * File Name : Message.java
015: * Author : Phelim O'Doherty
016: *
017: * HISTORY
018: * Version Date Author Comments
019: * 1.1 08/10/2002 Phelim O'Doherty
020: * 1.2 12/15/2004 M. Ranganathan Clarified comment on clone() method
021: * Clarified the getUnrecognizedHeaders() method
022: * Added removeFirst, addFirst, addLast methods
023: *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
024: */package javax.sip.message;
025:
026: import javax.sip.SipException;
027: import javax.sip.header.*;
028: import java.util.*;
029: import java.io.Serializable;
030: import java.text.ParseException;
031:
032: /**
033: * A SIP message is either a request from a client to a server, or a
034: * response from a server to a client. Both Request and Response messages
035: * use the basic format of <a href ="http://www.ietf.org/rfc/rfc2822.txt">
036: * RFC 2822</a>, even though the syntax differs in
037: * character set and syntax specifics. (SIP allows header fields that
038: * would not be valid RFC 2822 header fields, for example.) Both types
039: * of messages consist of a method name, address and protocol version,
040: * one or more header fields which describe the routing of the message, and
041: * an optional message-body. The message-body contains a session description
042: * in a format such as Session Description Protocol see
043: * <a href ="http://jcp.org/jsr/detail/141.jsp">JSR 141</a>.
044: *
045:
046: * <p>
047: * This interface contains common elements of both Request and Response such as:
048: * <ul>
049: * <li> Generic accessor functions to headers.
050: * <li> Convenience accessor to the expiration value of the message.
051: * <li> Convenience header accessor methods for the body content type, language,
052: * disposition and length.
053: * <li> Accessor methods to the body content itself.
054: * </ul>
055: * <p> Although the SIP Protocol allows headers of a given kind to be interspaced
056: * with headers of different kinds, an implementation of this specification
057: * is required to organize headers so that headers that can appear multiple
058: * times in a SIP Message (such as the Via header) are grouped together and can
059: * be retrieved collectively and iterated over. Although an implementation may
060: * use short forms internally, the specification refers to all headers by their
061: * long form names.
062: *
063: * @see Request
064: * @see Response
065: * @see Header
066: *
067: * @author BEA Systems, NIST
068: * @version 1.2
069: *
070: */
071:
072: public interface Message extends Cloneable, Serializable {
073:
074: // Generic header methods of the Message
075:
076: /**
077: * Adds the new Header to the existing list of Headers contained in this
078: * Message. The Header is added to the end of the List and will appear in
079: * that order in the SIP Message.
080: * <p>
081: * Required Headers that are singletons should not be added to the message
082: * as they already exist in the message and therefore should be changed using
083: * the {@link Message#setHeader(Header)} method.
084: * <p>
085: * This method should be used to support the special case of adding
086: * required ViaHeaders to a message. When adding a ViaHeader using this
087: * method the implementation will add the ViaHeader to the top of the
088: * ViaHeader list, and not the end like all other Headers.
089: *
090: * @param header the new Header to be added to the existing Headers List.
091: */
092: public void addHeader(Header header);
093:
094: /**
095: * Adds the new Header to the end of existing list of Headers contained in this
096: * Message. The Header is added to the end of the List and will appear in
097: * that order in the SIP Message.
098: * <p>
099: * Required Headers that are singletons should not be added to the message
100: * as they already exist in the message and therefore should be changed using
101: * the {@link Message#setHeader(Header)} method. This does the same thing
102: * as addHeader in all cases including the Via header.
103: * Add a header explicitly to the end of a list of headers.
104: *
105: * @param header -- the new Header to be added to the end of the existing
106: * list of headers
107: * @throws NullPointerException -- if the argument is null.
108: * @throws SipException -- if the header is a singleton and an instance of the header
109: * already exists.
110: * @since v1.2
111: */
112: public void addLast(Header header) throws SipException,
113: NullPointerException;
114:
115: /**
116: * Adds the new Header to the head of the existing list of Headers
117: * contained in this Message.
118: * The Header is added to the head of the List and will appear in
119: * that order in the SIP Message.
120: * <p>
121: * Required Headers that are singletons should not be added to the message
122: * as they already exist in the message and therefore should be
123: * changed using the {@link Message#setHeader(Header)} method.
124: *
125: * @throws SipException -- if the header to be added is a singleton and an instance of the header
126: * already exists.
127: * @throws NullPointerException -- if the argument is null.
128: * @param header the new Header to be added to the existing Headers List.
129: * @since v1.2
130: */
131: public void addFirst(Header header) throws SipException,
132: NullPointerException;
133:
134: /**
135: * Removes the first header from a list of headers.
136: * If there's only one header of this kind, then it is removed
137: * from the message.
138: * @throws NullPointerException -- if the arg is null
139: * @param headerName the name of the header to be removed.
140: * @since v1.2
141: */
142: public void removeFirst(String headerName)
143: throws NullPointerException;
144:
145: /**
146: * Removes the last header from a list of headers.
147: * If there's only one header of this kind, then it is removed
148: * from the message.
149: *
150: * @param headerName the name of the header to be removed.
151: * @since v1.2
152: */
153: public void removeLast(String headerName)
154: throws NullPointerException;
155:
156: /**
157: * Removes the Header of the supplied name from the list of headers in
158: * this Message. If multiple headers exist then they are all removed from
159: * the header list. If no headers exist then this method returns silently.
160: * This method should not be used to remove required Headers, required
161: * Headers should be replaced using the {@link Message#setHeader(Header)}.
162: *
163: * @param headerName the new string value name of the Header to be
164: * removed.
165: */
166: public void removeHeader(String headerName);
167:
168: /**
169: * Gets a ListIterator over the set of all all the header names in this Message.
170: * Note that the order of the Header Names in the ListIterator is same as the
171: * order in which they appear in the SIP Message.
172: *
173: * @return the ListIterator over the set of all the Header Names in the Message.
174: */
175: public ListIterator getHeaderNames();
176:
177: /**
178: * Gets a ListIterator over all the Headers of the newly specified name
179: * in this Message. Note that order of the Headers in ListIterator is the
180: * same as the order in which they appear in the SIP Message.
181: *
182: * @param headerName the new string name of Header types requested.
183: * @return the ListIterator over all the Headers of the specified name in
184: * the Message, this method returns an empty ListIterator if no Headers
185: * exist of this header type.
186: */
187: public ListIterator getHeaders(String headerName);
188:
189: /**
190: * Gets the Header of the specified name in this Message. If multiple
191: * Headers of this header name exist in the message, the first header
192: * in the message is returned.
193: *
194: * @param headerName the new string name of Header type requested.
195: * @return the Header of the specified name in the Message, this method
196: * returns null if the Header does not exist.
197: */
198: public Header getHeader(String headerName);
199:
200: /**
201: * Returns a ListIterator over all the UnrecognizedHeaders in this Message. Note
202: * the order of the UnrecognizedHeaders in the ListIterator is the same as
203: * order in which they appeared in the SIP Message. UnrecognizedHeaders are
204: * headers that the underlying implementation does not recognize. If the
205: * message is missing a required header (From, To, Call-ID, CSeq, Via)
206: * the entire message willl be dropped by the underlying implementation and
207: * the header will not be included in the list. Headers that are part of the
208: * supported set of headers but are not properly formatted will be included
209: * in this list. Note that Headers that are not part of the supported set of
210: * headers are retrieved as Extension Headers. These must have a name:value
211: * format else they will be rejected by the underling implementation and
212: * included in this list. A Proxy should not delete UnrecognizedHeaders and
213: * should add these Headers to the end of the header list of the Message
214: * that is being forwarded. A User Agent may display these unrecognized
215: * headers to the user.
216: *
217: * @return the ListIterator over all the UnrecognizedHeaders in the Message
218: * represented as Strings, this method returns an empty ListIterator if no
219: * UnrecognizedHeaders exist.
220: */
221: public ListIterator getUnrecognizedHeaders();
222:
223: /**
224: * Sets the new Header to replace existings Header of that type in
225: * the message. If the SIP message contains more than one Header of
226: * the new Header type it should replace the first occurance of this
227: * Header and removes all other Headers of this type. If no Header of this
228: * type exists this header is added to the end of the SIP Message.
229: * This method should be used to change required Headers and overwrite
230: * optional Headers.
231: *
232: * @param header the new Header to replace any existing Headers of that
233: * type.
234: */
235: public void setHeader(Header header);
236:
237: // Content manipulation methods of the Message
238:
239: /**
240: * Set the ContentLengthHeader of this Message.
241: * The actual content length for the outgoing message will be computed from
242: * the content assigned. If the content is speficied as an object it will
243: * be converted to a String before the message is sent out and the content
244: * length computed from the length of the string. If the message content is
245: * specified in bytes, the length of the byte array specified will be used
246: * to determine the content length header, that is in both cases, the length
247: * of the content overrides any value specified in the content-length
248: * header.
249: *
250: * @param contentLength the new ContentLengthHeader object containing the
251: * content length value of this Message.
252: *
253: */
254: public void setContentLength(ContentLengthHeader contentLength);
255:
256: /**
257: * Gets the ContentLengthHeader of the body content of this Message. This is
258: * the same as <code>this.getHeader(Content-Length);</code>
259: *
260: * @return the ContentLengthHeader of the message body.
261: */
262: public ContentLengthHeader getContentLength();
263:
264: /**
265: * Sets the ContentLanguageHeader of this Message. This overrides the
266: * ContentLanguageHeader set using the setHeaders method. If no
267: * ContentLanguageHeader exists in this message this ContentLanguageHeader
268: * is added to the end of the Header List.
269: *
270: * @param contentLanguage the new ContentLanguageHeader object containing the
271: * content language value of this Message.
272: */
273: public void setContentLanguage(ContentLanguageHeader contentLanguage);
274:
275: /**
276: * Gets the ContentLanguageHeader of this Message. This is the same as
277: * <code>this.getHeader(Content-Langauge);</code>
278: *
279: * @return the ContentLanguageHeader of the message body.
280: */
281: public ContentLanguageHeader getContentLanguage();
282:
283: /**
284: * Sets the ContentEncodingHeader of this Message. This overrides the
285: * ContentEncodingHeader set using the setHeaders method. If no
286: * ContentEncodingHeader exists in this message this ContentEncodingHeader
287: * is added to the end of the Header List.
288: *
289: * @param contentEncoding the new ContentEncodingHeader object containing the
290: * content encoding values of this Message.
291: */
292: public void setContentEncoding(ContentEncodingHeader contentEncoding);
293:
294: /**
295: * Gets the ContentEncodingHeader of this Message. This is the same as
296: * <code>this.getHeader(Content-Encoding);</code>
297: *
298: * @return the ContentEncodingHeader of the message body.
299: */
300: public ContentEncodingHeader getContentEncoding();
301:
302: /**
303: * Sets the ContentDispositionHeader of this Message. This overrides the
304: * ContentDispositionHeader set using the setHeaders method. If no
305: * ContentDispositionHeader exists in this message this ContentDispositionHeader
306: * is added to the end of the Header List.
307: *
308: * @param contentDisposition the new ContentDispositionHeader object
309: * containing the content disposition value of this Message.
310: */
311: public void setContentDisposition(
312: ContentDispositionHeader contentDisposition);
313:
314: /**
315: * Gets the ContentDispositionHeader of this Message. This is the same as
316: * <code>this.getHeader(Content-Disposition);</code>
317: *
318: * @return the ContentDispositionHeader of the message body.
319: */
320: public ContentDispositionHeader getContentDisposition();
321:
322: /**
323: * Sets the body of this Message, with the ContentType defined by the new
324: * ContentTypeHeader object and the string value of the content.
325: *
326: * @param content the new Object value of the content of the Message.
327: * @param contentTypeHeader the new ContentTypeHeader object that defines
328: * the content type value.
329: * @throws ParseException which signals that an error has been reached
330: * unexpectedly while parsing the body.
331: */
332: public void setContent(Object content,
333: ContentTypeHeader contentTypeHeader) throws ParseException;
334:
335: /**
336: * Gets the body content of the Message as a byte array.
337: *
338: * @return the body content of the Message as a byte array, this method
339: * returns null if a body does not exist.
340: */
341: public byte[] getRawContent();
342:
343: /**
344: * Gets the body content of the Message as an Object.
345: *
346: * @return the body content of the Message as an Object, this method
347: * returns null if a body does not exist.
348: */
349: public Object getContent();
350:
351: /**
352: * Removes the body content from this Message and all associated entity
353: * headers, if a body exists, this method returns sliently if no body exists.
354: */
355: public void removeContent();
356:
357: // Additional Utility methods
358:
359: /**
360: * Sets the ExpiresHeader of this Message. This overrides the ExpiresHeader
361: * set using the setHeaders method. If no ExpiresHeader exists in this
362: * message this ExpiresHeader is added to the end of the Header List.
363: *
364: * @param expires the new ExpiresHeader object containing the expires
365: * values of this Message.
366: */
367: public void setExpires(ExpiresHeader expires);
368:
369: /**
370: * Gets the ExpiresHeader of this Message. This is the same as
371: * <code>this.getHeader(Expires);</code>
372: *
373: * @return the ExpiresHeader of the message body.
374: */
375: public ExpiresHeader getExpires();
376:
377: /**
378: * Sets the protocol version of SIP being used by this Message.
379: *
380: * @param version the new String object containing the version of the SIP
381: * Protocol of this Message.
382: * @throws ParseException which signals that an error has been reached
383: * unexpectedly while parsing the version argument.
384: */
385: public void setSIPVersion(String version) throws ParseException;
386:
387: /**
388: * Gets the protocol version of SIP being used by this Message.
389: *
390: * @return the protocol version of the SIP protocol of this message.
391: */
392: public String getSIPVersion();
393:
394: // Java Utility methods for Message
395:
396: /**
397: * Creates and returns a deep copy of the Message. This methods must ensure a
398: * deep copy of the message, so that it can be modified without effecting
399: * the original message. This provides useful functionality for proxying
400: * Requests and Responses, for example:
401: * <ul>
402: * <li>Recieve a message.
403: * <li>Create a deep clone of the message.
404: * <li>Modify necessary headers.
405: * <li>Proxy the message using the send methods on the SipProvider.
406: * </ul>
407: * The message contents are cloned as follows:
408: * <ul>
409: * <li>If the content is of type byte[] a new byte[] array is allocated and the
410: * original contents are copied over to the cloned Message.
411: * <li>If the content is of type String then a new String equal to the old
412: * String is allocated and assigned to the cloned Message.
413: * <li>If the content is of type Object and it has a public clone method
414: * then it is invoked and the resultant Object is used in the new cloned
415: * Message.
416: * </ul>
417: *
418: * @return a deep copy of Message
419: */
420: public Object clone();
421:
422: /**
423: * Compare this SIP Message for equality with another.
424: * Implementations need only compare Request/Response line, From,
425: * To, CallID, MaxForwards, CSeq and Via headers for message equality.
426: *
427: * @param object the object to compare this Message with.
428: * @return <code>true</code> if <code>obj</code>
429: * is an instance of this class representing the same SIP Message as
430: * this (on the basis of comparing the headers above),
431: * <code>false</code> otherwise.
432: */
433: public boolean equals(Object object);
434:
435: /**
436: * Gets a integer hashcode representation of the Header. This method
437: * overrides the hashcode method in java.lang.Object. Only the
438: * Request/Response line and the required headers should be used to
439: * generate the unique hashcode of a message.
440: *
441: * @return integer representation of the Message hashcode
442: * @since v1.2
443: */
444: public int hashCode();
445:
446: /**
447: * Gets string representation of Message
448: * @return string representation of Message
449: */
450: public String toString();
451:
452: }
|