FileDocCategorySizeDatePackage
Message.javaAPI DocphoneME MR2 API (J2ME)51112Wed May 02 18:00:42 BST 2007gov.nist.siplite.message

Message

public abstract class Message extends GenericObject
This is the main SIP Message structure.
see
StringMsgParser
see
PipelinedMsgParser
version
JAIN-SIP-1.1 This code is in the public domain. IMPL_NOTE: remove 'Vector headers' because its contents is duplicated in nameTable

Fields Summary
private static Class
sipHeaderListClass
Class handle.
protected static final String
DEFAULT_ENCODING
Default encoding string.
protected Vector
unrecognizedHeaders
Unparsed headers.
protected Vector
headers
List of parsed headers (in the order they were added).
protected FromHeader
fromHeader
From header.
protected ToHeader
toHeader
To header.
protected CSeqHeader
cSeqHeader
C sequence header.
protected CallIdHeader
callIdHeader
Caller identification header.
protected ContentLengthHeader
contentLengthHeader
Content length header.
protected String
messageContent
Body of message content.
protected byte[]
messageContentBytes
Length of message content in bytes.
protected Object
messageContentObject
Object holding body contents.
private Hashtable
nameTable
Table of headers indexed by name.
Constructors Summary
public Message()
Constructor: Initializes lists and list headers. All the headers for which there can be multiple occurances in a message are derived from the HeaderListClass. All singleton headers are derived from Header class.

        unrecognizedHeaders = new Vector();
        headers = new Vector();
        nameTable = new Hashtable();
    
Methods Summary
public voidaddHeader(Header sipHeader)
Adds a SIP header.

param
sipHeader -- sip header to add.
throws
SipException if the header can't be added for some reason.

        Header sh = (Header) sipHeader;
        // Add the header value topmost of this type of headers
        // as required by JSR180.
        attachHeader(sh, false, true);

        /*
        if (sipHeader instanceof ViaHeader) {
            attachHeader(sh, false, true);
        } else {
            attachHeader(sh, false, false);
        }
        */
    
public voidaddHeader(java.lang.String sipHeader)
Adds a SIP header.

param
sipHeader -- string version of SIP header to add.
throws
SipException if the header can't be added for some reason.

        String hdrString = sipHeader.trim() + "\n";
        try {
            HeaderParser parser = ParserFactory.createParser(sipHeader);
            Header sh = parser.parse();
            attachHeader(sh, false);
        } catch (ParseException ex) {
            unrecognizedHeaders.addElement(hdrString);
        }
    
public voidaddUnparsed(java.lang.String unparsed)
Adds a header to the unparsed list of headers.

param
unparsed -- unparsed header to add to the list.

        unrecognizedHeaders.addElement(unparsed);
    
private voidattachHeader(Header h)
Attaches a header and dies if you get a duplicate header exception.

param
h Header to attach.
throws
IllegalArgumentException if the header to attach is null.
throws
SipException if the header can't be attached for some reason.

        if (h == null)
            throw new IllegalArgumentException("null header!");

        if (h instanceof HeaderList) {
            HeaderList hl = (HeaderList) h;
            if (hl.isEmpty()) {
                // System.out.println("Attaching an empty header: " +
                // h.getClass().getName());
                return;
            }
        }

        attachHeader(h, false, false);
    
public voidattachHeader(Header h, boolean replaceflag)
Attaches a header to the end of the existing headers in this Message structure. This is equivalent to the attachHeader(Header,replaceflag,false); which is the normal way in which headers are attached. This was added in support of JAIN-SIP.

since
1.0 (made this public)
param
h header to attach.
param
replaceflag if true then replace a header if it exists.
throws
SipException if the header can't be attached for some reason.

        attachHeader(h, replaceflag, false);
    
public voidattachHeader(Header header, boolean replaceFlag, boolean top)
Attaches the header to the SIP Message structure at a specified position in its list of headers.

