SIP Communicator: the OpenSource Java VoIP and Instant Messaging client.

net.java.sip.communicator.impl.protocol.sip
Class OperationSetPresenceSipImpl

java.lang.Object
  extended by net.java.sip.communicator.service.protocol.AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
      extended by net.java.sip.communicator.impl.protocol.sip.OperationSetPresenceSipImpl
All Implemented Interfaces:
EventListener, MethodProcessor, RegistrationStateChangeListener, OperationSet, OperationSetPersistentPresence, OperationSetPresence

public class OperationSetPresenceSipImpl
extends AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
implements MethodProcessor, RegistrationStateChangeListener

Sip presence implementation (SIMPLE). Compliant with rfc3261, rfc3265, rfc3856, rfc3863, rfc4480 and rfc3903

Author:
Benoit Pradelle, Lubomir Marinov, Emil Ivov, Grigorii Balutsel

Field Summary
 
Fields inherited from class net.java.sip.communicator.service.protocol.AbstractOperationSetPersistentPresence
parentProvider
 
Constructor Summary
OperationSetPresenceSipImpl(ProtocolProviderServiceSipImpl provider, boolean presenceEnabled, boolean forceP2PMode, int pollingPeriod, int subscriptionExpiration)
          Creates an instance of this operation set keeping a reference to the specified parent provider.
 
Method Summary
 void addServerStoredGroupChangeListener(ServerStoredGroupListener listener)
          Registers a listener that would receive events upong changes in server stored groups.
(package private)  String convertDocument(Document document)
          Convert a xml document
(package private)  Document convertDocument(String document)
          Convert a xml document
(package private)  Document createDocument()
          Returns a new valid xml document.
 void createServerStoredContactGroup(ContactGroup parentGroup, String groupName)
          Creates a group with the specified name and parent in the server stored contact list.
 Contact createUnresolvedContact(String address, String persistentData)
          Creates and returns a unresolved contact from the specified address and persistentData.
 Contact createUnresolvedContact(String contactId, String persistentData, ContactGroup parent)
          Creates and returns a unresolved contact from the specified address and persistentData.
 ContactGroup createUnresolvedContactGroup(String groupUID, String persistentData, ContactGroup parentGroup)
          Creates and returns a unresolved contact group from the specified address and persistentData.
 ContactSipImpl createVolatileContact(javax.sip.address.Address contactAddress)
          Creates a non persistent contact for the specified address.
 ContactSipImpl findContactByID(String contactID)
          Returns a ContactSipImpl with a specific ID in case we have a subscription for it and null otherwise.
 void fireProviderMsgStatusChangeEvent(String oldValue)
          Notifies all registered listeners of the new event.
 void forcePollContact(ContactSipImpl contact)
          Forces the poll of a contact to update its current state.
 String getCurrentStatusMessage()
          Returns the status message that was confirmed by the server
 ContactSipImpl getLocalContactForDst(javax.sip.address.Address destination)
          Returns the protocol specific contact instance representing the local user.
 ContactSipImpl getLocalContactForDst(ContactSipImpl destination)
          Returns the protocol specific contact instance representing the local user.
 byte[] getPidfPresenceStatus(ContactSipImpl contact)
          Converts the PresenceStatus of contact into a PIDF document.
 PresenceStatus getPresenceStatus()
          Returns a PresenceStatus instance representing the state this provider is currently in.
 ContactGroup getServerStoredContactListRoot()
          Returns the root group of the server stored contact list.
 Iterator<PresenceStatus> getSupportedStatusSet()
          Returns the set of PresenceStatus objects that a user of this service may request the provider to enter.
