GMaps4JSF with Ajax PUSH

Java Development News:

GMaps4JSF with Ajax PUSH

By Hazem Salah

01 Nov 2008 | TheServerSide.com

As we know from the previous article, GMaps4JSF aims at integrating Google maps with JavaServer Faces (JSF). JSF users will be also able to construct complex street view panoramas and maps with just few JSF tags. They would also be able to attach different components (markers, information texts, controls, ground overlays, polygons, polylines) to the map easily. GMaps4JSF also allows attaching different events to the components without writing JavaScript code to bind the event with the component. JSF users will write JavaScript code only if they want to implement the components’ event handlers. GMaps4JSF is one of the JSF Mashups libraries that enable JSF users to build web 2.0 Mashup applications in JSF easily.

Ajax PUSH or Comet or “Reverse Ajax” is usually used in the applications that make use of server notifications like distance learning, collaborative authoring, chatting, forums, and auctions web applications. Ajax4JSF implements Ajax PUSH by providing the push component.

In this article, I will show how to configure GMaps4JSF with Ajax4JSF, and will give a brief summary about the Ajax4JSF PUSH component, and finally will illustrate a weather application that uses GMaps4JSF with Ajax4JSF push component.

How to configure GMaps4JSF with Ajax4JSF

To configure GMaps4JSF with Ajax4JSF, you should follow the following steps:

  • For GMaps4JSF:
  • Sign up for Google Maps API http://code.google.com/apis/maps/signup.html, and generate a key for your website URL.
  • In your page HEAD element, place the Google Maps APIs script include:
    <script 
     src="http://maps.google.com/maps?file=api&v=2&key=gen_website_key"
           type="text/javascript">
           </script>
  • Download the library jar gmaps4jsf-core-1.1.1-SNAPSHOT.jar from here:
    http://gmaps4jsf.googlecode.com/files/gmaps4jsf-core-1.1.1-SNAPSHOT.jar
  • Place the downloaded jar in the WEB-INF/lib folder of your JSF web application.
  • Add the following tag library declaration to your JSP page in order to use GMaps4JSF components:
    <%@ taglib uri="http://code.google.com/p/gmaps4jsf/" prefix="m" %>
    • Copy the following jars to the lib folder of your JSF web application:
      • richfaces-api-3.1.6.GA.jar
      • richfaces-impl-3.1.6.GA.jar
      • richfaces-ui-3.1.6.GA.jar
    • Add the Ajax4jsf filter in the web.xml:
      <filter>
         <display-name>Ajax4jsf Filter</display-name>
        <filter-name>ajax4jsf</filter-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
       </filter>
       <filter-mapping>
        <filter-name>ajax4jsf</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
         <dispatcher>REQUEST</dispatcher>
         <dispatcher>FORWARD</dispatcher>
         <dispatcher>INCLUDE</dispatcher> 
      </filter-mapping>  
          
    • Add the following tag library declaration to your JSP page in order to use Ajax4JSF components:
      <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>

Ajax4JSF PUSH component

<a4j:push> is a powerful component included in the JBoss RichFaces library that implements Ajax PUSH. <a4j:push> registers a listener on the server and then performs a lightweight poll to check if an event occurred on the server. This can be very useful for applications that make use of notifications from the server like:

  • Blogging.
  • Distance Learning.
  • Auctions and biddings.
  • Collaborative authoring.
  • Chatting and forums.
  • Weather (Our example).

The weather application

Let’s create the weather application that uses GMaps4JSF with Ajax4JSF PUSH component. Every 30 seconds, the server will push a random temperature message on a random city of the world. Figure 1.1 shows a screenshot of the weather application.

In Listing 1.1, the <a4:push> registers a listener #{cityWeather.addListener} on the server, and when the server returns an update, it will re-render the map component. The <m:map> shows a marker points to the city, and an information window containing the temperature message returned from the server.

Listing 1.1. The weather application JSP page

