YOUR FEEDBACK
Gregor Rosenauer wrote: well, not what's your take on this? Did I miss a second page of this article or...
AJAXWorld RIA Conference
Early Bird Savings Expire Friday Register Today and SAVE !..


2008 East
DIAMOND SPONSOR:
Data Direct
Frontiers in Data Access: The Coming Wave in Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
Intel
Virtualization – Path to Predictive Enterprise
Green Hills
IT Security in a Hostile World
JBoss / freedom oss
Practical SOA Approach
GOLD SPONSORS:
Software AG
The Art & Science of SOA: How Governance Enables Adoption
PlateSpin
Effective Planning for Virtual Infrastructure Growth
Fujitsu
Automated Business Process Discovery & Virtualization Service
Ceedo
Workspace Virtualization
Click For 2007 West
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
SYS-CON.TV
TOP LINKS YOU MUST CLICK ON


Enterprise Mashup Services
Part 2: Combining JSF and mashup services to make mashup components

The MapModel and MapBean
The MapModel object (Listing 7) defines two abstract methods: onSelect and onMoveEnd. The onSelect method is called when a user selects a marker on the map, and the onMoveEnd method is invoked after a user completes a zoom or pan operation.

abstract public String onSelect(GeoPoint pt);

abstract public String onMoveEnd(String lat, String lng, String zoom);

Both methods represent steps in a simple template or behavior pattern in which behavior is implemented by a subclass of the MapModel object (Figure 5).

The onSelect and onMoveEnd methods are called by the selectPoint and moveEnd template methods, respectively. Both methods extract values for parameters from a request string, pass those values onto the methods that inject behavior (for example, onMove or onSelect) into the encapsulated method, and return a response using the writeResponse method.

The moveEnd and selectPoint methods are invoked by the faces/dynamic/mapbean/moveEnd and faces/dynamic/mapbean/selectPoint URLs, respectively. The addSelectPointListener and addMoveEndListener JavaScript functions defined in the mapScript.js file (Listing 9) associate a GEvent listener with the current GMap object. When called, a listener posts a request to the URL that invokes either the moveEnd or selectPoint method. In this example, Gevent listeners are generated on marker selections or pan and zoom operations. For more information on Gevent listeners or other facets of the Google Maps API, refer to the Google Maps API documentation (www.google.com/apis/maps).

The concrete implementation of the MapModel object used in this example is com.thepeninsulasedge.view.managed.MapBean (Listing 10). The class defines an onSelect method that extracts a message or string contained in a GeoPoint object, which is associated with a marker on the map. The extracted message is then written as a response to the initial XMLHttpRequest object using the writeResponse method, and displayed in an info window on the map (Figure 6).

The onMoveEnd method updates a display that shows the coordinates of the map's center and the current level of magnification (Figure 7).

Besides providing methods to respond to JavaScript events, the MapBean also defines three action methods - addPointToMap, removeSelectedPoint, and clearMap - that are executed by command components. These methods demonstrate how the tpe:map component can be integrated with existing JSF components. For example, the addPointToMap method adds a new point to the map by manipulating the collection of GeoPoint objects contained in the MapBean. The method creates a new GeoPoint instance from an address and adds the point to the MapBean's current list of points. The method is executed by h:commandButton and the address is provided by an h:inputText field (See Listing 11).

GeoPoints
Each GeoPoint object in the MapBean is associated with a marker on a map and located by latitude and longitude. (To better understand the relationship between GeoPoint objects and the MapBean, see the diagram in Figure 8.)

