The Source for Java Technology Collaboration
User: Password:



Carol McDonald's Blog

Carol McDonald As a Java Technology Evangelist at Sun Microsystems, Carol McDonald has spoken at various conferences including JavaOne, Java University, Sun Tech Days, Sun Network, Sun Code Camps, JDJEdge, and JUGs including Machester, Boston, Maine, Cologne, FAA, Richmond, Memphis, D.C... Carol blogs about the latest technologies that she is speaking about at http://weblogs.java.net/blog/caroljmcdonald/. Before returning to Sun in 2007, Carol worked 2 1/2 yrs as an Architect on massive OLTP Spring/hibernate application to manage > 10 mill loans for the consumer credit division of a leading automoblile manufacturer and a leading bank. Before joining Sun the first time in 1999 Carol worked on Pharmaceutical Intranet applications for Roche in Switzerland, a Telecom Network Management Application for Digital (now HP) in France, a X.400 Email Server for IBM in Germany, and as a student intern for the National Security Agency. Carol holds a M.S. in Computer Science from the University of Tennessee, a B.S. in Geology from Vanderbilt University, and is a Sun Certified Java Architect and Java Language Programmer. Carol is also Fluent in French and German.



example using jMaki and RESTful Web Services

Posted by caroljmcdonald on July 18, 2008 at 04:02 PM | Permalink | Comments (0)

Sample Application using jMaki and the Java Persistence APIs

a Dynamic Ajax table example using jMaki and RESTful Web Services on Glassfish


This Sample Catalog app demonstrates a RESTful Web Service, coded using JAX-RS: Java API for RESTful Web Services (JSR-311) and Java Persistence API, which provides a list of customers, and a jMaki client which  gets and displays the Web Service responses in a dynamic Ajax table.

Download the jMaki Sample Application Code

jMaki is an Ajax framework that provides a lightweight model for creating JavaScript centric Ajax-enabled web applications. jMaki provides wrapped widgets that can be used as JavaServer Pages tags, as JavaServer Faces components, within a Phobos application, or with PHP. This sample applicaton uses jMaki with JavaServer Pages.

JAX-RS provides a standardized API for building RESTful web services in Java. Central to the RESTful architecture is the concept of resources identified by universal resource identifiers (URIs). The API  provides a set of annotations which you can add to Plain Old Java Objects (POJOs)  to expose web resources identified by URIs .

Explanation of the usage of jMaki and JAX-RS in a sample Catalog Application

The image below shows the Customer Listing page, which allows the user to page through a list of customers.

pagingtable.jpg

jMaki dataTable widget

With  jMaki and JavaServer Pages, you can easily include wrapped widgets from ajax toolkits into a JavaServer Page as a custom JSP tag. With the Netbeans jMaki plugin you can drag  jMaki widgets from the Palette into a JSP. jMaki standardizes widget data and event models to simplify the programming model and to simplify interactions between widgets.

The sample application's index.jsp page uses a jMaki yahoo.dataTable widget to display a  list of customers in a dynamic table.

The jMaki table widgets (there is also a jMaki dojo table widget) are useful when you want to show a set of results in tabular data on a web page.  Table widgets provide sortable columns, row selection, and they can be updated using jMaki publish subscribe events.

In the List.jsp web page the dataTable is defined as shown below:   (Note: Red colors are for jMaki tags or variables,  and Green for my code or variables)

Code Sample from:  index.jsp

<a:widget name="yahoo.dataTable"
          subscribe="/table"
          service="webresources/customers/jMakiTable"/>


To determine the data format and events for the table you can refer to the  jMaki Table Data Model or look at the widget.json file for the table widget. This file is located in the resources/yahoo/dataTable directory.

The service attribute references the customers/jMakiTable RESTful web service which returns the data to be included in the table.  The data for the table should be a JSON object containing an object of columns and an array of row arrays. The column names need a unique id which is then used in the data to associate it with a given row. An example for a table of companies is shown below:


Code Sample from:  widget.json
{
 'columns':[
     {'label' :'Company', 'id' : 'name'},
     {'label':'City', 'id' : 'city'},
     {'label':'City', 'id' : 'state'}
 ],
 'rows':[
     {'name' : 'Sun Microsystems', 'city' : 'Santa Clara',
'state' : 'CA'},
     {'name' : 'IBM', 'city' : 'Raleigh','state' : 'NC'}
 ]
}



The subscribe="/table" attribute specifies a topic that events can be sent to. Publish and subscribe events can be used to tie widgets together (more on this later).

RESTful  Web Services with JAX-RS


The dataTable's service attribute references the URI  webresources/customers/jMakiTable for the customers jMakiTable  RESTful web service.  The customers RESTful web service was generated using Netbeans 6.1 as explained in the Generating RESTful Web Services from Entity Classes  tutorial.  Using Netbeans 6.1 you can generate JPA Entity Classes from Database tables, then you can Generate RESTful Web Services from Entity Classes, and then you can test the Web Services with a browser interface. The customers RESTful web service was generated from the customer data table which comes already created in the Java DB with Netbeans.  I added the jMakiTable method to the generated customers Web Service,  in order to return the customers in the jMaki table format. I followed the jMakiBackend example which comes with Jersey (the JAX-RS reference implementation) which is expained in Japods blog:  jMaki Widgets Talking To Jersey Resources In JSON.