param
header Header to attach.
param
replaceFlag If true then replace the existing header.
param
top flag to indicate attaching header to the front of list.
throws
SipException if the header can't be attached for some reason.

        if (header == null) {
            throw new NullPointerException("null header");
        }

        // System.out.println(">>> attachHeader( " +
        //                   header + ", " + replaceFlag + ");");

        Header h;
        String expandedHeaderName = NameMap.expandHeaderName(
            header.getHeaderName()).toLowerCase();

        if (ListMap.hasList(header) &&
                ! sipHeaderListClass.isAssignableFrom(header.getClass())) {
            HeaderList hdrList = ListMap.getList(header);

            // Actually, hdrList.size() is always 0.
            if (replaceFlag && (hdrList.size() > 0)) {
                // remove first element
                hdrList.removeElement(hdrList.elementAt(0));
            }

            hdrList.add(header);
            h = hdrList;
        } else {
            h = header;
        }

        if (!replaceFlag && nameTable.containsKey(expandedHeaderName) &&
                !(h instanceof HeaderList)) {
            // Throw an exception here because according to JSR180:
            // "The implementations MAY restrict the access to some
            // headers according to RFC 3261."
            //
            // It may happen if this function is called to add a header that
            // already exist and the only one header of this type may present
            // (Call-Id, From, To).
            //
            throw new SipException("Header '" + header.getHeaderName() +
                "' already exist. Only one header of this type is allowed.",
                    SipException.INVALID_OPERATION);
        }

        // Delete the first header with name = headerName
        // from our list structure.
        // If case of HeaderList the whole list is removed
        // to avoid duplication (it is added bellow).
        if (replaceFlag || (h instanceof HeaderList)) {
            Enumeration li = headers.elements();
            int index;

            for (index = 0; li.hasMoreElements(); index++) {
                Header next = (Header) li.nextElement();
                String currName = NameMap.expandHeaderName(
                    next.getHeaderName());

                if (expandedHeaderName.equalsIgnoreCase(currName)) {
                    headers.removeElementAt(index);
                    break;
                }
            }
        }

        Header hRef = h;

        if (h instanceof HeaderList) {
            HeaderList hdrlist = (HeaderList) nameTable.get(expandedHeaderName);

            if (hdrlist != null) {
                if (replaceFlag) {
                    hdrlist.removeFirst();
                }

                hdrlist.concatenate((HeaderList)h, top);

                // This is required due to the way that 'concatenate'
                // is implemented: if 'top' is false, it modifies
                // the objects itself; otherwise, the list passed
                // as the first parameter is modified.
                if (!top) {
                    hRef = hdrlist;
                }
            }
        }

        nameTable.put(expandedHeaderName, hRef);
        headers.addElement(hRef);

        // Direct accessor fields for frequently accessed headers.
        if (h instanceof FromHeader) {
            this.fromHeader = (FromHeader)h;
        } else if (h instanceof ContentLengthHeader) {
            this.contentLengthHeader = (ContentLengthHeader) h;
        } else if (h instanceof ToHeader) {
            this.toHeader = (ToHeader)h;
        } else if (h instanceof CSeqHeader) {
            this.cSeqHeader = (CSeqHeader) h;
        } else if (h instanceof CallIdHeader) {
            this.callIdHeader = (CallIdHeader) h;
        }
    
public java.lang.Objectclone()
Clones this message (create a new deep physical copy). All headers in the message are cloned. You can modify the cloned copy without affecting the original.

return
A cloned copy of this object.

        Message retval = null;
        try {
            retval = (Message) this.getClass().newInstance();
        } catch (IllegalAccessException ex) {
            InternalErrorHandler.handleException(ex);
        } catch (InstantiationException ex) {
            InternalErrorHandler.handleException(ex);
        }

        Enumeration li = headers.elements();
        while (li.hasMoreElements()) {
            Header sipHeader = (Header) ((Header) li.nextElement()).clone();
            try {
                retval.attachHeader(sipHeader);
            } catch (SipException ex) {
                if (Logging.REPORT_LEVEL <= Logging.ERROR) {
                    Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
                        "Message.clone(): can't attach header '" +
                            sipHeader.getName() + "'.");
                    ex.printStackTrace();
                }
            }
        }

        if (retval instanceof Request) {
            Request thisRequest = (Request) this;
            RequestLine rl = (RequestLine)
            (thisRequest.getRequestLine()).clone();
            ((Request) retval).setRequestLine(rl);
        } else {
            Response thisResponse = (Response) this;
            StatusLine sl = (StatusLine)
            (thisResponse.getStatusLine()).clone();
            ((Response) retval).setStatusLine(sl);
        }

        if (getContent() != null) {
            try {
                retval.setContent(getContent(), getContentTypeHeader());
            } catch (SipException ex) {  // Ignore
                if (Logging.REPORT_LEVEL <= Logging.ERROR) {
                    Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
                        "Message.clone(): can't set the content!");
                    ex.printStackTrace();
                }
            }
        }

        return retval;
    
public java.lang.Stringencode()
Encodes this message as a string. This is more efficient when the payload is a string (rather than a binary array of bytes). If the payload cannot be encoded as a UTF-8 string then it is simply ignored (will not appear in the encoded message).

