Getting Started With Project jMaki for the GlassFish v3 Application Server

Developing the plotCity Application Using Project jMaki and the NetBeans IDE 6.1

In this exercise you create the plotCity web application using the NetBeans IDE 6.1.

ProcedureCreating the plotCity Project

When you complete this task, you'll have a skeleton jMaki application.

  1. Choose File > New Project.

  2. Under Categories, select Web.

  3. Under Projects, select Web Application and click Next.

  4. Type plotCity for Project Name.

  5. Change the Project Location to any directory on your computer and click Next.

  6. Select the GlassFish V3 TP2 Server for the server.

  7. Keep the other settings at their default and Click Next.

  8. Select the jMaki Ajax Framework and select the No CSS layout template.

  9. Click Finish.

ProcedureAdding the Widgets to the Page

With this task, you will add the thisState and thisCity combobox widgets and the Google map widget to the page.

  1. Open index.jsp in the editor pane if it is not already there.

  2. Expand the jMaki Dojo node in the jMaki Palette, located on the right side of the IDE window.

  3. Select and drag two Combobox widgets onto index.jsp

  4. Save your changes.

    You should now see the following tags on index.jsp:

    <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
    ...
    <a:widget name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
    <a:widget name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
  5. Add the ID, thisState to the first Combobox widget and the ID, thisCity to the second combobox widget, so that the page now looks like the following:

    <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
    ...
    <a:widget id="thisState" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
    <a:widget id="thisCity" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
  6. Add the text, Select a state: right before the first Combobox widget.

  7. Add a paragraph tag and the text, Select a city: right before the second combobox widget.

    The page should now look like this:

    <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
    ...
    Select a state:
    <a:widget id="thisState" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
    <p>
    Select a city:
    <a:widget id="thisCity" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
  8. Expand the jMaki Google node in the jMaki Palette, located on the right side of the IDE window.

  9. Select and drag a Google Map widget onto index.jsp, right after the Combobox widgets.

  10. Add another paragraph tag directly before the Google map widget.

    The page should now look like this:

    <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
    ...
    Select a state:
    <a:widget id="thisState" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
    
    <p>
    Select a city:
    <a:widget id="thisCity" name="dojo.combobox"
       value="[
           {label : 'Alabama', value : 'AL'},
           {label : 'California', value : 'CA'},
           {label : 'New York', value : 'NY', selected : true},
           {label : 'Texas', value : 'TX'}	           
        ]" />
     <p>     
     <a:widget  name="google.map"
    	args="{ centerLat : 37.4041960114344,
    	centerLon : -122.008194923401 }" />
  11. Save index.jsp.

  12. (Optional) Run the application by right-clicking the project node and selecting Run.

    You will see the three widgets on the page in the browser, but the combobox widgets are populated with the default set of data, and nothing happens when you select values from them. With the next task, you'll load the appropriate data into the combobox widgets.

Loading Data Into a Widget in the plotCity Application

This section details the tasks required to populate a widget with data, using the comboboxes included in the plotCity application as examples. These tasks are:

ProcedureCreating the Server-Side Data

With this task, you are creating a properties file that contains a set of states and a set of cities for each state. This file acts as the database for the application for simplicity's sake.

  1. Expand the plotCity node and right-click on the Source Packages node.

  2. Select New > Java Package.

  3. Enter plotCity as the package name.

  4. Click Finish.

  5. Right-click on the project in the Projects window and choose New > Other

  6. In the New File dialog, select Other from the Categories pane.

  7. Select Properties File from the File Types pane.

  8. Click Next.

  9. Enter cities in the File Name field.

  10. Click Finish.

  11. Select plotCity/src/java/plotCity as the location of the properties file.

  12. Copy the following content to the cities.properties file:

    AK=Anchorage,Fairbanks,Juneau,Nome
    AZ=Mesa,Phoenix,Scottsdale,Tucson
    CA=Los Angeles,Sacramento,San Diego,San Francisco
    OR=Bend,Eugene,Portland,Salem
    WA=Olympia,Seattle,Spokane,Tacoma
  13. Save the file.

ProcedureCreating a JavaBeans Component That Holds the Data