Below is a snippet from the CustomersResource.java class which was generated by the Netbeans "Generate RESTful Web Services from Entity Classes" feature :

Code Sample from: CustomersResource.java

// Service URI path "/customers/"

@Path("/customers/")

public class CustomersResource {
  
    @GET
    @ProduceMime("application/json")
    public
CustomersConverter get(@QueryParam("start")
            @DefaultValue("0") int start, @QueryParam("max")
            @DefaultValue("4") int max, @QueryParam("expandLevel")
            @DefaultValue("1") int expandLevel, @QueryParam("query")
            @DefaultValue("SELECT e FROM Customer e") String query) {
        try {
            CustomersConverter custs = new CustomersConverter(
                getEntities(start, max, query),
                context.getAbsolutePath(), expandLevel);
            return
custs;
        } finally {
            PersistenceService.getInstance().close();
        }
    }


The CustomersResource represents a list of customers. The CustomersResource  get method returns a list of Customer objects in JSON format. 
  • To address a resource in REST you specify its URI.  @Path is a JAX-RS annotation that identifies the URI path for the resource. For the CustomersResource  the URI path is /customers/.
  • @GET specifies that the get method supports the HTTP GET method.
  • @ProduceMime specifies the MIME types that a method can produce. Here, the annotation specifies that the get method returns a JSONArray object.  The CustomersConverter class is a JAXB annotated class which is used to marshal a list of Customer objects into XML or JSON format.   The getEntities method returns a list of Customer entity objects and is explained below.  
  • @QueryParam specifies input parameters for methods.  When the method is invoked, the input value will be injected into the corresponding input argument. 
  • @DefaultValue specifies a default value for an arguement if no input value is given.
Here is an example of an HTTP request for this Web Service:

Request: GET http://host/jMakiRest/webresources/customers/?start=0


Here is an example of an HTTP response for this Web Service:

Received:
{"customers":
  {"@uri":"http://host/jMakiRest/webresources/customers/",
   "customer":[
     {"@uri":"http://host/jMakiRest/webresources/customers/1/",
       "name":"JumboCom",
      "city":"Fort Lauderdale",     
       "state":"FL",
       "zip":"33015"},
     {"@uri":"http://host/jMakiRest/webresources/customers/2/",
       "name":"Livermore Enterprises",
       "city":"Miami",
       "state":"FL",
       "zip":"33055"}
    ]
  }
}


Below is the getTable method  from the CustomersResource.java class,  which returns a list of Customers in the jMaki  JSON table format.

Code Sample from: CustomersResource.java

public class CustomersResource {
     . . .
  
    @GET
    @Path("/jMakiTable")
    @ProduceMime("application/json")
    public CustomerTableModel getTable(@QueryParam("start")
            @DefaultValue("0") int start, @QueryParam("max")
            @DefaultValue("4") int max, @QueryParam("expandLevel")
            @DefaultValue("1") int expandLevel, @QueryParam("query")
            @DefaultValue("SELECT e FROM Customer e") String query) {

        CustomersConverter custs = get(start, max,
                   expandLevel, query);
        return new CustomerTableModel(custs.getCustomer());
    }


The getTable method calls the CustomersResource get method, explained above,  to get a list of Customer Entities which are used to create a CustomerTableModel class. The CustomerTableModel class is a JAXB annotated class, used to marshal a list of Customer objects into the jMaki  JSON table format.  A snippet of the CustomerTableModel class is shown below:


Code Sample from: CustomerTableModel.java

@XmlRootElement
public class CustomerTableModel {

    public static class JMakiTableHeader {

        public String id;
        public String label;

        public JMakiTableHeader(String id,
           String label) {
            this.id = id;
            this.label = label;
        }
    }
    public List<JMakiTableHeader> columns =
          initHeaders();
    public List<CustomerConverter> rows;
  
    . ..



Java Persistence Query API

The CustomersResource getEntities method uses the Java Persistence API Query object to return a list of customers.

Code Sample from: CustomersResource.java

@Path("/customers/")

public class CustomersResource {
  
    . . .

    protected Collection<Customer> getEntities(int start, int max, String query) {
       
PersistenceService ps = PersistenceService.getInstance();
        Query query = ps.
createQuery(query);
        query.
setFirstResult(start);
        query.setMaxResults(max);
        return query.getResultList();
    }

 

The Java Persistence Query APIs are used to create and execute queries that can return a list of results.  The JPA Query interface provides support for pagination via the setFirstResult() and setMaxResults() methods: query.setMaxResults(int maxResult) sets the maximum number of results to retrieve. query.setFirstResult(int startPosition) sets the position of the first result to retrieve.

In the code below, we show the Customer entity class which maps to the  CUSTOMER table that stores the customer instances. This is a typical Java Persistence entity object. There are two requirements for an entity:
  1. annotating the class with an @Entity annotation.
  2. annotating the primary key identifier with @Id
Because the fields name, description.... are basic mappings from the object fields to columns of the same name in the database table, they don't have to be annotated. 
For more information on Netbeans and JPA see basics of developing a web application using Java™ Persistence API.

Code Sample from: Customer.java

@Entity

public class Customer implements Serializable {

   
@Id  
    private Integer customerId;