return
The Canonical String representation of the message (including the canonical string representation of the SDP payload if it exists).

        StringBuffer encoding = new StringBuffer();
        // Synchronization added because of concurrent modification exception
        // noticed by Lamine Brahimi.
        synchronized (this.headers) {
            Enumeration it = this.headers.elements();

            while (it.hasMoreElements()) {
                Header siphdr = (Header) it.nextElement();
                if (! (siphdr instanceof ContentLengthHeader)) {
                    encoding.append(siphdr.encode());
                }
            }
        }

        // Add the content-length header
        if (contentLengthHeader != null) {
            encoding.append(contentLengthHeader.encode()).append
                    (Separators.NEWLINE);
        }

        if (this.messageContentObject != null) {
            String mbody = this.getContent().toString();
            encoding.append(mbody);
        } else if (this.messageContent != null ||
                this.messageContentBytes != null) {
            String content = null;
            try {
                if (messageContent != null) {
                    content = messageContent;
                } else {
                    content = new String(messageContentBytes,
                                         DEFAULT_ENCODING);
                }
            } catch (UnsupportedEncodingException ex) {
                content = "";
            }
            encoding.append(content);
        }
        
        return encoding.toString();
    
public byte[]encodeAsBytes()
Encodes the message as a byte array. Use this when the message payload is a binary byte array.

return
The Canonical byte array representation of the message (including the canonical byte array representation of the SDP payload if it exists all in one contiguous byte array).

        StringBuffer encoding = new StringBuffer();
        Enumeration it = this.headers.elements();

        while (it.hasMoreElements()) {
            Header siphdr = (Header) it.nextElement();
            if (! (siphdr instanceof ContentLengthHeader))
                encoding.append(siphdr.encode());

        }
        byte[] retval = null;
        byte[] content = this.getRawContent();
        if (content != null) {
            encoding.append(Header.CONTENT_LENGTH +
                    Separators.COLON +
                    Separators.SP + content.length
                    + Separators.NEWLINE);
            encoding.append(Separators.NEWLINE);
            // Append the content
            byte[] msgarray = null;
            try {
                msgarray = encoding.toString().getBytes("UTF-8");
            } catch (UnsupportedEncodingException ex) {
                InternalErrorHandler.handleException(ex);
            }

            retval = new byte[msgarray.length + content.length];
            System.arraycopy(msgarray, 0, retval, 0, msgarray.length);
            System.arraycopy(content, 0, retval, msgarray.
                    length, content.length);
        } else {
            // Message content does not exist.
            encoding.append(Header.CONTENT_LENGTH +
                    Separators.COLON + Separators.SP + '0"
                    + Separators.NEWLINE);
            encoding.append(Separators.NEWLINE);
            try {
                retval = encoding.toString().getBytes("UTF-8");
            } catch (UnsupportedEncodingException ex) {
                InternalErrorHandler.handleException(ex);
            }
        }
        return retval;
    
public booleanequals(java.lang.Object other)
Compares for equality.

param
other the other object to compare with.
return
true if object matches

        if (!other.getClass().equals(this.getClass()))
            return false;

        Message otherMessage = (Message) other;
        Enumeration values = this.nameTable.elements();
        Hashtable otherNameTable = otherMessage.nameTable;

        if (otherNameTable.size() != nameTable.size())
            return false;

        while (values.hasMoreElements()) {
            Header mine = (Header) values.nextElement();
            // maybe short form
            String mineName = 
                NameMap.expandHeaderName(mine.getHeaderName()).trim()
                    .toLowerCase();
            Header hisHeader = (Header) otherNameTable.get(mineName);
            String his = null;
            if (hisHeader != null) {
                his = hisHeader.toString().trim();
            }
            
            if (his == null) {
                return false;
            } else if (! his.equals(mine.toString().trim())) {
                return false;
            }
        }

        return true;
    
public CSeqHeadergetCSeqHeader()
Gets the CSeqHeader list of header (null if one does not exist).

return
CSeqHeader header

        return cSeqHeader; 
public intgetCSeqHeaderNumber()
Gets the sequence number.

return
the sequence number.

        return cSeqHeader.getSequenceNumber();
    
public CallIdHeadergetCallId()
Gets the CallIdHeader header (null if one does not exist).

return
Call-ID header.

        return callIdHeader;
    
public java.lang.StringgetCallIdentifier()
Gets the call ID string. A conveniance function that returns the stuff following the header name for the call id header.

return
the call identifier.

        return callIdHeader.getCallId();
    
public ContactListgetContactHeaders()
Gets the Contact list of headers (null if one does not exist).

return
List containing Contact headers.

        return (ContactList) getHeaderList(Header.CONTACT);
    
public java.lang.ObjectgetContent()
Gets the content of the header.

return
the content of the sip message.

        if (this.messageContentObject != null)
            return messageContentObject;
        else if (this.messageContentBytes != null)
            return this.messageContentBytes;
        else if (this.messageContent != null)
            return this.messageContent;
        else return null;
    
public ContentLengthHeadergetContentLengthHeader()
Gets the ContentLengthHeader header (null if one does not exist).

return
content-length header.

        return contentLengthHeader;
    
public ContentTypeHeadergetContentTypeHeader()
Gets the contentType header (null if one does not exist).

return
contentType header

        return (ContentTypeHeader) getHeader(Header.CONTENT_TYPE);
    
