001: /*
002: * Conditions Of Use
003: *
004: * This software was developed by employees of the National Institute of
005: * Standards and Technology (NIST), and others.
006: * This software is has been contributed to the public domain.
007: * As a result, a formal license is not needed to use the software.
008: *
009: * This software is provided "AS IS."
010: * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
011: * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
012: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
013: * AND DATA ACCURACY. NIST does not warrant or make any representations
014: * regarding the use of the software or the results thereof, including but
015: * not limited to the correctness, accuracy, reliability or usefulness of
016: * the software.
017: *
018: *
019: */
020: package test.tck.msgflow;
021:
022: import javax.sip.*;
023:
024: import org.apache.log4j.Logger;
025:
026: import java.util.TooManyListenersException;
027: import test.tck.*;
028:
029: /**
030: * <p>
031: * This class collects a single event from a given provider. The collector
032: * listens for incoming events until the desired event has been received, all
033: * following events are ignored. After extractCollectedEvent method has been
034: * called, the SipEventCollecter removes itself as a listener from the provider
035: * and goes back to its original state (i.e. could be reused). The collector
036: * ignores all events except the one it is supposed to collect. If an extract
037: * operation is a attempted on an event other than the collected event a
038: * TckInternalError is thrown. All exceptions raised within the collector are
039: * let to pass through and are responsibility of the using class
040: * </p>
041: *
042: * <p>
043: * This class does not test event dispatching! Event dispatching tests should
044: * have been performed before using this class in order to assure coherent test
045: * reports.
046: * </p>
047: *
048: * @author Emil Ivov Network Research Team, Louis Pasteur University,
049: * Strasbourg, France.
050: * @version 1.0
051: */
052:
053: class SipEventCollector {
054: private static long MESSAGE_QUEUE_EMPTIES_FOR = 500;
055:
056: private RequestCollector requestCollector = null;
057:
058: private ResponseCollector responseCollector = null;
059:
060: private TimeoutCollector timeoutCollector = null;
061:
062: private DialogTerminationCollector dialogTerminationCollector = null;
063:
064: private TransactionTerminationCollector transactionTerminationCollector = null;
065:
066: private static Logger logger = Logger
067: .getLogger(SipEventCollector.class);
068:
069: private void initCollectors(SipProvider sipProvider) {
070: this .requestCollector = new RequestCollector(sipProvider);
071: this .responseCollector = new ResponseCollector(sipProvider);
072: this .timeoutCollector = new TimeoutCollector(sipProvider);
073: this .dialogTerminationCollector = new DialogTerminationCollector(
074: sipProvider);
075: this .transactionTerminationCollector = new TransactionTerminationCollector(
076: sipProvider);
077: }
078:
079: /**
080: * Collects the first javax.sip.RequestEvent fired by the specified
081: * provider. All subsequent events and events other than
082: * javax.sip.RequestEvent are ignored.
083: *
084: * @param provider
085: * the provider that this collector should listen to
086: * @throws TooManyListenersException
087: * in case the specified provider throws that exception. It is
088: * the responsibility of the calling class to encapsulate it
089: * with the corresponding error (e.g. TckInternalError,
090: * AssertFailure or TiUnexpectedError) and throw it in its turn
091: * to upper layers.
092: */
093: public void collectRequestEvent(SipProvider provider)
094: throws TooManyListenersException {
095:
096: initCollectors(provider);
097: provider.addSipListener(requestCollector);
098: }
099:
100: /**
101: * Collects the first javax.sip.ResponseEvent fired by the specified
102: * provider. All subsequent events and events other than
103: * javax.sip.ResponseEvent are ignored.
104: *
105: * @param provider
106: * the provider that this collector should listen to
107: * @throws TooManyListenersException
108: * in case the specified provider throws that exception. It is
109: * the responsibility of the calling class to encapsulate it
110: * with the corresponding error (e.g. TckInternalError,
111: * AssertFailure or TiUnexpectedError) and throw it in its turn
112: * to upper layers.
113: */
114: public void collectResponseEvent(SipProvider provider)
115: throws TooManyListenersException {
116:
117: initCollectors(provider);
118: provider.addSipListener(responseCollector);
119:
120: }
121:
122: /**
123: * Collects the first javax.sip.TimeoutEvent fired by the specified
124: * provider. All subsequent events and events other than
125: * javax.sip.TimeoutEvent are ignored.
126: *
127: * @param provider
128: * the provider that this collector should listen to
129: * @throws TooManyListenersException
130: * in case the specified provider throws that exception. It is
131: * the responsibility of the calling class to encapsulate it
132: * with the corresponding error (e.g. TckInternalError,
133: * AssertFailure or TiUnexpectedError) and throw it in its turn
134: * to upper layers.
135: */
136: public void collectTimeoutEvent(SipProvider provider)
137: throws TooManyListenersException {
138: initCollectors(provider);
139: provider.addSipListener(timeoutCollector);
140: }
141:
142: /**
143: * Collects the first javax.sip.TransactionTerminated fired by the specified
144: * provider. All subsequent events and events other than
145: * javax.sip.TimeoutEvent are ignored.
146: *
147: * @param provider
148: * the provider that this collector should listen to
149: * @throws TooManyListenersException
150: * in case the specified provider throws that exception. It is
151: * the responsibility of the calling class to encapsulate it
152: * with the corresponding error (e.g. TckInternalError,
153: * AssertFailure or TiUnexpectedError) and throw it in its turn
154: * to upper layers.
155: */
156: public void collectTransactionTermiatedEvent(SipProvider provider)
157: throws TooManyListenersException {
158: initCollectors(provider);
159: provider.addSipListener(transactionTerminationCollector);
160: }
161:
162: /**
163: * Collects the first javax.sip.TransactionTerminated fired by the specified
164: * provider. All subsequent events and events other than
165: * javax.sip.TimeoutEvent are ignored.
166: *
167: * @param provider
168: * the provider that this collector should listen to
169: * @throws TooManyListenersException
170: * in case the specified provider throws that exception. It is
171: * the responsibility of the calling class to encapsulate it
172: * with the corresponding error (e.g. TckInternalError,
173: * AssertFailure or TiUnexpectedError) and throw it in its turn
174: * to upper layers.
175: */
176: public void collectDialogTermiatedEvent(SipProvider provider)
177: throws TooManyListenersException {
178: initCollectors(provider);
179: provider.addSipListener(dialogTerminationCollector);
180: }
181:
182: /**
183: * Returns the collected javax.sip.RequestEvent or null if no event has been
184: * collected. After this method is called the SipEventCollector will remove
185: * itself from the corresponding javax.sip.SipProvider and reset its
186: * internal state so that it could be reused.
187: *
188: * @return the collected javax.sip.RequestEvent
189: * @throws TckInternalError
190: * in case the method is called without first calling the
191: * collectRequestEvent
192: */
193: public RequestEvent extractCollectedRequestEvent() {
194: return this .extractCollectedRequestEvent(true);
195: }
196:
197: public RequestEvent extractCollectedRequestEvent(boolean toReset) {
198: if (requestCollector == null)
199: throw new TckInternalError(
200: "A request collect was attempted when the requestCollector was null");
201: RequestEvent collectedEvent = requestCollector.collectedEvent;
202:
203: if (toReset) {
204: requestCollector.provider
205: .removeSipListener(requestCollector);
206: resetCollectors();
207: try {
208: Thread.sleep(200);
209: } catch (InterruptedException ex) {
210: }
211: }
212:
213: return collectedEvent;
214: }
215:
216: /**
217: * Returns the collected javax.sip.ResponseEvent or null if no event has
218: * been collected. After this method is called the SipEventCollector will
219: * remove itself from the corresponding javax.sip.SipProvider and reset its
220: * internal state so that it could be reused.
221: *
222: * @return the collected javax.sip.ResponseEvent
223: * @throws TckInternalError
224: * in case the method is called without first calling the
225: * collectResponseEvent
226: */
227: public ResponseEvent extractCollectedResponseEvent() {
228: if (responseCollector == null)
229: throw new TckInternalError(
230: "A response collect was attempted when the responseCollector was null");
231: ResponseEvent collectedEvent = responseCollector.collectedEvent;
232: responseCollector.provider.removeSipListener(responseCollector);
233: resetCollectors();
234: try {
235: Thread.sleep(200);
236: } catch (InterruptedException ex) {
237: }
238: return collectedEvent;
239: }
240:
241: /**
242: * Returns the collected javax.sip.TimeoutEvent or null if no event has been
243: * collected. After this method is called the SipEventCollector will remove
244: * itself from the corresponding javax.sip.SipProvider and reset its
245: * internal state so that it could be reused.
246: *
247: * @return the collected javax.sip.TimeoutEvent
248: * @throws TckInternalError
249: * in case the method is called without first calling the
250: * collectTimeoutEvent
251: */
252: public TimeoutEvent extractCollectedTimeoutEvent() {
253: if (timeoutCollector == null)
254: throw new TckInternalError(
255: "A timeout collect was attempted when the timeoutCollector was null");
256: TimeoutEvent collectedEvent = timeoutCollector.collectedEvent;
257:
258: timeoutCollector.provider.removeSipListener(timeoutCollector);
259: resetCollectors();
260: return collectedEvent;
261: }
262:
263: /**
264: * Returns the collected javax.sip.DialogTerminatedEvent or null if no event
265: * has been collected. After this method is called the SipEventCollector
266: * will remove itself from the corresponding javax.sip.SipProvider and reset
267: * its internal state so that it could be reused.
268: *
269: * @return the collected javax.sip.TimeoutEvent
270: * @throws TckInternalError
271: * in case the method is called without first calling the
272: * collectTimeoutEvent
273: */
274: public DialogTerminatedEvent extractCollectedDialogTerminatedEvent() {
275: if (dialogTerminationCollector == null)
276: throw new TckInternalError(
277: "A dialog-terminated collect was attempted when the dialogTerminationCollector was null");
278: DialogTerminatedEvent collectedEvent = this .dialogTerminationCollector.collectedEvent;
279:
280: dialogTerminationCollector.provider
281: .removeSipListener(dialogTerminationCollector);
282: resetCollectors();
283: return collectedEvent;
284: }
285:
286: /**
287: * Returns the collected javax.sip.DialogTerminatedEvent or null if no event
288: * has been collected. After this method is called the SipEventCollector
289: * will remove itself from the corresponding javax.sip.SipProvider and reset
290: * its internal state so that it could be reused.
291: *
292: * @return the collected javax.sip.TimeoutEvent
293: * @throws TckInternalError
294: * in case the method is called without first calling the
295: * collectTimeoutEvent
296: */
297: public TransactionTerminatedEvent extractCollectedTransactionTerminatedEvent() {
298: if (transactionTerminationCollector == null)
299: throw new TckInternalError(
300: "A timeout collect was attempted when the transactionTerminationCollector was null");
301: TransactionTerminatedEvent collectedEvent = this .transactionTerminationCollector.collectedEvent;
302:
303: transactionTerminationCollector.provider
304: .removeSipListener(transactionTerminationCollector);
305: resetCollectors();
306: return collectedEvent;
307: }
308:
309: private void resetCollectors() {
310: /**
311: * sipProvider = null;
312: *
313: * requestCollector = null; responseCollector = null; timeoutCollector =
314: * null; dialogTerminationCollector = null;
315: * transactionTerminationCollector = null;
316: */
317:
318: // Wait for the message queue to go empty
319: MessageFlowHarness.sleep(MESSAGE_QUEUE_EMPTIES_FOR);
320: }
321:
322: private void assertInitialState(Class eventClass) {
323: boolean failureFlag = false;
324: if (eventClass.equals(RequestEvent.class)) {
325: if (requestCollector != null
326: && requestCollector.collectedEvent != null) {
327: failureFlag = true;
328: }
329: } else if (eventClass.equals(ResponseEvent.class)) {
330: if (responseCollector != null
331: && responseCollector.collectedEvent != null) {
332:
333: failureFlag = true;
334: }
335: } else if (eventClass.equals(TimeoutEvent.class)) {
336: if (timeoutCollector != null
337: && timeoutCollector.collectedEvent != null) {
338: failureFlag = true;
339: }
340: } else if (eventClass.equals(TransactionTerminatedEvent.class)) {
341: if (this .transactionTerminationCollector != null
342: && this .transactionTerminationCollector.collectedEvent != null)
343: failureFlag = true;
344:
345: } else if (eventClass.equals(DialogTerminatedEvent.class)) {
346: if (this .dialogTerminationCollector != null
347: && this .dialogTerminationCollector.collectedEvent != null)
348: failureFlag = true;
349: }
350:
351: if (failureFlag)
352: throw new TckInternalError(
353: "Attempting to start a collect operation "
354: + "on a collector that is not in initial state!");
355: }
356:
357: // ========================= COLLECTOR
358: // ADAPTERS==============================
359:
360: private class RequestCollector implements SipListener {
361: private RequestEvent collectedEvent = null;
362:
363: private SipProvider provider;
364:
365: public RequestCollector(SipProvider sipProvider) {
366: this .provider = sipProvider;
367: }
368:
369: public void processRequest(RequestEvent evt) {
370: // Ignore secondary and null events
371: if (collectedEvent != null || evt == null)
372: return;
373: collectedEvent = evt;
374: }
375:
376: public void processResponse(ResponseEvent responseEvent) {
377: }
378:
379: public void processTimeout(TimeoutEvent timeoutEvent) {
380: }
381:
382: public void processIOException(IOExceptionEvent exceptionEvent) {
383: // TODO Auto-generated method stub
384: logger.debug("processIOException");
385: }
386:
387: public void processTransactionTerminated(
388: TransactionTerminatedEvent transactionTerminatedEvent) {
389: // TODO Auto-generated method stub
390: logger.debug("processTransactionTerminated");
391: }
392:
393: public void processDialogTerminated(
394: DialogTerminatedEvent dialogTerminatedEvent) {
395: // TODO Auto-generated method stub
396: logger.debug("processDialogTerminated");
397: }
398:
399: }
400:
401: private class ResponseCollector implements SipListener {
402: private ResponseEvent collectedEvent = null;
403:
404: private SipProvider provider;
405:
406: public ResponseCollector(SipProvider sipProvider) {
407: this .provider = sipProvider;
408: }
409:
410: public void processRequest(RequestEvent requestEvent) {
411: }
412:
413: public void processResponse(ResponseEvent evt) {
414: // Ignore secondary and null events
415: if (collectedEvent != null || evt == null)
416: return;
417: collectedEvent = evt;
418: }
419:
420: public void processTimeout(TimeoutEvent timeoutEvent) {
421: logger.debug("processTimeout");
422: }
423:
424: public void processIOException(IOExceptionEvent exceptionEvent) {
425: logger.error("processIOException");
426: }
427:
428: public void processTransactionTerminated(
429: TransactionTerminatedEvent transactionTerminatedEvent) {
430: logger.info("transaction terminated event recieved");
431: }
432:
433: public void processDialogTerminated(
434: DialogTerminatedEvent dialogTerminatedEvent) {
435: logger.info("processDialogTerminated");
436: }
437:
438: }
439:
440: private class TransactionTerminationCollector implements
441: SipListener {
442:
443: private TransactionTerminatedEvent collectedEvent;
444:
445: private SipProvider provider;
446:
447: public TransactionTerminationCollector(SipProvider sipProvider) {
448: this .provider = sipProvider;
449: }
450:
451: public void processRequest(RequestEvent requestEvent) {
452:
453: }
454:
455: public void processResponse(ResponseEvent responseEvent) {
456:
457: }
458:
459: public void processTimeout(TimeoutEvent timeoutEvent) {
460:
461: }
462:
463: public void processIOException(IOExceptionEvent exceptionEvent) {
464:
465: }
466:
467: public void processTransactionTerminated(
468: TransactionTerminatedEvent transactionTerminatedEvent) {
469: this .collectedEvent = transactionTerminatedEvent;
470: }
471:
472: public void processDialogTerminated(
473: DialogTerminatedEvent dialogTerminatedEvent) {
474:
475: }
476:
477: }
478:
479: private class DialogTerminationCollector implements SipListener {
480:
481: private DialogTerminatedEvent collectedEvent;
482:
483: private SipProvider provider;
484:
485: public DialogTerminationCollector(SipProvider sipProvider) {
486: this .provider = sipProvider;
487: }
488:
489: public void processRequest(RequestEvent requestEvent) {
490:
491: }
492:
493: public void processResponse(ResponseEvent responseEvent) {
494:
495: }
496:
497: public void processTimeout(TimeoutEvent timeoutEvent) {
498:
499: }
500:
501: public void processIOException(IOExceptionEvent exceptionEvent) {
502:
503: }
504:
505: public void processTransactionTerminated(
506: TransactionTerminatedEvent transactionTerminatedEvent) {
507:
508: }
509:
510: public void processDialogTerminated(
511: DialogTerminatedEvent dialogTerminatedEvent) {
512: this .collectedEvent = dialogTerminatedEvent;
513:
514: }
515:
516: }
517:
518: private class TimeoutCollector implements SipListener {
519: private TimeoutEvent collectedEvent = null;
520:
521: private SipProvider provider;
522:
523: public TimeoutCollector(SipProvider sipProvider) {
524: this .provider = sipProvider;
525: }
526:
527: public void processRequest(RequestEvent requestEvent) {
528: requestCollector.processRequest(requestEvent);
529: }
530:
531: public void processResponse(ResponseEvent responseEvent) {
532: }
533:
534: public void processTimeout(TimeoutEvent evt) {
535: // Ignore secondary and null events
536: if (collectedEvent != null || evt == null)
537: return;
538: collectedEvent = evt;
539: }
540:
541: public void processIOException(IOExceptionEvent exceptionEvent) {
542: // TODO Auto-generated method stub
543: logger.info("processIOException");
544: }
545:
546: public void processTransactionTerminated(
547: TransactionTerminatedEvent transactionTerminatedEvent) {
548: // TODO Auto-generated method stub
549: logger.info("processTransactionTerminated");
550: }
551:
552: public void processDialogTerminated(
553: DialogTerminatedEvent dialogTerminatedEvent) {
554: // TODO Auto-generated method stub
555: logger.info("processDialogTerminated");
556: }
557: }
558:
559: }
|