/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.service.protocol; import java.util.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; /** * A represenation of a Call. The Call class must obly be created by users (i.e. * telephony protocols) of the PhoneUIService such as a SIP protocol * implemenation. Extensions of this class might have names like SipCall * or H323Call or AnyOtherTelephonyProtocolCall * * @author Emil Ivov */ public abstract class Call { private static final Logger logger = Logger.getLogger(Call.class); /** * An identifier uniquely representing the call. */ private String callID = null; /** * A list of all listeners currently registered for * CallChangeEvents */ private Vector callListeners = new Vector(); /** * A reference to the ProtocolProviderService instance that created us. */ private ProtocolProviderService protocolProvider = null; /** * Creates a new Call instance. * * @param sourceProvider the proto provider that created us. */ protected Call(ProtocolProviderService sourceProvider) { //create the uid this.callID = String.valueOf( System.currentTimeMillis()) + String.valueOf(super.hashCode()); this.protocolProvider = sourceProvider; } /** * Returns the id of the specified Call. * @return a String uniquely identifying the call. */ public String getCallID() { return callID; } /** * Compares the specified object with this call and returns true if it the * specified object is an instance of a Call object and if the * extending telephony protocol considers the calls represented by both * objects to be the same. * * @param obj the call to compare this one with. * @return true in case both objects are pertaining to the same call and * false otherwise. */ public boolean equals(Object obj) { if(obj == null || !(obj instanceof Call)) return false; if (obj == this || ((Call)obj).getCallID().equals( getCallID() )) return true; return false; } /** * Returns a hash code value for this call. * * @return a hash code value for this call. */ public int hashCode() { return getCallID().hashCode(); } /** * Returns an iterator over all call participants. * @return an Iterator over all participants currently involved in the call. */ public abstract Iterator getCallParticipants(); /** * Returns the number of participants currently associated with this call. * @return an int indicating the number of participants currently * associated with this call. */ public abstract int getCallParticipantsCount(); /** * Adds a call change listener to this call so that it could receive events * on new call participants, theme changes and others. * * @param listener the listener to register */ public void addCallChangeListener(CallChangeListener listener) { synchronized(callListeners) { if(!callListeners.contains(listener)) this.callListeners.add(listener); } } /** * Removes listener to this call so that it won't receive further * CallChangeEvents. * @param listener the listener to register */ public void removeCallChangeListener(CallChangeListener listener) { synchronized(callListeners) { this.callListeners.remove(listener); } } /** * Returns a reference to the ProtocolProviderService instance * that created this call. * @return a reference to the ProtocolProviderService instance that * created this call. */ public ProtocolProviderService getProtocolProvider() { return this.protocolProvider; } /** * Creates a CallParticipantEvent with * sourceCallParticipant and eventID and dispatches it on * all currently registered listeners. * * @param sourceCallParticipant the source CallParticipant for the * newly created event. * @param eventID the ID of the event to create (see CPE member ints) */ protected void fireCallParticipantEvent(CallParticipant sourceCallParticipant, int eventID) { CallParticipantEvent cpEvent = new CallParticipantEvent( sourceCallParticipant, this, eventID); logger.debug("Dispatching a CallParticipant event to " + callListeners.size() +" listeners. event is: " + cpEvent.toString()); Iterator listeners = null; synchronized(callListeners) { listeners = new ArrayList(callListeners).iterator(); } while(listeners.hasNext()) { CallChangeListener listener = (CallChangeListener)listeners.next(); if(eventID == CallParticipantEvent.CALL_PARTICIPANT_ADDED) listener.callParticipantAdded(cpEvent); else if (eventID == CallParticipantEvent.CALL_PARTICIPANT_REMVOVED) listener.callParticipantRemoved(cpEvent); } } /** * Returns a string textually representing this Call. * * @return a string representation of the object. */ public String toString() { return "Call: id=" + getCallID() + " participants=" + getCallParticipantsCount(); } /** * Creates a CallChangeEvent with this class as * sourceCall, and the specified eventID and old and new * values and dispatches it on all currently registered listeners. * * @param type the type of the event to create (see CallChangeEvent member * ints) * @param oldValue the value of the call property that changed, before the * event had occurred. * @param newValue the value of the call property that changed, after the * event has occurred. */ protected void fireCallChangeEvent( String type, Object oldValue, Object newValue) { CallChangeEvent ccEvent = new CallChangeEvent( this, type, oldValue, newValue); logger.debug("Dispatching a CallChange event to " + callListeners.size() +" listeners. event is: " + ccEvent.toString()); Iterator listeners = null; synchronized(callListeners) { listeners = new ArrayList(callListeners).iterator(); } while(listeners.hasNext()) { CallChangeListener listener = (CallChangeListener)listeners.next(); if(type.equals(CallChangeEvent.CALL_STATE_CHANGE)) listener.callStateChanged(ccEvent); } } /** * Returns the state that this call is currently in. * * @return a reference to the CallState instance that the call is * currently in. */ public abstract CallState getCallState(); }