By performing this task, you are creating the bean that holds the state and city data that you can use with the comboboxes.

  1. Expand the plotCity > Source Packages nodes.

  2. Right-click the plotCity package and choose New > Java class.

  3. Type StateBean for the Class Name, plotCity for the Package and click Finish.

  4. Add the following variable declarations to the class:

    private String[] states = 
    	new String [] {"Alaska", "Arizona", "California", "Oregon"};
    private String[] stateCodes = 
    	new String[]{"AK", "AZ", "CA", "OR"};
    protected String[] AKCities = 
    	new String[] {"Anchorage", "Fairbanks", "Juneau", "Nome"};
    private ResourceBundle cityNames = null;
  5. Add an init method after the constructor that creates a ResourceBundle object from the cities.properties file:

    private void init() {
     cityNames = ResourceBundle.getBundle("plotCity.cities");   
    }
  6. Add a call to the init method inside the StateBean constructor:

    public StateBean(){
    	this.init();
    }
  7. Add the following getStates method to the class. It loads a JSON array with the list of state names that you initialized in step 4:

    public String getStates() throws JSONException {
    	JSONArray statesData = new JSONArray();
    	JSONObject stateData = new JSONObject();
    	for (int loop = 0; loop < states.length; loop++) {
    		stateData.put("label", states[loop]);
    		stateData.put("value", stateCodes[loop]);
    		statesData.put(stateData);
    		stateData = new JSONObject();
    	}
    	return jmaki.util.JSONUtil.jsonArrayToString(statesData, new StringBuffer());
    }
  8. Add the following getCities method to the class. It loads a JSON array with the list of Alaskan city names that you initialized in step 4:

    public String getCities() throws Exception {
    	JSONObject cityData = new JSONObject();
    	JSONArray citiesData = new JSONArray();
    	for(int i = 0; i < AKCities.length; i++){
    		cityData.put("label", AKCities[i]).toString();
    		cityData.put("value", AKCities[i]).toString();
    		citiesData.put(cityData);
    		cityData = new JSONObject();
    	}
    	return jmaki.util.JSONUtil.jsonArrayToString(citiesData, new StringBuffer());
    }
  9. Add the following getNewCities method to the class. It loads a JSON array with the list of city names for the selected state:

        
    public String getNewCities(String state) throws JSONException {
    	JSONObject city = new JSONObject();
    	JSONArray cities = new JSONArray();
    	String[] names = null;
    	try {
    		names = cityNames.getString(state).split(",");
    	} catch(Exception e){
    		return null;
    	}
    	for(int i = 0; i < names.length; i++){
    		city.put("label", names[i]);
    		city.put("value", names[i]);
    		cities.put(city);
    		city = new JSONObject();
    	}
    	return jmaki.util.JSONUtil.jsonArrayToString(cities, new StringBuffer());
    }
  10. Right-click the editor pane and select Fix Imports from the pop-up menu. The IDE will import the packages the class needs.

  11. Save StateBean.java

ProcedureAccessing Data From the Page

With this task, you will initialize the combobox widgets with the server-side data.

  1. Open index.jsp into the source editor pane.

  2. Expand the JSP node in the Palette and select and drag Use Bean into the Source Editor below the h1 tag.

  3. In the Insert Use Bean dialog box, enter the following values and then click OK.

    • ID: StateBean

    • Class: plotCity.StateBean

    • Scope: session

    The IDE generates the following tag:

    <jsp:useBean id="StateBean" scope="session" 
    	class="plotCity.StateBean" />

    This tag gives index.jsp access to the StateBean component.

  4. Replace the value attribute of the thisState tag with an EL expression that points to the states property of StateBean:

    value="${StateBean.states}"
  5. Replace the value element of the thisCity tag with an EL expression that points to the cities property of StateBean.

    value="${StateBean.cities}"
  6. Save the file.

  7. (Optional) Right-click the project node and select Run.

    Your browser should open and show the two comboboxes populated with the data your created. With the next set of tasks, you will add the event-handling mechanism so that you can select a city and plot it on the map.

Handling Events in the plotCity Application

This section details how you can use the publish/subscribe mechanism to handle events by performing the following tasks:

ProcedurePublishing to a Topic