public java.lang.StringgetDialogId(boolean isServer)
Gets a dialog identifier. Generates a string that can be used as a dialog identifier.

param
isServer is set to true if this is the UAS and set to false if this is the UAC
return
the dialig identifier

        CallIdHeader cid = (CallIdHeader) this.getCallId();
        StringBuffer retval = new StringBuffer(cid.getCallId());
        FromHeader from = (FromHeader) this.getFromHeader();
        ToHeader to = (ToHeader) this.getTo();
        if (! isServer) {
            if (to.getTag() != null) {
                retval.append(to.getTag());
            }
            if (from.getTag() != null) {
                retval.append(from.getTag());
            }
        } else {
            if (from.getTag() != null) {
                retval.append(from.getTag());
            }
            if (to.getTag() != null) {
                retval.append(to.getTag());
            }
        }
        return retval.toString().toLowerCase();

    
public java.lang.StringgetDialogId(boolean isServer, java.lang.String toTag)
Gets a dialog id given the remote tag.

param
isServer flag indicating a server request
param
toTag the target recipient
return
the dialog identifier

        FromHeader from = (FromHeader) this.getFromHeader();
        ToHeader to = (ToHeader) this.getTo();
        CallIdHeader cid = (CallIdHeader) this.getCallId();
        StringBuffer retval = new StringBuffer(cid.getCallId());
        if (! isServer) {
            if (toTag != null) {
                retval.append(toTag);
            }
            if (from.getTag() != null) {
                retval.append(from.getTag());
            }
        } else {
            if (from.getTag() != null) {
                retval.append(from.getTag());
            }
            if (toTag != null) {
                retval.append(toTag);
            }
        }
        return retval.toString().toLowerCase();
    
public abstract java.lang.StringgetFirstLine()
Returns the encoded first line.

return
the first line

public FromHeadergetFromHeader()
Gets the from header.

return
the from header.

        return (FromHeader) fromHeader;
    
public java.lang.StringgetFromHeaderTag()
Returns the from tag.

return
the tag from the from header.

        return fromHeader == null? null: fromHeader.getTag();
    
public HeadergetHeader(java.lang.String headerName)
Gets the first header of the given name.

param
headerName requested header
return
header the first header of the given name.

        if (headerName == null)
            throw new NullPointerException("bad name");

        headerName = NameMap.expandHeaderName(headerName).toLowerCase();
        Header sipHeader = (Header)nameTable.get(headerName);

        if (sipHeader == null) {
            return null;
        }

        if (sipHeader instanceof HeaderList) {
            return (Header) ((HeaderList) sipHeader).getFirst();
        } else {
            return (Header) sipHeader;
        }
    
public HeaderListgetHeaderList(java.lang.String headerName)
Gets a SIP Header list given its name.

param
headerName is the name of the header to get.
return
a header list that contains the retrieved header.

        Header header = (Header)nameTable.get(
            NameMap.expandHeaderName(headerName).toLowerCase());

        if (header == null) {
            return null;
        }

        if (header instanceof HeaderList) {
            return (HeaderList)header;
        } else {
            HeaderList hl = new HeaderList();
            hl.add(header);
            return hl;
        }
    
public java.util.EnumerationgetHeaderNames()
Gets the header names.

return
a list iterator to a list of header names. These are ordered in the same order as are present in the message.

        Enumeration li = this.headers.elements();
        Vector retval = new Vector();

        while (li.hasMoreElements()) {
            Header sipHeader = (Header) li.nextElement();
            String name = sipHeader.getName();
            retval.addElement(name);
        }

        return retval.elements();
    
public java.util.EnumerationgetHeaders()
Returns an iterator for the list of headers in this message.

return
an Iterator for the headers of this message.

        return headers.elements();
    
public java.util.EnumerationgetHeaders(java.lang.String headerName)
Gets a SIP header or Header list given its name.

param
headerName is the name of the header to get.
return
a header or header list that contians the retrieved header.

        if (headerName == null) {
            throw new NullPointerException("null headerName");
        }

        Header sipHeader = (Header)nameTable.get(
                NameMap.expandHeaderName(headerName).toLowerCase());

        // empty iterator
        if (sipHeader == null) {
            return new Vector().elements();
        }

        if (sipHeader instanceof HeaderList) {
            return ((HeaderList) sipHeader).getElements();
        } else {
            Vector v = new Vector();
            v.addElement(sipHeader);
            return v.elements();
        }
    
public java.lang.StringgetMessageContent()
Gets the message body as a string. If the message contains a content type header with a specified charset, and if the payload has been read as a byte array, then it is returned encoded into this charset.

