Designing a Google Maps plug-in for IBM Lotus Sametime Connect V7.5

Find where your Sametime partners are by using the Locate Partner plug-in for IBM Lotus Sametime Connect V7.5. This plug-in uses Google Maps technology to locate a Sametime partner and to provide directions to your partner's location.

Share:

Mark Talbot (talbotm@us.ibm.com), Developer, Industry Solutions, IBM

Mark Talbot works for IBM as a developer for Industry Solutions. You can reach Mark at talbotm@us.ibm.com.



Kulvir Singh Bhogal (kbhogal@us.ibm.com), Consultant, Software Services for WebSphere, IBM

Kulvir Singh Bhogal works as an IBM Software Services for WebSphere consultant, devising and implementing J2EE-centric solutions at customer sites across the nation. You can reach Kulvir at kbhogal@us.ibm.com.



22 August 2006 (First published 18 July 2006)

[Editor's note: This article was updated to reflect the final version of IBM Lotus Sametime Connect V7.5. It includes a new sample code download that works with IBM Lotus Sametime SDK V7.5.]

In the developerWorks Lotus article, "Extending the Lotus Sametime client with an LDAP directory lookup plug-in," we showed you how to extend the Lotus Sametime Connect V7.5 client with the Partner Lookup plug-in. This plug-in allowed you to lookup Sametime partner information stored in an LDAP directory. The extensibility of the Lotus Sametime client is made possible by the underlying Eclipse-based infrastructure, which allows you to create plug-in extensions that plug into extension points exposed by the Lotus Sametime client.

In this article, we further our study of extending the Lotus Sametime client through plug-ins. We also shed light on the concept of Eclipse preferences. To make our study intriguing, we thought we'd show you how you can build a plug-in that interacts with Google Maps.

Google Maps is a free service provided by Google, which provides Internet browser-based, door-to-door directions as well as maps of a particular location. The interactive maps can be zoomed in to show detailed information. The maps provided by Google are an excellent showcase of the powers of Ajax, a Web technology providing great user interactivity with a Web site by performing asynchronous network requests with JavaScript and XML.

In this article, you leverage the offerings of Google Maps within a Lotus Sametime client plug-in, the Locate Partner plug-in. The plug-in lets you get door-to-door directions from your location to the location of your Sametime partners. You can also get a map of the location of a Sametime partner. Figure 1 shows a screenshot of the Locate Partner plug-in. When you look up directions or a map of a Sametime partner using the plug-in, a browser window opens. The browser is pointed to the appropriate Google Maps URL, which shows the Sametime user either the directions or map he or she is interested in.

Figure 1. Locate Partner plug-in
Locate Partner plug-in

We used the IBM public Lotus Sametime server: messaging.ngi.ibm.com for our plug-in testing. You can learn more about the public Lotus Sametime server from the IBM Community Tools Web site. Your user name and password are the same as your IBM user name and password when interacting with the IBM public Lotus Sametime server. You can get an IBM user name and password by registering for one on the IBM Web site.

Eclipse preferences

Eclipse preferences represent a set of name-value pairs. Each name has two values, a default value and a user specified value. If no user specified value exists, the default value is used.

Allowing the Sametime client user to specify his physical street address

In order for the door-to-door directions functionality of the Locate Partner Plug-in to work, Google must know the starting address from which you want driving directions. We use an Eclipse preference to allow a Sametime user to specify his own starting address as shown in figure 2.

Figure 2. Eclipse preference
Eclipse preference

Specifying the location of the client's browser

The Locate Partner plug-in allows a Sametime user to specify the location of his/her Web browser. As with the starting address, the Web browser location is also stored using an Eclipse preference as shown in figure 2.

The Internet browser is used for displaying Google directions and maps.

Gathering the locations of your Sametime partners

Unfortunately, there is no way to obtain an Eclipse preference of another Sametime partner. Accordingly, you must devise a way to discover where each Sametime partner is located. This information may be obtainable from an LDAP directory as we demonstrated in our previous article. However, for simplicity purposes, we associate our Sametime partners with street addresses using a properties file that is dynamically read every time we want to obtain directions to or get a map for a particular Sametime partner. See figure 3.

Figure 3. Properties file
Properties file

Changing the target platform

We assume you have Eclipse SDK 3.2 installed. If not, go to the Eclipse Web site to obtain the software. To develop Sametime plug-ins, you need to change your target platform in Eclipse. After you start Eclipse, switch to the Plug-in Development perspective. From the Plug-in Development perspective, change the target platform to the directory where you installed Lotus Sametime Connect. The target platform tells the Eclipse Plug-in Development Environment (PDE) the name of the folder containing the target platform's plug-ins directory.

To change the target platform, follow these steps:

  1. From the Window menu in Eclipse, choose Preferences.
  2. In the left pane of the Preferences dialog box, expand the Plug-in Development item. Then select Target Platform.
  3. In the right pane the Target Platform Preference Page appears. Click the Browse button to change the location.
  4. Change your target platform to the location of the directory containing the Lotus Sametime 7.5 plug-ins directory on your system. If you installed Lotus Sametime 7.5 in the default location, the target platform location is C:\Program Files\IBM\Sametime Connect 7.5\sametime.
  5. Click Reload. You now see the Sametime plug-ins as shown in figure 4.
    Figure 4. Sametime plug-ins directory
    Sametime plug-ins directory

Creating a Plug-in Project

To create your Sametime plug-in, you need a plug-in project to house the plug-in during your development. To create a plug-in project, follow these steps:

  1. In Eclipse, choose File - New Project.
  2. From the New Project Wizard, select Plug-in Development - Plug-in Project. Then click Next.
  3. The New Plug-in Project wizard appears. Specify com.devworks.example.map as the project name, and then click Next.
  4. For the plug-in name, enter Google Maps. For the plug-in provider, enter DeveloperWorks.
  5. Notice that the option "This plug-in will make contributions to the UI" is selected in figure 5. The Lotus Sametime APIs provide a means of extending the Sametime UI. If you were just extending the Sametime UI, making a contribution to the Eclipse UI would not be necessary. In our case, we are creating an Eclipse preference page that extends the Eclipse UI. Accordingly, in the Plug-in Project wizard, we specify that the plug-in makes contributions to the UI.
    Figure 5. New Plug-in Project wizard
    New Plug-in Project wizard
  6. Accept the remaining default values and click finish.

Setting up plug-in dependencies

To allow your Lotus Sametime plug-in to resolve the Lotus Sametime classes, you need to edit the plug-in's dependencies. To do this:

  1. Open your META-INF/MANIFEST.MF file, and then click the Dependencies tab, which causes the Dependencies view to appear.
  2. Click Add. The Plug-in Selection dialog box appears as shown in figure 6.
    Figure 6. Plug-in Selection dialog box
    Plug-in Selection dialog box
  3. Select the com.ibm.collaboration.realtime.people plug-in and click OK.
  4. Save the Dependencies page. The dependencies page should look like figure 7.
    Figure 7. Dependencies page
    Dependencies page

Preferences via preference pages

In a Java program, settings are often externalized in a properties file. Alternatively, Eclipse-based applications provide extension points that allow an Eclipse developer to add a preference page to the preferences of the Eclipse-based application (in our case, the Lotus Sametime client). In your preference page, you have two preferences. The first preference is for the starting street address for your Google directions. The second preference is for Internet browser location. For example, editing the browser location, a Sametime user can opt to use either Internet Explorer or Firefox for displaying directions and/or maps.

Google Map preference page

You store your preferences in a preference page called Google Map as shown in figure 8.

Figure 8. Preference page
Preference page

To create the Google Map preference page, open your META-INF/MANIFEST.MF file. Select the Extensions tab and click the Add button to open the New Extension window. In the New Extension window, select the Extension Wizards tab. From the right pane of the Extension Wizards tab, select the Preference Page extension template and click Next. See figure 9.

Figure 9. New Extension wizard
New Extension wizard

This creates a template for your preference page, which you can modify to fit your needs. Set the class name for the preference page as GMapPreferencePage. Set the name for the preference page as Google Map. Use the default package name com.devworks.example.map.preferences as your Java package name and click Finish (see figure 10). Press Ctrl+S to save your changes in the Extensions view.

Figure 10. Preference Page dialog box
Preference Page dialog box

When you create your template, Eclipse generates a class named PreferenceConstants for you. This is a convenience class that can be used to store constant values used by your preference page. You can replace the auto-generated code with the following code:

/**
 * Constant definitions for plug-in preferences
 */
public class PreferenceConstants {
	public static final String MY_LOCATION = "myLocation";
	public static final String BROWSER_LOCATION = "browserLocation";
}

As you can see from the code above, the plug-in uses two constants: MY_LOCATION, which represents the physical street address of the person using the Lotus Sametime client and BROWSER_LOCATION, which represents the disk location for his/her Internet browser's executable.

Another class that was auto-generated for you is the PreferenceInitializer class. This class's initializeDefaultPreference method is used to populate default values for your preference values. Notice in the following code how the class uses the constants you defined in the PreferencesConstants class. By default, the browser location is set to Microsoft Internet Explorer's default installation location (c:\Program Files\Internet Explorer\iexplore.exe).

public class PreferenceInitializer extends AbstractPreferenceInitializer {
	public void initializeDefaultPreferences() {
		IPreferenceStore store = Activator.getDefault()
				.getPreferenceStore();
		store.setDefault(PreferenceConstants.MY_LOCATION,
				"");
		store.setDefault(PreferenceConstants.BROWSER_LOCATION,
		"c:\\progra~1\\intern~1\\iexplore.exe");
	}
}

The template generation created another class named GMapPreferencePage. This class defines the layout for the preference page. You can replace the auto-generated constructor with the following constructor snippet:

	public GMapPreferencePage() {
		super(GRID);
		setPreferenceStore(Activator.getDefault().getPreferenceStore());
		setDescription("Preferences for the Google Map feature.");
	}

In the code above, the constructor of the parent class takes one argument, an integer representing the layout. We chose a GRID layout, which by default has one column. Each of the FieldEditor widgets that you add will have its own row.

You need to provide input areas through which the client can edit the values for its preferences (more specifically, browser location and street address). The graphical input facility you incorporate into your preference page is shown in figure 2 earlier in the article.

To create the input areas, you replace the generated createFieldEditors method (which you must override from your parent FieldEditorPreferencePage class) with your own code. In the following code, we programmatically add two field editors using the StringFieldEditor Eclipse widget: one field editor to capture the Sametime user's physical street address and another to capture his browser location.

public void createFieldEditors() {
	addField(
		new StringFieldEditor(PreferenceConstants.MY_LOCATION, 
		"My Location:", getFieldEditorParent()));
	addField(
		new StringFieldEditor(PreferenceConstants.BROWSER_LOCATION, 
		"Browser Path:", getFieldEditorParent()));
}
public void init(IWorkbench workbench) {}

The MapUtilities class

Now that you have your preference page created, it is time to move on to addressing the business function of the Locate Partner plug-in. The MapUtilities class is a class you need to create under the com.devworks.example.map package. The MapUtilities class is the plug-in's workhorse; it is responsible for generating the Google URLs necessary for displaying directions and maps. The MapUtilities class is also responsible for opening a Web browser on the client machine for viewing the generated URLs. We now dissect the class and its various methods and explain the roles and anatomy of each method. Two of the methods showMap and getAddressURL work in tandem to display the map of a Sametime partner's street address. Similarly, the methods showDirections and getDirectionsURL work in tandem to display driving directions to a Sametime partner's street address.

The showMap method

The showMap method of the MapUtilities class is responsible for opening an instance of the client's Web browser and displaying a map of a Sametime partner's location using Google Maps. The class retrieves the user specified browser disk location from the Eclipse preference store. This value is the same value that the user specifies in the GMapPreference page created earlier. The class then calls the Java Runtime.getRuntime().exec() method to launch the browser. Pay particular attention to how we programmatically acquire the location of the browser from the org.eclipse.jface.preference.PreferenceStore object. Also notice how the browser location is followed by a method call to the getMapURL method.

public static void showMap(String address) {
	String browserLocation = Activator.getDefault().getPreferenceStore()
			.getString(PreferenceConstants.BROWSER_LOCATION);
	try {
		Runtime.getRuntime().exec(
					browserLocation + " " + getMapURL(address));
		} catch (IOException e) {
			e.printStackTrace();
		}
}

You may be wondering from where the showMap method gets its address String argument from. We cover this later in the "Address Store" section.

The getMapURL method

Given a Sametime partner's physical street address in the form of a String, the getMapURL method constructs a Google URL address string, which when visited by an Internet browser, shows a map for the specified physical street address.

private static String getMapURL(String address) {
		String startURLFragment = "http://maps.google.com/maps?f=q&hl=en&q=";
		String endURLFragment = "&om=1";
		return startURLFragment + encodeAddress(address) + endURLFragment;
	}

The getMapURL method uses an auxiliary method named encodeAddress. This method encodes street addresses into a format that Google accepts. Don't worry, the encoding process isn't rocket science. The method simply replaces spaces with plus signs:

private static String encodeAddress(String unEncodedAddress) 
{
	return unEncodedAddress.replace(' ', '+');
}

The showDirections method

The showDirections method displays directions using Google Maps from the address specified in the GMapPreference page created earlier to the Sametime partner's street address. The partner's street address is gathered from the Address Store. As done in the showMap method covered earlier, the showDirections method uses the Runtime.getRuntime.exec() method to launch the browser application. The showDirections method relies on the getDirectionsURL method's return String to act as an argument to the browser's invocation.

public static void showDirections(String partnerAddress) {
	String browserLocation = Activator.getDefault().getPreferenceStore()
			.getString(PreferenceConstants.BROWSER_LOCATION);
	try {
		Runtime.getRuntime().exec(
				browserLocation + " " + getDirectionsURL(partnerAddress));
	} catch (IOException e) {
		e.printStackTrace();
	} catch (Exception e) {
		showErrorMessage(e.getMessage(), "Preference Store Error");
	}
}

The getDirectionsURL method

Given a Sametime partner's street address (as gathered from the Address Store), the getDirectionsURL method constructs a Google Map URL address for a Web page that shows the driving directions. The getDirectionsURL method gathers the address in the PreferenceStore as the starting address:

private static String getDirectionsURL(String toAddress) throws Exception {
String myAddress = Activator.getDefault().getPreferenceStore()
		.getString(PreferenceConstants.MY_LOCATION);
if ((myAddress==null) || (myAddress.trim().equals("")))
{
		throw new Exception("No originating address specified 
		in the preference store.");
}
String sourceUrlFragment = "http://maps.google.com/maps?f=d&hl=en&saddr=";
String destinationURLFragment = "&daddr=";
String endURLFragment = "&om=1";
return sourceUrlFragment + encodeAddress(myAddress)
		+ destinationURLFragment + encodeAddress(toAddress)
		+ endURLFragment;
}

The getDirectionsURL method makes use of the encodeAddress method (like the getMapURL method did) to format street addresses to Google Map's liking.

The showErrorMessage method

As you will see in the "Address Store" section, the onus of defining the physical address of a Sametime partner is left up to the Lotus Sametime client user. In the event that the user did not specify an address for a Sametime partner whom he or she wants to get a street address map for or get driving directions to, then the showErrorMessage method displays an error message in the form of a message box as shown in figure 11:

Figure 11. Address error message
Address error message

The logic to produce such an error dialog is realized in the showErrorMessage method:

public static void showErrorMessage(String id, String text) {
	Shell shell = new Shell();
	MessageBox messageBox = new MessageBox(shell);
	messageBox.setMessage(id);
	messageBox.setText(text);
	messageBox.open();
}

Using the AddressStore object

You may be curious about how the Location Partner plug-in discovers the physical street address locations of Sametime partners. For simplicity purposes, as discussed in the "Gathering the locations of your Sametime partners" section, we designed our discovery process to be quite simple. A Sametime user is responsible for populating a properties file that is read into a ResourceBundle. The ResourceBundle is referenced by the class AddressStore whenever the Locate Partner plug-in needs to know the physical address of a Sametime partner (for purposes of displaying a map or directions).

public class AddressStore {
	private static final String BUNDLE_NAME = 
	"com.devworks.example.map.map"; //$NON-NLS-1$,
private AddressStore() { }
public static String getStreetAddress(String partnerId) { ResourceBundle RESOURCE_BUNDLE = ResourceBundle .getBundle(BUNDLE_NAME); try { return RESOURCE_BUNDLE.getString(partnerId); } catch (MissingResourceException e) { return null; } } }

The AddressStore object is used by the MapLookup and DirectionsLookup classes, both of which we cover shortly.


Extension and extension points

Our previous developerWorks Lotus article, "Extending the Lotus Sametime client with an LDAP directory lookup plug-in," covered the topic of creating an Eclipse plug-in in depth. If you are unfamiliar with the Eclipse concepts of extension points, extensions, and plug-ins, we suggest you get yourself up to speed by reading that article before moving on. To recap (in fast forward), an Eclipse plug-in is a component that contributes to the Eclipse platform. A plug-in can be configured to contribute to the user interface of the Eclipse platform. Eclipse plug-ins can define extension points, using an extension point schema. The extension point schema defines how a plug-in called an extender plug-in can modify the host plug-in by declaring an extension. Extension points are defined on host plug-ins, whereas extensions are declared by the extender plug-ins.

For example, an extension-point could define a means for modifying a host plug-in's menu item. The Lotus Sametime 7.5 client has a plug-in that defines an extension point whose ID is com.ibm.collaboration.realtime.people.personAction. In this article, you create an extension that extends the functionality of this extension point. More specifically, you add the Google Map and Google Map Directions functionality graphically depicted in figure 1.

Map lookup extension

Having created the map lookup functionality in the MapUtilities class covered earlier, you need a way for the user to access this functionality through the Sametime GUI. The Eclipse APIs provide an extension point to add a menu item to the list of items that appear when right-clicking (invoking the context menu) of a Sametime partner. To add your menu item, you extend the org.eclipse.ui.popupMenus extension point by adding the following section to the project's plugin.xml file:

<extension
       point="org.eclipse.ui.popupMenus">
    <objectContribution
          adaptable="false"
          id="com.devworks.example.map.prersonselection"
      objectClass="com.ibm.collaboration.realtime.livenames.PersonSelection">
       <action
             class="com.devworks.example.map.MapLookupDelegate"
             enablesFor="1"
             id="com.devworks.example.map.MapLookupDelegate"
             label="Google Map"
             style="push"/>
    </objectContribution>
 </extension>

The value of the class attribute in the XML above is the name of a Java class that extends the LiveNameActionDelegate class. Namely, you identify that the com.devworks.example.map.MapLookupDelegate class is called when the Google Map menu item is selected. The value of the id attribute is a unique ID for the extension. We used the fully qualified class name (com.devworks.example.map.MapLookupDelegate) as our unique ID.

The MapLookup class is shown below.

public class MapLookupDelegate extends LiveNameActionDelegate {
	public void run(IAction arg0) {
        Person persons[] = getSelectedPersons();
		Person person = persons[0];
		if (person != null) {
			String id = person.getContactId();
			System.out.println("Performing Lookup for" + id); //$NON-NLS-1$
			String partnerAddress = AddressStore.getStreetAddress(id);
			if (partnerAddress != null)
				MapUtilities.showMap(partnerAddress);
			else 
				MapUtilities.showErrorMessage("No street address 
				found for talbotm@us.ibm.com.", 
				"Partner Location Not Registered");
		}
	}
}

When the Google Map menu item is selected, the run method is triggered. In this method, you extract the Sametime partner's contact ID for which the Google Map menu item is selected. Then look up the associated street address for the partner in the AddressStore object. Finally, the showMap method is called to show the Sametime user a Google Map for the Sametime partner in a browser window. See figure 12.

Figure 12. Google map of Sametime partner
Google map of Sametime partner

Direction lookup extension

Just as you did in the map lookup extension, you again use the org.eclipse.ui.popupMenus extension point to add a menu item, but this time your menu item is labeled Google Map Directions. Edit the previous extension definition in the plugin.xml file to include the action for the Google Map Directions Lookup:

<extension
       point="org.eclipse.ui.popupMenus">
    <objectContribution
          adaptable="false"
          id="com.devworks.example.map.prersonselection"
          objectClass="com.ibm.collaboration.realtime.livenames.PersonSelection">
       <action
             class="com.devworks.example.map.DirectionsLookupDelegate"
             enablesFor="1"
             id="com.devworks.example.map.DirectionsLookupDelegate"
             label="Google Map Directions"
             style="push"/>       
       <action 
		   class="com.devworks.example.map.MapLookupDelegate" 
		   enablesFor="1" 
		   id="com.devworks.example.map.MapLookupDelegate"
		   label="Google Map"
		   style="push"/>
    </objectContribution>
</extension>

The value of the class attribute in the extension definition above is: com.devworks.example.map.DirectionsLookupDelegate, which is the name of a class that extends the LiveNameActionDelegate class. The com.devworks.example.map.DirectionsLookupDelegate class is called when the Google Map Directions context menu item is selected for a Sametime partner. The value of the id attribute is a unique ID for the extension. We used the fully qualified class name (com.devworks.example.map.DirectionsLookupDelegate) as our unique ID.

The DirectionsLookupDelegate class is shown below:

public class DirectionsLookupDelegate 
extends LiveNameActionDelegate {
	public void run(IAction arg0) {
		Person persons[] = getSelectedPersons();
		Person person = persons[0];
		if (person != null) {
			String id = person.getContactId();
			System.out.println("Performing Lookup for" 
			+ id);
			String partnerAddress = 
			AddressStore.getStreetAddress(id);
			if (partnerAddress != null)
				MapUtilities.showDirections(partnerAddress);
			else 
				MapUtilities.showErrorMessage("No street 
				address found for:" + id, 
				"Partner not Found");
			}
		}
	}

When the Google Map Directions menu item is selected, the run method of the DirectionsLookupDelegate class is triggered. In this method, you gather the Sametime partner's contact ID for which the Google Map Directions context menu item is selected. Then look up the associated street address for the Sametime partner in the AddressStore object. Finally, the showDirections method of the MapUtilities class is invoked to show directions to the Sametime partner's physical street address using the browser-based directions offering of Google Maps. See figure 13.

Figure 13. Google map directions for Sametime partner
Google map directions for Sametime partner

Deploying to Lotus Sametime Connect

To deploy this to Lotus Sametime, you need to create an Install/Update site. To learn more about Install/Update sites read the Eclipse article, "How to Keep Up to Date" to learn more about the Install/Update Site and the client Update Manager.


Conclusion

If you are like us, we deal with Sametime partners all across the nation (as well as around the world!). Sometimes you need to find out where your Sametime partners exist so you can pay them a face-to-face visit. In this article, we showed you how you can use the Google Maps offerings in tandem with the extensibility of Lotus Sametime. You saw how the Eclipse-based infrastructure of the Lotus Sametime client opens up opportunities of extensibility that you can capitalize on. Specifically, you learned about Eclipse preferences, which allow a user to customize their Eclipse-based experience.


Download

DescriptionNameSize
Sample Google Maps plug-ingoogleMaps.zip8 KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into IBM collaboration and social software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=146623
ArticleTitle=Designing a Google Maps plug-in for IBM Lotus Sametime Connect V7.5
publish-date=08222006