Getting Started With Project jMaki for the GlassFish v3 Application Server

Accessing an External Service From a Widget

One characteristic of an Ajax-based client is that it cannot make calls to URLs outside of its domain, which means that it cannot access services located on another server. Project jMaki provides a proxy, called the XmlHttpProxy client, that communicates with external services on a widget's behalf.

To access an external service, a widget uses an XmlHttpRequest object to access the service through the XmlHttpProxy client. Project jMaki already includes some code that allows you to access the Yahoo Geocoder service. This service takes a location, such as a city, and returns the coordinates for that location. The code jMaki provides for widgets to use this service includes the configuration of the service in the centralized xhp.json file:

{"xhp": {
    "version": "1.0",
    "services": [
        {"id": "yahoogeocoder",
         "url":"http://api.local.yahoo.com/MapsService/V1/geocode",
         "apikey" : "appid=jmaki-key",
         "xslStyleSheet": "yahoo-geocoder.xsl",
         "defaultURLParams": "location=santa+clara,+ca"
        },
	...
]}}

The preceding JSON code configures the Yahoo Geocoder service under the ID yahoogeocoder with the XmlHttpProxy client. The configuration includes the URL to the service, a reference to the API key to use for Yahoo services and widgets, a reference to a stylesheet that styles the data returned from the service, and a default location.

To obtain coordinates for a location from the Yahoo Geocoder service from your glue code, you create a string URL out of these elements:

An example URL constructed from this string would be the following:

http://localhost:8080/jmaki/xhp?key=yahoogeocoder&urlparams=location=Eugene,Oregon

Once you have the string URL, you use Ajax to do the following:

  1. Access the service with the URL.

  2. Obtain the coordinates from the service.

  3. Publish the coordinates to the /jmaki/plotmap topic.

The first thing to do is to get the location so that you can provide it to the service. In the plotCity application, the thisCity widget publishes the city to be plotted to the /cities topic when the user selects a city:

<a:widget id="thisCity"
	name="dojo.combobox"
	publish="/cities"
	subscribe="/cb"
	value="${StateBean.cities}" />

A combobox widget always publishes its selected value to the global onSelect topic and to the onSelect sub-topic of any developer-defined parent topic. In this case, the combobox widget publishes its value to the parent topic, /cities. Therefore, the value is published to /cities/onSelect.

Here is the handler from the plotCity example that subscribes to the /cities/onSelect topic:

jmaki.subscribe("/cities/onSelect", function(item) {
	var city = item.value;
	var state = jmaki.attributes.get('thisState').getValue();
	var location = city + ", " + state;
	var encodedLocation = encodeURIComponent("location=" + location);
	var url = jmaki.xhp + 
		"?id=yahoogeocoder&urlparams=" + 	
		encodedLocation;
	jmaki.doAjax({url: url, callback : function(req) {
		if (req.responseText.length > 0) {
			// convert the response to an object
			var response = eval("(" + req.responseText + ")");
			var coordinates = response.coordinates;
			v = {results:coordinates};
			jmaki.publish("/jmaki/plotmap", coordinates);
		} else {
			jmaki.log("Failed to get coordinates for " + 
				location );
		}
	}
});

This handler does the following:

  1. Gets the city name from the args argument that is passed to it from the topic, /cities/onSelect.

  2. Gets the current state from thisState and appends it to the city to construct the location argument.

  3. Calls encodeURIComponent on the location variable to encode it so that it is the proper format for the URL.

  4. Constructs the URL to pass to access the service.

  5. Uses Ajax to pass the location to the service, retrieve the coordinates from the service, and publish the coordinates to the /jmaki/plotmap topic.

All widgets automatically subscribe to the /jmaki/plotmap topic. Therefore, when new coordinates are posted to the topic, the Google map widget plots the city located at the coordinates.