return
Message body (as a string)

        if (this.messageContent == null && this.messageContentBytes == null)
            return null;
        else if (this.messageContent == null) {
            ContentTypeHeader contentTypeHeader =
                    (ContentTypeHeader) this.nameTable
                    .get(Header.CONTENT_TYPE.toLowerCase());
            if (contentTypeHeader != null) {
                String charset = contentTypeHeader.getCharset();
                if (charset != null) {
                    this.messageContent =
                            new String(messageContentBytes, charset);
                } else {
                    this.messageContent =
                            new String(messageContentBytes, DEFAULT_ENCODING);
                }
            } else this.messageContent =
                    new String(messageContentBytes, DEFAULT_ENCODING);
        }
        return this.messageContent;
    
public byte[]getRawContent()
Gets the message content as an array of bytes. If the payload has been read as a String then it is decoded using the charset specified in the content type header if it exists. Otherwise, it is encoded using the default encoding which is UTF-8.

return
an array of bytes that is the message payload.

        try {
            if (this.messageContent == null &&
                    this.messageContentBytes == null &&
                    this.messageContentObject == null) {
                return null;
            } else if (this.messageContentObject != null) {
                String messageContent = this.messageContentObject.toString();
                byte[] messageContentBytes;
                ContentTypeHeader contentTypeHeader =
                        (ContentTypeHeader)this.nameTable.get
                        (Header.CONTENT_TYPE.toLowerCase());
                if (contentTypeHeader != null) {
                    String charset = contentTypeHeader.getCharset();
                    if (charset != null) {
                        messageContentBytes = messageContent.getBytes(charset);
                    } else {
                        messageContentBytes =
                                messageContent.getBytes(DEFAULT_ENCODING);
                    }
                } else messageContentBytes =
                        messageContent.getBytes(DEFAULT_ENCODING);
                return messageContentBytes;
            } else if (this.messageContent != null) {
                byte[] messageContentBytes;
                ContentTypeHeader contentTypeHeader =
                        (ContentTypeHeader)this.nameTable.get
                        (Header.CONTENT_TYPE.toLowerCase());
                if (contentTypeHeader != null) {
                    String charset = contentTypeHeader.getCharset();
                    if (charset != null) {
                        messageContentBytes =
                                this.messageContent.getBytes(charset);
                    } else {
                        messageContentBytes =
                                this.messageContent.getBytes(DEFAULT_ENCODING);
                    }
                } else messageContentBytes =
                        this.messageContent.getBytes(DEFAULT_ENCODING);
                return messageContentBytes;
            } else {
                return messageContentBytes;
            }
        } catch (UnsupportedEncodingException ex) {
            InternalErrorHandler.handleException(ex);
            return null;
        }
    
public RecordRouteListgetRecordRouteHeaders()
Gets the RecordRoute header list (null if one does not exist).

return
Record-Route header

        return (RecordRouteList) this.getHeaderList(Header.RECORD_ROUTE); 
public RouteListgetRouteHeaders()
Gets the Route List of headers (null if one does not exist).

return
List containing Route headers

        return (RouteList) getHeaderList(Header.ROUTE);
    
public abstract java.lang.StringgetSIPVersion()
Gets the SIP vesrion string.

return
the SIP version string

public ToHeadergetTo()
Gets the To header (null if one does not exist).

return
To header

        return (ToHeader) toHeader; 
public java.lang.StringgetToTag()
Returns the To tag.

return
the To tag field

        return toHeader == null ? null : toHeader.getTag();
    
public ViaHeadergetTopmostVia()
Gets the topmost via header.

return
the top most via header if one exists or null if none exists.
throws
SipException if the header can't be set for some reason.

        if (getViaHeaders() == null)
            return null;
        else
            return (ViaHeader) (getViaHeaders().getFirst());
    
public java.lang.StringgetTransactionId()
Generates (compute) a transaction ID for this SIP message.

