Source Code Cross Referenced for Message.java in  » 6.0-JDK-Modules » j2me » gov » nist » siplite » message » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » gov.nist.siplite.message 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Portions Copyright  2000-2007 Sun Microsystems, Inc. All Rights
0003:         * Reserved.  Use is subject to license terms.
0004:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0005:         * 
0006:         * This program is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU General Public License version
0008:         * 2 only, as published by the Free Software Foundation.
0009:         * 
0010:         * This program is distributed in the hope that it will be useful, but
0011:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0012:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013:         * General Public License version 2 for more details (a copy is
0014:         * included at /legal/license.txt).
0015:         * 
0016:         * You should have received a copy of the GNU General Public License
0017:         * version 2 along with this work; if not, write to the Free Software
0018:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0019:         * 02110-1301 USA
0020:         * 
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0022:         * Clara, CA 95054 or visit www.sun.com if you need additional
0023:         * information or have any questions.
0024:         */
0025:        /*
0026:         */
0027:        package gov.nist.siplite.message;
0028:
0029:        import gov.nist.siplite.header.*;
0030:        import gov.nist.siplite.parser.*;
0031:        import gov.nist.siplite.*;
0032:        import java.util.*;
0033:        import gov.nist.core.*;
0034:        import java.io.UnsupportedEncodingException;
0035:        import javax.microedition.sip.SipException;
0036:
0037:        import com.sun.midp.log.Logging;
0038:        import com.sun.midp.log.LogChannels;
0039:
0040:        /**
0041:         * This is the main SIP Message structure.
0042:         *
0043:         * @see StringMsgParser
0044:         * @see PipelinedMsgParser
0045:         *
0046:         *
0047:         * @version JAIN-SIP-1.1
0048:         *
0049:         *
0050:         *<a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
0051:         *
0052:         * IMPL_NOTE: remove 'Vector headers' because its contents is duplicated in nameTable
0053:         */
0054:        public abstract class Message extends GenericObject {
0055:            /** Class handle. */
0056:            private static Class sipHeaderListClass;
0057:            /** Default encoding string. */
0058:            protected static final String DEFAULT_ENCODING = "UTF-8";
0059:            /** Unparsed headers. */
0060:            protected Vector unrecognizedHeaders;
0061:            /** List of parsed headers (in the order they were added).  */
0062:            protected Vector headers;
0063:            /** From header. */
0064:            protected FromHeader fromHeader;
0065:            /** To header. */
0066:            protected ToHeader toHeader;
0067:            /** C sequence header. */
0068:            protected CSeqHeader cSeqHeader;
0069:            /** Caller identification header. */
0070:            protected CallIdHeader callIdHeader;
0071:            /** Content length header. */
0072:            protected ContentLengthHeader contentLengthHeader;
0073:            // protected MaxForwards maxForwardsHeader;
0074:            /** Body of message content. */
0075:            protected String messageContent;
0076:            /** Length of message content in bytes. */
0077:            protected byte[] messageContentBytes;
0078:            /** Object holding body contents. */
0079:            protected Object messageContentObject;
0080:
0081:            static {
0082:                try {
0083:                    sipHeaderListClass = Class
0084:                            .forName("gov.nist.siplite.header.HeaderList");
0085:                } catch (ClassNotFoundException ex) {
0086:                    InternalErrorHandler.handleException(ex);
0087:                }
0088:            }
0089:
0090:            /** Table of headers indexed by name. */
0091:            private Hashtable nameTable;
0092:
0093:            /**
0094:             * Removes the specified header from "headers" list.
0095:             *
0096:             * @param headerName expanded name of the header to remove.
0097:             */
0098:            private void removeHeaderFromList(String headerName) {
0099:                Enumeration li = headers.elements();
0100:                int index = -1;
0101:
0102:                while (li.hasMoreElements()) {
0103:                    Header sipHeader = (Header) li.nextElement();
0104:                    index++;
0105:
0106:                    String currName = NameMap.expandHeaderName(sipHeader
0107:                            .getName());
0108:
0109:                    if (Utils.equalsIgnoreCase(currName, headerName)) {
0110:                        break;
0111:                    }
0112:                }
0113:
0114:                if (index != -1 && index < headers.size()) {
0115:                    headers.removeElementAt(index);
0116:                }
0117:            }
0118:
0119:            /**
0120:             * Returns true if the header belongs only in a Request.
0121:             *
0122:             * @param sipHeader is the header to test.
0123:             * @return true if header is part of a request
0124:             */
0125:            public static boolean isRequestHeader(Header sipHeader) {
0126:                return sipHeader.getHeaderName().equals(Header.ALERT_INFO)
0127:                        || sipHeader.getHeaderName().equals(Header.IN_REPLY_TO)
0128:                        || sipHeader.getHeaderName().equals(
0129:                                Header.AUTHORIZATION)
0130:                        || sipHeader.getHeaderName()
0131:                                .equals(Header.MAX_FORWARDS)
0132:                        || sipHeader.getHeaderName().equals(Header.PRIORITY)
0133:                        || sipHeader.getHeaderName().equals(
0134:                                Header.PROXY_AUTHORIZATION)
0135:                        || sipHeader.getHeaderName().equals(
0136:                                Header.PROXY_REQUIRE)
0137:                        || sipHeader.getHeaderName().equals(Header.ROUTE)
0138:                        || sipHeader.getHeaderName().equals(Header.SUBJECT)
0139:                        || sipHeader.getHeaderName().equals(
0140:                                Header.ACCEPT_CONTACT);
0141:
0142:            }
0143:
0144:            /**
0145:             * Returns true if the header belongs only in a response.
0146:             *
0147:             * @param sipHeader is the header to test.
0148:             * @return true if header is part of a response
0149:             */
0150:            public static boolean isResponseHeader(Header sipHeader) {
0151:                return sipHeader.getHeaderName().equals(Header.ERROR_INFO)
0152:                        || sipHeader.getHeaderName().equals(
0153:                                Header.PROXY_AUTHENTICATE)
0154:                        || sipHeader.getHeaderName().equals(Header.SERVER)
0155:                        || sipHeader.getHeaderName().equals(Header.UNSUPPORTED)
0156:                        || sipHeader.getHeaderName().equals(Header.RETRY_AFTER)
0157:                        || sipHeader.getHeaderName().equals(Header.WARNING)
0158:                        || sipHeader.getHeaderName().equals(
0159:                                Header.WWW_AUTHENTICATE);
0160:
0161:            }
0162:
0163:            /**
0164:             * Gets a dialog identifier.
0165:             * Generates a string that can be used as a dialog identifier.
0166:             *
0167:             * @param isServer is set to true if this is the UAS
0168:             * and set to false if this is the UAC
0169:             * @return the dialig identifier
0170:             */
0171:            public String getDialogId(boolean isServer) {
0172:                CallIdHeader cid = (CallIdHeader) this .getCallId();
0173:                StringBuffer retval = new StringBuffer(cid.getCallId());
0174:                FromHeader from = (FromHeader) this .getFromHeader();
0175:                ToHeader to = (ToHeader) this .getTo();
0176:                if (!isServer) {
0177:                    if (to.getTag() != null) {
0178:                        retval.append(to.getTag());
0179:                    }
0180:                    if (from.getTag() != null) {
0181:                        retval.append(from.getTag());
0182:                    }
0183:                } else {
0184:                    if (from.getTag() != null) {
0185:                        retval.append(from.getTag());
0186:                    }
0187:                    if (to.getTag() != null) {
0188:                        retval.append(to.getTag());
0189:                    }
0190:                }
0191:                return retval.toString().toLowerCase();
0192:
0193:            }
0194:
0195:            /**
0196:             * Gets a dialog id given the remote tag.
0197:             * @param isServer flag indicating a server request
0198:             * @param toTag the target recipient
0199:             * @return the dialog identifier
0200:             */
0201:            public String getDialogId(boolean isServer, String toTag) {
0202:                FromHeader from = (FromHeader) this .getFromHeader();
0203:                ToHeader to = (ToHeader) this .getTo();
0204:                CallIdHeader cid = (CallIdHeader) this .getCallId();
0205:                StringBuffer retval = new StringBuffer(cid.getCallId());
0206:                if (!isServer) {
0207:                    if (toTag != null) {
0208:                        retval.append(toTag);
0209:                    }
0210:                    if (from.getTag() != null) {
0211:                        retval.append(from.getTag());
0212:                    }
0213:                } else {
0214:                    if (from.getTag() != null) {
0215:                        retval.append(from.getTag());
0216:                    }
0217:                    if (toTag != null) {
0218:                        retval.append(toTag);
0219:                    }
0220:                }
0221:                return retval.toString().toLowerCase();
0222:            }
0223:
0224:            /**
0225:             * Encodes this message as a string. This is more efficient when
0226:             * the payload is a string (rather than a binary array of bytes).
0227:             * If the payload cannot be encoded as a UTF-8 string then it is
0228:             * simply ignored (will not appear in the encoded message).
0229:             * @return The Canonical String representation of the message
0230:             * (including the canonical string representation of
0231:             * the SDP payload if it exists).
0232:             */
0233:            public String encode() {
0234:                StringBuffer encoding = new StringBuffer();
0235:                // Synchronization added because of concurrent modification exception
0236:                // noticed by Lamine Brahimi.
0237:                synchronized (this .headers) {
0238:                    Enumeration it = this .headers.elements();
0239:
0240:                    while (it.hasMoreElements()) {
0241:                        Header siphdr = (Header) it.nextElement();
0242:                        if (!(siphdr instanceof  ContentLengthHeader)) {
0243:                            encoding.append(siphdr.encode());
0244:                        }
0245:                    }
0246:                }
0247:
0248:                // Add the content-length header
0249:                if (contentLengthHeader != null) {
0250:                    encoding.append(contentLengthHeader.encode()).append(
0251:                            Separators.NEWLINE);
0252:                }
0253:
0254:                if (this .messageContentObject != null) {
0255:                    String mbody = this .getContent().toString();
0256:                    encoding.append(mbody);
0257:                } else if (this .messageContent != null
0258:                        || this .messageContentBytes != null) {
0259:                    String content = null;
0260:                    try {
0261:                        if (messageContent != null) {
0262:                            content = messageContent;
0263:                        } else {
0264:                            content = new String(messageContentBytes,
0265:                                    DEFAULT_ENCODING);
0266:                        }
0267:                    } catch (UnsupportedEncodingException ex) {
0268:                        content = "";
0269:                    }
0270:                    encoding.append(content);
0271:                }
0272:
0273:                return encoding.toString();
0274:            }
0275:
0276:            /**
0277:             * Encodes the message as a byte array.
0278:             * Use this when the message payload is a binary byte array.
0279:             *
0280:             * @return The Canonical byte array representation of the message
0281:             * (including the canonical byte array representation of
0282:             * the SDP payload if it exists all in one contiguous byte array).
0283:             *
0284:             */
0285:            public byte[] encodeAsBytes() {
0286:                StringBuffer encoding = new StringBuffer();
0287:                Enumeration it = this .headers.elements();
0288:
0289:                while (it.hasMoreElements()) {
0290:                    Header siphdr = (Header) it.nextElement();
0291:                    if (!(siphdr instanceof  ContentLengthHeader))
0292:                        encoding.append(siphdr.encode());
0293:
0294:                }
0295:                byte[] retval = null;
0296:                byte[] content = this .getRawContent();
0297:                if (content != null) {
0298:                    encoding.append(Header.CONTENT_LENGTH + Separators.COLON
0299:                            + Separators.SP + content.length
0300:                            + Separators.NEWLINE);
0301:                    encoding.append(Separators.NEWLINE);
0302:                    // Append the content
0303:                    byte[] msgarray = null;
0304:                    try {
0305:                        msgarray = encoding.toString().getBytes("UTF-8");
0306:                    } catch (UnsupportedEncodingException ex) {
0307:                        InternalErrorHandler.handleException(ex);
0308:                    }
0309:
0310:                    retval = new byte[msgarray.length + content.length];
0311:                    System.arraycopy(msgarray, 0, retval, 0, msgarray.length);
0312:                    System.arraycopy(content, 0, retval, msgarray.length,
0313:                            content.length);
0314:                } else {
0315:                    // Message content does not exist.
0316:                    encoding.append(Header.CONTENT_LENGTH + Separators.COLON
0317:                            + Separators.SP + '0' + Separators.NEWLINE);
0318:                    encoding.append(Separators.NEWLINE);
0319:                    try {
0320:                        retval = encoding.toString().getBytes("UTF-8");
0321:                    } catch (UnsupportedEncodingException ex) {
0322:                        InternalErrorHandler.handleException(ex);
0323:                    }
0324:                }
0325:                return retval;
0326:            }
0327:
0328:            /**
0329:             * Clones this message (create a new deep physical copy).
0330:             * All headers in the message are cloned.
0331:             * You can modify the cloned copy without affecting
0332:             * the original.
0333:             *
0334:             * @return A cloned copy of this object.
0335:             */
0336:            public Object clone() {
0337:                Message retval = null;
0338:                try {
0339:                    retval = (Message) this .getClass().newInstance();
0340:                } catch (IllegalAccessException ex) {
0341:                    InternalErrorHandler.handleException(ex);
0342:                } catch (InstantiationException ex) {
0343:                    InternalErrorHandler.handleException(ex);
0344:                }
0345:
0346:                Enumeration li = headers.elements();
0347:                while (li.hasMoreElements()) {
0348:                    Header sipHeader = (Header) ((Header) li.nextElement())
0349:                            .clone();
0350:                    try {
0351:                        retval.attachHeader(sipHeader);
0352:                    } catch (SipException ex) {
0353:                        if (Logging.REPORT_LEVEL <= Logging.ERROR) {
0354:                            Logging.report(Logging.ERROR,
0355:                                    LogChannels.LC_JSR180,
0356:                                    "Message.clone(): can't attach header '"
0357:                                            + sipHeader.getName() + "'.");
0358:                            ex.printStackTrace();
0359:                        }
0360:                    }
0361:                }
0362:
0363:                if (retval instanceof  Request) {
0364:                    Request this Request = (Request) this ;
0365:                    RequestLine rl = (RequestLine) (this Request
0366:                            .getRequestLine()).clone();
0367:                    ((Request) retval).setRequestLine(rl);
0368:                } else {
0369:                    Response this Response = (Response) this ;
0370:                    StatusLine sl = (StatusLine) (this Response.getStatusLine())
0371:                            .clone();
0372:                    ((Response) retval).setStatusLine(sl);
0373:                }
0374:
0375:                if (getContent() != null) {
0376:                    try {
0377:                        retval.setContent(getContent(), getContentTypeHeader());
0378:                    } catch (SipException ex) { // Ignore
0379:                        if (Logging.REPORT_LEVEL <= Logging.ERROR) {
0380:                            Logging.report(Logging.ERROR,
0381:                                    LogChannels.LC_JSR180,
0382:                                    "Message.clone(): can't set the content!");
0383:                            ex.printStackTrace();
0384:                        }
0385:                    }
0386:                }
0387:
0388:                return retval;
0389:            }
0390:
0391:            /**
0392:             *
0393:             * Constructor: Initializes lists and list headers.
0394:             * All the headers for which there can be multiple occurances in
0395:             * a message are derived from the HeaderListClass. All singleton
0396:             * headers are derived from Header class.
0397:             *
0398:             */
0399:            public Message() {
0400:                unrecognizedHeaders = new Vector();
0401:                headers = new Vector();
0402:                nameTable = new Hashtable();
0403:            }
0404:
0405:            /**
0406:             * Attaches a header and dies if you get a duplicate header exception.
0407:             * @param h Header to attach.
0408:             * @throws IllegalArgumentException if the header to attach is null.
0409:             * @throws SipException if the header can't be attached for some reason.
0410:             */
0411:            private void attachHeader(Header h)
0412:                    throws IllegalArgumentException, SipException {
0413:                if (h == null)
0414:                    throw new IllegalArgumentException("null header!");
0415:
0416:                if (h instanceof  HeaderList) {
0417:                    HeaderList hl = (HeaderList) h;
0418:                    if (hl.isEmpty()) {
0419:                        // System.out.println("Attaching an empty header: " +
0420:                        // h.getClass().getName());
0421:                        return;
0422:                    }
0423:                }
0424:
0425:                attachHeader(h, false, false);
0426:            }
0427:
0428:            /**
0429:             * Attaches a header (replacing the original header).
0430:             * @param header Header that replaces a header of the same type.
0431:             * @throws IllegalArgumentException if the header to add is null.
0432:             * @throws SipException if the header can't be set for some reason.
0433:             */
0434:            public void setHeader(Header header)
0435:                    throws IllegalArgumentException, SipException {
0436:                if (header == null)
0437:                    throw new IllegalArgumentException("null header!");
0438:
0439:                if (header instanceof  HeaderList) {
0440:                    HeaderList hl = (HeaderList) header;
0441:                    // Ignore empty lists.
0442:                    if (hl.isEmpty())
0443:                        return;
0444:                }
0445:
0446:                attachHeader(header, true, false);
0447:            }
0448:
0449:            /**
0450:             * Sets a header from a linked list of headers.
0451:             *
0452:             * @param headers -- a list of headers to set.
0453:             * @throws SipException if some header can't be set for some reason.
0454:             */
0455:            public void setHeaders(Vector headers) throws SipException {
0456:                Enumeration elements = headers.elements();
0457:                while (elements.hasMoreElements()) {
0458:                    Header sipHeader = (Header) elements.nextElement();
0459:                    attachHeader(sipHeader, false);
0460:                }
0461:            }
0462:
0463:            /**
0464:             * Attaches a header to the end of the existing headers in
0465:             * this Message structure.
0466:             * This is equivalent to the attachHeader(Header,replaceflag,false);
0467:             * which is the normal way in which headers are attached.
0468:             * This was added in support of JAIN-SIP.
0469:             *
0470:             * @since 1.0 (made this public)
0471:             * @param h header to attach.
0472:             * @param replaceflag if true then replace a header if it exists.
0473:             * @throws SipException if the header can't be attached for some reason.
0474:             */
0475:            public void attachHeader(Header h, boolean replaceflag)
0476:                    throws SipException {
0477:                attachHeader(h, replaceflag, false);
0478:            }
0479:
0480:            /**
0481:             * Attaches the header to the SIP Message structure at a specified
0482:             * position in its list of headers.
0483:             *
0484:             * @param header Header to attach.
0485:             * @param replaceFlag If true then replace the existing header.
0486:             * @param top flag to indicate attaching header to the front of list.
0487:             * @throws SipException if the header can't be attached for some reason.
0488:             */
0489:            public void attachHeader(Header header, boolean replaceFlag,
0490:                    boolean top) throws SipException {
0491:                if (header == null) {
0492:                    throw new NullPointerException("null header");
0493:                }
0494:
0495:                // System.out.println(">>> attachHeader( " +
0496:                //                   header + ", " + replaceFlag + ");");
0497:
0498:                Header h;
0499:                String expandedHeaderName = NameMap.expandHeaderName(
0500:                        header.getHeaderName()).toLowerCase();
0501:
0502:                if (ListMap.hasList(header)
0503:                        && !sipHeaderListClass.isAssignableFrom(header
0504:                                .getClass())) {
0505:                    HeaderList hdrList = ListMap.getList(header);
0506:
0507:                    // Actually, hdrList.size() is always 0.
0508:                    if (replaceFlag && (hdrList.size() > 0)) {
0509:                        // remove first element
0510:                        hdrList.removeElement(hdrList.elementAt(0));
0511:                    }
0512:
0513:                    hdrList.add(header);
0514:                    h = hdrList;
0515:                } else {
0516:                    h = header;
0517:                }
0518:
0519:                if (!replaceFlag && nameTable.containsKey(expandedHeaderName)
0520:                        && !(h instanceof  HeaderList)) {
0521:                    // Throw an exception here because according to JSR180:
0522:                    // "The implementations MAY restrict the access to some
0523:                    // headers according to RFC 3261."
0524:                    //
0525:                    // It may happen if this function is called to add a header that
0526:                    // already exist and the only one header of this type may present
0527:                    // (Call-Id, From, To).
0528:                    //
0529:                    throw new SipException(
0530:                            "Header '"
0531:                                    + header.getHeaderName()
0532:                                    + "' already exist. Only one header of this type is allowed.",
0533:                            SipException.INVALID_OPERATION);
0534:                }
0535:
0536:                // Delete the first header with name = headerName
0537:                // from our list structure.
0538:                // If case of HeaderList the whole list is removed
0539:                // to avoid duplication (it is added bellow).
0540:                if (replaceFlag || (h instanceof  HeaderList)) {
0541:                    Enumeration li = headers.elements();
0542:                    int index;
0543:
0544:                    for (index = 0; li.hasMoreElements(); index++) {
0545:                        Header next = (Header) li.nextElement();
0546:                        String currName = NameMap.expandHeaderName(next
0547:                                .getHeaderName());
0548:
0549:                        if (expandedHeaderName.equalsIgnoreCase(currName)) {
0550:                            headers.removeElementAt(index);
0551:                            break;
0552:                        }
0553:                    }
0554:                }
0555:
0556:                Header hRef = h;
0557:
0558:                if (h instanceof  HeaderList) {
0559:                    HeaderList hdrlist = (HeaderList) nameTable
0560:                            .get(expandedHeaderName);
0561:
0562:                    if (hdrlist != null) {
0563:                        if (replaceFlag) {
0564:                            hdrlist.removeFirst();
0565:                        }
0566:
0567:                        hdrlist.concatenate((HeaderList) h, top);
0568:
0569:                        // This is required due to the way that 'concatenate'
0570:                        // is implemented: if 'top' is false, it modifies
0571:                        // the objects itself; otherwise, the list passed
0572:                        // as the first parameter is modified.
0573:                        if (!top) {
0574:                            hRef = hdrlist;
0575:                        }
0576:                    }
0577:                }
0578:
0579:                nameTable.put(expandedHeaderName, hRef);
0580:                headers.addElement(hRef);
0581:
0582:                // Direct accessor fields for frequently accessed headers.
0583:                if (h instanceof  FromHeader) {
0584:                    this .fromHeader = (FromHeader) h;
0585:                } else if (h instanceof  ContentLengthHeader) {
0586:                    this .contentLengthHeader = (ContentLengthHeader) h;
0587:                } else if (h instanceof  ToHeader) {
0588:                    this .toHeader = (ToHeader) h;
0589:                } else if (h instanceof  CSeqHeader) {
0590:                    this .cSeqHeader = (CSeqHeader) h;
0591:                } else if (h instanceof  CallIdHeader) {
0592:                    this .callIdHeader = (CallIdHeader) h;
0593:                }
0594:            }
0595:
0596:            /**
0597:             * Removes a header given its name. If multiple headers of a given name
0598:             * are present then the top flag determines which end to remove headers
0599:             * from.
0600:             *
0601:             * @param headerName is the name of the header to remove.
0602:             * @param top flag that indicates which end of header list to process.
0603:             */
0604:            public void removeHeader(String headerName, boolean top) {
0605:                // System.out.println("removeHeader " + headerName);
0606:
0607:                headerName = NameMap.expandHeaderName(headerName).toLowerCase();
0608:                Header toRemove = (Header) nameTable.get(headerName);
0609:
0610:                // nothing to do then we are done.
0611:                if (toRemove == null)
0612:                    return;
0613:
0614:                if (toRemove instanceof  HeaderList) {
0615:                    HeaderList hdrList = (HeaderList) toRemove;
0616:                    if (top)
0617:                        hdrList.removeFirst();
0618:                    else
0619:                        hdrList.removeLast();
0620:
0621:                    // Clean up empty list
0622:                    if (hdrList.isEmpty()) {
0623:                        removeHeaderFromList(headerName);
0624:                    }
0625:                } else {
0626:                    nameTable.remove(headerName);
0627:
0628:                    if (toRemove instanceof  FromHeader) {
0629:                        this .fromHeader = null;
0630:                    } else if (toRemove instanceof  ToHeader) {
0631:                        this .toHeader = null;
0632:                    } else if (toRemove instanceof  CSeqHeader) {
0633:                        this .cSeqHeader = null;
0634:                    } else if (toRemove instanceof  CallIdHeader) {
0635:                        this .callIdHeader = null;
0636:                    } else if (toRemove instanceof  ContentLengthHeader) {
0637:                        this .contentLengthHeader = null;
0638:                    }
0639:
0640:                    removeHeaderFromList(headerName);
0641:                }
0642:            }
0643:
0644:            /**
0645:             * Removes all headers given its name.
0646:             *
0647:             * @param headerName is the name of the header to remove.
0648:             */
0649:            public void removeHeader(String headerName) {
0650:                if (headerName == null) {
0651:                    throw new NullPointerException("null arg");
0652:                }
0653:
0654:                headerName = NameMap.expandHeaderName(headerName).toLowerCase();
0655:                Header toRemove = (Header) nameTable.get(headerName);
0656:
0657:                // nothing to do then we are done.
0658:                if (toRemove == null)
0659:                    return;
0660:
0661:                nameTable.remove(headerName);
0662:
0663:                // Remove the fast accessor fields.
0664:                if (toRemove instanceof  FromHeader) {
0665:                    this .fromHeader = null;
0666:                } else if (toRemove instanceof  ToHeader) {
0667:                    this .toHeader = null;
0668:                } else if (toRemove instanceof  CSeqHeader) {
0669:                    this .cSeqHeader = null;
0670:                } else if (toRemove instanceof  CallIdHeader) {
0671:                    this .callIdHeader = null;
0672:                } else if (toRemove instanceof  ContentLengthHeader) {
0673:                    this .contentLengthHeader = null;
0674:                }
0675:
0676:                removeHeaderFromList(headerName);
0677:            }
0678:
0679:            /**
0680:             * Generates (compute) a transaction ID for this SIP message.
0681:             * @return A string containing the concatenation of various
0682:             * portions of the FromHeader,To,Via and RequestURI portions
0683:             * of this message as specified in RFC 2543:
0684:             * All responses to a request contain the same values in
0685:             * the Call-ID, CSeqHeader, To, and FromHeader fields
0686:             * (with the possible addition of a tag in the To field
0687:             * (section 10.43)). This allows responses to be matched with requests.
0688:             * Incorporates a fix 
0689:             * for generating transactionIDs when no port is present in the
0690:             * via header.
0691:             * Incorporates a fix 
0692:             *  (converts to lower case when returning the
0693:             * transaction identifier).
0694:             *
0695:             * @return a string that can be used as a transaction identifier
0696:             * for this message. This can be used for matching responses and
0697:             * requests (i.e. an outgoing request and its matching response have
0698:             * the same computed transaction identifier).
0699:             */
0700:            public String getTransactionId() {
0701:                ViaHeader topVia = null;
0702:                if (!this .getViaHeaders().isEmpty()) {
0703:                    topVia = (ViaHeader) this .getViaHeaders().first();
0704:                }
0705:                // Have specified a branch Identifier so we can use it to identify
0706:                // the transaction.
0707:                if (topVia.getBranch() != null
0708:                        && topVia.getBranch().startsWith(
0709:                                SIPConstants.GENERAL_BRANCH_MAGIC_COOKIE)) {
0710:                    // Bis 09 compatible branch assignment algorithm.
0711:                    // implies that the branch id can be used as a transaction
0712:                    // identifier.
0713:                    return topVia.getBranch().toLowerCase();
0714:                } else {
0715:                    // Old style client so construct the transaction identifier
0716:                    // from various fields of the request.
0717:                    StringBuffer retval = new StringBuffer();
0718:                    FromHeader from = (FromHeader) this .getFromHeader();
0719:                    ToHeader to = (ToHeader) this .getTo();
0720:                    String hpFromHeader = from.getUserAtHostPort();
0721:                    retval.append(hpFromHeader).append(":");
0722:                    if (from.hasTag())
0723:                        retval.append(from.getTag()).append(":");
0724:                    String hpTo = to.getUserAtHostPort();
0725:                    retval.append(hpTo).append(":");
0726:                    String cid = this .callIdHeader.getCallId();
0727:                    retval.append(cid).append(":");
0728:                    retval.append(this .cSeqHeader.getSequenceNumber()).append(
0729:                            ":").append(this .cSeqHeader.getMethod());
0730:                    if (topVia != null) {
0731:                        retval.append(":").append(topVia.getSentBy().encode());
0732:                        if (!topVia.getSentBy().hasPort()) {
0733:                            retval.append(":").append(5060);
0734:                        }
0735:                    }
0736:                    String hc = Utils.toHexString(retval.toString()
0737:                            .toLowerCase().getBytes());
0738:                    if (hc.length() < 32)
0739:                        return hc;
0740:                    else
0741:                        return hc.substring(hc.length() - 32, hc.length() - 1);
0742:                }
0743:                // Convert to lower case
0744:            }
0745:
0746:            /**
0747:             * Returns true if this message has a body.
0748:             * @return true if message body included
0749:             */
0750:            public boolean hasContent() {
0751:                return messageContent != null || messageContentBytes != null;
0752:            }
0753:
0754:            /**
0755:             * Returns an iterator for the list of headers in this message.
0756:             * @return an Iterator for the headers of this message.
0757:             */
0758:            public Enumeration getHeaders() {
0759:                return headers.elements();
0760:            }
0761:
0762:            /**
0763:             * Gets the first header of the given name.
0764:             * @param headerName requested header
0765:             * @return header the first header of the given name.
0766:             */
0767:            public Header getHeader(String headerName) {
0768:                if (headerName == null)
0769:                    throw new NullPointerException("bad name");
0770:
0771:                headerName = NameMap.expandHeaderName(headerName).toLowerCase();
0772:                Header sipHeader = (Header) nameTable.get(headerName);
0773:
0774:                if (sipHeader == null) {
0775:                    return null;
0776:                }
0777:
0778:                if (sipHeader instanceof  HeaderList) {
0779:                    return (Header) ((HeaderList) sipHeader).getFirst();
0780:                } else {
0781:                    return (Header) sipHeader;
0782:                }
0783:            }
0784:
0785:            /**
0786:             * Gets the contentType header (null if one does not exist).
0787:             * @return contentType header
0788:             */
0789:            public ContentTypeHeader getContentTypeHeader() {
0790:                return (ContentTypeHeader) getHeader(Header.CONTENT_TYPE);
0791:            }
0792:
0793:            /**
0794:             * Gets the from header.
0795:             * @return the from header.
0796:             */
0797:            public FromHeader getFromHeader() {
0798:                return (FromHeader) fromHeader;
0799:            }
0800:
0801:            /**
0802:             * Gets the Contact list of headers (null if one does not exist).
0803:             * @return List containing Contact headers.
0804:             */
0805:            public ContactList getContactHeaders() {
0806:                return (ContactList) getHeaderList(Header.CONTACT);
0807:            }
0808:
0809:            /**
0810:             * Gets the Via list of headers (null if one does not exist).
0811:             * @return List containing Via headers.
0812:             */
0813:            public ViaList getViaHeaders() {
0814:                return (ViaList) getHeaderList(Header.VIA);
0815:            }
0816:
0817:            /**
0818:             * Gets an iterator to the list of vial headers.
0819:             * @return a list iterator to the list of via headers.
0820:             * public ListIterator getVia() {
0821:             * return this.viaHeaders.listIterator();
0822:             * }
0823:             */
0824:
0825:            /**
0826:             * Sets a list of via headers.
0827:             * @param viaList a list of via headers to add.
0828:             * @throws SipException if the header can't be set for some reason.
0829:             */
0830:            public void setVia(ViaList viaList) throws SipException {
0831:                setHeader(viaList);
0832:            }
0833:
0834:            /**
0835:             * Sets a list of via headers.
0836:             * @param viaList a list of via headers to add.
0837:             * @throws SipException if the header can't be set for some reason.
0838:             */
0839:            public void setVia(Vector viaList) throws SipException {
0840:                this .removeHeader(ViaHeader.NAME);
0841:                for (int i = 0; i < viaList.size(); i++) {
0842:                    ViaHeader via = (ViaHeader) viaList.elementAt(i);
0843:                    this .addHeader(via);
0844:                }
0845:            }
0846:
0847:            /**
0848:             * Sets the header given a list of headers.
0849:             *
0850:             * @param sipHeaderList a headerList to set
0851:             * @throws SipException if the header can't be set for some reason.
0852:             */
0853:            public void setHeader(HeaderList sipHeaderList) throws SipException {
0854:                setHeader((Header) sipHeaderList);
0855:            }
0856:
0857:            /**
0858:             * Gets the topmost via header.
0859:             * @return the top most via header if one exists or null if none exists.
0860:             * @throws SipException if the header can't be set for some reason.
0861:             */
0862:            public ViaHeader getTopmostVia() {
0863:                if (getViaHeaders() == null)
0864:                    return null;
0865:                else
0866:                    return (ViaHeader) (getViaHeaders().getFirst());
0867:            }
0868:
0869:            /**
0870:             * Gets the CSeqHeader list of header (null if one does not exist).
0871:             * @return CSeqHeader header
0872:             */
0873:            public CSeqHeader getCSeqHeader() {
0874:                return cSeqHeader;
0875:            }
0876:
0877:            /**
0878:             * Gets the sequence number.
0879:             * @return the sequence number.
0880:             */
0881:            public int getCSeqHeaderNumber() {
0882:                return cSeqHeader.getSequenceNumber();
0883:            }
0884:
0885:            /**
0886:             * Gets the Route List of headers (null if one does not exist).
0887:             * @return List containing Route headers
0888:             */
0889:            public RouteList getRouteHeaders() {
0890:                return (RouteList) getHeaderList(Header.ROUTE);
0891:            }
0892:
0893:            /**
0894:             * Gets the CallIdHeader header (null if one does not exist).
0895:             *
0896:             * @return Call-ID header.
0897:             */
0898:            public CallIdHeader getCallId() {
0899:                return callIdHeader;
0900:            }
0901:
0902:            /**
0903:             * Sets the call id header.
0904:             *
0905:             * @param callId call idHeader (what else could it be?)
0906:             * @throws SipException if the header can't be set for some reason.
0907:             */
0908:            public void setCallId(CallIdHeader callId) throws SipException {
0909:                setHeader(callId);
0910:            }
0911:
0912:            /**
0913:             * Gets the CallIdHeader header (null if one does not exist)
0914:             *
0915:             * @param callId -- the call identifier to be assigned to the call id header
0916:             * @throws SipException if the header can't be set for some reason.
0917:             */
0918:            public void setCallId(String callId) throws ParseException,
0919:                    SipException {
0920:                if (callIdHeader == null) {
0921:                    setHeader(new CallIdHeader());
0922:                }
0923:                callIdHeader.setCallId(callId);
0924:            }
0925:
0926:            /**
0927:             * Gets the call ID string.
0928:             * A conveniance function that returns the stuff following
0929:             * the header name for the call id header.
0930:             *
0931:             * @return the call identifier.
0932:             *
0933:             */
0934:            public String getCallIdentifier() {
0935:                return callIdHeader.getCallId();
0936:            }
0937:
0938:            /**
0939:             * Gets the RecordRoute header list (null if one does not exist).
0940:             *
0941:             * @return Record-Route header
0942:             */
0943:            public RecordRouteList getRecordRouteHeaders() {
0944:                return (RecordRouteList) this 
0945:                        .getHeaderList(Header.RECORD_ROUTE);
0946:            }
0947:
0948:            /**
0949:             * Gets the To header (null if one does not exist).
0950:             * @return To header
0951:             */
0952:            public ToHeader getTo() {
0953:                return (ToHeader) toHeader;
0954:            }
0955:
0956:            /**
0957:             * Sets the To header field  value.
0958:             * @param to the new To field value
0959:             * @throws SipException if the header can't be set for some reason.
0960:             */
0961:            public void setTo(ToHeader to) throws SipException {
0962:                setHeader(to);
0963:            }
0964:
0965:            /**
0966:             * Sets the From header field value.
0967:             * @param from the new From header field  value.
0968:             * @throws SipException if the header can't be set for some reason.
0969:             */
0970:            public void setFromHeader(FromHeader from) throws SipException {
0971:                setHeader(from);
0972:            }
0973:
0974:            /**
0975:             * Gets the ContentLengthHeader header (null if one does not exist).
0976:             *
0977:             * @return content-length header.
0978:             */
0979:            public ContentLengthHeader getContentLengthHeader() {
0980:                return contentLengthHeader;
0981:            }
0982:
0983:            /**
0984:             * Gets the message body as a string.
0985:             * If the message contains a content type header with a specified
0986:             * charset, and if the payload has been read as a byte array, then
0987:             * it is returned encoded into this charset.
0988:             *
0989:             * @return Message body (as a string)
0990:             */
0991:            public String getMessageContent()
0992:                    throws UnsupportedEncodingException {
0993:                if (this .messageContent == null
0994:                        && this .messageContentBytes == null)
0995:                    return null;
0996:                else if (this .messageContent == null) {
0997:                    ContentTypeHeader contentTypeHeader = (ContentTypeHeader) this .nameTable
0998:                            .get(Header.CONTENT_TYPE.toLowerCase());
0999:                    if (contentTypeHeader != null) {
1000:                        String charset = contentTypeHeader.getCharset();
1001:                        if (charset != null) {
1002:                            this .messageContent = new String(
1003:                                    messageContentBytes, charset);
1004:                        } else {
1005:                            this .messageContent = new String(
1006:                                    messageContentBytes, DEFAULT_ENCODING);
1007:                        }
1008:                    } else
1009:                        this .messageContent = new String(messageContentBytes,
1010:                                DEFAULT_ENCODING);
1011:                }
1012:                return this .messageContent;
1013:            }
1014:
1015:            /**
1016:             * Gets the message content as an array of bytes.
1017:             * If the payload has been read as a String then it is decoded using
1018:             * the charset specified in the content type header if it exists.
1019:             * Otherwise, it is encoded using the default encoding which is
1020:             * UTF-8.
1021:             *
1022:             * @return an array of bytes that is the message payload.
1023:             *
1024:             */
1025:            public byte[] getRawContent() {
1026:                try {
1027:                    if (this .messageContent == null
1028:                            && this .messageContentBytes == null
1029:                            && this .messageContentObject == null) {
1030:                        return null;
1031:                    } else if (this .messageContentObject != null) {
1032:                        String messageContent = this .messageContentObject
1033:                                .toString();
1034:                        byte[] messageContentBytes;
1035:                        ContentTypeHeader contentTypeHeader = (ContentTypeHeader) this .nameTable
1036:                                .get(Header.CONTENT_TYPE.toLowerCase());
1037:                        if (contentTypeHeader != null) {
1038:                            String charset = contentTypeHeader.getCharset();
1039:                            if (charset != null) {
1040:                                messageContentBytes = messageContent
1041:                                        .getBytes(charset);
1042:                            } else {
1043:                                messageContentBytes = messageContent
1044:                                        .getBytes(DEFAULT_ENCODING);
1045:                            }
1046:                        } else
1047:                            messageContentBytes = messageContent
1048:                                    .getBytes(DEFAULT_ENCODING);
1049:                        return messageContentBytes;
1050:                    } else if (this .messageContent != null) {
1051:                        byte[] messageContentBytes;
1052:                        ContentTypeHeader contentTypeHeader = (ContentTypeHeader) this .nameTable
1053:                                .get(Header.CONTENT_TYPE.toLowerCase());
1054:                        if (contentTypeHeader != null) {
1055:                            String charset = contentTypeHeader.getCharset();
1056:                            if (charset != null) {
1057:                                messageContentBytes = this .messageContent
1058:                                        .getBytes(charset);
1059:                            } else {
1060:                                messageContentBytes = this .messageContent
1061:                                        .getBytes(DEFAULT_ENCODING);
1062:                            }
1063:                        } else
1064:                            messageContentBytes = this .messageContent
1065:                                    .getBytes(DEFAULT_ENCODING);
1066:                        return messageContentBytes;
1067:                    } else {
1068:                        return messageContentBytes;
1069:                    }
1070:                } catch (UnsupportedEncodingException ex) {
1071:                    InternalErrorHandler.handleException(ex);
1072:                    return null;
1073:                }
1074:            }
1075:
1076:            /**
1077:             * Sets the message content given type and subtype.
1078:             *
1079:             * @param type is the message type (eg. application)
1080:             * @param subType is the message sybtype (eg. sdp)
1081:             * @param messageContent is the message content as a string.
1082:             * @throws IllegalArgumentException if some parameter is invalid.
1083:             */
1084:            public void setMessageContent(String type, String subType,
1085:                    String messageContent) throws IllegalArgumentException {
1086:                if (messageContent == null) {
1087:                    throw new IllegalArgumentException("messgeContent is null");
1088:                }
1089:
1090:                ContentTypeHeader ct = new ContentTypeHeader(type, subType);
1091:
1092:                try {
1093:                    setHeader(ct);
1094:                } catch (SipException se) {
1095:                    throw new IllegalArgumentException(se.getMessage());
1096:                }
1097:
1098:                messageContent = messageContent;
1099:                messageContentBytes = null;
1100:                messageContentObject = null;
1101:
1102:                ContentLengthHeader h = getContentLengthHeader();
1103:                if (h != null) {
1104:                    h.setContentLength(messageContent.length());
1105:                }
1106:            }
1107:
1108:            /**
1109:             * Sets the message content after converting the given object to a
1110:             * String.
1111:             *
1112:             * @param content content to set.
1113:             * @param contentTypeHeader content type header corresponding to
1114:             * content.
1115:             * @throws NullPointerException if the 'content' parameter is null.
1116:             * @throws SipException if the content can't be set for some reason.
1117:             */
1118:            public void setContent(Object content,
1119:                    ContentTypeHeader contentTypeHeader) throws SipException {
1120:                if (content == null) {
1121:                    throw new NullPointerException("null content");
1122:                }
1123:
1124:                String contentString = content.toString();
1125:                this .setMessageContent(contentString);
1126:                this .setHeader(contentTypeHeader);
1127:                this .removeContent();
1128:
1129:                if (content instanceof  String) {
1130:                    this .messageContent = (String) content;
1131:                } else if (content instanceof  byte[]) {
1132:                    this .messageContentBytes = (byte[]) content;
1133:                } else
1134:                    this .messageContentObject = content;
1135:
1136:                int length = -1;
1137:                if (content instanceof  String)
1138:                    length = ((String) content).length();
1139:                else if (content instanceof  byte[])
1140:                    length = ((byte[]) content).length;
1141:
1142:                ContentLengthHeader h = getContentLengthHeader();
1143:                if (length != -1 && h != null) {
1144:                    h.setContentLength(length);
1145:                }
1146:            }
1147:
1148:            /**
1149:             * Sets the message content after converting the given object to a
1150:             * String.
1151:             *
1152:             * @param content content to set.
1153:             * @throws NullPointerException if the content parameter is null.
1154:             */
1155:            public void setContent(Object content) {
1156:                if (content == null)
1157:                    throw new NullPointerException("null content");
1158:
1159:                String contentString = content.toString();
1160:                this .setMessageContent(contentString);
1161:                this .removeContent();
1162:
1163:                if (content instanceof  String) {
1164:                    this .messageContent = (String) content;
1165:                } else if (content instanceof  byte[]) {
1166:                    this .messageContentBytes = (byte[]) content;
1167:                } else
1168:                    this .messageContentObject = content;
1169:
1170:                int length = -1;
1171:                if (content instanceof  String)
1172:                    length = ((String) content).length();
1173:                else if (content instanceof  byte[])
1174:                    length = ((byte[]) content).length;
1175:
1176:                ContentLengthHeader h = getContentLengthHeader();
1177:                if (length != -1 && h != null) {
1178:                    h.setContentLength(length);
1179:                }
1180:            }
1181:
1182:            /**
1183:             * Gets the content of the header.
1184:             *
1185:             * @return the content of the sip message.
1186:             */
1187:            public Object getContent() {
1188:                if (this .messageContentObject != null)
1189:                    return messageContentObject;
1190:                else if (this .messageContentBytes != null)
1191:                    return this .messageContentBytes;
1192:                else if (this .messageContent != null)
1193:                    return this .messageContent;
1194:                else
1195:                    return null;
1196:            }
1197:
1198:            /**
1199:             * Sets the message content for a given type and subtype.
1200:             *
1201:             * @param type is the messge type.
1202:             * @param subType is the message subType.
1203:             * @param messageContent is the message content as a byte array.
1204:             * @throws SipException if the message content can't be set.
1205:             */
1206:            public void setMessageContent(String type, String subType,
1207:                    byte[] messageContent) throws SipException {
1208:                ContentTypeHeader ct = new ContentTypeHeader(type, subType);
1209:                setHeader(ct);
1210:                setMessageContent(messageContent);
1211:
1212:                ContentLengthHeader h = getContentLengthHeader();
1213:                if (h != null) {
1214:                    h.setContentLength(messageContent.length);
1215:                }
1216:            }
1217:
1218:            /**
1219:             * Sets the message content for this message.
1220:             *
1221:             * @param content Message body as a string.
1222:             */
1223:            public void setMessageContent(String content) {
1224:                ContentLengthHeader h = getContentLengthHeader();
1225:
1226:                if (h != null) {
1227:                    int clength = (content == null ? 0 : content.length());
1228:                    h.setContentLength(clength);
1229:                }
1230:
1231:                messageContent = content;
1232:                messageContentBytes = null;
1233:                messageContentObject = null;
1234:            }
1235:
1236:            /**
1237:             * Sets the message content as an array of bytes.
1238:             *
1239:             * @param content is the content of the message as an array of bytes.
1240:             */
1241:            public void setMessageContent(byte[] content) {
1242:                ContentLengthHeader h = getContentLengthHeader();
1243:
1244:                if (h != null) {
1245:                    h.setContentLength(content.length);
1246:                }
1247:
1248:                messageContentBytes = content;
1249:                messageContent = null;
1250:                messageContentObject = null;
1251:            }
1252:
1253:            /**
1254:             * Removes the message content if it exists.
1255:             */
1256:            public void removeContent() {
1257:                messageContent = null;
1258:                messageContentBytes = null;
1259:                messageContentObject = null;
1260:            }
1261:
1262:            /**
1263:             * Gets a SIP header or Header list given its name.
1264:             * @param headerName is the name of the header to get.
1265:             * @return a header or header list that contians the retrieved header.
1266:             */
1267:            public Enumeration getHeaders(String headerName) {
1268:                if (headerName == null) {
1269:                    throw new NullPointerException("null headerName");
1270:                }
1271:
1272:                Header sipHeader = (Header) nameTable.get(NameMap
1273:                        .expandHeaderName(headerName).toLowerCase());
1274:
1275:                // empty iterator
1276:                if (sipHeader == null) {
1277:                    return new Vector().elements();
1278:                }
1279:
1280:                if (sipHeader instanceof  HeaderList) {
1281:                    return ((HeaderList) sipHeader).getElements();
1282:                } else {
1283:                    Vector v = new Vector();
1284:                    v.addElement(sipHeader);
1285:                    return v.elements();
1286:                }
1287:            }
1288:
1289:            /**
1290:             * Gets a SIP Header list given its name.
1291:             * @param headerName is the name of the header to get.
1292:             * @return a header list that contains the retrieved header.
1293:             */
1294:            public HeaderList getHeaderList(String headerName) {
1295:                Header header = (Header) nameTable.get(NameMap
1296:                        .expandHeaderName(headerName).toLowerCase());
1297:
1298:                if (header == null) {
1299:                    return null;
1300:                }
1301:
1302:                if (header instanceof  HeaderList) {
1303:                    return (HeaderList) header;
1304:                } else {
1305:                    HeaderList hl = new HeaderList();
1306:                    hl.add(header);
1307:                    return hl;
1308:                }
1309:            }
1310:
1311:            /**
1312:             * Returns true if the Message has a header of the given name.
1313:             *
1314:             * @param headerName is the header name for which we are testing.
1315:             * @return true if the header is present in the message
1316:             */
1317:            public boolean hasHeader(String headerName) {
1318:                return nameTable.containsKey(NameMap.expandHeaderName(
1319:                        headerName).toLowerCase());
1320:            }
1321:
1322:            /**
1323:             * Returns true if the message has a FromHeader header tag.
1324:             *
1325:             * @return true if the message has a from header and that header has
1326:             * a tag.
1327:             */
1328:            public boolean hasFromHeaderTag() {
1329:                return fromHeader != null && fromHeader.getTag() != null;
1330:            }
1331:
1332:            /**
1333:             * Returns true if the message has a To header tag.
1334:             *
1335:             * @return true if the message has a to header and that header has
1336:             * a tag.
1337:             */
1338:            public boolean hasToTag() {
1339:                return toHeader != null && toHeader.getTag() != null;
1340:            }
1341:
1342:            /**
1343:             * Returns the from tag.
1344:             *
1345:             * @return the tag from the from header.
1346:             *
1347:             */
1348:            public String getFromHeaderTag() {
1349:                return fromHeader == null ? null : fromHeader.getTag();
1350:            }
1351:
1352:            /**
1353:             * Sets the FromHeader Tag.
1354:             *
1355:             * @param tag -- tag to set in the from header.
1356:             * @throws SipException if the header can't be set for some reason.
1357:             */
1358:            public void setFromHeaderTag(String tag) throws SipException {
1359:                fromHeader.setTag(tag);
1360:            }
1361:
1362:            /**
1363:             * Sets the to tag.
1364:             *
1365:             * @param tag -- tag to set.
1366:             * @throws SipException if the header can't be set for some reason.
1367:             */
1368:            public void setToTag(String tag) throws SipException {
1369:                toHeader.setTag(tag);
1370:            }
1371:
1372:            /**
1373:             * Returns the To tag.
1374:             * @return the To tag field
1375:             */
1376:            public String getToTag() {
1377:                return toHeader == null ? null : toHeader.getTag();
1378:            }
1379:
1380:            /**
1381:             * Returns the encoded first line.
1382:             * @return the first line
1383:             */
1384:            public abstract String getFirstLine();
1385:
1386:            /**
1387:             * Adds a SIP header.
1388:             * @param sipHeader -- sip header to add.
1389:             * @throws SipException if the header can't be added for some reason.
1390:             */
1391:            public void addHeader(Header sipHeader) throws SipException {
1392:                Header sh = (Header) sipHeader;
1393:                // Add the header value topmost of this type of headers
1394:                // as required by JSR180.
1395:                attachHeader(sh, false, true);
1396:
1397:                /*
1398:                if (sipHeader instanceof ViaHeader) {
1399:                    attachHeader(sh, false, true);
1400:                } else {
1401:                    attachHeader(sh, false, false);
1402:                }
1403:                 */
1404:            }
1405:
1406:            /**
1407:             * Adds a header to the unparsed list of headers.
1408:             *
1409:             * @param unparsed -- unparsed header to add to the list.
1410:             */
1411:            public void addUnparsed(String unparsed) {
1412:                unrecognizedHeaders.addElement(unparsed);
1413:            }
1414:
1415:            /**
1416:             * Adds a SIP header.
1417:             * @param sipHeader -- string version of SIP header to add.
1418:             * @throws SipException if the header can't be added for some reason.
1419:             */
1420:            public void addHeader(String sipHeader) throws SipException {
1421:                String hdrString = sipHeader.trim() + "\n";
1422:                try {
1423:                    HeaderParser parser = ParserFactory.createParser(sipHeader);
1424:                    Header sh = parser.parse();
1425:                    attachHeader(sh, false);
1426:                } catch (ParseException ex) {
1427:                    unrecognizedHeaders.addElement(hdrString);
1428:                }
1429:            }
1430:
1431:            /**
1432:             * Gets a list containing the unrecognized headers.
1433:             * @return a linked list containing unrecongnized headers.
1434:             */
1435:            public Enumeration getUnrecognizedHeaders() {
1436:                return unrecognizedHeaders.elements();
1437:            }
1438:
1439:            /**
1440:             * Gets the header names.
1441:             *
1442:             * @return a list iterator to a list of header names. These are ordered
1443:             * in the same order as are present in the message.
1444:             */
1445:            public Enumeration getHeaderNames() {
1446:                Enumeration li = this .headers.elements();
1447:                Vector retval = new Vector();
1448:
1449:                while (li.hasMoreElements()) {
1450:                    Header sipHeader = (Header) li.nextElement();
1451:                    String name = sipHeader.getName();
1452:                    retval.addElement(name);
1453:                }
1454:
1455:                return retval.elements();
1456:            }
1457:
1458:            /**
1459:             * Compares for equality.
1460:             *
1461:             * @param other the other object to compare with.
1462:             * @return true if object matches
1463:             */
1464:            public boolean equals(Object other) {
1465:                if (!other.getClass().equals(this .getClass()))
1466:                    return false;
1467:
1468:                Message otherMessage = (Message) other;
1469:                Enumeration values = this .nameTable.elements();
1470:                Hashtable otherNameTable = otherMessage.nameTable;
1471:
1472:                if (otherNameTable.size() != nameTable.size())
1473:                    return false;
1474:
1475:                while (values.hasMoreElements()) {
1476:                    Header mine = (Header) values.nextElement();
1477:                    // maybe short form
1478:                    String mineName = NameMap.expandHeaderName(
1479:                            mine.getHeaderName()).trim().toLowerCase();
1480:                    Header hisHeader = (Header) otherNameTable.get(mineName);
1481:                    String his = null;
1482:                    if (hisHeader != null) {
1483:                        his = hisHeader.toString().trim();
1484:                    }
1485:
1486:                    if (his == null) {
1487:                        return false;
1488:                    } else if (!his.equals(mine.toString().trim())) {
1489:                        return false;
1490:                    }
1491:                }
1492:
1493:                return true;
1494:            }
1495:
1496:            /**
1497:             * Sets the content length header.
1498:             *
1499:             * @param contentLength content length header.
1500:             * @throws SipException if Content-Length header can't be set
1501:             * for some reason.
1502:             */
1503:            public void setContentLength(ContentLengthHeader contentLength)
1504:                    throws SipException {
1505:                setHeader(contentLength);
1506:            }
1507:
1508:            /**
1509:             * Sets the CSeqHeader header.
1510:             *
1511:             * @param cseqHeader CSeqHeader Header.
1512:             * @throws SipException if CSeq header can't be added for some reason.
1513:             */
1514:            public void setCSeqHeader(CSeqHeader cseqHeader)
1515:                    throws SipException {
1516:                setHeader(cseqHeader);
1517:            }
1518:
1519:            /**
1520:             * Sets the SIP version header.
1521:             * @param sipVersion the new version string
1522:             */
1523:            public abstract void setSIPVersion(String sipVersion)
1524:                    throws ParseException;
1525:
1526:            /**
1527:             * Gets the SIP vesrion string.
1528:             * @return the SIP version string
1529:             */
1530:            public abstract String getSIPVersion();
1531:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.