[sip-comm-dev] OperationSetGeolocation


#1

Hello all,

I just want to submit to the project a new OperationSet wich adds
support for geolocation. With this set, you could receive the location
from your buddies and also send your current location. I've written a
basic implementation for the jabber protocol which embedded
geolocation message in the presence status as specified in XEP-0080.
Following this standard, future implementations should rather use
PubSub or PEP for improving privacy.
Any comments would be strongly appreciated.

Guillaume

geolocation.patch (76.4 KB)


#2

Hello Guillaume,

First of all, I'd like you to know that I find this a really excellent idea! You've done some pretty good work! An excellent contribution! Thanks!

I have committed your code with the only exception being the registration of the operation set in the Jabber provider. I've been doing some modifications so that your code would better fit our conventions. I might have broken something in the process so I would like to ask you to review the code the way I've committed and let me know if all is still working as expected.

Here's the list of modifications:

* Removed an unnecessary import for gibberish in the protocol provider

* Most of the classes in the patch had tab indentation - converted to spaces.

* added javadocs for all fields defined in OperationSetGeolocation

* Replaced explicit imports in all classes with generic asterisk (*) imports (according to conventions).

* Renamed GeolocationContactChangeEvent to GeolocationEvent

* Renamed GeolocationEvent.getNewPosition() to getNewLocation()

* Changed the source for GeolocationEvent to the operation set

* Added a redundant getSourceGeolocationOperationSet() for retrieving the source operation set

* Added license header to GeolocationListener

* Renamed GeolocationListener.contactGeolocationPresenceChanged() to contactGeolocationChanged()

* Added class javadocs do GeolocationListener

* GeolocationExtension - added javadocs for all constructor params
* GeolocationExtension - added javadocs to all private methods (addXmlElement ..)

* Added javadoc comments to all setXxx() and getXxx() geolocation detail accessors in GeolocationExtension.

* Renamed GeolocationExtension to GeolocationPacketExtension to better reflect extended smack message.

* Added javadocs in GeolocationPacketExtensionProvider

* Changed log levels (debug -> trace) in GeolocationPacketExtensionProvider

* Added javadocs to all constructors in GeolocationMessage.

* Added a call to addExtension() in the third constructor of GeolocationMessage.

* Added javadocs for constructors in GeolocationPresence.

* Renamed addFloatMap() -> addFloatToMap()

* addStringMap() addStringToMap()

* are you sure you want to ignore null values in putXxx? Didn't change that I was just thinking that simply ignoring null values might be unwanted in some cases (as opposed to throwing an exception).

* Removed the methods that convert smack jabber states to SC states (and vice versa). Thought it would be a better idea to use those that already exist in the presence operation set.

* Renamed OperationSetGeolocationImpl to OperationSetGeolocationJabberImpl

* OperationSetGeolocationJabberImpl.fireGeolcationEvent -> moved comas in the beginning of each line (following convention)

* Removed publishContactGeolocation() from both service and impl as it seemed unnecessary to me.

As you can see , most of these are minor changes so don't be impressed by their number.

Let me know if any of the modifications break your code.

Great work once again!

Thanks
Emil

P.S. my battery is going down so i am sending the mail without a second read. please excuse any possible errors.

Guillaume Schreiner wrote:

···

Hello all,

I just want to submit to the project a new OperationSet wich adds
support for geolocation. With this set, you could receive the location
from your buddies and also send your current location. I've written a
basic implementation for the jabber protocol which embedded
geolocation message in the presence status as specified in XEP-0080.
Following this standard, future implementations should rather use
PubSub or PEP for improving privacy.
Any comments would be strongly appreciated.

Guillaume

------------------------------------------------------------------------

### Eclipse Workspace Patch 1.0
#P sip-communicator
Index: src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java