return
A string containing the concatenation of various portions of the FromHeader,To,Via and RequestURI portions of this message as specified in RFC 2543: All responses to a request contain the same values in the Call-ID, CSeqHeader, To, and FromHeader fields (with the possible addition of a tag in the To field (section 10.43)). This allows responses to be matched with requests. Incorporates a fix for generating transactionIDs when no port is present in the via header. Incorporates a fix (converts to lower case when returning the transaction identifier).
return
a string that can be used as a transaction identifier for this message. This can be used for matching responses and requests (i.e. an outgoing request and its matching response have the same computed transaction identifier).

        ViaHeader topVia = null;
        if (! this.getViaHeaders().isEmpty()) {
            topVia = (ViaHeader) this.getViaHeaders().first();
        }
        // Have specified a branch Identifier so we can use it to identify
        // the transaction.
        if (topVia.getBranch() != null &&
                topVia.getBranch().startsWith
                (SIPConstants.GENERAL_BRANCH_MAGIC_COOKIE)) {
            // Bis 09 compatible branch assignment algorithm.
            // implies that the branch id can be used as a transaction
            // identifier.
            return topVia.getBranch().toLowerCase();
        } else {
            // Old style client so construct the transaction identifier
            // from various fields of the request.
            StringBuffer retval = new StringBuffer();
            FromHeader from = (FromHeader) this.getFromHeader();
            ToHeader to = (ToHeader) this.getTo();
            String hpFromHeader = from.getUserAtHostPort();
            retval.append(hpFromHeader).append(":");
            if (from.hasTag()) retval.append(from.getTag()).append(":");
            String hpTo = to.getUserAtHostPort();
            retval.append(hpTo).append(":");
            String cid = this.callIdHeader.getCallId();
            retval.append(cid).append(":");
            retval.append(this.cSeqHeader.getSequenceNumber()).append(":").
                    append(this.cSeqHeader.getMethod());
            if (topVia != null) {
                retval.append(":").append(topVia.getSentBy().encode());
                if (!topVia.getSentBy().hasPort()) {
                    retval.append(":").append(5060);
                }
            }
            String hc =
		Utils.toHexString(retval.toString().toLowerCase().getBytes());
            if (hc.length() < 32)
                return hc;
            else return hc.substring(hc.length() - 32, hc.length() -1);
        }
        // Convert to lower case
    
public java.util.EnumerationgetUnrecognizedHeaders()
Gets a list containing the unrecognized headers.

return
a linked list containing unrecongnized headers.

        return unrecognizedHeaders.elements();
    
public ViaListgetViaHeaders()
Gets the Via list of headers (null if one does not exist).

return
List containing Via headers.

        return (ViaList) getHeaderList(Header.VIA);
    
public booleanhasContent()
Returns true if this message has a body.

return
true if message body included

        return messageContent != null || messageContentBytes != null;
    
public booleanhasFromHeaderTag()
Returns true if the message has a FromHeader header tag.

return
true if the message has a from header and that header has a tag.

        return fromHeader != null && fromHeader.getTag() != null;
    
public booleanhasHeader(java.lang.String headerName)
Returns true if the Message has a header of the given name.

param
headerName is the header name for which we are testing.
return
true if the header is present in the message

        return nameTable.containsKey(
            NameMap.expandHeaderName(headerName).toLowerCase());
    
public booleanhasToTag()
Returns true if the message has a To header tag.

return
true if the message has a to header and that header has a tag.

        return toHeader != null && toHeader.getTag() != null;
    
public static booleanisRequestHeader(Header sipHeader)
Returns true if the header belongs only in a Request.

param
sipHeader is the header to test.
return
true if header is part of a request

        return sipHeader.getHeaderName().equals(Header.ALERT_INFO) ||
                sipHeader.getHeaderName().equals(Header.IN_REPLY_TO) ||
                sipHeader.getHeaderName().equals(Header.AUTHORIZATION) ||
                sipHeader.getHeaderName().equals(Header.MAX_FORWARDS) ||
                sipHeader.getHeaderName().equals(Header.PRIORITY) ||
                sipHeader.getHeaderName().equals(Header.PROXY_AUTHORIZATION) ||
                sipHeader.getHeaderName().equals(Header.PROXY_REQUIRE) ||
                sipHeader.getHeaderName().equals(Header.ROUTE) ||
                sipHeader.getHeaderName().equals(Header.SUBJECT) ||
                sipHeader.getHeaderName().equals(Header.ACCEPT_CONTACT);

    
public static booleanisResponseHeader(Header sipHeader)
Returns true if the header belongs only in a response.

param
sipHeader is the header to test.
return
true if header is part of a response

        return sipHeader.getHeaderName().equals(Header.ERROR_INFO) ||
                sipHeader.getHeaderName().equals(Header.PROXY_AUTHENTICATE) ||
                sipHeader.getHeaderName().equals(Header.SERVER) ||
                sipHeader.getHeaderName().equals(Header.UNSUPPORTED) ||
                sipHeader.getHeaderName().equals(Header.RETRY_AFTER) ||
                sipHeader.getHeaderName().equals(Header.WARNING) ||
                sipHeader.getHeaderName().equals(Header.WWW_AUTHENTICATE);

    
public voidremoveContent()
Removes the message content if it exists.

        messageContent = null;
        messageContentBytes = null;
        messageContentObject = null;
    
public voidremoveHeader(java.lang.String headerName, boolean top)
Removes a header given its name. If multiple headers of a given name are present then the top flag determines which end to remove headers from.