Thus, when a user clicks a marker, the corresponding GeoPoint object is located in the MapBean by finding a GeoPoint object with a matching set of coordinates. The following Predicate (see the Apache Commons Collection at http://jakarta.apache.org/commons/collections/) is used to perform the evaluation between latitude and longitude and a corresponding GeoPoint object. The Predicate performs this evaluation while iterating through a collection of GeoPoint objects.

   public static Predicate findPredicate(final String lat, final String lng) {
     return new Predicate() {
       public boolean evaluate(Object obj) {
     if (!(obj instanceof GeoPoint))
       return false;
     GeoPoint pt = (GeoPoint)obj;
     if (pt.getLat().equals(lat) && pt.getLng().equals(lng)) {
       return true;
     } else {
       return false;
     }
    }
     };
   }

The GeoPointUtil class also provides a convenient way to create new instances of GeoPoint objects using the Yahoo! Geocoding API. The technique simply parses coordinates from an XML result generated by a request and uses the coordinates to create a new instance. The result is parsed with the Apache Commons Digester (http://jakarta.apache.org/commons/digester/).

The MapRenderer
The HTML and JavaScript in Listing 6 is the code used to create a new instance of the GMap2 object - the JavaScript object that represents a map in the Google Maps API. The code also ties the JavaScript used to consume the Google Maps API to the Java code in the MapBean. The com.thepeninsulasedge.components.MapRenderer class (Listing 3) is responsible for producing the markup shown in Listing 6. To understand which method in the MapRenderer class produced a specific snippet of JavaScript or HTML, look at the comments generated by the MapRenderer class in Listing 6. Note that only the load function used to instantiate the GMap2 object and a set of variables are dynamically generated in the MapRenderer class. This is done to ensure that each tpe:map component has a unique load function and set variables, allowing multiple tpe:map components to be used in a single page. Uniqueness is guaranteed by appending the component's client identifier to the name associated with the dynamically generated variable or function. According to JSR 127, each server-side component in JSF is guaranteed a unique client identifier.

The MapRenderer class relies on functions defined in the mapScripts.js file (Listing 9). These functions limit the need to hardcode JavaScript into the class and define essential functions such as addSelectPointListener and addMoveEndEvent. For the JavaScript generated by the MapRenenderer class to use functions defined in mapScripts.js, the file must first be imported. This is done with Shale Remoting. The linkJavascript method in org.apache.shale.remoting.XhtmlHelper is used for the import statement for the mapScripts.js file:

<script type="text/javascript"
src="/GoogleMapsAndDWR-JSFView-context-root/faces/static/com/thepeninsulasedge/
components/scripts/mapScripts.js">
</script>

The script import provides a reference to the mapScript.js file relative to the Web applications class path. Thus, the file specified is located under the package structure com/thepeninsulasedge/components/scripts/. A similar import is generated for the prototype.js file.

Conclusion
Consuming mashup services in the enterprise is a reality, and encapsulating mashup APIs with custom JSF components provides an elegant solution for packaging and reusing these services. The example in this article consolidated the complex markup and script shown in Listing 6 into a simple and concise component that amounted to a single XML tag. Imagine that - the power of Google Maps packaged in a simple component. Moreover, the componentization of the Google Maps API, as well as the linkage between JavaScript events and the JSF managed bean facility, makes it relatively easy to tie Google Maps to J2EE services such as EJB 3.0. The result of this blending of external mashups, Shale, and JSF is an enterprise-ready mashup service in very accessible package. To learn more about the technologies referenced in this article, please refer to the references provided.

References

About Ric Smith
Ric Smith is director, business and product strategy at Kaazing. provides Kaazing Corporation with a wealth of experience in product management and consulting for enterprise products and services. Prior to joining Kaazing, Ric was a principal product manager for Oracle's Fusion Middleware at Oracle's Headquarters in Redwood Shores, CA. In his role as a Principal Product Manager he was responsible for the evangelism and product direction of Oracle's AJAX and Java EE Web Tier offerings. Before joining the Fusion Middleware team, Ric worked for Oracle's consulting business as a principal consultant where he led development of mission-critical applications for prominent organizations within the defense/intelligence industry. In addition, Ric won consecutive awards for technical achievement for each year of his tenure as a consultant. Ric is a frequent speaker at international events and has written articles featured in leading industry publications such as Java Developer's Journal and AJAXWorld Magazine. He is also a representative to the OpenAjax Alliance and an honors graduate of the University of Arizona.

LATEST ECLIPSE STORIES . . .
Join Scott Guthrie as he discusses Microsoft’s commitment to web standards development, Rich Internet Applications and how Microsoft is contributing to help move the web forward. Join Adobe’s Kevin Lynch as he demonstrates how Flash and HTML come together to make the most engaging,...
Reminding people of how its backing was the making of Linux, IBM, to no one's surprise, has thrown its support behind cloud computing, that delicious nexus of every chi-chi buzzword technology currently in vogue: Web 2.0, rich Internet applications, software-as-a-service, SOA, grid com...
This guide explains how you can install the Google Android SDK 1.0 on an Ubuntu 8.04 desktop. With this stable release of the Android SDK, you can now develop applications for Android smartphones (like T-Mobile's G1) and offer them on the Android Market.
Virtualization has become a critical part of Enterprise IT strategy. Why and how has it become one of the most important change agents in our industry? To answer these questions I had the good fortune recently to be able to speak to a select group of top IT industry executives who join...
Watching VMware stock and its market cap spike since it IPO'd must have had Red Hat positively pea green with envyWatching VMware stock and its market cap spike since it IPO'd must have had Red Hat positively pea green with envy - so green in fact that it's gonna try taking VMware on b...
Well, Egenera - which has no market cap at all because it hasn't gone public yet - claims it is. IDC, which coined the term, defines 'Virtualization 2.0' as the next step beyond server virtualization replete with faster provisioning, high availability, disaster recovery, resource balan...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE