mirror of https://github.com/sipwise/jitsi.git
The implementation of OperationSetGeolocation for jabber (by Guillaume Schreiner, Louis Pasteur University, France).cusax-fix
parent
b9c3f1d2e2
commit
0d8d715096
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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.impl.protocol.jabber;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smack.provider.*;
|
||||
import org.jivesoftware.smack.util.*;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.geolocation.*;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* The Jabber implementation of an OperationSetGeolocation done with the
|
||||
* XEP-0080: User Geolocation. This class broadcast our own geolocation and
|
||||
* manage the geolocation status of our buddies.
|
||||
*
|
||||
* Currently, we send geolocation message in presence. We passively listen
|
||||
* to buddies geolocation when their presence are updated.
|
||||
*
|
||||
* @author Guillaume Schreiner
|
||||
*/
|
||||
public class OperationSetGeolocationJabberImpl
|
||||
implements OperationSetGeolocation
|
||||
{
|
||||
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(OperationSetGeolocationJabberImpl.class);
|
||||
|
||||
/**
|
||||
* The list of Geolocation status listeners interested in receiving presence
|
||||
* notifications of changes in geolocation of contacts in our contact list.
|
||||
*/
|
||||
private Vector geolocationContactsListeners = new Vector();
|
||||
|
||||
/**
|
||||
* A callback to the provider
|
||||
*/
|
||||
private ProtocolProviderServiceJabberImpl jabberProvider;
|
||||
|
||||
/**
|
||||
* A callback to the persistent presence operation set.
|
||||
*/
|
||||
private OperationSetPersistentPresence opsetprez = null;
|
||||
|
||||
/**
|
||||
* Constuctor
|
||||
*
|
||||
* @param provider <tt>ProtocolProviderServiceJabberImpl</tt>
|
||||
*/
|
||||
public OperationSetGeolocationJabberImpl(
|
||||
ProtocolProviderServiceJabberImpl provider)
|
||||
{
|
||||
|
||||
this.jabberProvider = provider;
|
||||
|
||||
this.opsetprez = (OperationSetPersistentPresence)
|
||||
provider.getOperationSet(OperationSetPersistentPresence.class);
|
||||
|
||||
this.jabberProvider.addRegistrationStateChangeListener(
|
||||
new RegistrationStateListener());
|
||||
|
||||
// Add the custom GeolocationExtension to the Smack library
|
||||
ProviderManager pManager = ProviderManager.getInstance();
|
||||
pManager.addExtensionProvider(
|
||||
GeolocationPacketExtensionProvider.ELEMENT_NAME
|
||||
, GeolocationPacketExtensionProvider.NAMESPACE
|
||||
, new GeolocationPacketExtensionProvider());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast our current Geolocation trough this provider using a Jabber
|
||||
* presence message.
|
||||
*
|
||||
* @param geolocation our current Geolocation ready to be sent
|
||||
*/
|
||||
public void publishGeolocation(Map geolocation)
|
||||
{
|
||||
|
||||
GeolocationPresence myGeolocPrez = new GeolocationPresence(opsetprez);
|
||||
|
||||
GeolocationPacketExtension geolocExt = GeolocationJabberUtils
|
||||
.convertMapToExtension(geolocation);
|
||||
|
||||
myGeolocPrez.setGeolocationExtention(geolocExt);
|
||||
|
||||
this.jabberProvider.getConnection()
|
||||
.sendPacket(myGeolocPrez.getGeolocPresence());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the geolocation of the given contact.
|
||||
* <p>
|
||||
* Note: Currently not implemented because we can not actively poll the
|
||||
* server for the presence of a given contact ?
|
||||
* <p>
|
||||
* @param contactIdentifier the <tt>Contact</tt> we want to retrieve its
|
||||
* geolocation by its identifier.
|
||||
* @return the <tt>Geolocation</tt> of the contact.
|
||||
*/
|
||||
public Map queryContactGeolocation(String contactIdentifier)
|
||||
{
|
||||
/** @todo implement queryContactGeolocation() */
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener that would get notifications any time a contact
|
||||
* refreshed its geolocation via Presence.
|
||||
*
|
||||
* @param listener the <tt>ContactGeolocationPresenceListener</tt> to
|
||||
* register
|
||||
*/
|
||||
public void addGeolocationListener(GeolocationListener listener)
|
||||
{
|
||||
synchronized (geolocationContactsListeners)
|
||||
{
|
||||
geolocationContactsListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener that would get notifications any time a contact
|
||||
* refreshed its geolocation via Presence.
|
||||
*
|
||||
* @param listener the <tt>ContactGeolocationPresenceListener</tt> to
|
||||
* register
|
||||
*/
|
||||
public void removeGeolocationListener(GeolocationListener listener)
|
||||
{
|
||||
synchronized (geolocationContactsListeners)
|
||||
{
|
||||
geolocationContactsListeners.remove(listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Our listener that will tell us when we're registered to server
|
||||
* and we are ready to launch the listener for GeolocationPacketExtension
|
||||
* packets
|
||||
*/
|
||||
private class RegistrationStateListener
|
||||
implements RegistrationStateChangeListener
|
||||
{
|
||||
/**
|
||||
* The method is called by a ProtocolProvider implementation whenver
|
||||
* a change in the registration state of the corresponding provider had
|
||||
* occurred.
|
||||
* @param evt ProviderStatusChangeEvent the event describing the status
|
||||
* change.
|
||||
*/
|
||||
public void registrationStateChanged(RegistrationStateChangeEvent evt)
|
||||
{
|
||||
logger.debug("The Jabber provider changed state from: "
|
||||
+ evt.getOldState()
|
||||
+ " to: " + evt.getNewState());
|
||||
|
||||
if (evt.getNewState() == RegistrationState.REGISTERED)
|
||||
{
|
||||
|
||||
PacketExtensionFilter filterGeoloc =
|
||||
new PacketExtensionFilter(
|
||||
GeolocationPacketExtensionProvider.ELEMENT_NAME,
|
||||
GeolocationPacketExtensionProvider.NAMESPACE
|
||||
);
|
||||
|
||||
// launch the listener
|
||||
try
|
||||
{
|
||||
jabberProvider.getConnection().addPacketListener(
|
||||
new GeolocationPresencePacketListener()
|
||||
, filterGeoloc
|
||||
);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
else if (evt.getNewState() == RegistrationState.UNREGISTERED
|
||||
|| evt.getNewState()
|
||||
== RegistrationState.AUTHENTICATION_FAILED
|
||||
|| evt.getNewState()
|
||||
== RegistrationState.CONNECTION_FAILED)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class listen to GeolocationExtension into Presence Packet.
|
||||
* If GeolocationExtension is found, an event is sent.
|
||||
*
|
||||
* @author Guillaume Schreiner
|
||||
*/
|
||||
private class GeolocationPresencePacketListener
|
||||
implements PacketListener
|
||||
{
|
||||
/**
|
||||
* Match incoming packets with geolocation Extension tags for
|
||||
* dispatching a new event.
|
||||
*
|
||||
* @param packet matching Geolocation Extension tags.
|
||||
*/
|
||||
public void processPacket(Packet packet)
|
||||
{
|
||||
String from = StringUtils.parseBareAddress(packet.getFrom());
|
||||
|
||||
GeolocationPacketExtension geolocExt =
|
||||
(GeolocationPacketExtension) packet.getExtension(
|
||||
GeolocationPacketExtensionProvider.ELEMENT_NAME,
|
||||
GeolocationPacketExtensionProvider.NAMESPACE);
|
||||
|
||||
if (geolocExt != null)
|
||||
{
|
||||
logger.debug("GeolocationExtension found from " + from + ":" +
|
||||
geolocExt.toXML());
|
||||
|
||||
Map newGeolocation = GeolocationJabberUtils
|
||||
.convertExtensionToMap(geolocExt);
|
||||
|
||||
this.fireGeolocationContactChangeEvent(
|
||||
from,
|
||||
newGeolocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify registred listeners for a new incoming GeolocationExtension.
|
||||
*
|
||||
* @param sourceContact which send a new Geolocation.
|
||||
* @param newGeolocation the new given Geolocation.
|
||||
*/
|
||||
public void fireGeolocationContactChangeEvent(String sourceContact,
|
||||
Map newGeolocation)
|
||||
{
|
||||
|
||||
logger.debug("Trying to dispatch geolocation contact update for "
|
||||
+ sourceContact);
|
||||
|
||||
Contact source = opsetprez.findContactByID(sourceContact);
|
||||
|
||||
GeolocationEvent evt =
|
||||
new GeolocationEvent(
|
||||
source
|
||||
, jabberProvider
|
||||
, newGeolocation
|
||||
, OperationSetGeolocationJabberImpl.this);
|
||||
|
||||
logger.debug("Dispatching geolocation contact update. Listeners="
|
||||
+ geolocationContactsListeners.size()
|
||||
+ " evt=" + evt);
|
||||
|
||||
Iterator listeners = null;
|
||||
|
||||
synchronized (geolocationContactsListeners)
|
||||
{
|
||||
listeners = new ArrayList
|
||||
(geolocationContactsListeners).iterator();
|
||||
}
|
||||
|
||||
while (listeners.hasNext())
|
||||
{
|
||||
GeolocationListener listener =
|
||||
(GeolocationListener) listeners.next();
|
||||
|
||||
listener.contactGeolocationChanged(evt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in new issue