param
headerName is the name of the header to remove.
param
top flag that indicates which end of header list to process.

        // System.out.println("removeHeader " + headerName);

        headerName = NameMap.expandHeaderName(headerName).toLowerCase();
        Header toRemove = (Header) nameTable.get(headerName);

        // nothing to do then we are done.
        if (toRemove == null)
            return;

        if (toRemove instanceof HeaderList) {
            HeaderList hdrList = (HeaderList) toRemove;
            if (top) hdrList.removeFirst();
            else hdrList.removeLast();

            // Clean up empty list
            if (hdrList.isEmpty()) {
                removeHeaderFromList(headerName);
            }
        } else {
            nameTable.remove(headerName);

            if (toRemove instanceof FromHeader) {
                this.fromHeader = null;
            } else if (toRemove instanceof ToHeader) {
                this.toHeader = null;
            } else if (toRemove instanceof CSeqHeader) {
                this.cSeqHeader = null;
            } else if (toRemove instanceof CallIdHeader) {
                this.callIdHeader = null;
            } else if (toRemove instanceof ContentLengthHeader) {
                this.contentLengthHeader = null;
            }

            removeHeaderFromList(headerName);
        }
    
public voidremoveHeader(java.lang.String headerName)
Removes all headers given its name.

param
headerName is the name of the header to remove.

        if (headerName == null) {
            throw new NullPointerException("null arg");
        }

        headerName = NameMap.expandHeaderName(headerName).toLowerCase();
        Header toRemove = (Header) nameTable.get(headerName);

        // nothing to do then we are done.
        if (toRemove == null)
            return;

        nameTable.remove(headerName);

        // Remove the fast accessor fields.
        if (toRemove instanceof FromHeader) {
            this.fromHeader = null;
        } else if (toRemove instanceof ToHeader) {
            this.toHeader = null;
        } else if (toRemove instanceof CSeqHeader) {
            this.cSeqHeader = null;
        } else if (toRemove instanceof CallIdHeader) {
            this.callIdHeader = null;
        } else if (toRemove instanceof ContentLengthHeader) {
            this.contentLengthHeader = null;
        }

        removeHeaderFromList(headerName);
    
private voidremoveHeaderFromList(java.lang.String headerName)
Removes the specified header from "headers" list.

param
headerName expanded name of the header to remove.

        Enumeration li = headers.elements();
        int index = -1;

        while (li.hasMoreElements()) {
            Header sipHeader = (Header) li.nextElement();
            index ++;

            String currName = NameMap.expandHeaderName(
                sipHeader.getName());

            if (Utils.equalsIgnoreCase(currName, headerName)) {
                break;
            }
        }

        if (index != -1 && index < headers.size()) {
            headers.removeElementAt(index);
        }
    
public voidsetCSeqHeader(CSeqHeader cseqHeader)
Sets the CSeqHeader header.

param
cseqHeader CSeqHeader Header.
throws
SipException if CSeq header can't be added for some reason.

        setHeader(cseqHeader);
    
public voidsetCallId(CallIdHeader callId)
Sets the call id header.

param
callId call idHeader (what else could it be?)
throws
SipException if the header can't be set for some reason.

        setHeader(callId);
    
public voidsetCallId(java.lang.String callId)
Gets the CallIdHeader header (null if one does not exist)

param
callId -- the call identifier to be assigned to the call id header
throws
SipException if the header can't be set for some reason.

        if (callIdHeader == null) {
            setHeader(new CallIdHeader());
        }
        callIdHeader.setCallId(callId);
    
public voidsetContent(java.lang.Object content, ContentTypeHeader contentTypeHeader)
Sets the message content after converting the given object to a String.

param
content content to set.
param
contentTypeHeader content type header corresponding to content.
throws
NullPointerException if the 'content' parameter is null.
throws
SipException if the content can't be set for some reason.

        if (content == null) {
            throw new NullPointerException("null content");
        }

        String contentString = content.toString();
        this.setMessageContent(contentString);
        this.setHeader(contentTypeHeader);
        this.removeContent();

        if (content instanceof String) {
            this.messageContent = (String)content;
        } else if (content instanceof byte[]) {
            this.messageContentBytes = (byte[]) content;
        } else this.messageContentObject = content;

        int length = -1;
        if (content instanceof String)
            length = ((String)content).length();
        else if (content instanceof byte[])
            length = ((byte[])content).length;

        ContentLengthHeader h = getContentLengthHeader();
        if (length != -1 && h != null) {
            h.setContentLength(length);
        }
    
public voidsetContent(java.lang.Object content)
Sets the message content after converting the given object to a String.

param
content content to set.
throws
NullPointerException if the content parameter is null.

        if (content == null)
            throw new NullPointerException("null content");

        String contentString = content.toString();
        this.setMessageContent(contentString);
        this.removeContent();

        if (content instanceof String) {
            this.messageContent = (String)content;
        } else if (content instanceof byte[]) {
            this.messageContentBytes = (byte[]) content;
        } else this.messageContentObject = content;

        int length = -1;
        if (content instanceof String)
            length = ((String)content).length();
        else if (content instanceof byte[])
            length = ((byte[])content).length;

        ContentLengthHeader h = getContentLengthHeader();
        if (length != -1 && h != null) {
            h.setContentLength(length);
        }
    
