Source Code Cross Referenced for Transaction.java in  » 6.0-JDK-Modules » j2me » gov » nist » siplite » stack » 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.stack 
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:        package gov.nist.siplite.stack;
026:
027:        import gov.nist.siplite.parser.*;
028:        import gov.nist.siplite.header.*;
029:        import gov.nist.siplite.message.*;
030:        import gov.nist.siplite.*;
031:        import gov.nist.siplite.address.*;
032:        import gov.nist.core.*;
033:        import java.util.*;
034:
035:        import java.io.IOException;
036:        import javax.microedition.sip.SipException;
037:
038:        import com.sun.midp.log.Logging;
039:        import com.sun.midp.log.LogChannels;
040:
041:        /**
042:         * Abstract class to support both client and server transactions.
043:         * Provides an encapsulation of a message channel, handles timer events,
044:         * and creation of the Via header for a message.
045:         *
046:         * @version JAIN-SIP-1.1
047:         *
048:         */
049:        public abstract class Transaction extends MessageChannel {
050:            /** Transaction timer interval. */
051:            protected static final int BASE_TIMER_INTERVAL = SIPTransactionStack.BASE_TIMER_INTERVAL;
052:            /** RTT Estimate. 500ms default. */
053:            protected static final int T1 = 500 / BASE_TIMER_INTERVAL;
054:            /** 5 sec Maximum duration a message will remain in the network */
055:            protected static final int T4 = 5000 / BASE_TIMER_INTERVAL;
056:            /**
057:             * The maximum retransmit interval for non-INVITE
058:             * requests and INVITE responses
059:             */
060:            protected static final int T2 = 4000 / BASE_TIMER_INTERVAL;
061:            /** INVITE request retransmit interval, for UDP only */
062:            protected static final int TIMER_A = 1 * T1;
063:            /** INVITE transaction timeout timer */
064:            protected static final int TIMER_B = 64 * T1;
065:            /** INVITE transaction timeout timer */
066:            protected static final int TIMER_J = 64 * T1;
067:            /** INVITE transaction timeout timer */
068:            protected static final int TIMER_F = 64 * T1;
069:            /** INVITE transaction timeout timer */
070:            protected static final int TIMER_H = 64 * T1;
071:            /** INVITE transaction timeout timer */
072:            protected static final int TIMER_I = T4;
073:            /** INVITE transaction timeout timer */
074:            protected static final int TIMER_K = T4;
075:            /** INVITE transaction timeout timer */
076:            protected static final int TIMER_D = 32000 / BASE_TIMER_INTERVAL;
077:            /** INVITE transaction timeout timer */
078:            protected static final int TIMER_C = 3 * 60 * 1000 / BASE_TIMER_INTERVAL;
079:            /** Last response message. */
080:            protected Response lastResponse;
081:            /** Current SIP dialog. */
082:            protected Dialog dialog;
083:            /** Flag indicating an ACK was received. */
084:            protected boolean ackSeenFlag;
085:            /** Flag indicating listener waiting. */
086:            protected boolean toListener;
087:            /**
088:             * Initialized but no state assigned.
089:             */
090:            public static final int INITIAL_STATE = -1;
091:            /**
092:             * Trying state.
093:             */
094:            public static final int TRYING_STATE = 1;
095:            /**
096:             * CALLING State.
097:             */
098:            public static final int CALLING_STATE = 2;
099:            /**
100:             * Proceeding state.
101:             */
102:            public static final int PROCEEDING_STATE = 3;
103:            /**
104:             * Completed state.
105:             */
106:            public static final int COMPLETED_STATE = 4;
107:            /**
108:             * Confirmed state.
109:             */
110:            public static final int CONFIRMED_STATE = 5;
111:            /**
112:             * Terminated state.
113:             */
114:            public static final int TERMINATED_STATE = 6;
115:            /**
116:             * Maximum number of ticks between retransmissions.
117:             */
118:            protected static final int MAXIMUM_RETRANSMISSION_TICK_COUNT = 4000 / BASE_TIMER_INTERVAL;
119:            /** Parent stack for this transaction. */
120:            protected SIPTransactionStack parentStack;
121:            /** Original request that is being handled by this transaction. */
122:            private Request originalRequest;
123:            /**
124:             * Underlying channel being used to send messages for this
125:             * transaction.
126:             */
127:            protected MessageChannel encapsulatedChannel;
128:            /** Transaction branch ID. */
129:            private String branch;
130:            /** Current transaction state. */
131:            private int currentState;
132:            /** Number of ticks the retransmission timer was set to last. */
133:            private int retransmissionTimerLastTickCount;
134:            /** Number of ticks before the message is retransmitted. */
135:            private int retransmissionTimerTicksLeft;
136:            /** Number of ticks before the transaction times out. */
137:            private int timeoutTimerTicksLeft;
138:            /** List of event listeners for this transaction. */
139:            private Vector eventListeners;
140:            /** Flag to indcate that this has been cancelled. */
141:            protected boolean isCancelled;
142:            /**
143:             * Object representing the connection being held by the JSR180
144:             * Implementation It can be either a SipClientConnection in case
145:             * of a ClientTransaction or a SipConnectionNotifier in case of a
146:             *ServerTransaction.
147:             */
148:            protected Object applicationData;
149:
150:            /**
151:             * Retrieves the application data.
152:             * @return Object representing the connection being held by the JSR180
153:             * Implementation. It can be either a SipClientConnection in case of a
154:             * ClientTransaction or a SipConnectionNotifier in case of a
155:             * ServerTransaction
156:             */
157:            public Object getApplicationData() {
158:                return applicationData;
159:            }
160:
161:            /**
162:             * Sets the application data.
163:             * @param newApplicationData Object representing the connection being held
164:             * by the JSR180
165:             * Implementation. It can be either a SipClientConnection in case of a
166:             * ClientTransaction or a SipConnectionNotifier in case of a
167:             * ServerTransaction
168:             */
169:            public void setApplicationData(Object newApplicationData) {
170:                applicationData = newApplicationData;
171:            }
172:
173:            /**
174:             * Gets the branch identifier.
175:             * @return the current branch id
176:             */
177:            public String getBranchId() {
178:                return branch;
179:            }
180:
181:            /**
182:             * Transaction constructor.
183:             *
184:             * @param newParentStack Parent stack for this transaction.
185:             * @param newEncapsulatedChannel
186:             * Underlying channel for this transaction.
187:             */
188:            protected Transaction(SIPTransactionStack newParentStack,
189:                    MessageChannel newEncapsulatedChannel) {
190:                parentStack = newParentStack;
191:                encapsulatedChannel = newEncapsulatedChannel;
192:                currentState = INITIAL_STATE;
193:                disableRetransmissionTimer();
194:                disableTimeoutTimer();
195:                eventListeners = new Vector();
196:                // Always add the parent stack as a listener
197:                // of this transaction
198:                addEventListener(newParentStack);
199:            }
200:
201:            /**
202:             * Sets the request message that this transaction handles.
203:             *
204:             * @param newOriginalRequest Request being handled.
205:             */
206:            public void setOriginalRequest(Request newOriginalRequest) {
207:                // Branch value of topmost Via header
208:                String newBranch;
209:
210:                originalRequest = newOriginalRequest;
211:                originalRequest.setTransaction(this );
212:                // If the message has an explicit branch value set,
213:                newBranch = ((ViaHeader) newOriginalRequest.getViaHeaders()
214:                        .getFirst()).getBranch();
215:                if (newBranch != null) {
216:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
217:                        Logging.report(Logging.INFORMATION,
218:                                LogChannels.LC_JSR180, "Setting Branch id : "
219:                                        + newBranch);
220:                    }
221:
222:                    // Override the default branch with the one
223:                    // set by the message
224:                    setBranch(newBranch);
225:                } else {
226:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
227:                        Logging.report(Logging.INFORMATION,
228:                                LogChannels.LC_JSR180, "Branch id is null!"
229:                                        + newOriginalRequest.encode());
230:                    }
231:                }
232:            }
233:
234:            /**
235:             * Gets the request being handled by this transaction.
236:             * @return Request being handled.
237:             */
238:            public Request getOriginalRequest() {
239:                return originalRequest;
240:            }
241:
242:            /**
243:             * Gets the original request but cast to a Request structure.
244:             * @return the request that generated this transaction.
245:             */
246:            public Request getRequest() {
247:                return (Request) originalRequest;
248:            }
249:
250:            /**
251:             * Returns a flag stating whether this transaction is for an
252:             * INVITE request or not.
253:             * @return True if this is an INVITE request, false if not.
254:             */
255:            protected final boolean isInviteTransaction() {
256:                return originalRequest.getMethod().equals(Request.INVITE);
257:            }
258:
259:            /**
260:             * Returns true if the transaction corresponds to a CANCEL message.
261:             * @return true if the transaciton is a CANCEL transaction.
262:             */
263:            protected final boolean isCancelTransaction() {
264:                return originalRequest.getMethod().equals(Request.CANCEL);
265:            }
266:
267:            /**
268:             * Returns a flag that states if this is a BYE transaction.
269:             * @return true if the transaciton is a BYE transaction.
270:             */
271:            protected final boolean isByeTransaction() {
272:                return originalRequest.getMethod().equals(Request.BYE);
273:            }
274:
275:            /**
276:             * Returns the message channel used for
277:             * transmitting/receiving messages
278:             * for this transaction. Made public in support of JAIN dual
279:             * transaction model.
280:             * @return Encapsulated MessageChannel.
281:             */
282:            public MessageChannel getMessageChannel() {
283:                return encapsulatedChannel;
284:            }
285:
286:            /**
287:             * Sets the Via header branch parameter used to identify
288:             * this transaction.
289:             * @param newBranch New string used as the branch
290:             * for this transaction.
291:             */
292:            public final void setBranch(String newBranch) {
293:                branch = newBranch;
294:            }
295:
296:            /**
297:             * Gets the current setting for the branch parameter of this transaction.
298:             * @return Branch parameter for this transaction.
299:             */
300:            public final String getBranch() {
301:                if (branch == null) {
302:                    branch = getOriginalRequest().getTopmostVia().getBranch();
303:                }
304:                return branch;
305:            }
306:
307:            /**
308:             * Changes the state of this transaction.
309:             * @param newState New state of this transaction.
310:             */
311:            public void setState(int newState) {
312:                currentState = newState;
313:
314:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
315:                    Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
316:                            "setState " + this  + " " + newState);
317:                }
318:
319:                // If this transaction is being terminated,
320:                if (newState == TERMINATED_STATE) {
321:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
322:                        Logging.report(Logging.INFORMATION,
323:                                LogChannels.LC_JSR180,
324:                                "Transaction is being terminated!");
325:                        // new Exception().printStackTrace();
326:                    }
327:                }
328:            }
329:
330:            /**
331:             * Gets the current state of this transaction.
332:             * @return Current state of this transaction.
333:             */
334:            public final int getState() {
335:                return currentState;
336:            }
337:
338:            /**
339:             * Enables retransmission timer events for this transaction to begin in
340:             * one tick.
341:             */
342:            protected final void enableRetransmissionTimer() {
343:                enableRetransmissionTimer(1);
344:            }
345:
346:            /**
347:             * Enables retransmission timer events for this
348:             * transaction to begin after the number of ticks passed to
349:             * this routine.
350:             * @param tickCount Number of ticks before the
351:             * next retransmission timer
352:             * event occurs.
353:             */
354:            protected final void enableRetransmissionTimer(int tickCount) {
355:                retransmissionTimerTicksLeft = Math.min(tickCount,
356:                        MAXIMUM_RETRANSMISSION_TICK_COUNT);
357:                retransmissionTimerLastTickCount = retransmissionTimerTicksLeft;
358:            }
359:
360:            /**
361:             * Turns off retransmission events for this transaction.
362:             */
363:            protected final void disableRetransmissionTimer() {
364:                retransmissionTimerTicksLeft = -1;
365:            }
366:
367:            /**
368:             * Enables a timeout event to occur for this transaction after the number
369:             * of ticks passed to this method.
370:             * @param tickCount Number of ticks before this transaction times out.
371:             */
372:            protected final void enableTimeoutTimer(int tickCount) {
373:                timeoutTimerTicksLeft = tickCount;
374:            }
375:
376:            /**
377:             * Disabled the timeout timer.
378:             */
379:            protected final void disableTimeoutTimer() {
380:                timeoutTimerTicksLeft = -1;
381:            }
382:
383:            /**
384:             * Fired after each timer tick.
385:             * Checks the retransmission and timeout
386:             * timers of this transaction, and fired these events
387:             * if necessary.
388:             */
389:            synchronized final void fireTimer() {
390:                // If the timeout timer is enabled,
391:                if (timeoutTimerTicksLeft != -1) {
392:                    // Count down the timer, and if it has run out,
393:                    if (--timeoutTimerTicksLeft == 0) {
394:                        // Fire the timeout timer
395:                        fireTimeoutTimer();
396:                    }
397:                }
398:                // If the retransmission timer is enabled,
399:                if (retransmissionTimerTicksLeft != -1) {
400:                    // Count down the timer, and if it has run out,
401:                    if (--retransmissionTimerTicksLeft == 0) {
402:                        // Enable this timer to fire again after
403:                        // twice the original time
404:                        enableRetransmissionTimer(retransmissionTimerLastTickCount * 2);
405:                        // Fire the timeout timer
406:                        fireRetransmissionTimer();
407:                    }
408:                }
409:            }
410:
411:            /**
412:             * Tests a message to see if it is part of this transaction.
413:             * @param messageToHeaderTest message to be processed
414:             * @return True if the message is part of this
415:             * transaction, false if not.
416:             */
417:            public abstract boolean isMessagePartOfTransaction(
418:                    Message messageToHeaderTest);
419:
420:            /**
421:             * This method is called when this transaction's
422:             * retransmission timer has fired.
423:             */
424:            protected abstract void fireRetransmissionTimer();
425:
426:            /**
427:             * This method is called when this transaction's
428:             * timeout timer has fired.
429:             */
430:            protected abstract void fireTimeoutTimer();
431:
432:            /**
433:             * Tests if this transaction has terminated.
434:             * @return Trus if this transaction is terminated, false if not.
435:             */
436:            protected final boolean isTerminated() {
437:                return (getState() == TERMINATED_STATE);
438:            }
439:
440:            /**
441:             * Gets the host.
442:             * @return the host
443:             */
444:            public String getHost() {
445:                return encapsulatedChannel.getHost();
446:            }
447:
448:            /**
449:             * Gets the key.
450:             * @return the key
451:             */
452:            public String getKey() {
453:                return encapsulatedChannel.getKey();
454:            }
455:
456:            /**
457:             * Gets the port.
458:             * @return the port
459:             */
460:            public int getPort() {
461:                return encapsulatedChannel.getPort();
462:            }
463:
464:            /**
465:             * Gets the SIP stack context.
466:             * @return the SIP Stack
467:             */
468:            public SIPMessageStack getSIPStack() {
469:                return parentStack;
470:            }
471:
472:            /**
473:             * Gets the remote address.
474:             * @return the remote address
475:             */
476:            public String getPeerAddress() {
477:                return encapsulatedChannel.getPeerAddress();
478:            }
479:
480:            /**
481:             * Gets the remote port number.
482:             * @return the remote port number
483:             */
484:            public int getPeerPort() {
485:                return encapsulatedChannel.getPeerPort();
486:            }
487:
488:            /**
489:             * Gets the connection transport.
490:             * @return the connection transport
491:             */
492:            public String getTransport() {
493:                return encapsulatedChannel.getTransport();
494:            }
495:
496:            /**
497:             * Checks if the connection is reliable
498:             * @return true if channel is on a stream connection
499:             */
500:            public boolean isReliable() {
501:                return encapsulatedChannel.isReliable();
502:            }
503:
504:            /**
505:             * Returns the Via header for this channel. Gets the Via header of the
506:             * underlying message channel, and adds a branch parameter to it for this
507:             * transaction.
508:             * @return the via header
509:             */
510:            public ViaHeader getViaHeader() {
511:                // Via header of the encapulated channel
512:                ViaHeader channelViaHeader;
513:                // Add the branch parameter to the underlying
514:                // channel's Via header
515:                channelViaHeader = super .getViaHeader();
516:                channelViaHeader.setBranch(branch);
517:                return channelViaHeader;
518:            }
519:
520:            /**
521:             * Process an exception.
522:             * @param ex the exception to handle
523:             */
524:            public void handleException(SIPServerException ex) {
525:                encapsulatedChannel.handleException(ex);
526:            }
527:
528:            /**
529:             * Processes the message through the transaction and sends it to the SIP
530:             * peer.
531:             * @param messageToHeaderSend Message to send to the SIP peer.
532:             */
533:            abstract public void sendMessage(Message messageToHeaderSend)
534:                    throws IOException;
535:
536:            /**
537:             * Parses the byte array as a message, process it through the
538:             * transaction, and send it to the SIP peer.
539:             *
540:             * @param messageBytes Bytes of the message to send.
541:             * @param receiverAddress Address of the target peer.
542:             * @param receiverPort Network port of the target peer.
543:             *
544:             * @throws IOException If there is an error parsing
545:             * the byte array into an object.
546:             */
547:            protected void sendMessage(byte[] messageBytes,
548:                    String receiverAddress, int receiverPort)
549:                    throws IOException {
550:                // Object representation of the SIP message
551:                Message messageToHeaderSend;
552:                try {
553:                    StringMsgParser messageParser = new StringMsgParser();
554:                    messageToHeaderSend = messageParser
555:                            .parseSIPMessage(messageBytes);
556:                    sendMessage(messageToHeaderSend);
557:                } catch (ParseException e) {
558:                    throw new IOException(e.getMessage());
559:                }
560:            }
561:
562:            /**
563:             * Adds a new event listener to this transaction.
564:             * @param newListener Listener to add.
565:             */
566:            public void addEventListener(SIPTransactionEventListener newListener) {
567:                eventListeners.addElement(newListener);
568:            }
569:
570:            /**
571:             * Removes an event listener from this transaction.
572:             * @param oldListener Listener to remove.
573:             */
574:            public void removeEventListener(
575:                    SIPTransactionEventListener oldListener) {
576:                eventListeners.removeElement(oldListener);
577:            }
578:
579:            /**
580:             * Creates a SIPTransactionErrorEvent and sends it
581:             * to all of the listeners of this transaction.
582:             * This method also flags the transaction as
583:             * terminated.
584:             * @param errorEventID ID of the error to raise.
585:             */
586:            protected void raiseErrorEvent(int errorEventID) {
587:                // Error event to send to all listeners
588:                SIPTransactionErrorEvent newErrorEvent;
589:                // Iterator through the list of listeners
590:                Enumeration listenerIterator;
591:                // Next listener in the list
592:                SIPTransactionEventListener nextListener;
593:                // Create the error event
594:                newErrorEvent = new SIPTransactionErrorEvent(this , errorEventID);
595:                // Loop through all listeners of this transaction
596:                synchronized (eventListeners) {
597:                    listenerIterator = eventListeners.elements();
598:                    while (listenerIterator.hasMoreElements()) {
599:                        // Send the event to the next listener
600:                        nextListener = (SIPTransactionEventListener) listenerIterator
601:                                .nextElement();
602:                        nextListener.transactionErrorEvent(newErrorEvent);
603:                    }
604:                }
605:                // Clear the event listeners after propagating the error.
606:                eventListeners.removeAllElements();
607:                // Errors always terminate a transaction
608:                setState(TERMINATED_STATE);
609:                if (this  instanceof  ServerTransaction
610:                        && this .isByeTransaction() && this .dialog != null)
611:                    this .dialog.setState(Dialog.TERMINATED_STATE);
612:            }
613:
614:            /**
615:             * A shortcut way of telling if we are a server transaction.
616:             * @return true if this is a servertransaction
617:             */
618:            protected boolean IsServerTransaction() {
619:                return this  instanceof  ServerTransaction;
620:            }
621:
622:            /**
623:             * Gets the dialog object of this Transaction object. This object
624:             * returns null if no dialog exists. A dialog only exists for a
625:             * transaction when a session is setup between a User Agent Client and a
626:             * User Agent Server, either by a 1xx Provisional Response for an early
627:             * dialog or a 200OK Response for a committed dialog.
628:             * @return the Dialog Object of this Transaction object.
629:             * @see Dialog
630:             */
631:            public Dialog getDialog() {
632:                return dialog;
633:            }
634:
635:            /**
636:             * Sets the dialog object.
637:             * @param newDialog the dialog to set.
638:             */
639:            public void setDialog(Dialog newDialog) {
640:                dialog = newDialog;
641:            }
642:
643:            /**
644:             * Returns the current value of the retransmit timer in
645:             * milliseconds used to retransmit messages over unreliable transports.
646:             * @return the integer value of the retransmit timer in milliseconds.
647:             */
648:            public int getRetransmitTimer() {
649:                return SIPTransactionStack.BASE_TIMER_INTERVAL;
650:            }
651:
652:            /**
653:             * Gets the host to assign for an outgoing Request via header.
654:             * @return the via host
655:             */
656:            public String getViaHost() {
657:                return getViaHeader().getHost();
658:            }
659:
660:            /**
661:             * Gets the last response.
662:             * @return the last response
663:             */
664:            public Response getLastResponse() {
665:                return this .lastResponse;
666:            }
667:
668:            /**
669:             * Gets the transaction Id.
670:             * @return the transaction id
671:             */
672:            public String getTransactionId() {
673:                return getOriginalRequest().getTransactionId();
674:            }
675:
676:            /**
677:             * Gets the port to assign for the via header of an outgoing message.
678:             * @return the via port number
679:             */
680:            public int getViaPort() {
681:                return getViaHeader().getPort();
682:            }
683:
684:            /**
685:             * A method that can be used to test if an incoming request
686:             * belongs to this transction. This does not take the transaction
687:             * state into account when doing the check otherwise it is identical
688:             * to isMessagePartOfTransaction. This is useful for checking if
689:             * a CANCEL belongs to this transaction.
690:             * @param requestToHeaderTest is the request to test.
691:             * @return true if the the request belongs to the transaction.
692:             */
693:            public boolean doesCancelMatchTransaction(
694:                    Request requestToHeaderTest) {
695:                // List of Via headers in the message to test
696:                ViaList viaHeaders;
697:                // ToHeaderpmost Via header in the list
698:                ViaHeader topViaHeader;
699:                // Branch code in the topmost Via header
700:                String messageBranch;
701:                // Flags whether the select message is part of this transaction
702:                boolean transactionMatches;
703:                transactionMatches = false;
704:
705:                if (getOriginalRequest() == null
706:                        || getOriginalRequest().getMethod().equals(
707:                                Request.CANCEL)) {
708:                    return false;
709:                }
710:
711:                // Get the topmost Via header and its branch parameter
712:                viaHeaders = requestToHeaderTest.getViaHeaders();
713:                if (viaHeaders != null) {
714:                    topViaHeader = (ViaHeader) viaHeaders.getFirst();
715:                    messageBranch = topViaHeader.getBranch();
716:                    if (messageBranch != null) {
717:                        // If the branch parameter exists but
718:                        // does not start with the magic cookie,
719:                        if (!messageBranch.toUpperCase().startsWith(
720:                                SIPConstants.GENERAL_BRANCH_MAGIC_COOKIE
721:                                        .toUpperCase())) {
722:                            // Flags this as old
723:                            // (RFC2543-compatible) client
724:                            // version
725:                            messageBranch = null;
726:                        }
727:                    }
728:                    // If a new branch parameter exists,
729:                    if (messageBranch != null && this .getBranch() != null) {
730:                        // If the branch equals the branch in
731:                        // this message,
732:                        if (getBranch().equals(messageBranch)
733:                                && topViaHeader.getSentBy().equals(
734:                                        ((ViaHeader) getOriginalRequest()
735:                                                .getViaHeaders().getFirst())
736:                                                .getSentBy())) {
737:                            transactionMatches = true;
738:
739:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
740:                                Logging
741:                                        .report(Logging.INFORMATION,
742:                                                LogChannels.LC_JSR180,
743:                                                "returning true");
744:                            }
745:                        }
746:                    } else {
747:                        // If this is an RFC2543-compliant message,
748:                        // If RequestURI, ToHeader tag, FromHeader tag,
749:                        // CallIdHeader, CSeqHeader number, and top Via
750:                        // headers are the same,
751:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
752:                            Logging.report(Logging.INFORMATION,
753:                                    LogChannels.LC_JSR180, "testing against "
754:                                            + getOriginalRequest());
755:                        }
756:
757:                        if (
758:
759:                        getOriginalRequest().getRequestURI().equals(
760:                                requestToHeaderTest.getRequestURI())
761:                                && getOriginalRequest().getTo().equals(
762:                                        requestToHeaderTest.getTo())
763:                                && getOriginalRequest().getFromHeader().equals(
764:                                        requestToHeaderTest.getFromHeader())
765:                                && getOriginalRequest().getCallId().getCallId()
766:                                        .equals(
767:                                                requestToHeaderTest.getCallId()
768:                                                        .getCallId())
769:                                && getOriginalRequest().getCSeqHeader()
770:                                        .getSequenceNumber() == requestToHeaderTest
771:                                        .getCSeqHeader().getSequenceNumber()
772:                                && topViaHeader.equals(getOriginalRequest()
773:                                        .getViaHeaders().getFirst())) {
774:                            transactionMatches = true;
775:                        }
776:                    }
777:                }
778:                return transactionMatches;
779:            }
780:
781:            /**
782:             * Checks if transaction has been sent to the listener.
783:             * @return true if transaction has been sent
784:             */
785:            public boolean passToListener() {
786:                return toListener;
787:            }
788:
789:            /**
790:             * Closes the encapsulated channel.
791:             */
792:            public void close() {
793:                encapsulatedChannel.close();
794:            }
795:
796:            /**
797:             * Check if this connection is secure.
798:             * @return true if this is a secure channel
799:             */
800:            public boolean isSecure() {
801:                return encapsulatedChannel.isSecure();
802:            }
803:
804:            /**
805:             * Gets the message processor handling this transaction.
806:             * @return the mesage processor for this transaction
807:             */
808:            public MessageProcessor getMessageProcessor() {
809:                return encapsulatedChannel.getMessageProcessor();
810:            }
811:
812:            /**
813:             * Sets the ACK has been seen flag.
814:             */
815:            public void setAckSeen() {
816:                ackSeenFlag = true;
817:            }
818:
819:            /**
820:             * Checks if the ACK has been seen flag is set.
821:             * @return true if the ACK has been seen
822:             */
823:            public boolean isAckSeen() {
824:                return ackSeenFlag;
825:            }
826:
827:            /**
828:             * Create route set for request.
829:             *
830:             * @param request the input request
831:             * @throws SipException if any occurs
832:             */
833:            protected void buildRouteSet(Request request) throws SipException {
834:                Message origMsg = lastResponse;
835:                boolean isServer = false;
836:                Dialog dlg = getDialog();
837:
838:                if (dlg != null) { // inside of dialog
839:                    Transaction firstTransaction = dlg.getFirstTransaction();
840:                    if (dlg.isServer()) { // dialog was created on server side
841:                        origMsg = firstTransaction.getOriginalRequest();
842:                        isServer = true;
843:                    } else { // dialog was created on client side
844:                        origMsg = firstTransaction.getLastResponse();
845:                    }
846:                } else { // out of dialog
847:                    // IMPL_NOTE: implement a support for the case when Contact
848:                    // header is not present.
849:                    if (this  instanceof  ServerTransaction) {
850:                        origMsg = getOriginalRequest();
851:                        isServer = true;
852:                    }
853:                }
854:
855:                if (origMsg == null) {
856:                    // Avoid NPE in case when sending ACK from the part that
857:                    // initiated a Re-INVITE.
858:                    return;
859:                }
860:
861:                RecordRouteList recordRouteList = origMsg
862:                        .getRecordRouteHeaders();
863:                ContactList cl = origMsg.getContactHeaders();
864:
865:                if (cl == null) {
866:                    // Prevent NPE and log an error: Contact header is absent.
867:                    if (Logging.REPORT_LEVEL <= Logging.ERROR) {
868:                        Logging
869:                                .report(Logging.ERROR, LogChannels.LC_JSR180,
870:                                        "Transaction.buildRouteSet(): Contact must be present!");
871:                    }
872:                    return;
873:                }
874:
875:                ContactHeader contact = (ContactHeader) cl.getFirst();
876:
877:                if (recordRouteList == null) {
878:                    URI remoteTarget = contact.getAddress().getURI();
879:
880:                    // RFC 3261, 12.2.1.1 Generating the Request
881:                    // If the route set is empty, the UAC MUST place the remote
882:                    // target URI into the Request-URI.  The UAC MUST NOT add
883:                    // a Route header field to the request.
884:                    request.setRequestURI(remoteTarget);
885:                } else {
886:                    request.removeHeader(Header.ROUTE);
887:
888:                    RouteList routeList = new RouteList();
889:                    // start at the end of the list and walk backwards
890:                    Vector li = recordRouteList.getHeaders();
891:
892:                    int recSize = li.size();
893:                    for (int i = 0; i < recSize; i++) {
894:                        int j = i;
895:                        if (!isServer) { // on client side the order is reversed
896:                            j = recSize - i - 1;
897:                        }
898:                        RecordRouteHeader rr = (RecordRouteHeader) li
899:                                .elementAt(j);
900:                        Address addr = rr.getAddress();
901:                        RouteHeader route = new RouteHeader();
902:                        route.setAddress((Address) rr.getAddress().clone());
903:                        route.setParameters((NameValueList) rr.getParameters()
904:                                .clone());
905:                        routeList.add(route);
906:                    }
907:
908:                    RouteHeader firstRoute = (RouteHeader) routeList.getFirst();
909:
910:                    if (!((SipURI) firstRoute.getAddress().getURI())
911:                            .hasLrParam()) {
912:                        RouteHeader route = new RouteHeader();
913:                        route
914:                                .setAddress((Address) contact.getAddress()
915:                                        .clone());
916:                        routeList.removeFirst();
917:                        // IMPL_NOTE: is clone() need?
918:                        URI uri = firstRoute.getAddress().getURI();
919:                        request.setRequestURI(uri);
920:                        routeList.add(route);
921:                        request.addHeader(routeList);
922:                    } else {
923:                        URI uri = (URI) contact.getAddress().getURI().clone();
924:                        request.setRequestURI(uri);
925:                        request.addHeader(routeList);
926:                    }
927:                }
928:            }
929:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.