RCS file: /cvs/sip-communicator/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java,v
retrieving revision 1.30
diff -u -r1.30 ProtocolProviderServiceJabberImpl.java
--- src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java 12 Apr 2007 11:28:48 -0000 1.30
+++ src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java 13 Apr 2007 14:37:20 -0000
@@ -1,190 +1,189 @@
-/*
- * 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.net.*;
-import java.util.*;
-
-import org.jivesoftware.smack.*;
-import org.jivesoftware.smack.util.*;
-
-import net.java.sip.communicator.impl.protocol.gibberish.*;
-import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.service.protocol.event.*;
-import net.java.sip.communicator.service.protocol.jabberconstants.*;
-import net.java.sip.communicator.util.*;
-import java.text.*;
-
-/**
- * An implementation of the protocol provider service over the Jabber protocol
- *
- * @author Damian Minkov
- */
-public class ProtocolProviderServiceJabberImpl
- implements ProtocolProviderService
-{
- private static final Logger logger =
- Logger.getLogger(ProtocolProviderServiceJabberImpl.class);
-
- /**
- * The hashtable with the operation sets that we support locally.
- */
- private Hashtable supportedOperationSets = new Hashtable();
-
- private XMPPConnection connection = null;
-
- /**
- * Indicates whether or not the provider is initialized and ready for use.
- */
- private boolean isInitialized = false;
-
- /**
- * We use this to lock access to initialization.
- */
- private Object initializationLock = new Object();
-
- /**
- * A list of all listeners registered for
- * <tt>RegistrationStateChangeEvent</tt>s.
- */
- private List registrationListeners = new ArrayList();
-
- /**
- * The identifier of the account that this provider represents.
- */
- private AccountID accountID = null;
-
- /**
- * Used when we need to re-register
- */
- private SecurityAuthority authority = null;
-
- private boolean reconnecting = false;
-
- /**
- * The icon corresponding to the jabber protocol.
- */
- private ProtocolIconJabberImpl jabberIcon
- = new ProtocolIconJabberImpl();
-
- /**
- * Returns the state of the registration of this protocol provider
- * @return the <tt>RegistrationState</tt> that this provider is
- * currently in or null in case it is in a unknown state.
- */
- public RegistrationState getRegistrationState()
- {
- if(connection == null)
- return RegistrationState.UNREGISTERED;
- else if(connection.isConnected() && connection.isAuthenticated())
- return RegistrationState.REGISTERED;
- else
- return RegistrationState.UNREGISTERED;
- }
-
- /**
- * Starts the registration process. Connection details such as
- * registration server, user name/number are provided through the
- * configuration service through implementation specific properties.
- *
- * @param authority the security authority that will be used for resolving
- * any security challenges that may be returned during the
- * registration or at any moment while wer're registered.
- * @throws OperationFailedException with the corresponding code it the
- * registration fails for some reason (e.g. a networking error or an
- * implementation problem).
- */
- public void register(final SecurityAuthority authority)
- throws OperationFailedException
- {
- if(authority == null)
- throw new IllegalArgumentException(
- "The register method needs a valid non-null authority impl "
- + " in order to be able and retrieve passwords.");
-
- this.authority = authority;
-
- try
- {
- connectAndLogin(authority);
- }
- catch (XMPPException ex)
- {
- logger.error("Error registering", ex);
-
- int reason
- = RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
-
- RegistrationState regState = RegistrationState.UNREGISTERED;
-
- if(ex.getWrappedThrowable() instanceof UnknownHostException)
- {
- reason
- = RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND;
- regState = RegistrationState.CONNECTION_FAILED;
- }
- else
- if((connection.getSASLAuthentication() != null &&
- connection.getSASLAuthentication().isAuthenticated()) ||
- !connection.isAuthenticated())
- {
- JabberActivator.getProtocolProviderFactory().
- storePassword(getAccountID(), null);
- reason
- = RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED;
- regState = RegistrationState.AUTHENTICATION_FAILED;
- }
-
- fireRegistrationStateChanged(
- getRegistrationState(), regState, reason, null);
- }
- }
-
- /**
- * Connects and logins again to the server
- */
- void reregister()
- {
- try
- {
- logger.trace("Trying to reregister us!");
-
- // sets this if any is tring to use us through registration
- // to know we are not registered
- this.unregister(false);
-
- this.reconnecting = true;
-
- connectAndLogin(authority);
- }
- catch(OperationFailedException ex)
- {
- logger.error("Error ReRegistering", ex);
-
- fireRegistrationStateChanged(getRegistrationState(),
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_INTERNAL_ERROR, null);
- }
- catch (XMPPException ex)
- {
- logger.error("Error ReRegistering", ex);
-
- int reason =
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
-
- if(ex.getWrappedThrowable() instanceof UnknownHostException)
- reason =
- RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND;
-
- fireRegistrationStateChanged(getRegistrationState(),
- RegistrationState.CONNECTION_FAILED, reason, null);
- }
- }
-
+/*
+ * 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.net.*;
+import java.util.*;
+
+import org.jivesoftware.smack.*;
+import org.jivesoftware.smack.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.protocol.jabberconstants.*;
+import net.java.sip.communicator.util.*;
+import java.text.*;
+
+/**
+ * An implementation of the protocol provider service over the Jabber protocol
+ *
+ * @author Damian Minkov
+ */
+public class ProtocolProviderServiceJabberImpl
+ implements ProtocolProviderService
+{
+ private static final Logger logger =
+ Logger.getLogger(ProtocolProviderServiceJabberImpl.class);
+
+ /**
+ * The hashtable with the operation sets that we support locally.
+ */
+ private Hashtable supportedOperationSets = new Hashtable();
+
+ private XMPPConnection connection = null;
+
+ /**
+ * Indicates whether or not the provider is initialized and ready for use.
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * We use this to lock access to initialization.
+ */
+ private Object initializationLock = new Object();
+
+ /**
+ * A list of all listeners registered for
+ * <tt>RegistrationStateChangeEvent</tt>s.
+ */
+ private List registrationListeners = new ArrayList();
+
+ /**
+ * The identifier of the account that this provider represents.
+ */
+ private AccountID accountID = null;
+
+ /**
+ * Used when we need to re-register
+ */
+ private SecurityAuthority authority = null;
+
+ private boolean reconnecting = false;
+
+ /**
+ * The icon corresponding to the jabber protocol.
+ */
+ private ProtocolIconJabberImpl jabberIcon
+ = new ProtocolIconJabberImpl();
+
+ /**
+ * Returns the state of the registration of this protocol provider
+ * @return the <tt>RegistrationState</tt> that this provider is
+ * currently in or null in case it is in a unknown state.
+ */
+ public RegistrationState getRegistrationState()
+ {
+ if(connection == null)
+ return RegistrationState.UNREGISTERED;
+ else if(connection.isConnected() && connection.isAuthenticated())
+ return RegistrationState.REGISTERED;
+ else
+ return RegistrationState.UNREGISTERED;
+ }
+
+ /**
+ * Starts the registration process. Connection details such as
+ * registration server, user name/number are provided through the
+ * configuration service through implementation specific properties.
+ *
+ * @param authority the security authority that will be used for resolving
+ * any security challenges that may be returned during the
+ * registration or at any moment while wer're registered.
+ * @throws OperationFailedException with the corresponding code it the
+ * registration fails for some reason (e.g. a networking error or an
+ * implementation problem).
+ */
+ public void register(final SecurityAuthority authority)
+ throws OperationFailedException
+ {
+ if(authority == null)
+ throw new IllegalArgumentException(
+ "The register method needs a valid non-null authority impl "
+ + " in order to be able and retrieve passwords.");
+
+ this.authority = authority;
+
+ try
+ {
+ connectAndLogin(authority);
+ }
+ catch (XMPPException ex)
+ {
+ logger.error("Error registering", ex);
+
+ int reason
+ = RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
+
+ RegistrationState regState = RegistrationState.UNREGISTERED;
+
+ if(ex.getWrappedThrowable() instanceof UnknownHostException)
+ {
+ reason
+ = RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND;
+ regState = RegistrationState.CONNECTION_FAILED;
+ }
+ else
+ if((connection.getSASLAuthentication() != null &&
+ connection.getSASLAuthentication().isAuthenticated()) ||
+ !connection.isAuthenticated())
+ {
+ JabberActivator.getProtocolProviderFactory().
+ storePassword(getAccountID(), null);
+ reason
+ = RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED;
+ regState = RegistrationState.AUTHENTICATION_FAILED;
+ }
+
+ fireRegistrationStateChanged(
+ getRegistrationState(), regState, reason, null);
+ }
+ }
+
+ /**
+ * Connects and logins again to the server
+ */
+ void reregister()
+ {
+ try
+ {
+ logger.trace("Trying to reregister us!");
+
+ // sets this if any is tring to use us through registration
+ // to know we are not registered
+ this.unregister(false);
+
+ this.reconnecting = true;
+
+ connectAndLogin(authority);
+ }
+ catch(OperationFailedException ex)
+ {
+ logger.error("Error ReRegistering", ex);
+
+ fireRegistrationStateChanged(getRegistrationState(),
+ RegistrationState.CONNECTION_FAILED,
+ RegistrationStateChangeEvent.REASON_INTERNAL_ERROR, null);
+ }
+ catch (XMPPException ex)
+ {
+ logger.error("Error ReRegistering", ex);
+
+ int reason =
+ RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
+
+ if(ex.getWrappedThrowable() instanceof UnknownHostException)
+ reason =
+ RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND;
+
+ fireRegistrationStateChanged(getRegistrationState(),
+ RegistrationState.CONNECTION_FAILED, reason, null);
+ }
+ }
+
     /**
      * Connects and logins to the server
      * @param authority SecurityAuthority
@@ -344,278 +343,286 @@
                     OperationFailedException.INVALID_ACCOUNT_PROPERTIES, ex);
             }
         }
- }
-
- /**
- * Ends the registration of this protocol provider with the service.
- */
- public void unregister()
- {
- unregister(true);
- }
-
- /**
- * Unregister and fire the event if requested
- * @param fireEvent boolean
- */
- private void unregister(boolean fireEvent)
- {
- RegistrationState currRegState = getRegistrationState();
-
- if(connection != null)
- connection.disconnect();
-
- if(fireEvent)
- {
- fireRegistrationStateChanged(
- currRegState,
- RegistrationState.UNREGISTERED,
- RegistrationStateChangeEvent.REASON_USER_REQUEST, null);
- }
- }
-
- /**
- * Indicates whether or not this provider is signed on the service
- * @return true if the provider is currently signed on (and hence online)
- * and false otherwise.
- */
- public boolean isRegistered()
- {
- return getRegistrationState().equals(RegistrationState.REGISTERED);
- }
-
- /**
- * Returns the short name of the protocol that the implementation of this
- * provider is based upon (like SIP, Jabber, ICQ/AIM, or others for
- * example).
- *
- * @return a String containing the short name of the protocol this
- * service is taking care of.
- */
- public String getProtocolName()
- {
- return ProtocolNames.JABBER;
- }
-
- /**
- * Returns an array containing all operation sets supported by the
- * current implementation.
- *
- * @return an array of OperationSet-s supported by this protocol
- * provider implementation.
- */
- public Map getSupportedOperationSets()
- {
- return supportedOperationSets;
- }
-
- /**
- * Returns the operation set corresponding to the specified class or null
- * if this operation set is not supported by the provider implementation.
- *
- * @param opsetClass the <tt>Class</tt> of the operation set that we're
- * looking for.
- * @return returns an OperationSet of the specified <tt>Class</tt> if the
- * undelying implementation supports it or null otherwise.
- */
- public OperationSet getOperationSet(Class opsetClass)
- {
- return (OperationSet)getSupportedOperationSets()
- .get(opsetClass.getName());
- }
-
- /**
- * Initialized the service implementation, and puts it in a sate where it
- * could interoperate with other services. It is strongly recomended that
- * properties in this Map be mapped to property names as specified by
- * <tt>AccountProperties</tt>.
- *
- * @param screenname the account id/uin/screenname of the account that
- * we're about to create
- * @param accountID the identifier of the account that this protocol
- * provider represents.
- *
- * @see net.java.sip.communicator.service.protocol.AccountID
- */
- protected void initialize(String screenname,
- AccountID accountID)
- {
- synchronized(initializationLock)
- {
- this.accountID = accountID;
-
- String keepAliveStrValue = (String)accountID.getAccountProperties().
- get("SEND_KEEP_ALIVE");
-
- //initialize the presence operationset
- OperationSetPersistentPresence persistentPresence =
- new OperationSetPersistentPresenceJabberImpl(this);
-
- supportedOperationSets.put(
- OperationSetPersistentPresence.class.getName(),
- persistentPresence);
-
- //register it once again for those that simply need presence
- supportedOperationSets.put( OperationSetPresence.class.getName(),
- persistentPresence);
-
- //initialize the IM operation set
- OperationSetBasicInstantMessagingJabberImpl basicInstantMessaging =
- new OperationSetBasicInstantMessagingJabberImpl(this);
-
- if(keepAliveStrValue != null)
- basicInstantMessaging.
- setKeepAliveEnabled(
- new Boolean(keepAliveStrValue).booleanValue());
-
- supportedOperationSets.put(
- OperationSetBasicInstantMessaging.class.getName(),
- basicInstantMessaging);
-
- //initialize the typing notifications operation set
- OperationSetTypingNotifications typingNotifications =
- new OperationSetTypingNotificationsJabberImpl(this);
-
- supportedOperationSets.put(
- OperationSetTypingNotifications.class.getName(),
- typingNotifications);
-
- //initialize the multi user chat operation set
- OperationSetMultiUserChat multiUserChat =
- new OperationSetMultiUserChatJabberImpl(this);
-
- supportedOperationSets.put(
- OperationSetMultiUserChat.class.getName(),
- multiUserChat);
-
- isInitialized = true;
- }
- }
-
- /**
- * Makes the service implementation close all open sockets and release
- * any resources that it might have taken and prepare for
- * shutdown/garbage collection.
- */
- public void shutdown()
- {
- synchronized(initializationLock){
- connection.disconnect();
- connection = null;
- isInitialized = false;
- }
- }
-
- /**
- * Returns true if the provider service implementation is initialized and
- * ready for use by other services, and false otherwise.
- *
- * @return true if the provider is initialized and ready for use and false
- * otherwise
- */
- public boolean isInitialized()
- {
- return isInitialized;
- }
-
- /**
- * Removes the specified registration state change listener so that it does
- * not receive any further notifications upon changes of the
- * RegistrationState of this provider.
- *
- * @param listener the listener to register for
- * <tt>RegistrationStateChangeEvent</tt>s.
- */
- public void removeRegistrationStateChangeListener(
- RegistrationStateChangeListener listener)
- {
- synchronized(registrationListeners)
- {
- registrationListeners.remove(listener);
- }
- }
-
- /**
- * Registers the specified listener with this provider so that it would
- * receive notifications on changes of its state or other properties such
- * as its local address and display name.
- *
- * @param listener the listener to register.
- */
- public void addRegistrationStateChangeListener(
- RegistrationStateChangeListener listener)
- {
- synchronized(registrationListeners)
- {
- if (!registrationListeners.contains(listener))
- registrationListeners.add(listener);
- }
- }
-
- /**
- * Returns the AccountID that uniquely identifies the account represented
- * by this instance of the ProtocolProviderService.
- * @return the id of the account represented by this provider.
- */
- public AccountID getAccountID()
- {
- return accountID;
- }
-
- /**
- * Returns the <tt>XMPPConnection</tt>opened by this provider
- * @return a reference to the <tt>XMPPConnection</tt> last opened by this
- * provider.
- */
- protected XMPPConnection getConnection()
- {
- return connection;
- }
-
- /**
- * Creates a RegistrationStateChange event corresponding to the specified
- * old and new states and notifies all currently registered listeners.
- *
- * @param oldState the state that the provider had before the change
- * occurred
- * @param newState the state that the provider is currently in.
- * @param reasonCode a value corresponding to one of the REASON_XXX fields
- * of the RegistrationStateChangeEvent class, indicating the reason for
- * this state transition.
- * @param reason a String further explaining the reason code or null if
- * no such explanation is necessary.
- */
- void fireRegistrationStateChanged( RegistrationState oldState,
- RegistrationState newState,
- int reasonCode,
- String reason)
- {
- RegistrationStateChangeEvent event =
- new RegistrationStateChangeEvent(
- this, oldState, newState, reasonCode, reason);
-
- logger.debug("Dispatching " + event + " to "
- + registrationListeners.size()+ " listeners.");
-
- Iterator listeners = null;
- synchronized (registrationListeners)
- {
- listeners = new ArrayList(registrationListeners).iterator();
- }
-
- while (listeners.hasNext())
- {
- RegistrationStateChangeListener listener
- = (RegistrationStateChangeListener) listeners.next();
-
- listener.registrationStateChanged(event);
- }
-
- logger.trace("Done.");
- }
-
- private class JabberConnectionListener
+ }
+
+ /**
+ * Ends the registration of this protocol provider with the service.
+ */
+ public void unregister()
+ {
+ unregister(true);
+ }
+
+ /**
+ * Unregister and fire the event if requested
+ * @param fireEvent boolean
+ */
+ private void unregister(boolean fireEvent)
+ {
+ RegistrationState currRegState = getRegistrationState();
+
+ if(connection != null)
+ connection.disconnect();
+
+ if(fireEvent)
+ {
+ fireRegistrationStateChanged(
+ currRegState,
+ RegistrationState.UNREGISTERED,
+ RegistrationStateChangeEvent.REASON_USER_REQUEST, null);
+ }
+ }
+
+ /**
+ * Indicates whether or not this provider is signed on the service
+ * @return true if the provider is currently signed on (and hence online)
+ * and false otherwise.
+ */
+ public boolean isRegistered()
+ {
+ return getRegistrationState().equals(RegistrationState.REGISTERED);
+ }
+
+ /**
+ * Returns the short name of the protocol that the implementation of this
+ * provider is based upon (like SIP, Jabber, ICQ/AIM, or others for
+ * example).
+ *
+ * @return a String containing the short name of the protocol this
+ * service is taking care of.
+ */
+ public String getProtocolName()
+ {
+ return ProtocolNames.JABBER;
+ }
+
+ /**
+ * Returns an array containing all operation sets supported by the
+ * current implementation.
+ *
+ * @return an array of OperationSet-s supported by this protocol
+ * provider implementation.
+ */
+ public Map getSupportedOperationSets()
+ {
+ return supportedOperationSets;
+ }
+
+ /**
+ * Returns the operation set corresponding to the specified class or null
+ * if this operation set is not supported by the provider implementation.
+ *
+ * @param opsetClass the <tt>Class</tt> of the operation set that we're
+ * looking for.
+ * @return returns an OperationSet of the specified <tt>Class</tt> if the
+ * undelying implementation supports it or null otherwise.
+ */
+ public OperationSet getOperationSet(Class opsetClass)
+ {
+ return (OperationSet)getSupportedOperationSets()
+ .get(opsetClass.getName());
+ }
+
+ /**
+ * Initialized the service implementation, and puts it in a sate where it
+ * could interoperate with other services. It is strongly recomended that
+ * properties in this Map be mapped to property names as specified by
+ * <tt>AccountProperties</tt>.
+ *
+ * @param screenname the account id/uin/screenname of the account that
+ * we're about to create
+ * @param accountID the identifier of the account that this protocol
+ * provider represents.
+ *
+ * @see net.java.sip.communicator.service.protocol.AccountID
+ */
+ protected void initialize(String screenname,
+ AccountID accountID)
+ {
+ synchronized(initializationLock)
+ {
+ this.accountID = accountID;
+
+ String keepAliveStrValue = (String)accountID.getAccountProperties().
+ get("SEND_KEEP_ALIVE");
+
+ //initialize the presence operationset
+ OperationSetPersistentPresence persistentPresence =
+ new OperationSetPersistentPresenceJabberImpl(this);
+
+ supportedOperationSets.put(
+ OperationSetPersistentPresence.class.getName(),
+ persistentPresence);
+
+ //register it once again for those that simply need presence
+ supportedOperationSets.put( OperationSetPresence.class.getName(),
+ persistentPresence);
+
+ //initialize the IM operation set
+ OperationSetBasicInstantMessagingJabberImpl basicInstantMessaging =
+ new OperationSetBasicInstantMessagingJabberImpl(this);
+
+ if(keepAliveStrValue != null)
+ basicInstantMessaging.
+ setKeepAliveEnabled(
+ new Boolean(keepAliveStrValue).booleanValue());
+
+ supportedOperationSets.put(
+ OperationSetBasicInstantMessaging.class.getName(),
+ basicInstantMessaging);
+
+ //initialize the typing notifications operation set
+ OperationSetTypingNotifications typingNotifications =
+ new OperationSetTypingNotificationsJabberImpl(this);
+
+ supportedOperationSets.put(
+ OperationSetTypingNotifications.class.getName(),
+ typingNotifications);
+
+ + //initialize the multi user chat operation set
+ OperationSetMultiUserChat multiUserChat =
+ new OperationSetMultiUserChatJabberImpl(this);
+
+ supportedOperationSets.put(
+ OperationSetMultiUserChat.class.getName(),
+ multiUserChat);
+
+ //initialize the geolocation operation set
+ OperationSetGeolocation geolocation =
+ new OperationSetGeolocationImpl(this);
+
+ supportedOperationSets.put(
+ OperationSetGeolocation.class.getName(),
+ geolocation);
+
+ isInitialized = true;
+ }
+ }
+
+ /**
+ * Makes the service implementation close all open sockets and release
+ * any resources that it might have taken and prepare for
+ * shutdown/garbage collection.
+ */
+ public void shutdown()
+ {
+ synchronized(initializationLock){
+ connection.disconnect();
+ connection = null;
+ isInitialized = false;
+ }
+ }
+
+ /**
+ * Returns true if the provider service implementation is initialized and
+ * ready for use by other services, and false otherwise.
+ *
+ * @return true if the provider is initialized and ready for use and false
+ * otherwise
+ */
+ public boolean isInitialized()
+ {
+ return isInitialized;
+ }
+
+ /**
+ * Removes the specified registration state change listener so that it does
+ * not receive any further notifications upon changes of the
+ * RegistrationState of this provider.
+ *
+ * @param listener the listener to register for
+ * <tt>RegistrationStateChangeEvent</tt>s.
+ */
+ public void removeRegistrationStateChangeListener(
+ RegistrationStateChangeListener listener)
+ {
+ synchronized(registrationListeners)
+ {
+ registrationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Registers the specified listener with this provider so that it would
+ * receive notifications on changes of its state or other properties such
+ * as its local address and display name.
+ *
+ * @param listener the listener to register.
+ */
+ public void addRegistrationStateChangeListener(
+ RegistrationStateChangeListener listener)
+ {
+ synchronized(registrationListeners)
+ {
+ if (!registrationListeners.contains(listener))
+ registrationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Returns the AccountID that uniquely identifies the account represented
+ * by this instance of the ProtocolProviderService.
+ * @return the id of the account represented by this provider.
+ */
+ public AccountID getAccountID()
+ {
+ return accountID;
+ }
+
+ /**
+ * Returns the <tt>XMPPConnection</tt>opened by this provider
+ * @return a reference to the <tt>XMPPConnection</tt> last opened by this
+ * provider.
+ */
+ public XMPPConnection getConnection()
+ {
+ return connection;
+ }
+
+ /**
+ * Creates a RegistrationStateChange event corresponding to the specified
+ * old and new states and notifies all currently registered listeners.
+ *
+ * @param oldState the state that the provider had before the change
+ * occurred
+ * @param newState the state that the provider is currently in.
+ * @param reasonCode a value corresponding to one of the REASON_XXX fields
+ * of the RegistrationStateChangeEvent class, indicating the reason for
+ * this state transition.
+ * @param reason a String further explaining the reason code or null if
+ * no such explanation is necessary.
+ */
+ void fireRegistrationStateChanged( RegistrationState oldState,
+ RegistrationState newState,
+ int reasonCode,
+ String reason)
+ {
+ RegistrationStateChangeEvent event =
+ new RegistrationStateChangeEvent(
+ this, oldState, newState, reasonCode, reason);
+
+ logger.debug("Dispatching " + event + " to "
+ + registrationListeners.size()+ " listeners.");
+
+ Iterator listeners = null;
+ synchronized (registrationListeners)
+ {
+ listeners = new ArrayList(registrationListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ RegistrationStateChangeListener listener
+ = (RegistrationStateChangeListener) listeners.next();
+
+ listener.registrationStateChanged(event);
+ }
+
+ logger.trace("Done.");
+ }
+
+ private class JabberConnectionListener
         implements ConnectionListener
     {
         public void connectionClosed()
@@ -655,14 +662,14 @@
         {
             logger.info("reconnectionFailed ", exception);
         }
- }
-
- /**
- * Returns the jabber protocol icon.
- * @return the jabber protocol icon
- */
- public ProtocolIcon getProtocolIcon()
- {
- return jabberIcon;
- }
-}
+ }
+
+ /**
+ * Returns the jabber protocol icon.
+ * @return the jabber protocol icon
+ */
+ public ProtocolIcon getProtocolIcon()
+ {
+ return jabberIcon;
+ }
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationPresence.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationPresence.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationPresence.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationPresence.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,52 @@
+/*
+ * 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.extensions.geolocation;
+
+import net.java.sip.communicator.service.protocol.OperationSetPresence;
+import net.java.sip.communicator.service.protocol.jabberconstants.JabberStatusEnum;
+
+import org.jivesoftware.smack.packet.Presence;
+
+/**
+ * This class construct a Jabber presence message with Geolocation Extension
+ * + * @author Guillaume Schreiner
+ */
+public class GeolocationPresence +{
+
+ /**
+ * the presence message to send via a XMPPConnection
+ */
+ private Presence prez = null;
+
+ public GeolocationPresence(OperationSetPresence persistentPresence) + {
+ this.prez = new Presence(Presence.Type.available);
+
+ // set the custom status message
+ this.prez.setStatus(persistentPresence
+ .getCurrentStatusMessage());
+
+ // set the presence mode (available, NA, free for chat)
+ this.prez.setMode( + GeolocationJabberUtils.presenceStatusToJabberMode( + (JabberStatusEnum) persistentPresence
+ .getPresenceStatus()));
+ }
+
+ public void setGeolocationExtention(GeolocationExtension ext) + {
+ this.prez.addExtension(ext);
+ }
+
+ public Presence getGeolocPresence() + {
+ return this.prez;
+ }
+
+}
Index: src/net/java/sip/communicator/service/protocol/event/GeolocationContactChangeEvent.java

RCS file: src/net/java/sip/communicator/service/protocol/event/GeolocationContactChangeEvent.java
diff -N src/net/java/sip/communicator/service/protocol/event/GeolocationContactChangeEvent.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/service/protocol/event/GeolocationContactChangeEvent.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,93 @@
+/*
+ * 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.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Instances of this class represent a change in the geolocation of the contact
+ * from the given provider that triggerred them.
+ * + * @author Guillaume Schreiner
+ */
+public class GeolocationContactChangeEvent extends EventObject {
+
+ /**
+ * The provider which generate this event
+ */
+ private ProtocolProviderService sourceProvider = null;
+
+ /**
+ * The contact which generate this event
+ */
+ private Contact sourceContact = null;
+
+
+ /**
+ * Creates an event instance indicating that the specified source contact
+ * has changed Geolocation from <tt>oldValue</tt> to <tt>newValue</tt>.
+ * @param sourceContact the contact associated with this event.
+ * @param sourceProvider the protocol provider that the contact belongs to.
+ * @param newLocation the geolocation where the sourceCountact currently is.
+ */
+ public GeolocationContactChangeEvent(
+ Contact sourceContact,
+ ProtocolProviderService sourceProvider,
+ Map newLocation)
+ {
+ super(newLocation);
+ this.sourceContact = sourceContact;
+ this.sourceProvider = sourceProvider;
+ }
+
+ /**
+ * Returns the provider that the source contact belongs to.
+ * @return the provider that the source contact belongs to.
+ */
+ public ProtocolProviderService getSourceProvider()
+ {
+ return sourceProvider;
+ }
+
+ /**
+ * Returns the source contact associated with the event.
+ * @return the source contact associated with the event.
+ */
+ public Contact getSourceContact()
+ {
+ return this.sourceContact;
+ }
+
+ /**
+ * Returns the Geolocation of the contact after this event took place.
+ * (i.e. at the time the event is being dispatched).
+ * @return geolocation stored into a Map indicating the current location
+ * of the source Contact at the moment the event was dispatched.
+ */
+ public Map getNewPosition()
+ {
+ return (Map) super.getSource();
+ }
+
+ /**
+ * Returns a String representation of this GeolocationContactChangeEvent
+ *
+ * @return A a String representation of this
+ * ContactPresenceStatusChangeEvent.
+ */
+ public String toString()
+ {
+ StringBuffer buff = new StringBuffer
+ ("ContactGeolocationPresenceChangeEvent-[ ContactID=");
+ buff.append(getSourceContact().getAddress());
+ return buff.append(", NewPosition=").append(getNewPosition())
+ .append("]").toString();
+ }
+
+}
Index: src/net/java/sip/communicator/service/protocol/event/GeolocationContactListener.java

RCS file: src/net/java/sip/communicator/service/protocol/event/GeolocationContactListener.java
diff -N src/net/java/sip/communicator/service/protocol/event/GeolocationContactListener.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/service/protocol/event/GeolocationContactListener.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,18 @@
+package net.java.sip.communicator.service.protocol.event;
+
+import java.util.EventListener;
+
+public interface GeolocationContactListener extends EventListener {
+
+
+ /**
+ * Called whenever a change occurs in the GeolocationPresence of one of the
+ * contacts that we have subscribed for.
+ * @param evt the ContactGeolocationPresenceChangeEvent describing the + * status change.
+ */
+ public void contactGeolocationPresenceChanged(
+ GeolocationContactChangeEvent evt);
+
+
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationMessage.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationMessage.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationMessage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationMessage.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,37 @@
+/*
+ * 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.extensions.geolocation;
+
+import org.jivesoftware.smack.packet.Message;
+
+/**
+ * This class construct a Jabber message with Geolocation Extension
+ * + * @author Guillaume Schreiner
+ */
+public class GeolocationMessage extends Message +{
+
+ public GeolocationMessage(GeolocationExtension geoloc) + {
+ super();
+ this.addExtension(geoloc);
+ }
+
+ public GeolocationMessage(String to, GeolocationExtension geoloc) + {
+ super(to);
+ this.addExtension(geoloc);
+ }
+
+ public GeolocationMessage(String to, Message.Type type, + GeolocationExtension geoloc) + {
+ super(to, type);
+ }
+
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtension.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtension.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtension.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtension.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,431 @@
+/*
+ * 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.extensions.geolocation;
+
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * This class implements the Geolocation Extension defined into the XEP-0080
+ * + * @author Guillaume Schreiner
+ */
+public class GeolocationExtension implements PacketExtension +{
+
+ /**
+ * BEGIN
+ * Jabber static XML parameters for geolocation message
+ */
+ public final static String ALT = "alt";
+ public final static String AREA = "area";
+ public final static String BEARING = "bearing";
+ public final static String BUILDING = "building";
+ public final static String COUNTRY = "country";
+ public final static String DATUM = "datum";
+ public final static String DESCRIPTION = "description";
+ public final static String ERROR = "error";
+ public final static String FLOOR = "floor";
+ public final static String LAT = "lat";
+ public final static String LOCALITY = "locality";
+ public final static String LON = "lon";
+ public final static String POSTALCODE = "postalcode";
+ public final static String REGION = "region";
+ public final static String ROOM = "room";
+ public final static String STREET = "street";
+ public final static String TEXT = "text";
+ public final static String TIMESTAMP = "timestamp";
+
+ /**
+ * END
+ * Jabber static XML parameters for geolocation message
+ */
+
+ /**
+ * Altitude in meters above or below sea level
+ * example: 1609
+ */
+ private float alt = -1;
+
+ /**
+ * A named area such as a campus or neighborhood
+ * example: Central Park
+ */
+ private String area = null;
+
+ /**
+ * GPS bearing (direction in which the entity is heading to reach its + * next waypoint), measured in decimal degrees relative to true north
+ */
+ private float bearing = -1 ;
+
+ /**
+ * A specific building on a street or in an area
+ * example: The Empire State Building
+ */
+ private String building = null;
+
+ /**
+ * The nation where the user is located
+ * example: USA
+ */
+ private String country = null;
+
+ /**
+ * GPS datum
+ */
+ private String datum = null;
+
+ /**
+ * A natural-language name for or description of the location
+ * example: Bill's house
+ */
+ private String description = null;
+
+ /**
+ * Horizontal GPS error in arc minutes
+ * example: 10
+ */
+ private float error = -1;
+
+ /**
+ * A particular floor in a building
+ * example: 102
+ */
+ private String floor = null;
+
+ /**
+ * Latitude in decimal degrees North
+ * example: 39.75
+ */
+ private float lat = -1;
+
+ /**
+ * A locality within the administrative region, such as a town or city
+ * example: New York City
+ */
+ private String locality = null;
+
+ /**
+ * Longitude in decimal degrees East
+ * example: -104.99
+ */
+ private float lon = -1;
+
+ /**
+ * A code used for postal delivery
+ * example: 10027
+ */
+ private String postalcode = null;
+
+ /**
+ * An administrative region of the nation, such as a state or province
+ * example: New York
+ */
+ private String region = null;
+
+ /**
+ * A particular room in a building
+ * example: Observatory
+ */
+ private String room = null;
+
+ /**
+ * A thoroughfare within the locality, or a crossing of two thoroughfares
+ * example: 34th and Broadway
+ */
+ private String street = null;
+
+ /**
+ * A catch-all element that captures any other information about the location
+ * example: Northwest corner of the lobby
+ */
+ private String text = null;
+
+ /**
+ * UTC timestamp specifying the moment when the reading was taken + * example: 2004-02-19T21:12Z
+ */
+ private String timestamp = null;
+
+ /**
+ * Returns the XML reppresentation of the PacketExtension.
+ *
+ * @return the packet extension as XML.
+ * @todo Implement this org.jivesoftware.smack.packet.PacketExtension
+ * method
+ */
+ public String toXML()
+ {
+ StringBuffer buf = new StringBuffer();
+ + // open extension
+ buf.append("<").append(getElementName()).
+ append(" xmlns=\"").append(getNamespace()).append("\">");
+
+ // adding geolocation extension parameters
+ + buf = addFloatXmlElement(buf, ALT, this.getAlt());
+ buf = addXmlElement(buf, AREA, this.getArea());
+ buf = addFloatXmlElement(buf, BEARING, this.getBearing());
+ buf = addXmlElement(buf, BUILDING, this.getBuilding());
+ buf = addXmlElement(buf, COUNTRY, this.getCountry());
+ buf = addXmlElement(buf, DATUM, this.getDatum());
+ buf = addXmlElement(buf, DESCRIPTION, this.getDescription());
+ buf = addFloatXmlElement(buf, ERROR, this.getError());
+ buf = addXmlElement(buf, FLOOR, this.getFloor());
+ buf = addFloatXmlElement(buf, LAT, this.getLat());
+ buf = addXmlElement(buf, LOCALITY, this.getLocality());
+ buf = addFloatXmlElement(buf, LON, this.getLon());
+ buf = addXmlElement(buf, POSTALCODE, this.getPostalcode());
+ buf = addXmlElement(buf, REGION, this.getRegion());
+ buf = addXmlElement(buf, ROOM, this.getRoom());
+ buf = addXmlElement(buf, STREET, this.getStreet());
+ buf = addXmlElement(buf, TEXT, this.getText());
+ buf = addXmlElement(buf, TIMESTAMP, this.getTimestamp());
+ + // close extension
+ buf.append("</").append(getElementName()).append(">");
+ + return buf.toString();
+ }
+ + private StringBuffer addXmlElement(StringBuffer buf, String element, + String value ) + {
+ if( value != null ) {
+ buf.append("<").
+ append(element).append(">").
+ append(value).append("</").
+ append(element).append(">");
+ }
+
+ return buf;
+ }
+ + private StringBuffer addFloatXmlElement(StringBuffer buf, String element, + float value ) + {
+ + if( value != -1) {
+ buf.append("<").
+ append(element).append(">").
+ append(value).append("</").
+ append(element).append(">");
+ }
+
+ return buf;
+ }
+ + + /**
+ * Returns the XML element name of the extension sub-packet root element.
+ * Always returns "geoloc"
+ *
+ * @return the XML element name of the packet extension.
+ */
+ public String getElementName()
+ {
+ return GeolocationExtensionProvider.ELEMENT_NAME;
+ }
+
+ /**
+ * Returns the XML namespace of the extension sub-packet root element.
+ * The namespace is always "http://jabber.org/protocol/geoloc"
+ *
+ * @return the XML namespace of the packet extension.
+ */
+ public String getNamespace()
+ {
+ return GeolocationExtensionProvider.NAMESPACE;
+ }
+
+ /**
+ * Getters and Setters
+ */
+
+ public float getAlt() {
+ return alt;
+ }
+
+ public void setAlt(float alt) {
+ this.alt = alt;
+ }
+
+ public void setAlt(String alt) {
+ this.alt = (new Float(alt)).floatValue();
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public float getBearing() {
+ return bearing;
+ }
+
+ public void setBearing(float bearing) {
+ this.bearing = bearing;
+ }
+
+ public void setBearing(String bearing) {
+ this.bearing = (new Float(bearing)).floatValue();
+ }
+
+ public String getBuilding() {
+ return building;
+ }
+
+ public void setBuilding(String building) {
+ this.building = building;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getDatum() {
+ return datum;
+ }
+
+ public void setDatum(String datum) { + this.datum = datum;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public float getError() {
+ return error;
+ }
+
+ public void setError(float error) {
+ this.error = error;
+ }
+
+ public void setError(String error) {
+ this.error = (new Float(error)).floatValue();
+ }
+
+ public String getFloor() {
+ return floor;
+ }
+
+ public void setFloor(String floor) {
+ this.floor = floor;
+ }
+
+ public float getLat() {
+ return lat;
+ }
+
+ public void setLat(float lat) {
+ this.lat = lat;
+ }
+
+ public void setLat(String lat) {
+ this.lat = (new Float(lat)).floatValue();
+ }
+
+ public String getLocality() {
+ return locality;
+ }
+
+ public void setLocality(String locality) {
+ this.locality = locality;
+ }
+
+ public float getLon() {
+ return lon;
+ }
+
+ public void setLon(float lon) {
+ this.lon = lon;
+ }
+
+ public void setLon(String lon) {
+ this.lon = (new Float(lon)).floatValue();
+ }
+
+ public String getPostalcode() {
+ return postalcode;
+ }
+
+ public void setPostalcode(String postalcode) {
+ this.postalcode = postalcode;
+ }
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public String getRoom() {
+ return room;
+ }
+
+ public void setRoom(String room) {
+ this.room = room;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * Set timestamp in UTC format as described in
+ * XEP-0082: XMPP Date and Time Profiles
+ * @param timestamp in UTC format
+ */
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Test if latitude and longitude are set
+ * @return
+ */
+ public boolean containLatLon() {
+
+ if (this.lat != -1 && this.lon != -1 ) + return true;
+ else
+ return false;
+ }
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationImpl.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationImpl.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationImpl.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationImpl.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,286 @@
+/*
+ * 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 OperationSetGeolocationImpl + implements OperationSetGeolocation +{
+
+ private static final Logger logger =
+ Logger.getLogger(OperationSetGeolocationImpl.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 OperationSetGeolocationImpl(
+ 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(
+ GeolocationExtensionProvider.ELEMENT_NAME,
+ GeolocationExtensionProvider.NAMESPACE,
+ new GeolocationExtensionProvider()
+ );
+
+ }
+ + /**
+ * Broadcast our current Geolocation trough this provider via Presence + * Jabber Message
+ * + * @param geolocation our current Geolocation ready to be sent
+ */
+ public void publishProviderGeolocation(Map geolocation) + {
+
+ GeolocationPresence myGeolocPrez = new GeolocationPresence(opsetprez);
+
+ GeolocationExtension geolocExt = GeolocationJabberUtils
+ .convertMapToExtension(geolocation);
+
+ myGeolocPrez.setGeolocationExtention(geolocExt);
+
+ this.jabberProvider.getConnection()
+ .sendPacket(myGeolocPrez.getGeolocPresence());
+
+ }
+ + /**
+ * Retrieve the geolocation of the given contact.
+ * + * Note: Currently not implemented because we can not actively poll the + * server for the presence of a given contact ?
+ * + * @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 contactIdentifiert) + {
+ return null;
+ }
+ + /**
+ * Currently not implemented because we are based on presence message.
+ */
+ public void publishContactGeolocation(
+ String contactIdentifier,
+ Map geolocation) + {}
+
+ /**
+ * 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 addGeolocationContactListener
+ (GeolocationContactListener 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 removeGeolocationContactListener
+ (GeolocationContactListener 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 GeolocationExtension
+ */
+ 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(
+ GeolocationExtensionProvider.ELEMENT_NAME,
+ GeolocationExtensionProvider.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());
+
+ GeolocationExtension geolocExt = + (GeolocationExtension) packet.getExtension(
+ GeolocationExtensionProvider.ELEMENT_NAME, + GeolocationExtensionProvider.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);
+
+ GeolocationContactChangeEvent evt = + new GeolocationContactChangeEvent (
+ source,
+ jabberProvider,
+ newGeolocation);
+
+ logger.debug("Dispatching geolocation contact update. Listeners="
+ + geolocationContactsListeners.size()
+ + " evt=" + evt);
+
+ Iterator listeners = null;
+ + synchronized (geolocationContactsListeners)
+ {
+ listeners = new ArrayList
+ (geolocationContactsListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ GeolocationContactListener listener =
+ (GeolocationContactListener) listeners.next();
+
+ listener.contactGeolocationPresenceChanged(evt);
+ }
+ + }
+
+ }
+ +}
Index: src/net/java/sip/communicator/service/protocol/OperationSetGeolocation.java

RCS file: src/net/java/sip/communicator/service/protocol/OperationSetGeolocation.java
diff -N src/net/java/sip/communicator/service/protocol/OperationSetGeolocation.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/service/protocol/OperationSetGeolocation.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,88 @@
+/*
+ * 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.*;
+
+/**
+ * This interface is an extension of the operation set, meant to be
+ * implemented by protocols that support geolocation message (like Jabber
+ * for example).
+ * + * @author Guillaume Schreiner
+ */
+public interface OperationSetGeolocation extends OperationSet +{
+
+ /**
+ * Static parameters description for String output
+ */
+
+ public final static String ALT = "alt";
+ public final static String AREA = "area";
+ public final static String BEARING = "bearing";
+ public final static String BUILDING = "building";
+ public final static String COUNTRY = "country";
+ public final static String DATUM = "datum";
+ public final static String DESCRIPTION = "description";
+ public final static String ERROR = "error";
+ public final static String FLOOR = "floor";
+ public final static String LAT = "lat";
+ public final static String LOCALITY = "locality";
+ public final static String LON = "lon";
+ public final static String POSTALCODE = "postalcode";
+ public final static String REGION = "region";
+ public final static String ROOM = "room";
+ public final static String STREET = "street";
+ public final static String TEXT = "text";
+ public final static String TIMESTAMP = "timestamp";
+
+ /**
+ * Publish the location for the associated provider
+ * @param <tt>Map</tt> geolocation
+ */
+ public void publishProviderGeolocation(Map geolocation);
+
+ /**
+ * Retrieve the geolocation of the given contact.
+ * @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);
+
+ /**
+ * Publish the geolocation for the given contact.
+ * @param contact the <tt>Contact</tt> receiving Geolocation update
+ * @param geolocation the Geolocation associated with the contact + */
+ public void publishContactGeolocation(String contactIdentifier,
+ Map geolocation);
+
+ /**
+ * 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 addGeolocationContactListener(GeolocationContactListener + 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 removeGeolocationContactListener(GeolocationContactListener + listener);
+
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtensionProvider.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtensionProvider.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtensionProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationExtensionProvider.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,155 @@
+/*
+ * 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.extensions.geolocation;
+
+import net.java.sip.communicator.util.Logger;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * This class parses incoming messages and extract the geolocation parameters
+ * from the raw XML messages. + * + * @author Guillaume Schreiner
+ */
+public class GeolocationExtensionProvider + implements PacketExtensionProvider {
+
+ private static final Logger logger =
+ Logger.getLogger(GeolocationExtensionProvider.class);
+
+ public static final String ELEMENT_NAME = "geoloc";
+ public static final String NAMESPACE = "http://jabber.org/protocol/geoloc";
+
+ /**
+ * Creates a new GeolocationExtensionProvider.
+ * ProviderManager requires that every PacketExtensionProvider has a public,
+ * no-argument constructor
+ */
+ public GeolocationExtensionProvider() {}
+
+
+ /**
+ * Parses a GeolocationExtension packet (extension sub-packet).
+ *
+ * @param parser an XML parser.
+ * @return a new GeolocationExtension instance.
+ * @throws Exception if an error occurs parsing the XML.
+ * @todo Implement this
+ * org.jivesoftware.smack.provider.PacketExtensionProvider method
+ */
+ public PacketExtension parseExtension(XmlPullParser parser)
+ throws Exception {
+
+ GeolocationExtension result = new GeolocationExtension();
+
+
+ logger.debug("Trying to map XML Geolocation Extension");
+
+ boolean done = false;
+ while (!done)
+ {
+ try
+ {
+ int eventType = parser.next();
+ if(eventType == XmlPullParser.START_TAG)
+ {
+ if(parser.getName().equals(GeolocationExtension.ALT))
+ {
+ result.setAlt(Float.parseFloat(parser.nextText()));
+ }
+ if(parser.getName().equals(GeolocationExtension.AREA))
+ {
+ result.setArea(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.BEARING))
+ {
+ result.setBearing(Float.parseFloat(parser.nextText()));
+ }
+ if(parser.getName().equals(GeolocationExtension.BUILDING))
+ {
+ result.setBuilding(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.COUNTRY))
+ {
+ result.setCountry(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.DATUM))
+ {
+ result.setDatum(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.DESCRIPTION))
+ {
+ result.setDescription(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.ERROR))
+ {
+ result.setError(Float.parseFloat(parser.nextText()));
+ }
+ if(parser.getName().equals(GeolocationExtension.FLOOR))
+ {
+ result.setFloor(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.LAT))
+ {
+ result.setLat(Float.parseFloat(parser.nextText()));
+ }
+ if(parser.getName().equals(GeolocationExtension.LOCALITY))
+ {
+ result.setLocality(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.LON))
+ {
+ result.setLon(Float.parseFloat(parser.nextText()));
+ }
+ if(parser.getName().equals(GeolocationExtension.POSTALCODE))
+ {
+ result.setPostalcode(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.REGION))
+ {
+ result.setRegion(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.ROOM))
+ {
+ result.setRoom(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.STREET))
+ {
+ result.setStreet(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.TEXT))
+ {
+ result.setText(parser.nextText());
+ }
+ if(parser.getName().equals(GeolocationExtension.TIMESTAMP))
+ {
+ result.setText(parser.nextText());
+ }
+ }
+ else if(eventType == XmlPullParser.END_TAG)
+ {
+ if(parser.getName().equals(GeolocationExtensionProvider
+ .ELEMENT_NAME))
+ {
+ done = true;
+ logger.debug("Parsing finish");
+ }
+ }
+ }
+ catch(NumberFormatException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ return result;
+ }
+
+}
Index: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationJabberUtils.java

RCS file: src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationJabberUtils.java
diff -N src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationJabberUtils.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/net/java/sip/communicator/impl/protocol/jabber/extensions/geolocation/GeolocationJabberUtils.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,176 @@
+/*
+ * 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.extensions.geolocation;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.jabberconstants.*;
+import net.java.sip.communicator.util.*;
+
+import org.jivesoftware.smack.packet.*;
+
+/**
+ * This class give some static methods for converting a geolocation message + * to a different format.
+ * + * @author Guillaume Schreiner
+ */
+public class GeolocationJabberUtils +{
+
+ protected static final Logger logger =
+ Logger.getLogger(GeolocationJabberUtils.class);
+
+ private static Map scToJabberModesMappings = new Hashtable();
+ static{
+ scToJabberModesMappings.put(JabberStatusEnum.AWAY,
+ Presence.Mode.away);
+ scToJabberModesMappings.put(JabberStatusEnum.DO_NOT_DISTURB,
+ Presence.Mode.dnd);
+ scToJabberModesMappings.put(JabberStatusEnum.FREE_FOR_CHAT,
+ Presence.Mode.chat);
+ scToJabberModesMappings.put(JabberStatusEnum.AVAILABLE,
+ Presence.Mode.available);
+ }
+
+ /**
+ * Converts the specified jabber status to one of the status fields of the
+ * JabberStatusEnum class.
+ *
+ * @param mode the Jabber Status
+ * @return a PresenceStatus instance representation of the Jabber Status
+ * parameter. The returned result is one of the JabberStatusEnum fields.
+ */
+ public static JabberStatusEnum jabberStatusToPresenceStatus(Presence.Mode mode)
+ {
+ if(mode.equals(Presence.Mode.available))
+ return JabberStatusEnum.AVAILABLE;
+ else if(mode.equals(Presence.Mode.away))
+ return JabberStatusEnum.AWAY;
+ else if(mode.equals(Presence.Mode.chat))
+ return JabberStatusEnum.FREE_FOR_CHAT;
+ else if(mode.equals(Presence.Mode.dnd))
+ return JabberStatusEnum.DO_NOT_DISTURB;
+ else return JabberStatusEnum.OFFLINE;
+ }
+
+ /**
+ * Converts the specified JabberStatusEnum member to the corresponding
+ * Jabber Mode
+ *
+ * @param status the jabberStatus
+ * @return a PresenceStatus instance
+ */
+ public static Presence.Mode presenceStatusToJabberMode(JabberStatusEnum status)
+ {
+ return (Presence.Mode)scToJabberModesMappings.get(status);
+ }
+
+ /**
+ * Convert geolocation from GeolocationExtension format to Map format
+ * + * @param geolocExt the GeolocationExtension XML message
+ * @return a Map with geolocation information
+ */
+ public static Map convertExtensionToMap(GeolocationExtension geolocExt) + {
+ Map geolocMap = new Hashtable();
+
+ addFloatMap( geolocMap, OperationSetGeolocation.ALT, geolocExt.getAlt() );
+ addStringMap(geolocMap, OperationSetGeolocation.AREA, geolocExt.getArea());
+ addFloatMap( geolocMap, OperationSetGeolocation.BEARING, geolocExt.getBearing());
+ addStringMap(geolocMap, OperationSetGeolocation.BUILDING, geolocExt.getBuilding());
+ addStringMap(geolocMap, OperationSetGeolocation.COUNTRY, geolocExt.getCountry());
+ addStringMap(geolocMap, OperationSetGeolocation.DATUM, geolocExt.getDatum());
+ addStringMap(geolocMap, OperationSetGeolocation.DESCRIPTION, geolocExt.getDescription());
+ addFloatMap( geolocMap, OperationSetGeolocation.ERROR, geolocExt.getError());
+ addStringMap(geolocMap, OperationSetGeolocation.FLOOR, geolocExt.getFloor());
+ addFloatMap( geolocMap, OperationSetGeolocation.LAT, geolocExt.getLat());
+ addStringMap(geolocMap, OperationSetGeolocation.LOCALITY, geolocExt.getLocality());
+ addFloatMap( geolocMap, OperationSetGeolocation.LON, geolocExt.getLon());
+ addStringMap(geolocMap, OperationSetGeolocation.POSTALCODE, geolocExt.getPostalcode());
+ addStringMap(geolocMap, OperationSetGeolocation.REGION, geolocExt.getRegion());
+ addStringMap(geolocMap, OperationSetGeolocation.ROOM, geolocExt.getRoom());
+ addStringMap(geolocMap, OperationSetGeolocation.STREET, geolocExt.getStreet());
+ addStringMap(geolocMap, OperationSetGeolocation.TEXT, geolocExt.getText());
+ addStringMap(geolocMap, OperationSetGeolocation.TIMESTAMP, geolocExt.getTimestamp());
+
+ return geolocMap;
+ }
+
+ /**
+ * Extra functions for above
+ */
+ private static void addFloatMap(Map map, String key, float value) + {
+ Float valor = new Float(value);
+
+ if(valor != null) {
+ map.put(key, valor.toString());
+ }
+ }
+
+ private static void addStringMap(Map map, String key, String value) + {
+ if(value != null) {
+ map.put(key, value);
+ }
+ }
+
+ /**
+ * Convert geolocation from Map format to GeolocationExtension format
+ * + * @param geolocation a Map with geolocation information
+ * @return a GeolocationExtension ready to be included into a Jabber message
+ */
+ public static GeolocationExtension convertMapToExtension(Map geolocation) + {
+ GeolocationExtension geolocExt = new GeolocationExtension();
+
+ Set entries = geolocation.entrySet();
+ Iterator itLine = entries.iterator();
+
+ while(itLine.hasNext()) {
+
+ Map.Entry line = (Entry) itLine.next();
+
+ String curParam = (String) line.getKey();
+ String curValue = (String) line.getValue();
+
+ String prototype = Character.toUpperCase(curParam.charAt(0)) + + curParam.substring(1);
+
+ String setterFunction = "set" + prototype;
+
+ try {
+
+ Method toCall = GeolocationExtension
+ .class.getMethod(setterFunction, new Class[]{String.class});
+ Object[] arguments = new Object[] {curValue};
+
+ try {
+ toCall.invoke(geolocExt,arguments);
+ } catch (IllegalArgumentException e) {
+ logger.error(e);
+ } catch (IllegalAccessException e) {
+ logger.error(e);
+ } catch (InvocationTargetException e) {
+ logger.error(e);
+ }
+ } catch (SecurityException e) {
+ logger.error(e);
+ } catch (NoSuchMethodException e) {
+ logger.error(e);
+ }
+ }
+ return geolocExt;
+ }
+
+}

------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#3

Hi Emil,

sorry for the delay, thank you for your very precise report, it would
be very helpful for writing new bundles or services. By the way, here
is the GeolocationService needed to implement geolocation based
services like GPS or GeoIP, etc.

Guillaume

geolocation_service.tar.gz (1.59 KB)

···

2007/5/14, Emil Ivov <emcho@emcho.com>:

Hello Guillaume,

First of all, I'd like you to know that I find this a really excellent
idea! You've done some pretty good work! An excellent contribution! Thanks!

I have committed your code with the only exception being the
registration of the operation set in the Jabber provider. I've been
doing some modifications so that your code would better fit our
conventions. I might have broken something in the process so I would
like to ask you to review the code the way I've committed and let me
know if all is still working as expected.

Here's the list of modifications:

* Removed an unnecessary import for gibberish in the protocol provider

* Most of the classes in the patch had tab indentation - converted to
spaces.

* added javadocs for all fields defined in OperationSetGeolocation

* Replaced explicit imports in all classes with generic asterisk (*)
imports (according to conventions).

* Renamed GeolocationContactChangeEvent to GeolocationEvent

* Renamed GeolocationEvent.getNewPosition() to getNewLocation()

* Changed the source for GeolocationEvent to the operation set

* Added a redundant getSourceGeolocationOperationSet() for retrieving
the source operation set

* Added license header to GeolocationListener

* Renamed GeolocationListener.contactGeolocationPresenceChanged() to
contactGeolocationChanged()

* Added class javadocs do GeolocationListener

* GeolocationExtension - added javadocs for all constructor params
* GeolocationExtension - added javadocs to all private methods
(addXmlElement ..)

* Added javadoc comments to all setXxx() and getXxx() geolocation detail
accessors in GeolocationExtension.

* Renamed GeolocationExtension to GeolocationPacketExtension to better
reflect extended smack message.

* Added javadocs in GeolocationPacketExtensionProvider

* Changed log levels (debug -> trace) in GeolocationPacketExtensionProvider

* Added javadocs to all constructors in GeolocationMessage.

* Added a call to addExtension() in the third constructor of
GeolocationMessage.

* Added javadocs for constructors in GeolocationPresence.

* Renamed addFloatMap() -> addFloatToMap()

* addStringMap() addStringToMap()

* are you sure you want to ignore null values in putXxx? Didn't change
that I was just thinking that simply ignoring null values might be
unwanted in some cases (as opposed to throwing an exception).

* Removed the methods that convert smack jabber states to SC states (and
vice versa). Thought it would be a better idea to use those that already
exist in the presence operation set.

* Renamed OperationSetGeolocationImpl to OperationSetGeolocationJabberImpl

* OperationSetGeolocationJabberImpl.fireGeolcationEvent -> moved comas
in the beginning of each line (following convention)

* Removed publishContactGeolocation() from both service and impl as it
seemed unnecessary to me.

As you can see , most of these are minor changes so don't be impressed
by their number.

Let me know if any of the modifications break your code.

Great work once again!

Thanks
Emil

P.S. my battery is going down so i am sending the mail without a second
read. please excuse any possible errors.


#4

Hi Guillaume,

A promising contribution once again. I am looking forward to the moment when we'll have the whole thing working!

I've just reviewed your patch and your code is immaculate, so I've committed it as it is! Very good work!

The only thing that's left to discuss are the names of the various properties/leys that a geolocation Map can contain. I imagine that you were planning to use as keys the fields defined in OperationSetGeolocation. Is this the case?

Wouldn't it be better if we also defined them in the service?

We could start out by having them defined in both the op set and the geolocation service. I vaguely remember telling you a few months ago that a provider shouldn't be dependent on external stuff like a GeolocationService. I am beginning to think, however, that maybe you were right back then and maybe its not really a problem.

So let's start by also defining the fields in the geolocation service and see where we go from there.

Thanks for your contributions, Guillaume!

Emil

Guillaume Schreiner wrote:

···

Hi Emil,

sorry for the delay, thank you for your very precise report, it would
be very helpful for writing new bundles or services. By the way, here
is the GeolocationService needed to implement geolocation based
services like GPS or GeoIP, etc.

Guillaume

2007/5/14, Emil Ivov <emcho@emcho.com>:

Hello Guillaume,

First of all, I'd like you to know that I find this a really excellent
idea! You've done some pretty good work! An excellent contribution! Thanks!

I have committed your code with the only exception being the
registration of the operation set in the Jabber provider. I've been
doing some modifications so that your code would better fit our
conventions. I might have broken something in the process so I would
like to ask you to review the code the way I've committed and let me
know if all is still working as expected.

Here's the list of modifications:

* Removed an unnecessary import for gibberish in the protocol provider

* Most of the classes in the patch had tab indentation - converted to
spaces.

* added javadocs for all fields defined in OperationSetGeolocation

* Replaced explicit imports in all classes with generic asterisk (*)
imports (according to conventions).

* Renamed GeolocationContactChangeEvent to GeolocationEvent

* Renamed GeolocationEvent.getNewPosition() to getNewLocation()

* Changed the source for GeolocationEvent to the operation set

* Added a redundant getSourceGeolocationOperationSet() for retrieving
the source operation set

* Added license header to GeolocationListener

* Renamed GeolocationListener.contactGeolocationPresenceChanged() to
contactGeolocationChanged()

* Added class javadocs do GeolocationListener

* GeolocationExtension - added javadocs for all constructor params
* GeolocationExtension - added javadocs to all private methods
(addXmlElement ..)

* Added javadoc comments to all setXxx() and getXxx() geolocation detail
accessors in GeolocationExtension.

* Renamed GeolocationExtension to GeolocationPacketExtension to better
reflect extended smack message.

* Added javadocs in GeolocationPacketExtensionProvider

* Changed log levels (debug -> trace) in GeolocationPacketExtensionProvider

* Added javadocs to all constructors in GeolocationMessage.

* Added a call to addExtension() in the third constructor of
GeolocationMessage.

* Added javadocs for constructors in GeolocationPresence.

* Renamed addFloatMap() -> addFloatToMap()

* addStringMap() addStringToMap()

* are you sure you want to ignore null values in putXxx? Didn't change
that I was just thinking that simply ignoring null values might be
unwanted in some cases (as opposed to throwing an exception).

* Removed the methods that convert smack jabber states to SC states (and
vice versa). Thought it would be a better idea to use those that already
exist in the presence operation set.

* Renamed OperationSetGeolocationImpl to OperationSetGeolocationJabberImpl

* OperationSetGeolocationJabberImpl.fireGeolcationEvent -> moved comas
in the beginning of each line (following convention)

* Removed publishContactGeolocation() from both service and impl as it
seemed unnecessary to me.

As you can see , most of these are minor changes so don't be impressed
by their number.

Let me know if any of the modifications break your code.

Great work once again!

Thanks
Emil

P.S. my battery is going down so i am sending the mail without a second
read. please excuse any possible errors.

------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net