static boolean isEquals(URI uri1, URI uri2)
          Checks whether to URIs are equal with safe null check.
 void moveContactToGroup(Contact contactToMove, ContactGroup newParent)
          Removes the specified contact from its current parent and places it under newParent.
 boolean processDialogTerminated(javax.sip.DialogTerminatedEvent dialogTerminatedEvent)
          Called when a dialog is terminated
 boolean processIOException(javax.sip.IOExceptionEvent exceptionEvent)
          Called when an IO error occurs
 boolean processRequest(javax.sip.RequestEvent requestEvent)
          Process a request from a distant contact
 boolean processResponse(javax.sip.ResponseEvent responseEvent)
          Analyzes the incoming responseEvent and then forwards it to the proper event handler.
 boolean processTimeout(javax.sip.TimeoutEvent timeoutEvent)
          Called when a timeout occur
 boolean processTransactionTerminated(javax.sip.TransactionTerminatedEvent transactionTerminatedEvent)
          Called when a transaction is terminated
 void publishPresenceStatus(PresenceStatus status, String statusMsg)
          Requests the provider to enter into a status corresponding to the specified parameters.
 PresenceStatus queryContactStatus(String contactIdentifier)
          Get the PresenceStatus for a particular contact.
 void registrationStateChanged(RegistrationStateChangeEvent evt)
          The method is called by a ProtocolProvider implementation whenever a change in the registration state of the corresponding provider had occurred.
 void removeServerStoredContactGroup(ContactGroup group)
          Removes the specified group from the server stored contact list.
 void removeServerStoredGroupChangeListener(ServerStoredGroupListener listener)
          Removes the specified group change listener so that it won't receive any further events.
 void renameServerStoredContactGroup(ContactGroup group, String newName)
          Renames the specified group from the server stored contact list.
(package private)  ContactSipImpl resolveContactID(String contactID)
          Tries to find a ContactSipImpl which is identified either by a specific contactID or by a derivation of it.
 void setAuthorizationHandler(AuthorizationHandler handler)
          Handler for incoming authorization requests.
 void setPidfPresenceStatus(String presenceDoc)
          Sets the contact's presence status using the PIDF document provided.
 void subscribe(ContactGroup parentGroup, String contactIdentifier)
          Persistently adds a subscription for the presence status of the contact corresponding to the specified contactIdentifier and indicates that it should be added to the specified group of the server stored contact list.
 void subscribe(String contactIdentifier)
          Adds a subscription for the presence status of the contact corresponding to the specified contactIdentifier.
 void unsubscribe(Contact contact)
          Removes a subscription for the presence status of the specified contact.
 void unsubscribeToAllContact()
          Unsubscribe to every contact.
 
Methods inherited from class net.java.sip.communicator.service.protocol.AbstractOperationSetPersistentPresence
addContactPresenceStatusListener, addProviderPresenceStatusListener, addSubscriptionListener, fireContactPresenceStatusChangeEvent, fireContactPresenceStatusChangeEvent, fireContactPropertyChangeEvent, fireProviderStatusChangeEvent, fireProviderStatusChangeEvent, fireProviderStatusMessageChangeEvent, fireServerStoredGroupEvent, fireSubscriptionEvent, fireSubscriptionEvent, fireSubscriptionMovedEvent, removeContactPresenceStatusListener, removeProviderPresenceStatusListener, removeSubscriptionListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

OperationSetPresenceSipImpl

public OperationSetPresenceSipImpl(ProtocolProviderServiceSipImpl provider,
                                   boolean presenceEnabled,
                                   boolean forceP2PMode,
                                   int pollingPeriod,
                                   int subscriptionExpiration)
Creates an instance of this operation set keeping a reference to the specified parent provider.

Parameters:
provider - the ProtocolProviderServiceSipImpl instance that created us.
presenceEnabled - if we are activated or if we don't have to handle the presence informations for contacts
forceP2PMode - if we should start in the p2p mode directly
pollingPeriod - the period between two poll for offline contacts
subscriptionExpiration - the default subscription expiration value to use
Method Detail

addServerStoredGroupChangeListener

public void addServerStoredGroupChangeListener(ServerStoredGroupListener listener)
Registers a listener that would receive events upong changes in server stored groups.

Specified by:
addServerStoredGroupChangeListener in interface OperationSetPersistentPresence
Overrides:
addServerStoredGroupChangeListener in class AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
Parameters:
listener - a ServerStoredGroupChangeListener impl that would receive events upong group changes.

removeServerStoredGroupChangeListener

public void removeServerStoredGroupChangeListener(ServerStoredGroupListener listener)
Removes the specified group change listener so that it won't receive any further events.

Specified by:
removeServerStoredGroupChangeListener in interface OperationSetPersistentPresence
Overrides:
removeServerStoredGroupChangeListener in class AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
Parameters:
listener - the ServerStoredGroupChangeListener to remove

getPresenceStatus

public PresenceStatus getPresenceStatus()
Returns a PresenceStatus instance representing the state this provider is currently in. Note that PresenceStatus instances returned by this method MUST adequately represent all possible states that a provider might enter during its lifecycle, including those that would not be visible to others (e.g. Initializing, Connecting, etc ..) and those that will be sent to contacts/buddies (On-Line, Eager to chat, etc.).

Specified by:
getPresenceStatus in interface OperationSetPresence
Returns:
the PresenceStatus last published by this provider.

getServerStoredContactListRoot

public ContactGroup getServerStoredContactListRoot()
Returns the root group of the server stored contact list.

Specified by:
getServerStoredContactListRoot in interface OperationSetPersistentPresence
Returns:
the root ContactGroup for the ContactList stored by this service.

createServerStoredContactGroup

public void createServerStoredContactGroup(ContactGroup parentGroup,
                                           String groupName)
                                    throws OperationFailedException
Creates a group with the specified name and parent in the server stored contact list.

Specified by:
createServerStoredContactGroup in interface OperationSetPersistentPresence
Parameters:
parentGroup - the group where the new group should be created
groupName - the name of the new group to create.
Throws:
OperationFailedException - with code NETWORK_FAILURE if creating the group fails because of a network error.

createUnresolvedContactGroup

public ContactGroup createUnresolvedContactGroup(String groupUID,
                                                 String persistentData,
                                                 ContactGroup parentGroup)
Creates and returns a unresolved contact group from the specified address and persistentData. The method will not try to establish a network connection and resolve the newly created ContactGroup against the server or the contact itself. The protocol provider will later resolve the contact group. When this happens the corresponding event would notify interested subscription listeners.

Specified by:
createUnresolvedContactGroup in interface OperationSetPersistentPresence
Parameters:
groupUID - an identifier, returned by ContactGroup's getGroupUID, that the protocol provider may use in order to create the group.
persistentData - a String returned ContactGroups's getPersistentData() method during a previous run and that has been persistently stored locally.
parentGroup - the group under which the new group is to be created or null if this is group directly underneath the root.
Returns:
the unresolved ContactGroup created from the specified uid and persistentData

renameServerStoredContactGroup

public void renameServerStoredContactGroup(ContactGroup group,
                                           String newName)
Renames the specified group from the server stored contact list.

Specified by:
renameServerStoredContactGroup in interface OperationSetPersistentPresence
Parameters:
group - the group to rename.
newName - the new name of the group.

moveContactToGroup

public void moveContactToGroup(Contact contactToMove,
                               ContactGroup newParent)
Removes the specified contact from its current parent and places it under newParent.

Specified by:
moveContactToGroup in interface OperationSetPersistentPresence
Parameters:
contactToMove - the Contact to move
newParent - the ContactGroup where Contact would be placed.

removeServerStoredContactGroup

public void removeServerStoredContactGroup(ContactGroup group)
Removes the specified group from the server stored contact list.

Specified by:
removeServerStoredContactGroup in interface OperationSetPersistentPresence
Parameters:
group - the group to remove.
Throws:
IllegalArgumentException - if group was not found in this protocol's contact list.

publishPresenceStatus

public void publishPresenceStatus(PresenceStatus status,
                                  String statusMsg)
                           throws IllegalArgumentException,
                                  IllegalStateException,
                                  OperationFailedException