...
 <a4j:push id="push"
   eventProducer="#{cityWeather.addListener}"  
   enabled="#{cityWeather.enabled}" 
   reRender="mapPanel"/>       
     
    <h:panelGroup id="mapPanel">
     
   <h:outputText id="status" styleClass="statusClass"
           value="Current city is: #{cityWeather.cityName}"/>
     
     <m:map id="map" address="#{cityWeather.cityName}" 
       type="G_NORMAL_MAP"
       width="350px" height="350px"
       locationNotFoundErrorMessage="Connection failed!"
       renderOnWindowLoad="false">
              <m:marker />
                 <m:htmlInformationWindow htmlText="#{cityWeather.weatherStatus}"/>
     </m:map>     
    </h:panelGroup>
...

Listing 1.2 shows the weather application managed bean. The CityWeather represents the server-side thread which pushes (every thirty seconds) new information to the client map. In the run() method, a random city name and a random temperature messages are pushed to the client using the listener.onEvent(new EventObject(this)) call.

Listing 1.2. The weather application managed bean class

public class CityWeather implements Runnable {


...
 public void addListener(EventListener listener) {
  synchronized (listener) {
   if (this.listener != listener) {
    this.listener = (PushEventListener) listener;
   }
  }
 }

 public void start() {
  if (cityWeatherThread == null) {
   cityWeatherThread = new Thread(this);
   cityWeatherThread.setDaemon(true);
   cityWeatherThread.start();
   setStartDate(new Date());
   setEnabled(true);
  }
 }

 public void run() {
  while (cityWeatherThread != null) {
   try {
    if (((new Date()).getTime() - startDate.getTime()) >= MAXIMUM_PUSH_DURATION) {
     stop();
    }
    
    // construct new data ...
    cityName = getRandomCity(); 
    weatherStatus = getRandomTemperature();

    // deliver the new data to the client.
    listener.onEvent(new EventObject(this));

    Thread.sleep(PUSH_DURATION);
   } catch (InterruptedException e) {
    // handle the stuff ...
   }
  }
 }

 public void stop() {
  if (cityWeatherThread != null) {
   setStartDate(null);
   setEnabled(false);
   cityWeatherThread = null;
  }
 } 
...
}

The online demo

You can see the online demo here: http://mashups.s43.eatj.com/gmaps4jsf-push/index.jsf, and you can download the complete source code from here: http://gmaps4jsf.googlecode.com/files/gmaps4jsf-push-1.1.1.war

Biographies

Alexander Smirnov is the founder of the Ajax4jsf project, which he started as a personal side effort. It grew out of his interest in JSF and was originally run as a stand alone, self-hosted project. As he developed Ajax4jsf, Alexander began working with the MyFaces community, and started communicating more with the larger JSF community. He moved the project to SourceForge at the suggestion of RichFaces lead developer Sergey Smirnov (no relation.) Exadel began developing the RichFaces JSF components library and Alexander joined the project as a framework background developer. At the time it moved to java.net , Ajax4jsf had grown more useful when integrated with the RichFaces component library. RichFaces, however, was still not open source. The combined projects came to the attention of JBoss, which contracted with Exadel to open source both projects as JBoss projects. These were recently combined into a single project under the RichFaces name, available through JBoss.org. (RichFaces is combined with the JBoss Tools Eclipse -based developer environment to make up the JBoss Developer Studio subscription offering. He is also a JSF 2.0 EG member.

Hazem Saleh has five years of experience in JEE and open source technologies. He is an Apache MyFaces committer. He is the initiator of many components in MyFaces Tomahawk and sandbox projects such as CAPTCHA, pdfExport, media, passwordStrength and others. He is also a YUI4JSF committer. He is the founder of GMaps4JSF (an integration project that allows Google Maps to work using JSF tags). He is an expert in OpenLogic expert community. He is the author of the "The Definitive Guide to Apache MyFaces and Facelets (Apress)" book. He is now working for IBM Egypt as a staff engineer. He is a SME (Subject Matter Expert) in web 2.0 technologies.