    private String name;
    private String addressline1;   
    private String city;  
    private String state; 
    private String zip;

    
    public
Customer() { }
     
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }



}   


jMaki Publish Subscribe events 

jMaki publish subscribe events tie widgets actions together. The sample app uses two jMaki yahoo.button widgets which publish to the /button/previous, /button/next topics when the respective button is clicked:

Code Sample from: List.jsp

<a:widget name="yahoo.button" value="{label : '<<',
                 action : {topic : '/button/previous'}}" />

<a:widget name="yahoo.button" value="{label : '>>',
                 action : {topic : '/button/next'}}" />


Events in jMaki are handled by jMaki Glue , which allows JavaScript components to talk to each other. You put function listeners which Subscribe to topics that your widgets Publish to in a file called glue.js (to read more about this see A practical guide to jMaki Events ).

Connecting the listener to the handler
 
The listener handler for the  /button/next topic is shown below. First you declare the topic to listen to and then the listener function which will handle the notification. The /button/next listener handler  increments the page number and then calls the getNextPage funtion.

Code Sample from: glue.js
var page= 0;
var start= 0;
var batchSize=4;

jmaki.subscribe("/button/next", function(args) {
    page =page + 1;
    getNextPage(page);
});

jmaki.subscribe("/button/previous", function(args) {
    page =page - 1;
    if (page < 0) page = 0;
    getNextPage(page);
});

function getNextPage(page) {
    start = page * batchSize;
    jmaki.doAjax({method: "POST",
        url: "webresources/customers/?start="+encodeURIComponent(start),
        callback : function(req) {
            var respObj = eval('('+ req.responseText +')');
            var rows =  respObj.customers.customer;
            jmaki.publish("/table/clear", { });
            for(j=0;j<rows.length;j++) {
                var row = rows[j];
                jmaki.publish("/table/addRow",{
                    value: row
                });
            }
           
        }
    });    
}
       

The getNextPage function uses  jmaki.doAjax, which provides an easy way to make an  XMLHttpRequest, to call the /customers/ RESTful Web Service  passing the start index  as a URI parameter.  The  callback function uses  eval to convert the XMLHttpRequest response into a JSON object. Then  jmaki.publish is called to publish the returned customer JSON objects to the /table/addRow topic.

The yahoo.dataTable widget subscribes to the table topic.
Subscribe events allow you to manipulate a given instance of a widget. The event names are appended to the the subscribe topic name following a "/". For example  "/table/addRow" will call the yahoo.dataTable addRow function which will add the  payload value passed to the widget to the the table. This will cause the  returned customer JSON object to be displayed in the table on the html page.


Conclusion
This concludes the sample application which  demonstrates a RESTful Web Service, coded using JAX-RS: Java API for RESTful Web Services (JSR-311) , which provides a list of customers, and a  jMaki  client which  gets and displays the Web Service responses in a dynamic Ajax table.

Configuration of the Application for jMaki, JPA, Netbeans 6.1 and Glassfish V2

  • Download and install NetBeans 6.1 bundled with GlassFish V2
  • Alternatively you can  Download and install GlassFish V2 separately.
  • Download and install the jMaki plug-in in the NetBeans update center.

Open and Run the Sample code:

  1. Download the sample code and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/jmakiRest, where <sample_install_dir> is the directory where you installed the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\jmakiRest.

  2. Start the NetBeans IDE. Click Open Project in the File menu and select the jmakiRest directory you just unzipped.

  3. Build the project as follows:

    • Right click the jmakiRest node in the Projects window.
    • Select Clean and Build Project.

  4. Run the project as follows:

    • Right click the jmakiRest node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the opening page of the Sample Application (at http://localhost:8080/jmakiRest/).


If you want to create your own jMaki application:
  • check out Arun Gupta's blog and screencasts.

References:






Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL

Posted by caroljmcdonald on July 07, 2008 at 07:54 PM | Permalink | Comments (0)

grailsexample

Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL


I modified this Groovy and Grails  Catalog Sample application to use JPA entity java classes instead of  Groovy domain classes. I followed the steps in this InfoQ article Grails + EJB Domain Models Step-by-Step  and I was really surprised at how easy it was !

download Catalog sample code

Overview of the Technologies and Frameworks in the Sample Application

The Java Persistence API provides a POJO-based persistence model for Java EE and Java SE applications. It handles the details of how relational data is mapped to Java objects, and it standardizes Object/Relational (O/R) mapping.

Grails aims to bring the "coding by convention" paradigm to Groovy. It's an open-source web application framework that leverages the Groovy language and complements Java Web development.

Groovy is an agile and dynamic language for the Java Virtual Machine, it compiles to Java bytecode, and it combines popular features from languages such as Smalltalk, Python, and Ruby.

Grails is a Model-View-Controller based framework that simplifies the development of  web applications by reducing the need for configuration files and by generating a lot of the things needed in a database-backed Web application.

mvc.gif



The Sample Application

The sample application displays an online catalog of pets sold in a pet store. The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.

  listpet.jpg


The Model - JPA Entity Classes

The Model is your application's persistent business domain objects. A JPA Entity instance represents a row in a database table.  Item is an Entity class -- a typical Java Persistence entity object -- which maps to an ITEM table that stores the item instances.

The Item class has a many-to-one relationship with the Address class,  this is specified using the @ManyToOne annotation in the Item class and the @OneToMany(mappedBy = "address") annotation in the Address entity class shown below:


Code Sample from: model\Item.java
package model;

// import ....

@Entity
@Table(name = "item")
public class Item implements Serializable{
    @Id
    private Long id;
    private String name;
    private String description;
    private String imageurl;
    private String imagethumburl;
    private BigDecimal price;
    @ManyToOne(optional = false)
    @JoinColumn(name = "address_id")
    private Address address;

    // getters and setters ...
}
   


 
Code Sample from: model\Address.java
package model;

// import ....

@Entity
@Table(name = "address")

public class Address implements Serializable{
    @Id
    private Long id;
    private String street1;
    private String street2;
    private String city;
    private String state;
    private String zip;
    private BigDecimal latitude;
    private BigDecimal longitude;
    private BigInteger version;
    @OneToMany(mappedBy = "address")
    private Collection<Item> items ;
   
   
// getters and setters ...
 
}
   



classrel.gif

SQL  Sample for items table

CREATE TABLE item (
 id BIGINT NOT NULL,
 product_id BIGINT NOT NULL,
 name VARCHAR(30) NOT NULL,
 description VARCHAR(500) NOT NULL,
 imageurl VARCHAR(55),
 imagethumburl VARCHAR(55),
 price DECIMAL(14,2) NOT NULL,
 address_id BIGINT NOT NULL,
 primary key (id),
 foreign key (address_id) references address(id),
 foreign key (product_id) references product(id)
);
   



Using the Java Persistence API With Grails and MySQL

Entering the Grails command
> grails create-app catalog
creates a standard directory structure for a grails application named catalog.  After you have your directory structure , to use JPA entities with a grails application:
  1. copy your entity files into the application name\src\java directory,  in this case I copied the model.Item and the model.Address  java files into the catalog\src\java\model directory.
  2. copy the MySQL jdbc driver mysql-connector-java-5.1.6-bin.jar into the directory  catalog\lib .
  3. modify the DataSource.groovy file in the catalog\grails-app\conf directory to use MySQL as the data base and  the GrailsAnnotationConfiguration class to use the annotations in the JPA entities as shown below :


    Code Sample from: catalog\grails-app\conf\DataSource.groovy

    import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
    dataSource {
        configClass = GrailsAnnotationConfiguration.class
        pooled = false
        driverClassName = "com.mysql.jdbc.Driver"
        username = "root"
        password = ""
        dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
    }
    hibernate {
        cache.use_second_level_cache=true
        cache.use_query_cache=true
        cache.provider_class='org.hibernate.cache.EhCacheProvider'
    }
    // environment specific settings
    environments {
        development {
            dataSource {
                dbCreate = "update"
                url = "jdbc:mysql://localhost/petcatalog"
            }
        }
        test {
            dataSource {
                dbCreate = "update"
                url = "jdbc:mysql://localhost/petcatalog"
            }
        }
        production {
            dataSource {
                dbCreate = "update"
                url = "jdbc:mysql://localhost/petcatalog"
            }
        }
    }                       
       


  4. In order for Grails to recognize the JPA Entity classes as domain classes,  add the hibernate.cfg.xml file shown below to the catalog\grails-app\conf\hibernate directory:


    Code Sample from: catalog\grails-app\conf\hibernate\hibernate.cfg.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>
        <session-factory>
            <mapping package="model" />
            <mapping class="model.Item" />
            <mapping class="model.Address" />
        </session-factory>
    </hibernate-configuration>

The Controller

Entering the Grails command  (in the directory catalog)
> grails generate-controller model.Item
will generate the ItemController.groovy   class for the model.Item entity class.

Controllers handle incoming http requests, interact with the model to get data and to process requests,  invoke the correct view, and direct domain data to the view for display.  In Grails, http requests are handled by Controller classes which are made up of one or more action methods that are executed on request and then either render a Groovy Server Page or redirect to another action. Grails routes requests to the controller action which corresponds to the URL mapping for the request. In Grails the default mapping from URL to action method follows this convention: http://host/app/controller/action/id .  For example the URL http://host/catalog/item/list calls the list action method in the item controller class shown below.     Grails Scaffolding provides a series of standardized Controller action methods for listing, showing, creating, updating, and deleting objects of a class.  These standardized actions come with both controller logic and default view Groovy Server Pages. The ItemController list action renders a view with a paginated list of item objects.

Code Sample from: grails-app\controllers\ItemController.groovy

class ItemController {

 
def index = { redirect(action:list,params:params) }

  def list = {
    if(!params.max) params.max = 10
    [ itemList: Item.list( params ) ]
  }
. . .


When a URL has a controller but no action (e.g. http://localhost:8080/catalog/item/  ), Grails defaults to the index action. In the ItemController code the  index action method redirects to the list action.  The ItemController list action method calls the Item.list() method which returns an ArrayList of item objects retrieved from the item database table . If there are more than params.max objects in the table, Grails creates next and previous pagination links automatically. The itemList variable  is automatically made available to the view by the framework.

After executing code, actions usually render a GSP in the views directory corresponding to the name of the controller and action, for example the list action will render the grails-app\views\item\list.gsp .

The View

Entering the Grails command  (in the directory catalog)
> grails generate-views model.Item
will generate the create.gsp , edit.gsp, list.gsp, show.gsp  groovy server pages for the model.Item entity class.
The view layer generates a web page, using data from domain objects provided by the controller. In Grails, the view is rendered using Groovy Server Pages. Below is part of the list.gsp for the Catalog application (note I modified the html table format from the default generated).


Code Sample from: grails-app\views\item\list.gsp

<table>
   <thead>
     <tr>
        <g:sortableColumn property="name" title="Name" />
        <g:sortableColumn property="imagethumburl" title="Photo" />
        <g:sortableColumn property="price" title="Price" />
     </tr>
   </thead>
   <tbody>
     <g:each in="${itemList}" status="i" var="item">
        <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
           <td>
             <g:link action="show" id="${item.id}">
                ${item.name?.encodeAsHTML()}</g:link>
           </td>
           <td>
             <img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
           </td>
           <td>${item.price?.encodeAsHTML()}</td>
        </tr>
     </g:each>
  </tbody>
 </table>

<div class="paginateButtons">
 <g:paginate total="${Item.count()}" />
</div>


The view uses instance variables set by the controller to access the data it needs to render the GSP.

GSP has a GroovyTagLib similar to the  JSP tag library. <g: are GroovyTags.
  

<g:sortableColumn
       The sortableColumn tag renders a sortable column to support sorting in tables.

<g:each in="${itemList}" status="i" var="item">
loops through each object in the itemList variable, which is an ordered ArrayList of Item model objects,  and assigns each Item model object to the item variable.
 
<g:link action="show" id="${item.id}">${item.name?.encodeAsHTML()}</g:link> 
the <g:link> GroovyTag creates an html anchor tag href based on the action, id, controller parameters specified. In this example it generates a link to the item/show/id action which when clicked will display the corresponding item details. For example this line will generate the following HTML for the variable item:
<a href="/catalog/item/show/2">Friendly Cat</a>
<img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/> 
The createLinkTo tag generates an HTML link for the item's imagethumburl attribute. 

${item.price?.encodeAsHTML()}
displays the value of the  item 's price attribute as escaped HTML text.

<g:paginate total="${Item.count()}" />
The paginate tag creates next/previous buttons and a breadcrumb trail to allow pagination of results using the Item.count() domain method.

The Show Action Method

In Grails the mapping for the URL http://host/item/show/1  ( http://host/controller/action/id )  will route to the show action in the ItemController passing 1 to the method as the id of the params parameter hash. The show action of the ItemController class is shown below. The ItemController show action renders a view showing the details of the item object corresponding to the id parameter.

Code Sample from: grails-app\controllers\ItemController.groovy

 def show = {
   def item = Item.get( params.id )

   if(!item) {
      flash.message = "Item not found with id ${params.id}"
      redirect(action:list)
   }
   else { return [ item : item ] }
 }



The show action method  calls the Item.get() method which queries the items table returning the item instance variable corresponding to the item with the attribute id (primary key) equal to the  id parameter. This is the equivalent of the following sql : select * from items where id='1' . The item variable is automatically made available to the Show view by the framework.

The Show View GSP

After executing code in the action, the show action renders the app/views/item/show.gsp . Below is the GSP for the item show view :


Code Sample from: grails-app\views\item\show.gsp

<h2> Detail of item</h2>

<table>
<tbody>
    <tr class="prop">
      <td valign="top" class="name">Name:</td>                          
      <td valign="top" class="value">${item.name}</td>                          
    </tr>                   
    <tr class="prop">
        <td valign="top" class="name">
           Description:
        </td>                           
        <td valign="top" class="value">
           ${item.description}
        </td>                          
    </tr>                       
    <tr class="prop">
        <td valign="top" class="name">Imageurl:</td>                          
        <td valign="top" class="value">
            <img src="${createLinkTo(dir:'images',file:item.imageurl)}" />
        </td>                           
    </tr>                                           
    <tr class="prop">
        <td valign="top" class="name">Price:</td>                           
        <td valign="top" class="value">$ ${item.price}</td>                           
    </tr>
    <tr class="prop">
        <td valign="top" class="name">Address:</td>                           
        <td valign="top" class="value">
          ${item?.address?.street1}, ${item?.address?.city},    
          ${item?.address?.state}
        </td>                          
    </tr>                       
</tbody>
</table>  



${item.description}
displays the value of the  item 's description attribute.
<img src="${createLinkTo(dir:'images',file:item.imageurl)}" /> 
generates an HTML image tag for the item's imageurl attribute.
${item?.address?.city}
displays the value of the  item's address city attribute.

The image below shows the resulting page for the url http://host/catalog/item/show/105, which displays the item 105's details:

     showpet.jpg

Layouts

Grails layouts  let you put common html on multiple views (for example page headers,  footers, sidebars).  Default layout templates are in the views layouts directory with a file name corresponding to the controller, or you can associate a view with a layout using the "layout" meta tag to your page:
<meta name="layout" content="main">
To add a title and parrot image to the top of the Pet Catalog pages, I put this table in the app\views\layouts\main.gsp  layout:

Code Sample from: app/views/layouts/main.gsp

<table>
  <tr>
   <td>Pet Catalog</td>
   <td>
     <img src="${createLinkTo(dir:'images',file:'pet_logo.jpg')}"/>
   </td>
 </tr>
</table>




Conclusion
This concludes the sample application which demonstrates how to work with Groovy and Grails  to page through a list of  Item JPA Entities which are retrieved using Item Controller action methods, and displayed using Item View GSPs.

Setting Things Up and Running the Sample code on MySQL and Jetty:

  1. If MySQL is already installed, then download GlassFish v2 UR1. Otherwise you can also Download GlassFish v2 UR1 and MySQL co-bundle from the usual Download Page (instructions).

  2. Download and install Grails.

  3. Download the sample code and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/Catalog, where <sample_install_dir> is the directory where you unzipped the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\Catalog
    The file  "/Catalog/grails-app/conf/DataSource.groovy" is configured for a MySQL configuration.

  4. Start the MySQL database as follows:

    • > mysqld_safe --user root --console

  5. Create the pet-catalog database:

    • > mysqladmin create petcatalog --user root

  6. Create the tables in the MySQL pet-catalog database as follows:

    • shell> mysql pet-catalog < catalog.sql
    • using the file catalog.sql file from the /Catalog directory.

  7. Run the project as follows:
    in a command window in the /Catalog directory enter the command
  8. > grails run-app
    This will run the Application using the built-in Jetty Servlet engine.
When you run the project, your browser should display the Catalog home page at http://localhost:8080/catalog/ .


Run the Sample code on Glassfish:
  1. Use the  WAR file in <sample_install_dir>/Catalog/Catalog.war or Create a WAR file:
    • > grails war
  2. Copy the WAR file (catalog-0.1.war) to  your Glassfish installation "domains/domain/autodeploy" directory. (Start Glassfish and MySQL if you haven't already)

  3. Enter the URL  http://localhost:8080/catalog-0.1/  in your browser, you should see the home page of the Sample Application.

For more information:




Comet Slideshow example on Grizzly

Posted by caroljmcdonald on July 01, 2008 at 02:37 PM | Permalink | Comments (0)

Comet Slideshow example on Grizzly


A Comet Slideshow example using dojo, Comet, Bayeux, on Grizzly with Glassfish

ajax comet bayeux    grizzly    glassfish 
This Sample Slideshow app demonstrates the usage of the dojo Ajax framework, Comet, Bayeux, with Grizzly and Glassfish.

Download the dojo Comet Sample Application Code

dojo  is an open source DHTML toolkit written in JavaScript. It includes many utilities that go beyond Ajax, for example the dojox.comet module simplifies programming comet applications. Comet is a term coined by Alex Russell  to describe applications where the Server pushes data to the client.  For example in the diagram below on the left you see  Ajax polling which uses synchronous requests/responses to get events from the server. Comet  uses long-lived previously-opened HTTP connections to "push" data to the client at any time, not only in response to user input.

comet http
Grizzly is an HTTP framework which uses the Java™ NIO API to provide fast HTTP processing . Grizzly provides Comet (long-lived streaming HTTP connections) support built on top of Grizzly's Asynchronous Request Processing (ARP).  With Grizzly ARP,  each Comet request isn't holding onto a thread which gives scalability.   Bayeux is a protocol for routing JSON encoded events between clients and servers in a publish subscribe model.  Grizzly provides an implementation of Bayeux, which makes it really easy to build Comet applications with dojo, you just configure Glassfish for Comet and configure your Web Application's web.xml for the Grizzly  Bayeux servlet  then you can use the dojox cometd publish and subscribe methods to send and receive Comet events as described in more detail below. 




Grizzly comes with Glassfish , or it can be used separately. To use Comet with Glassfish you just need to add the bold red line to the Glassfish config  domain.xml:
Code Sample from:  index.html
<http-listener acceptor-threads="1" address="0.0.0.0" 
blocking-enabled="false" default-virtual-server="server"
enabled="true" family="inet" id="http-listener-1" port="8080"
security-enabled="false" server-name="" xpowered-by="true">
<property name="cometSupport" value="true"/>
</http-listener>

Enabling Bayeux in GlassFish

to enable Bayeux on Glassfish, add the following to your Web application web.xml :

Code Sample from:  index.html

<servlet>
<servlet-name>Grizzly Cometd Servlet</servlet-name>
<servlet-class>
com.sun.grizzly.cometd.servlet.CometdServlet
</servlet-class>
<init-param>
<description>
expirationDelay is the long delay before a request is
resumed. -1 means never.
</description>
<param-name>expirationDelay</param-name>
<param-value>-1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Grizzly Cometd Servlet</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>

Package your war and deploy it on Glassfish,  then every request sent to your war's context-path/cometd/ will be serviced by the Grizzly Bayeux runtime.

Explanation of the usage of dojox cometd in the sample Slideshow Application

I modified the comet chat example from here (originally written by Greg Wilkins), to share a slideshow presentation among all subscribed clients. The image below shows the Comet Slideshow page, which allows the users to share a Slideshow and chat at the same time.





Quick installation and use of dojo with Netbeans

There are 3 ways to install dojo which you can read about at in the book of dojo. A quick and easy way to use dojo with Netbeans is to download the JavaScript libraries from http://dojotoolkit.org/downloads.   Create a new NetBeans Web Applications project. Extract the dojo toolkit  into the project web directory: .../web , then rename dojo-release-1.1.1/ to src/  this will give you the project structure shown below.  I have already done this for the sample project so you do not have to download dojo in order to run the sample.

Loading base dojo and required modules into an application

In order to load dojo into your application,  put the relative path to the dojo.js file in a script element in the head section of your  HTML page as shown below:

Code Sample from:  index.html

<script type="text/javascript" src="src/dojo/dojo.js"></script>
<script type="text/javascript" src="chat.js"></script>



This script element will load the base dojo script which gives you access to all the dojo functionality. The rest of the Java Script for this application is in the file chat.js.

Next in chat.js the application specifies which  dojo modules to load, using  the dojo.require function (kind of like  import in Java):

Code Sample from:  chat.js

dojo.require("dojox.cometd");



Dojo is organized into three major layers: Dojo Core, Dijit, and DojoX.   DojoX builds on  Dojo Core and provides newer extensions to the Dojo toolkit. DojoX cometd  implements a Bayeux protocol client for use with a Bayeux server.

Initializing a connection between the dojo client and the Grizzly BayeuxServlet

When a user first loads the slideshow application, he can enter a username and join a slideshow session.



When a user clicks on the Join button, the join javascript function is called.  In the join function, the call to dojox.cometd.init initialises a connection to the given Comet server, in this case with the Glassfish Grizzly Bayeux servlet (note /cometd/*  is the url-pattern for the Grizzly Cometd Servlet configured in the web.xml for the application).

Code Sample from:  chat.js
var room = {
 ...
 join: function(name){
  
   dojox.cometd.init(
"/cometd");
   dojox.cometd.subscribe("/chat/demo", room, "_chat");
   dojox.cometd.publish("/chat/demo",
      { user: room._username,
        join: true, chat : room._username+" has joined"});
 }


The dojox.cometd.subscribe line subscribes the _chat callback function to the /chat/demo channel. Any time a message is sent to the  /chat/demo channel the _chat function will be called.
The dojox.cometd.publish line publishes the message that the user  (the name that was entered with the join button) has joined the /chat/demo channel. Subscribers   to the /chat/demo channel will get this message.

Publishing the next slide for the Comet Slideshow

When the user clicks on the "Next Slide" button shown below,  a javascript funtion is called which publishes the url for the next slide.



Code Sample from:  index.html
<input id="previousB" class="button" type="submit" name="previous" value="Previous Slide"/> 
<input id="nextB" class="button" type="submit" name="next" value="Next Slide"/>



When the user clicks on the Next Slide button, the  javascript function shown below is called. This function calls room.next passing the url for the next slide. The function then increments the index for the next slide. The urls for the slides are stored in the slideUrls array shown below. 

Code Sample from:  widget.json
var room = {
...
  _init: function(){

    var slideUrls=[
            "/dojoComet/images/image0.jpg",
            "/dojoComet/images/image1.jpg",
            "/dojoComet/images/image2.jpg",
            "/dojoComet/images/image3.jpg",
            "/dojoComet/images/image4.jpg",
            "/dojoComet/images/image5.jpg"];
    var i=0;

   
element=dojo.byId('nextB');
    element.onclick = function(){
       room.next( slideUrls[i]);
       if (i>=
slideUrls.length){i=0;}
       else {i++;}
    }

    element=dojo.byId('previousB');
    element.onclick = function(){
       room.next( slideUrls[i]);
       if (i<=0){i=0;}
       else {i--;}
    }

  }
...


The function  room.next, shown below, calls dojox.cometd.publish to publish the next slide url (input argument)  to the /chat/demo channel. Subscribers   to the /chat/demo channel will get this message.


Code Sample from:   chat.js
var room = {
    ...

    next: function(text){
        dojox.cometd.publish("/chat/demo", {slide: text});
    }
    ...
}


When a message is published to a Bayeux channel on the server,  it is delivered to all clients subscribed to that channel,  in this case to the  "/chat/demo" channel . In the  room.join function shown before dojox.cometd.subscribe("/chat/demo", room, "_chat") was called  to subscribe the _chat callback function to the /chat/demo channel.   The _chat callback function, shown below,  is called  with the published message as an input argument.  The _chat callback function  updates the browser page by setting the slide dom element innerHTML to an html img tag with the slide url from the published message "<img src='" + slideUrl + "'/>" . This updates the browser page with the image corresponding to the slide URL which was published.

Code Sample from: chat.js 
var room = {
    ...
    _chat: function(message){
        var slide=dojo.byId('slide');
        var slideUrl=message.data.slide;
        slide.innerHTML ="<img src='" + slideUrl + "'/>";
    ...
}



Conclusion
This concludes the sample application which demonstrates the usage of the dojo Ajax framework, Comet, Bayeux, with Grizzly and Glassfish.

Running the Sample Code

The sample code  is available as a NetBeans project. You can build and run the sample code using the NetBeans IDE.

Setting Things Up

  • Download and install NetBeans 6.1 bundled with GlassFish V2
  • Alternatively you can  Download and install GlassFish V2 separately.
  • To use Comet with Glassfish you just need to add the bold red line to the Glassfish config  domain.xml (in the directory glassfish/domains/domain1/config ):
    Code Sample from:  index.html
    <http-listener acceptor-threads="1" address="0.0.0.0" 
    blocking-enabled="false" default-virtual-server="server"
    enabled="true" family="inet" id="http-listener-1" port="8080"
    security-enabled="false" server-name="" xpowered-by="true">
    <property name="cometSupport" value="true"/>
    </http-listener>
  • Bayeux and dojo are already configured in the sample code.

Open and Run the Sample code:

  1. Download the sample code and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/dojoComet, where <sample_install_dir> is the directory where you unzipped the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\dojoComet.

  2. Start the NetBeans IDE. Click Open Project in the File menu and select the dojoComet directory you just unzipped.

  3. Build the project as follows:

    • Right click the dojoComet node in the Projects window.
    • Select Clean and Build Project.

  4. Run the project as follows:

    • Right click the dojoComet node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the opening page of the Sample Application (at http://localhost:8080/dojoComet/). Open another browser and set that url to http://localhost:8080/dojoComet/  then enter a name and click on the join button in both browser windows.   Then click on the next slide button in one browser window.  Both browsers should get updated with the next slide.  

For more Information:






jMaki Presentation slides and Sample code

Posted by caroljmcdonald on June 06, 2008 at 04:26 PM | Permalink | Comments (2)

jMaki Presentation slides and Sample code

jMaki is a lightweight framework for creating Web 2.0 applications using standards-based technologies such as CSS, HTML, and JavaScript. I have updated the Sun Tech Days  jMaki presentation I am giving in Manilla with explanatory notes for the slides.  I have also updated the Dynamic Ajax table example using jMaki and Java Persistence APIs on Glassfish on my blog. Download the presentation and sample code.
Deploy the sample code as described in the blog, try out the example, look at the code, read the slides, learn about the jMaki framework.



Sample Store Catalog using using Groovy and Grails

Posted by caroljmcdonald on April 28, 2008 at 07:35 PM | Permalink | Comments (3)

grailsexample

Sample Store Catalog using using Groovy and Grails



This Catalog Sample app demonstrates the usage of Groovy and Grails to implement pagination of data sets for a Store Catalog.
download Catalog sample code

Overview of the Technologies and Frameworks in the Sample Application

Grails aims to bring the "coding by convention" paradigm to Groovy. It's an open-source web application framework that leverages the Groovy language and complements Java Web development.

Groovy is an agile and dynamic language for the Java Virtual Machine, it compiles to Java bytecode, and it combines popular features from languages such as Smalltalk, Python, and Ruby.

Grails is a Model-View-Controller based framework that simplifies the development of  web applications by reducing the need for configuration files and by generating a lot of the things needed in a database-backed Web application.

mvc.gif



The Sample Application

The sample application displays an online catalog of pets sold in a pet store. The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.

  listpet.jpg


The Model - Grails Domain Classes

The Model is your application's persistent business domain objects. A Grails domain object instance represents a row in a database table.  The command grails create-domain-class Item generates the Item.groovy class shown below corresponding to the item table.

After model code generation you have to add the domain object's attributes and relationships. The Item class has a many-to-one relationship with the Address class. In Grails hasMany is the many end of a many-to-one  relationship.


Code Sample from: domain\Item.groovy

class Item {
  Long id
  String name
  String description
  String imageurl
  String imagethumburl
  BigDecimal price
  Address address
}
   


 
Code Sample from: domain\Address.groovy

class Address {
  Long id
  String street1
  String street2
  String city
  String state
  String zip
  float latitude
  float longitude
  static hasMany = [item:Item]
}
   



classrel.gif

SQL  Sample for items table

CREATE TABLE item (
 id BIGINT NOT NULL,
 product_id BIGINT NOT NULL,
 name VARCHAR(30) NOT NULL,
 description VARCHAR(500) NOT NULL,
 imageurl VARCHAR(55),
 imagethumburl VARCHAR(55),
 price DECIMAL(14,2) NOT NULL,
 address_id BIGINT NOT NULL,
 primary key (id),
 foreign key (address_id) references address(id),
 foreign key (product_id) references product(id)
);
   


Groovy with Grails dynamically generates getters and setters and the dynamic methods Item.save(), Item.delete(),  Item.list(), Item.get() to retrieve/update data from/to the db table.

Grails Object Relational Mapping (GORM) is currently built on top of Hibernate but you don't have to know Hibernate to use it ( Grails  1.1 will support  the Java Persistence API) .


The Controller

Controllers handle incoming http requests, interact with the model to get data and to process requests,  invoke the correct view, and direct domain data to the view for display.  In Grails, http requests are handled by Controller classes which are made up of one or more action methods that are executed on request and then either render a Groovy Server Page or redirect to another action. Grails routes requests to the controller action which corresponds to the URL mapping for the request. In Grails the default mapping from URL to action method follows this convention: http://host/app/controller/action/id .  For example the URL http://host/catalog/item/list calls the list