Requests the provider to enter into a status corresponding to the specified parameters.

Specified by:
publishPresenceStatus in interface OperationSetPresence
Parameters:
status - the PresenceStatus as returned by getRequestableStatusSet
statusMsg - the message that should be set as the reason to enter that status
Throws:
IllegalArgumentException - if the status requested is not a valid PresenceStatus supported by this provider.
IllegalStateException - if the provider is not currently registered.
OperationFailedException - with code NETWORK_FAILURE if publishing the status fails due to a network error.

fireProviderMsgStatusChangeEvent

public void fireProviderMsgStatusChangeEvent(String oldValue)
Notifies all registered listeners of the new event.

Parameters:
oldValue - the presence status we were in before the change.

getSupportedStatusSet

public Iterator<PresenceStatus> getSupportedStatusSet()
Returns the set of PresenceStatus objects that a user of this service may request the provider to enter. Note that the provider would most probably enter more states than those returned by this method as they only depict instances that users may request to enter. (e.g. a user may not request a "Connecting..." state - it is a temporary state that the provider enters while trying to enter the "Connected" state).

Specified by:
getSupportedStatusSet in interface OperationSetPresence
Returns:
Iterator a PresenceStatus array containing "enterable" status instances.

queryContactStatus

public PresenceStatus queryContactStatus(String contactIdentifier)
                                  throws IllegalArgumentException,
                                         IllegalStateException,
                                         OperationFailedException
Get the PresenceStatus for a particular contact.

Specified by:
queryContactStatus in interface OperationSetPresence
Parameters:
contactIdentifier - the identifier of the contact whose status we're interested in.
Returns:
PresenceStatus the PresenceStatus of the specified contact
Throws:
IllegalArgumentException - if contact is not a contact known to the underlying protocol provider
IllegalStateException - if the underlying protocol provider is not registered/signed on a public service.
OperationFailedException - with code NETWORK_FAILURE if retrieving the status fails due to errors experienced during network communication

subscribe

public void subscribe(String contactIdentifier)
               throws IllegalArgumentException,
                      IllegalStateException,
                      OperationFailedException
Adds a subscription for the presence status of the contact corresponding to the specified contactIdentifier.

Specified by:
subscribe in interface OperationSetPersistentPresence
Specified by:
subscribe in interface OperationSetPresence
Parameters:
contactIdentifier - the identifier of the contact whose status updates we are subscribing for.

Throws:
IllegalArgumentException - if contact is not a contact known to the underlying protocol provider
IllegalStateException - if the underlying protocol provider is not registered/signed on a public service.
OperationFailedException - with code NETWORK_FAILURE if subscribing fails due to errors experienced during network communication

subscribe

public void subscribe(ContactGroup parentGroup,
                      String contactIdentifier)
               throws IllegalArgumentException,
                      IllegalStateException,
                      OperationFailedException
Persistently adds a subscription for the presence status of the contact corresponding to the specified contactIdentifier and indicates that it should be added to the specified group of the server stored contact list.

Specified by:
subscribe in interface OperationSetPersistentPresence
Parameters:
parentGroup - the parent group of the server stored contact list where the contact should be added.

contactIdentifier - the contact whose status updates we are subscribing for.
Throws:
IllegalArgumentException - if contact or parent are not a contact known to the underlying protocol provider.
IllegalStateException - if the underlying protocol provider is not registered/signed on a public service.
OperationFailedException - with code NETWORK_FAILURE if subscribing fails due to errors experienced during network communication

unsubscribe

public void unsubscribe(Contact contact)
                 throws IllegalArgumentException,
                        IllegalStateException,
                        OperationFailedException
Removes a subscription for the presence status of the specified contact.

Specified by:
unsubscribe in interface OperationSetPersistentPresence
Specified by:
unsubscribe in interface OperationSetPresence
Parameters:
contact - the contact whose status updates we are unsubscribing from.
Throws:
OperationFailedException - with code NETWORK_FAILURE if unsubscribing fails due to errors experienced during network communication
IllegalArgumentException - if contact is not a contact known to the underlying protocol provider
IllegalStateException - if the underlying protocol provider is not registered/signed on a public service.

processResponse

public boolean processResponse(javax.sip.ResponseEvent responseEvent)
Analyzes the incoming responseEvent and then forwards it to the proper event handler.

Specified by:
processResponse in interface MethodProcessor
Parameters:
responseEvent - the responseEvent that we received ProtocolProviderService.
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

processRequest

public boolean processRequest(javax.sip.RequestEvent requestEvent)
Process a request from a distant contact

Specified by:
processRequest in interface MethodProcessor
Parameters:
requestEvent - the RequestEvent containing the newly received request.
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

processDialogTerminated

public boolean processDialogTerminated(javax.sip.DialogTerminatedEvent dialogTerminatedEvent)
Called when a dialog is terminated

Specified by:
processDialogTerminated in interface MethodProcessor
Parameters:
dialogTerminatedEvent - DialogTerminatedEvent
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

processIOException

public boolean processIOException(javax.sip.IOExceptionEvent exceptionEvent)
Called when an IO error occurs

Specified by:
processIOException in interface MethodProcessor
Parameters:
exceptionEvent - IOExceptionEvent
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

processTransactionTerminated

public boolean processTransactionTerminated(javax.sip.TransactionTerminatedEvent transactionTerminatedEvent)
Called when a transaction is terminated

Specified by:
processTransactionTerminated in interface MethodProcessor
Parameters:
transactionTerminatedEvent - TransactionTerminatedEvent
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

processTimeout

public boolean processTimeout(javax.sip.TimeoutEvent timeoutEvent)
Called when a timeout occur

Specified by:
processTimeout in interface MethodProcessor
Parameters:
timeoutEvent - TimeoutEvent
Returns:
true if the specified event has been handled by this processor and shouldn't be offered to other processors registered for the same method; false, otherwise

findContactByID

public ContactSipImpl findContactByID(String contactID)
Returns a ContactSipImpl with a specific ID in case we have a subscription for it and null otherwise.

Specified by:
findContactByID in interface OperationSetPresence
Parameters:
contactID - a String identifier of the contact which is to be retrieved
Returns:
the ContactSipImpl with the specified contactID or null if we don't have a subscription for the specified identifier

getLocalContactForDst

public ContactSipImpl getLocalContactForDst(ContactSipImpl destination)
Returns the protocol specific contact instance representing the local user.

Parameters:
destination - the destination that we would be sending our contact information to.
Returns:
a ContactSipImpl instance that represents us.

getLocalContactForDst

public ContactSipImpl getLocalContactForDst(javax.sip.address.Address destination)
Returns the protocol specific contact instance representing the local user.

Parameters:
destination - the destination that we would be sending our contact information to.
Returns:
a ContactSipImpl instance that represents us.

setAuthorizationHandler

public void setAuthorizationHandler(AuthorizationHandler handler)
Handler for incoming authorization requests.

Specified by:
setAuthorizationHandler in interface OperationSetPresence
Parameters:
handler - an instance of an AuthorizationHandler for authorization requests coming from other users requesting permission add us to their contact list.

getCurrentStatusMessage

public String getCurrentStatusMessage()
Returns the status message that was confirmed by the server

Specified by:
getCurrentStatusMessage in interface OperationSetPresence
Returns:
the last status message that we have requested and the server has confirmed.

createUnresolvedContact

public Contact createUnresolvedContact(String address,
                                       String persistentData)
Creates and returns a unresolved contact from the specified address and persistentData. The method will not try to establish a network connection and resolve the newly created Contact against the server. The protocol provider may will later try and resolve the contact. When this happens the corresponding event would notify interested subscription listeners.

Specified by:
createUnresolvedContact in interface OperationSetPresence
Parameters:
address - an identifier of the contact that we'll be creating.
persistentData - a String returned Contact's getPersistentData() method during a previous run and that has been persistently stored locally.
Returns:
the unresolved Contact created from the specified address and persistentData

createUnresolvedContact

public Contact createUnresolvedContact(String contactId,
                                       String persistentData,
                                       ContactGroup parent)
Creates and returns a unresolved contact from the specified address and persistentData. The method will not try to establish a network connection and resolve the newly created Contact against the server. The protocol provider may will later try and resolve the contact. When this happens the corresponding event would notify interested subscription listeners.

Specified by:
createUnresolvedContact in interface OperationSetPersistentPresence
Parameters:
contactId - an identifier of the contact that we'll be creating.
persistentData - a String returned Contact's getPersistentData() method during a previous run and that has been persistently stored locally.
parent - the group where the unresolved contact is supposed to belong to.
Returns:
the unresolved Contact created from the specified address and persistentData

createVolatileContact

public ContactSipImpl createVolatileContact(javax.sip.address.Address contactAddress)
Creates a non persistent contact for the specified address. This would also create (if necessary) a group for volatile contacts that would not be added to the server stored contact list. This method would have no effect on the server stored contact list.

Parameters:
contactAddress - the address of the volatile contact we'd like to create.
Returns:
the newly created volatile contact.

resolveContactID

ContactSipImpl resolveContactID(String contactID)
Tries to find a ContactSipImpl which is identified either by a specific contactID or by a derivation of it.

Parameters:
contactID - the identifier of the ContactSipImpl to retrieve either by directly using it or by deriving it
Returns:
a ContactSipImpl which is identified either by the specified contactID or by a derivation of it

createDocument

Document createDocument()
Returns a new valid xml document.

Returns:
a correct xml document or null if an error occurs

convertDocument

String convertDocument(Document document)
Convert a xml document

Parameters:
document - the document to convert
Returns:
a string representing document or null if an error occur

convertDocument

Document convertDocument(String document)
Convert a xml document

Parameters:
document - the document as a String
Returns:
a Document representing the document or null if an error occur

getPidfPresenceStatus

public byte[] getPidfPresenceStatus(ContactSipImpl contact)
Converts the PresenceStatus of contact into a PIDF document.

Parameters:
contact - The contact which interest us
Returns:
a PIDF document representing the current presence status of this contact or null if an error occurs.

setPidfPresenceStatus

public void setPidfPresenceStatus(String presenceDoc)
Sets the contact's presence status using the PIDF document provided. In case of conflict (more than one status per contact) the last valid status in the document is used. This implementation is very tolerant to be more compatible with bad implementations of SIMPLE. The limit of the tolerance is defined by the CPU cost: as far as the tolerance costs nothing more in well structured documents, we do it.

Parameters:
presenceDoc - the pidf document to use

isEquals

public static boolean isEquals(URI uri1,
                               URI uri2)
Checks whether to URIs are equal with safe null check.

Parameters:
uri1 - to be compared.
uri2 - to be compared.
Returns:
if uri1 is equal to uri2.

forcePollContact

public void forcePollContact(ContactSipImpl contact)
Forces the poll of a contact to update its current state.

Parameters:
contact - the contact to poll

unsubscribeToAllContact

public void unsubscribeToAllContact()
Unsubscribe to every contact.


registrationStateChanged

public void registrationStateChanged(RegistrationStateChangeEvent evt)
The method is called by a ProtocolProvider implementation whenever a change in the registration state of the corresponding provider had occurred. The method is particularly interested in events stating that the SIP provider has unregistered so that it would fire status change events for all contacts in our buddy list.

Specified by:
registrationStateChanged in interface RegistrationStateChangeListener
Parameters:
evt - ProviderStatusChangeEvent the event describing the status change.

SIP Communicator: the OpenSource Java VoIP and Instant Messaging client.

SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
Distributable under LGPL license.