public voidsetContentLength(ContentLengthHeader contentLength)
Sets the content length header.

param
contentLength content length header.
throws
SipException if Content-Length header can't be set for some reason.

        setHeader(contentLength);
    
public voidsetFromHeader(FromHeader from)
Sets the From header field value.

param
from the new From header field value.
throws
SipException if the header can't be set for some reason.

        setHeader(from);
    
public voidsetFromHeaderTag(java.lang.String tag)
Sets the FromHeader Tag.

param
tag -- tag to set in the from header.
throws
SipException if the header can't be set for some reason.

        fromHeader.setTag(tag);
    
public voidsetHeader(Header header)
Attaches a header (replacing the original header).

param
header Header that replaces a header of the same type.
throws
IllegalArgumentException if the header to add is null.
throws
SipException if the header can't be set for some reason.

        if (header == null)
            throw new IllegalArgumentException("null header!");

        if (header instanceof HeaderList) {
            HeaderList hl = (HeaderList) header;
            // Ignore empty lists.
            if (hl.isEmpty())
                return;
        }

        attachHeader(header, true, false);
    
public voidsetHeader(HeaderList sipHeaderList)
Sets the header given a list of headers.

param
sipHeaderList a headerList to set
throws
SipException if the header can't be set for some reason.

        setHeader((Header)sipHeaderList);
    
public voidsetHeaders(java.util.Vector headers)
Sets a header from a linked list of headers.

param
headers -- a list of headers to set.
throws
SipException if some header can't be set for some reason.

        Enumeration elements = headers.elements();
        while (elements.hasMoreElements()) {
            Header sipHeader = (Header) elements.nextElement();
            attachHeader(sipHeader, false);
        }
    
public voidsetMessageContent(java.lang.String type, java.lang.String subType, java.lang.String messageContent)
Sets the message content given type and subtype.

param
type is the message type (eg. application)
param
subType is the message sybtype (eg. sdp)
param
messageContent is the message content as a string.
throws
IllegalArgumentException if some parameter is invalid.

        if (messageContent == null) {
            throw new IllegalArgumentException("messgeContent is null");
        }

        ContentTypeHeader ct = new ContentTypeHeader(type, subType);

        try {
            setHeader(ct);
        } catch (SipException se) {
            throw new IllegalArgumentException(se.getMessage());
        }

        messageContent = messageContent;
        messageContentBytes = null;
        messageContentObject = null;

        ContentLengthHeader h = getContentLengthHeader();
        if (h != null) {
            h.setContentLength(messageContent.length());
        }
    
public voidsetMessageContent(java.lang.String type, java.lang.String subType, byte[] messageContent)
Sets the message content for a given type and subtype.

param
type is the messge type.
param
subType is the message subType.
param
messageContent is the message content as a byte array.
throws
SipException if the message content can't be set.

        ContentTypeHeader ct = new ContentTypeHeader(type, subType);
        setHeader(ct);
        setMessageContent(messageContent);

        ContentLengthHeader h = getContentLengthHeader();
        if (h != null) {
            h.setContentLength(messageContent.length);
        }
    
public voidsetMessageContent(java.lang.String content)
Sets the message content for this message.

param
content Message body as a string.

        ContentLengthHeader h = getContentLengthHeader();

        if (h != null) {
            int clength = (content == null ? 0: content.length());
            h.setContentLength(clength);
        }

        messageContent = content;
        messageContentBytes = null;
        messageContentObject = null;
    
public voidsetMessageContent(byte[] content)
Sets the message content as an array of bytes.

param
content is the content of the message as an array of bytes.

        ContentLengthHeader h = getContentLengthHeader();

        if (h != null) {
            h.setContentLength(content.length);
        }

        messageContentBytes = content;
        messageContent = null;
        messageContentObject = null;
    
public abstract voidsetSIPVersion(java.lang.String sipVersion)
Sets the SIP version header.

param
sipVersion the new version string

public voidsetTo(ToHeader to)
Sets the To header field value.

param
to the new To field value
throws
SipException if the header can't be set for some reason.

        setHeader(to);
    
public voidsetToTag(java.lang.String tag)
Sets the to tag.

param
tag -- tag to set.
throws
SipException if the header can't be set for some reason.

        toHeader.setTag(tag);
    
public voidsetVia(ViaList viaList)
Sets a list of via headers.

param
viaList a list of via headers to add.
throws
SipException if the header can't be set for some reason.

        setHeader(viaList);
    
public voidsetVia(java.util.Vector viaList)
Sets a list of via headers.

param
viaList a list of via headers to add.
throws
SipException if the header can't be set for some reason.

        this.removeHeader(ViaHeader.NAME);
        for (int i = 0; i < viaList.size(); i++) {
            ViaHeader via = (ViaHeader) viaList.elementAt(i);
            this.addHeader(via);
        }