Source Code Cross Referenced for Request.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) 


001:        /*
002:         * Portions Copyright  2000-2007 Sun Microsystems, Inc. All Rights
003:         * Reserved.  Use is subject to license terms.
004:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005:         * 
006:         * This program is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU General Public License version
008:         * 2 only, as published by the Free Software Foundation.
009:         * 
010:         * This program is distributed in the hope that it will be useful, but
011:         * WITHOUT ANY WARRANTY; without even the implied warranty of
012:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013:         * General Public License version 2 for more details (a copy is
014:         * included at /legal/license.txt).
015:         * 
016:         * You should have received a copy of the GNU General Public License
017:         * version 2 along with this work; if not, write to the Free Software
018:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019:         * 02110-1301 USA
020:         * 
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022:         * Clara, CA 95054 or visit www.sun.com if you need additional
023:         * information or have any questions.
024:         */
025:        /*
026:         */
027:        package gov.nist.siplite.message;
028:
029:        import gov.nist.core.*;
030:        import gov.nist.siplite.address.*;
031:        import gov.nist.siplite.header.*;
032:        import gov.nist.siplite.SIPConstants;
033:        import java.util.*;
034:        import java.io.UnsupportedEncodingException;
035:        import javax.microedition.sip.SipException;
036:
037:        import com.sun.midp.log.Logging;
038:        import com.sun.midp.log.LogChannels;
039:        import gov.nist.microedition.io.j2me.sip.DistributedRandom;
040:
041:        /**
042:         * The SIP Request structure-- this belongs to the parser who fills it up.
043:         *
044:         * @version JAIN-SIP-1.1
045:         *
046:         * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
047:         *
048:         */
049:        public final class Request extends Message {
050:            /** Acknowledgement request. */
051:            public static final String ACK = "ACK";
052:
053:            /** End of session request. */
054:            public static final String BYE = "BYE";
055:
056:            /** Terminate session request. */
057:            public static final String CANCEL = "CANCEL";
058:
059:            /** Invitation request. */
060:            public static final String INVITE = "INVITE";
061:
062:            /** Optional settings request. */
063:            public static final String OPTIONS = "OPTIONS";
064:
065:            /** Regsitration request. */
066:            public static final String REGISTER = "REGISTER";
067:
068:            /** Notification request. */
069:            public static final String NOTIFY = "NOTIFY";
070:
071:            /** Subscription for notification request. */
072:            public static final String SUBSCRIBE = "SUBSCRIBE";
073:
074:            /** Message request. */
075:            public static final String MESSAGE = "MESSAGE";
076:
077:            /** Redirection request. */
078:            public static final String REFER = "REFER";
079:
080:            /** Basic information request. */
081:            public static final String INFO = "INFO";
082:
083:            /** PRACK ??? RFC. */
084:            public static final String PRACK = "PRACK";
085:
086:            /** Update request. */
087:            public static final String UPDATE = "UPDATE";
088:
089:            /** Publish request. */
090:            public static final String PUBLISH = "PUBLISH";
091:
092:            /** Default user name is "ip". */
093:            public static final String DEFAULT_USER = "ip";
094:
095:            /** Default time to live is 1 second. */
096:            public static final int DEFAULT_TTL = 1;
097:
098:            /** Default transport is "udp". */
099:            public static final String DEFAULT_TRANSPORT = SIPConstants.TRANSPORT_UDP;
100:
101:            /** Default method is to intiate an INVITE. */
102:            public static final String DEFAULT_METHOD = INVITE;
103:
104:            /** Current transaction pointer. */
105:            private Object transactionPointer;
106:
107:            /** Current requestline. */
108:            protected RequestLine requestLine;
109:
110:            /**
111:             * Gets the Request Line of the Request.
112:             * @return the request line of the SIP Request.
113:             */
114:            public RequestLine getRequestLine() {
115:                return requestLine;
116:            }
117:
118:            /**
119:             * Sets the request line of the SIP Request.
120:             * @param requestLine is the request line to set in the SIP Request.
121:             */
122:            public void setRequestLine(RequestLine requestLine) {
123:                this .requestLine = requestLine;
124:            }
125:
126:            /**
127:             * Constructor.
128:             */
129:            public Request() {
130:                super ();
131:            }
132:
133:            /**
134:             * Checks header for constraints.
135:             * <pre>
136:             * (1) Invite options and bye requests can only have SIP URIs in the
137:             * contact headers.
138:             * (2) Request must have cseq, to and from and via headers.
139:             * (3) Method in request URI must match that in CSEQ.
140:             * </pre>
141:             */
142:            protected void checkHeaders() throws ParseException {
143:                String prefix = "Missing Header ";
144:
145:                /* Check for required headers */
146:
147:                if (getCSeqHeader() == null) {
148:                    throw new ParseException(prefix + Header.CSEQ, 0);
149:                }
150:                if (getTo() == null) {
151:                    throw new ParseException(prefix + Header.TO, 0);
152:                }
153:                if (getFromHeader() == null) {
154:                    throw new ParseException(prefix + Header.FROM, 0);
155:                }
156:                if (getViaHeaders() == null) {
157:                    throw new ParseException(prefix + Header.VIA, 0);
158:                }
159:
160:                /*
161:                 * BUGBUG
162:                 * Need to revisit this check later...
163:                 * for now we just leave this to the
164:                 * application to catch.
165:                 */
166:
167:                if (requestLine != null
168:                        && requestLine.getMethod() != null
169:                        && getCSeqHeader().getMethod() != null
170:                        && compareToIgnoreCase(requestLine.getMethod(),
171:                                getCSeqHeader().getMethod()) != 0) {
172:                    throw new ParseException(
173:                            "CSEQ method mismatch with Request-Line ", 0);
174:
175:                }
176:
177:            }
178:
179:            /**
180:             * Sets the default values in the request URI if necessary.
181:             */
182:            protected void setDefaults() {
183:                // The request line may be unparseable (set to null by the
184:                // exception handler.
185:                if (requestLine == null)
186:                    return;
187:                String method = requestLine.getMethod();
188:                // The requestLine may be malformed!
189:                if (method == null)
190:                    return;
191:                URI u = requestLine.getUri();
192:                if (u == null)
193:                    return;
194:                if (method.compareTo(REGISTER) == 0
195:                        || method.compareTo(INVITE) == 0) {
196:                    if (u instanceof  SipURI) {
197:                        SipURI sipUri = (SipURI) u;
198:                        sipUri.setUserParam(DEFAULT_USER);
199:                        try {
200:                            sipUri.setTransportParam(DEFAULT_TRANSPORT);
201:                        } catch (ParseException ex) {
202:                        }
203:                    }
204:                }
205:            }
206:
207:            /**
208:             * Patch up the request line as necessary.
209:             */
210:            protected void setRequestLineDefaults() {
211:                String method = requestLine.getMethod();
212:                if (method == null) {
213:                    CSeqHeader cseq = (CSeqHeader) this .getCSeqHeader();
214:                    if (cseq != null) {
215:                        method = cseq.getMethod();
216:                        requestLine.setMethod(method);
217:                    }
218:                }
219:            }
220:
221:            /**
222:             * A conveniance function to access the Request URI.
223:             * @return the requestURI if it exists.
224:             */
225:            public URI getRequestURI() {
226:                if (this .requestLine == null)
227:                    return null;
228:                else
229:                    return this .requestLine.getUri();
230:            }
231:
232:            /**
233:             * Sets the RequestURI of Request. The Request-URI is a SIP or
234:             * SIPS URI or a general URI. It indicates the user or service to which
235:             * this request is being addressed. SIP elements MAY support
236:             * Request-URIs with schemes other than "sip" and "sips", for
237:             * example the "tel" URI scheme. SIP elements MAY translate
238:             * non-SIP URIs using any mechanism at their disposal, resulting
239:             * in SIP URI, SIPS URI, or some other scheme.
240:             *
241:             * @param uri the new Request URI of this request message
242:             */
243:            public void setRequestURI(URI uri) {
244:                if (this .requestLine == null) {
245:                    this .requestLine = new RequestLine();
246:                }
247:                this .requestLine.setUri((URI) uri);
248:            }
249:
250:            /**
251:             * Sets the method.
252:             * @param method is the method to set.
253:             * @throws IllegalArgumentException if the method is null
254:             */
255:            public void setMethod(String method)
256:                    throws IllegalArgumentException {
257:                if (method == null)
258:                    throw new IllegalArgumentException("null method");
259:                if (this .requestLine == null) {
260:                    this .requestLine = new RequestLine();
261:                }
262:                this .requestLine.setMethod(method);
263:                if (this .cSeqHeader != null) {
264:                    this .cSeqHeader.setMethod(method);
265:                }
266:            }
267:
268:            /**
269:             * Gets the method from the request line.
270:             * @return the method from the request line if the method exits and
271:             * null if the request line or the method does not exist.
272:             */
273:            public String getMethod() {
274:                if (requestLine == null)
275:                    return null;
276:                else
277:                    return requestLine.getMethod();
278:            }
279:
280:            /**
281:             * Encodes the SIP Request as a string.
282:             *
283:             * @return an encoded String containing the encoded SIP Message.
284:             */
285:
286:            public String encode() {
287:                String retval;
288:                if (requestLine != null) {
289:                    this .setRequestLineDefaults();
290:                    retval = requestLine.encode() + super .encode();
291:                } else
292:                    retval = super .encode();
293:                return retval;
294:            }
295:
296:            /**
297:             * Alias for encode above.
298:             * @return encoded string of object contents
299:             */
300:            public String toString() {
301:                return this .encode();
302:            }
303:
304:            /**
305:             * Makes a clone (deep copy) of this object.
306:             * You can use this if you
307:             * want to modify a request while preserving the original
308:             *
309:             * @return a deep copy of this object.
310:             */
311:
312:            public Object clone() {
313:
314:                Request retval = (Request) super .clone();
315:                if (this .requestLine != null) {
316:                    retval.requestLine = (RequestLine) this .requestLine.clone();
317:                    retval.setRequestLineDefaults();
318:                }
319:                return retval;
320:            }
321:
322:            /**
323:             * Compares for equality.
324:             *
325:             * @param other object to compare ourselves with.
326:             * @return true if objects match
327:             */
328:            public boolean equals(Object other) {
329:                if (!this .getClass().equals(other.getClass()))
330:                    return false;
331:                Request that = (Request) other;
332:
333:                boolean retval = requestLine.equals(that.requestLine)
334:                        && super .equals(other);
335:
336:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION && !retval) {
337:                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
338:                            "this ... >>>>" + encode());
339:                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
340:                            "other ... >>>>" + that.encode());
341:                }
342:
343:                return retval;
344:            }
345:
346:            /**
347:             * Encodes this into a byte array.
348:             * This is used when the body has been set as a binary array
349:             * and you want to encode the body as a byte array for transmission.
350:             *
351:             * @return a byte array containing the Request encoded as a byte
352:             * array.
353:             */
354:            public byte[] encodeAsBytes() {
355:                byte[] rlbytes = null;
356:                if (requestLine != null) {
357:                    try {
358:                        rlbytes = requestLine.encode().getBytes("UTF-8");
359:                    } catch (UnsupportedEncodingException ex) {
360:                        InternalErrorHandler.handleException(ex);
361:                    }
362:                }
363:                byte[] super bytes = super .encodeAsBytes();
364:                byte[] retval = new byte[rlbytes.length + super bytes.length];
365:                int i = 0;
366:                System.arraycopy(rlbytes, 0, retval, 0, rlbytes.length);
367:                System.arraycopy(super bytes, 0, retval, rlbytes.length,
368:                        super bytes.length);
369:                return retval;
370:            }
371:
372:            /**
373:             * Creates a default Response message for this request. Note
374:             * You must add the necessary tags to outgoing responses if need
375:             * be. For efficiency, this method does not clone the incoming
376:             * request. If you want to modify the outgoing response, be sure
377:             * to clone the incoming request as the headers are shared and
378:             * any modification to the headers of the outgoing response will
379:             * result in a modification of the incoming request.
380:             * Tag fields are just copied from the incoming request.
381:             * Contact headers are removed from the incoming request.
382:             * Added by Jeff Keyser.
383:             *
384:             * @param statusCode Status code for the response.
385:             * Reason phrase is generated.
386:             *
387:             * @return A Response with the status and reason supplied, and a copy
388:             *of all the original headers from this request.
389:             */
390:            public Response createResponse(int statusCode) {
391:                String reasonPhrase = Response.getReasonPhrase(statusCode);
392:                return createResponse(statusCode, reasonPhrase);
393:            }
394:
395:            /**
396:             * Creates a default Response message for this request. Note
397:             * You must add the necessary tags to outgoing responses if need
398:             * be. For efficiency, this method does not clone the incoming
399:             * request. If you want to modify the outgoing response, be sure
400:             * to clone the incoming request as the headers are shared and
401:             * any modification to the headers of the outgoing response will
402:             * result in a modification of the incoming request.
403:             * Tag fields are just copied from the incoming request.
404:             * Contact headers are removed from the incoming request.
405:             * Added by Jeff Keyser. Route headers are not added to the
406:             * response.
407:             *
408:             * @param statusCode Status code for the response.
409:             * @param reasonPhrase Reason phrase for this response.
410:             * @return A Response with the status and reason supplied.
411:             * @throws IllegalArgumentException if some argument has an invalid value.
412:             */
413:            public Response createResponse(int statusCode, String reasonPhrase)
414:                    throws IllegalArgumentException {
415:                Response newResponse;
416:                Enumeration headerIterator;
417:                Header nextHeader;
418:
419:                newResponse = new Response();
420:                try {
421:                    newResponse.setStatusCode(statusCode);
422:                } catch (ParseException ex) {
423:                    throw new IllegalArgumentException("Bad code " + statusCode);
424:                }
425:
426:                if (reasonPhrase != null) {
427:                    newResponse.setReasonPhrase(reasonPhrase);
428:                } else {
429:                    newResponse.setReasonPhrase(Response
430:                            .getReasonPhrase(statusCode));
431:                }
432:
433:                headerIterator = super .getHeaders();
434:
435:                // Time stamp header should be stamped with delay but
436:                // we dont support this.
437:                while (headerIterator.hasMoreElements()) {
438:                    nextHeader = (Header) headerIterator.nextElement();
439:                    if (nextHeader instanceof  FromHeader
440:                            || nextHeader instanceof  ToHeader
441:                            || nextHeader instanceof  ViaList
442:                            || nextHeader instanceof  CallIdHeader
443:                            || nextHeader instanceof  RecordRouteList
444:                            || nextHeader instanceof  CSeqHeader
445:                            ||
446:                            // RFC 3265, 3.1.1 200-class responses to SUBSCRIBE
447:                            // requests also MUST contain an "Expires" header.
448:                            nextHeader instanceof  ExpiresHeader
449:                            || Utils.equalsIgnoreCase(nextHeader.getName(),
450:                                    Header.TIMESTAMP)) {
451:                        try {
452:                            newResponse.attachHeader(nextHeader, false);
453:                        } catch (SipException ex) {
454:                            if (Logging.REPORT_LEVEL <= Logging.ERROR) {
455:                                Logging.report(Logging.ERROR,
456:                                        LogChannels.LC_JSR180,
457:                                        "Request.createResponse(): can't attach header '"
458:                                                + nextHeader.getHeaderName()
459:                                                + "'.");
460:                                ex.printStackTrace();
461:                            }
462:                        }
463:                    } else if (Utils.equalsIgnoreCase(nextHeader.getName(),
464:                            Header.REQUIRE)) {
465:                        /*
466:                         * RFC3262, SECTION 3
467:                         * If the next header contains "Require" header with option
468:                         * tag as "100rel", we should add this header and also include 
469:                         * RSeq header field
470:                         */
471:                        boolean isReliableProvResponse = Header
472:                                .isReliableTagPresent(nextHeader
473:                                        .getHeaderValue());
474:
475:                        if (isReliableProvResponse) {
476:                            try {
477:                                newResponse.attachHeader(nextHeader, true);
478:                            } catch (SipException ex) {
479:                                if (Logging.REPORT_LEVEL <= Logging.ERROR) {
480:                                    Logging.report(Logging.ERROR,
481:                                            LogChannels.LC_JSR180,
482:                                            "Request.createResponse(): can't attach header"
483:                                                    + nextHeader
484:                                                            .getHeaderName()
485:                                                    + "'.");
486:                                    // ex.printStackTrace();
487:                                }
488:                            }
489:                        }
490:
491:                    }
492:                }
493:
494:                // RFC 3903, p. 5:
495:                // The Record-Route header field has no meaning in PUBLISH
496:                // requests or responses, and MUST be ignored if present.
497:                //
498:                // RFC 3261, p. 63:
499:                // Registrars MUST ignore the Record-Route header field if it is
500:                // included in a REGISTER request. Registrars MUST NOT include a
501:                // Record-Route header field in any response to a REGISTER request.
502:                String method = getMethod();
503:                if (method.equals(Request.PUBLISH)
504:                        || method.equals(Request.REGISTER)) {
505:                    newResponse.removeHeader(Header.RECORD_ROUTE);
506:                }
507:
508:                return newResponse;
509:            }
510:
511:            /**
512:             * Creates a default SIPResquest message that would cancel
513:             * this request. Note that tag assignment and removal of
514:             * is left to the caller (we use whatever tags are present in the
515:             * original request). Acknowledgement: Added by Jeff Keyser.
516:             *
517:             * @return A CANCEL Request with a copy all the original headers
518:             * from this request except for Require, ProxyRequire.
519:             * @throws SipException if the request can't be created.
520:             */
521:            public Request createCancelRequest() throws SipException {
522:                Request newRequest;
523:                Enumeration headerIterator;
524:                Header nextHeader;
525:
526:                newRequest = new Request();
527:
528:                // JSR180: Request-URI  // copy from original request
529:                RequestLine cancelRequestLine = (RequestLine) this 
530:                        .getRequestLine().clone();
531:                cancelRequestLine.setMethod(CANCEL);
532:                newRequest.setRequestLine(cancelRequestLine);
533:                newRequest.setMethod(CANCEL);
534:
535:                // JSR180: To           // copy from original request
536:                ToHeader toHeader = this .getTo();
537:                if (toHeader != null) {
538:                    newRequest.setHeader(toHeader);
539:                }
540:
541:                // JSR180: From         // copy from original request
542:                FromHeader fromHeader = this .getFromHeader();
543:                if (fromHeader != null) {
544:                    newRequest.setHeader(fromHeader);
545:                }
546:
547:                // JSR180: CSeq         // same value for the sequence
548:                // number as was present in the original request, but
549:                // the method parameter MUST be equal to "CANCEL"
550:                CSeqHeader cseqHeader = (CSeqHeader) this .getCSeqHeader()
551:                        .clone();
552:                if (cseqHeader != null) {
553:                    cseqHeader.setMethod(CANCEL);
554:                    newRequest.setHeader(cseqHeader);
555:                }
556:
557:                // JSR180: Call-ID      // copy from original request
558:                CallIdHeader callIdHeader = this .getCallId();
559:                if (callIdHeader != null) {
560:                    newRequest.setHeader(callIdHeader);
561:                }
562:
563:                // JSR180: Via          // single value equal to the
564:                // top Via header field of the request being cancelled
565:                ViaHeader viaHeader = this .getTopmostVia();
566:                if (viaHeader != null) {
567:                    newRequest.setHeader(viaHeader);
568:                }
569:
570:                // JSR180: Route        // If the request being cancelled
571:                // contains a Route header field, the CANCEL request MUST
572:                // include that Route header field's values
573:                RouteList routeList = this .getRouteHeaders();
574:                if (routeList != null) {
575:                    newRequest.setHeaders(routeList.getHeaders());
576:                }
577:
578:                // JSR180: Max-Forwards (TBD)// header field serves to limit the
579:                // number of hops a request can transit on the way to its destination.
580:                // Current version: copy from original request
581:                MaxForwardsHeader mfHeader = (MaxForwardsHeader) getHeader(Header.MAX_FORWARDS);
582:                if (mfHeader != null) {
583:                    newRequest.setHeader(mfHeader);
584:                }
585:
586:                return newRequest;
587:            }
588:
589:            /**
590:             * Creates a default ACK Request message for this original request.
591:             * Note that the defaultACK Request does not include the
592:             * content of the original Request. If responseToHeader
593:             * is null then the toHeader of this request is used to
594:             * construct the ACK. Note that tag fields are just copied
595:             * from the original SIP Request. Added by Jeff Keyser.
596:             *
597:             * @param responseToHeader To header to use for this request.
598:             * @return A Request with an ACK method.
599:             * @throws SipException if the request can't be created.
600:             */
601:            public Request createAckRequest(ToHeader responseToHeader)
602:                    throws SipException {
603:                Request newRequest;
604:                Enumeration headerIterator;
605:                Header nextHeader;
606:
607:                newRequest = new Request();
608:                newRequest.setRequestLine((RequestLine) this .requestLine
609:                        .clone());
610:                newRequest.setMethod(ACK);
611:                headerIterator = getHeaders();
612:                while (headerIterator.hasMoreElements()) {
613:                    nextHeader = (Header) headerIterator.nextElement();
614:                    if (nextHeader.getHeaderName().equals(Header.ROUTE)) {
615:
616:                        // Route header for ACK is assigned by the
617:                        // Dialog if necessary.
618:                        continue;
619:                    } else if (nextHeader.getHeaderName().equals(
620:                            Header.PROXY_AUTHORIZATION)) {
621:                        // Remove proxy auth header.
622:                        // Assigned by the Dialog if necessary.
623:                        continue;
624:                    } else if (nextHeader instanceof  ContentLengthHeader) {
625:                        // Adding content is responsibility of user.
626:                        nextHeader = (Header) nextHeader.clone();
627:                        ((ContentLengthHeader) nextHeader).setContentLength(0);
628:
629:                    } else if (nextHeader instanceof  ContentTypeHeader) {
630:                        // Content type header is removed since
631:                        // content length is 0. Bug fix from
632:                        // Antonis Kyardas.
633:                        continue;
634:                    } else if (nextHeader instanceof  CSeqHeader) {
635:                        CSeqHeader cseq = (CSeqHeader) nextHeader.clone();
636:                        cseq.setMethod(ACK);
637:                        nextHeader = cseq;
638:                    } else if (nextHeader instanceof  ToHeader) {
639:                        if (responseToHeader != null) {
640:                            nextHeader = responseToHeader;
641:                        } else {
642:                            nextHeader = (Header) nextHeader.clone();
643:                        }
644:                    } else {
645:                        nextHeader = (Header) nextHeader.clone();
646:                    }
647:
648:                    newRequest.attachHeader(nextHeader, false);
649:                }
650:
651:                return newRequest;
652:            }
653:
654:            /**
655:             * Creates a new default Request from the original request. Warning:
656:             * the newly created Request, shares the headers of
657:             * this request but we generate any new headers that we need to modify
658:             * so the original request is umodified. However, if you modify the
659:             * shared headers after this request is created, then the newly
660:             * created request will also be modified.
661:             * If you want to modify the original request
662:             * without affecting the returned Request
663:             * make sure you clone it before calling this method.
664:             * Following are the differences between the original request headers
665:             * and the generated request headers.
666:             * <ul>
667:             * <li>
668:             * Contact headers are not included in the newly created request.
669:             * Setting the appropriate sequence number is the responsibility of
670:             * the caller. </li>
671:             * <li> RouteList is not copied for ACK and CANCEL </li>
672:             * <li> Note that we DO NOT copy the body of the
673:             * argument into the returned header. We do not copy the content
674:             * type header from the original request either. These have to be
675:             * added seperately and the content length has to be correctly set
676:             * if necessary the content length is set to 0 in the returned header.
677:             * </li>
678:             * <li>Contact List is not copied from the original request.</li>
679:             * <li>RecordRoute List is not included from original request. </li>
680:             * <li>Via header is not included from the original request. </li>
681:             * </ul>
682:             *
683:             * @param requestLine is the new request line.
684:             *
685:             * @param switchHeaders is a boolean flag that causes to and from
686:             * headers to switch (set this to true if you are the
687:             * server of the transaction and are generating a BYE
688:             * request). If the headers are switched, we generate
689:             * new FromHeader and To headers otherwise we just use the
690:             * incoming headers.
691:             *
692:             * @return a new Default SIP Request which has the requestLine specified.
693:             *
694:             * @throws SipException if the request can't be created.
695:             */
696:            public Request createRequest(RequestLine requestLine,
697:                    boolean switchHeaders) throws SipException {
698:                Request newRequest = new Request();
699:                newRequest.requestLine = requestLine;
700:                Enumeration headerIterator = this .getHeaders();
701:                while (headerIterator.hasMoreElements()) {
702:                    Header nextHeader = (Header) headerIterator.nextElement();
703:                    // For BYE and cancel set the CSeqHeader header to the
704:                    // appropriate method.
705:                    if (nextHeader instanceof  CSeqHeader) {
706:                        CSeqHeader newCseq = (CSeqHeader) nextHeader.clone();
707:                        nextHeader = newCseq;
708:                        newCseq.setMethod(requestLine.getMethod());
709:                    } else if (requestLine.getMethod().equals(ACK)
710:                            && nextHeader instanceof  ContactList) {
711:                        // ACKS never get Contact headers.
712:                        continue;
713:                    } else if (nextHeader instanceof  ViaList) {
714:                        ViaHeader via = (ViaHeader) (((ViaList) nextHeader)
715:                                .getFirst().clone());
716:                        via.removeParameter(SIPConstants.GENERAL_BRANCH);
717:                        nextHeader = via;
718:                        // Cancel and ACK preserve the branch ID.
719:                    } else if (nextHeader instanceof  RouteList) {
720:                        continue; // Route is kept by dialog.
721:                    } else if (nextHeader instanceof  RecordRouteList) {
722:                        continue; // RR is added by the caller.
723:                    } else if (nextHeader instanceof  ContactList) {
724:                        continue;
725:                    } else if (nextHeader instanceof  ToHeader) {
726:                        ToHeader to = (ToHeader) nextHeader;
727:                        if (switchHeaders) {
728:                            nextHeader = new FromHeader(to);
729:                            ((FromHeader) nextHeader).removeTag();
730:                        } else {
731:                            nextHeader = (Header) to.clone();
732:                            ((ToHeader) nextHeader).removeTag();
733:                        }
734:                    } else if (nextHeader instanceof  FromHeader) {
735:                        FromHeader from = (FromHeader) nextHeader;
736:                        if (switchHeaders) {
737:                            nextHeader = new ToHeader(from);
738:                            ((ToHeader) nextHeader).removeTag();
739:                        } else {
740:                            nextHeader = (Header) from.clone();
741:                            ((FromHeader) nextHeader).removeTag();
742:                        }
743:                    } else if (nextHeader instanceof  ContentLengthHeader) {
744:                        ContentLengthHeader cl = (ContentLengthHeader) nextHeader
745:                                .clone();
746:                        cl.setContentLength(0);
747:                        nextHeader = cl;
748:                    } else if (nextHeader instanceof  ContentTypeHeader) {
749:                        continue;
750:                    } else if (nextHeader instanceof  MaxForwardsHeader) {
751:                        // Header is regenerated if the request is to be switched
752:                        if (switchHeaders) {
753:                            MaxForwardsHeader mf = (MaxForwardsHeader) nextHeader
754:                                    .clone();
755:                            mf.setMaxForwards(70);
756:                            nextHeader = mf;
757:                        }
758:                    } else if (!(nextHeader instanceof  CallIdHeader)
759:                            && !(nextHeader instanceof  MaxForwardsHeader)) {
760:                        // Route is kept by dialog.
761:                        // RR is added by the caller.
762:                        // Contact is added by the Caller
763:                        // Any extension headers must be added
764:                        // by the caller.
765:                        continue;
766:                    }
767:
768:                    newRequest.attachHeader(nextHeader, false);
769:
770:                }
771:                return newRequest;
772:
773:            }
774:
775:            /**
776:             * Creates a BYE request from this request.
777:             *
778:             * @param switchHeaders is a boolean flag that causes from and
779:             * isServerTransaction to headers to be swapped. Set this
780:             * to true if you are the server of the dialog and are generating
781:             * a BYE request for the dialog.
782:             * @return a new default BYE request.
783:             * @throws SipException if the request can't be created.
784:             */
785:            public Request createBYERequest(boolean switchHeaders)
786:                    throws SipException {
787:                RequestLine rl = (RequestLine) requestLine.clone();
788:                rl.setMethod(BYE);
789:                return createRequest(rl, switchHeaders);
790:            }
791:
792:            /**
793:             * Creates an ACK request from this request. This is suitable for
794:             * generating an ACK for an INVITE client transaction.
795:             *
796:             * @return an ACK request that is generated from this request.
797:             * @throws SipException if the request can't be created.
798:             */
799:            public Request createACKRequest() throws SipException {
800:                RequestLine rl = (RequestLine) requestLine.clone();
801:                rl.setMethod(ACK);
802:                return createRequest(rl, false);
803:            }
804:
805:            /**
806:             * Gets the host from the topmost via header.
807:             *
808:             * @return the string representation of the host from the topmost via
809:             * header.
810:             */
811:            public String getViaHost() {
812:                ViaHeader via = (ViaHeader) this .getViaHeaders().getFirst();
813:                return via.getHost();
814:
815:            }
816:
817:            /**
818:             * Gets the port from the topmost via header.
819:             *
820:             * @return the port from the topmost via header (5060 if there is
821:             * no port indicated).
822:             */
823:            public int getViaPort() {
824:                ViaHeader via = (ViaHeader) this .getViaHeaders().getFirst();
825:                if (via.hasPort())
826:                    return via.getPort();
827:                else
828:                    return 5060;
829:            }
830:
831:            /**
832:             * Gets the first line encoded.
833:             *
834:             * @return a string containing the encoded request line.
835:             */
836:            public String getFirstLine() {
837:                if (requestLine == null)
838:                    return null;
839:                else
840:                    return this .requestLine.encode();
841:            }
842:
843:            /**
844:             * Sets the sip version.
845:             *
846:             * @param sipVersion the sip version to set.
847:             */
848:
849:            public void setSIPVersion(String sipVersion) throws ParseException {
850:                if (sipVersion == null || !sipVersion.equals("SIP/2.0"))
851:                    throw new ParseException("sipVersion", 0);
852:                this .requestLine.setSIPVersion(sipVersion);
853:            }
854:
855:            /**
856:             * Gets the SIP version.
857:             *
858:             * @return the SIP version from the request line.
859:             */
860:            public String getSIPVersion() {
861:                return this .requestLine.getSipVersion();
862:            }
863:
864:            /**
865:             * Gets the transaction pointer.
866:             * @return the transaction pointer
867:             */
868:            public Object getTransaction() {
869:                // Return an opaque pointer to the transaction object.
870:                // This is for consistency checking and quick lookup.
871:                return this .transactionPointer;
872:            }
873:
874:            /**
875:             * Sets the transaction pointer.
876:             * @param transaction thenew transaction pointer
877:             */
878:            public void setTransaction(Object transaction) {
879:                this .transactionPointer = transaction;
880:            }
881:
882:            /**
883:             * Gets the Accept-Contact header (null if one does not exist).
884:             * @return Accept-Contact header
885:             */
886:            public AcceptContactHeader getAcceptContact() {
887:                return (AcceptContactHeader) getHeader(Header.ACCEPT_CONTACT);
888:            }
889:
890:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.