After completing this task, thisState will subscribe to the /cb/getState topic.

  1. Open index.jsp in a source editor pane.

  2. Add a subscribe attribute to the thisState combobox and set it to the topic, /cb/getState:

    <a:widget  id="thisState"
    	name="dojo.combobox"
    	publish="/cb/getState"
    	value="${StateBean.states}" />
  3. Save index.jsp.

ProcedureWriting a Handler that Handles the Widget Event

After this task is complete, the plotCity application will be able to populate the thisCity combobox widget with new data when the user selects a state from the thisState widget.

  1. Open the glue.js file, located in plotCity/Web Pages, in the editor pane.

  2. At the end of the glue.js file, add the following subscribe function:

    jmaki.subscribe("/cb/getState/*", function(args) {
    	var message = args.value;
    	jmaki.doAjax({method: "POST",
    	url: "Service?message=" + encodeURIComponent(message),
    	callback: function(_req) {
    		var tmp = _req.responseText;
    		var obj = eval("(" + tmp + ")");
    		jmaki.publish('/cb/setValues', obj);
    		// handle any errors
    		}
    	});
    });

ProcedureWriting a Servlet to Obtain the Server-Side Data for the Handler

While performing the previous task, you added an Ajax call to the Service servlet to obtain the values from StateBean. You'll create the servlet with this task.

  1. Expand the plotCity > Source Packages > plotCity node.

  2. Right-click on the plotCity package icon and select New > Servlet.

  3. Enter Service for the class name.

  4. Click Finish.

  5. Delete everything inside the servlet class so that all that the file contains are the package statement, the import statements automatically generated, and the following empty servlet class:

    public class Service extends HTTPServlet{}
  6. Add the following private variable declaration:

    private ServletContext context;
  7. Add the following init method to the class:

    @Override
    public void init(ServletConfig config) 
    	throws ServletException {
    	this.context = config.getServletContext();
    }
  8. Add the following doPost method to the class:

    public void doPost(
    	HttpServletRequest request, HttpServletResponse response) 
    	throws IOException, ServletException {
    	HttpSession session = request.getSession();
    	StateBean stateBean = 
    		(StateBean)session.getAttribute("StateBean");
    	String cityData = new String();
    	String message = request.getParameter("message");
    	try{
    		cityData = stateBean.getNewCities(message);
    	} catch (Exception e){
    		System.out.println("could not get city data");
    	}
    	PrintWriter writer = response.getWriter();
    	writer.write(cityData);
    	session.setAttribute("stateBean", stateBean);
    }

    This method gets the message parameter from the request, passes it to getNewCities, and passes the resulting list of cities to the response.

  9. Save the file.

ProcedureSubscribe to a Topic

With this task, you will get thisCities to subscribe to the /cb/setValues topic so that it populates with the cities returned from StateBean.

  1. Expand the plotCity > Web Pages nodes.

  2. Open index.jsp in a editor pane.

  3. Add a subscribe attribute to the thisCity widget and give it the topic /cb/setValues, as shown here:

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

  5. (Optional) Run the example by right-clicking the project node and selecting Run.

    Now you can select a state and see the thisCity combobox populate with the names of cities located in that state. With the next task, you'll make it so the application will plot a city on the map when you select the city.

ProcedureAccessing an External Service from a Widget

  1. Expand the plotCity > Web Pages node.

  2. Open index.jsp in the editor pane.

  3. Add a publish attribute to the thisCity combobox widget and set it to /cities:

    <a:widget id="thisCity"
    	name="dojo.combobox"
    	publish="/cities"
    	subscribe="/cb"
    	value="${StateBean.cities}" />
  4. Expand the plotCity > Web Pages node.

  5. Open glue.js in a source editor.

  6. Add the following handler to the end of glue.js:

    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 );
    		}
    	}
    });
    });
  7. Save glue.js.

ProcedureDeploying and Running on the GlassFish v3 Technology Preview 2 Application Server

  1. Right-click on the plotCity project node.

  2. Select Properties.

  3. Select Run.

  4. Select GlassFish V3 TP2 from the Server combobox.

  5. Click OK.

  6. Right-click on the plotCity project node.

  7. Select Run project.