Wednesday Jul 01, 2009

2 JavaOne Hands On Labs , Sun Technology Exchange, Java Technology Day Israel, and Java Day Turkey

jax

June: 2 JavaOne Hands On Labs , Sun Technology Exchange, Java Technology Day Israel, and Java Day Turkey  

I had a very busy June, I gave two Hands on Labs at JavaOne, two sessions at the Sun Technology Exchange, three sessions at Java Technology Day in Tel Aviv Israel, and one session at Java Day in Istanbul Turkey.

JavaOne Hands On Labs:

iguana.jpg iguana.jpg

I co-developed and delivered 2 Hands On Labs for JavaOne this year:

You can download these 2 HOLs documentation and code below:


Sun Technology Exchange:

iguana.jpg iguana.jpg
In Fort Lauderdale as part of the Sun Technology Exchange I gave two educational sessions to learn how:
  • JavaFX can help you build rich internet applications (RIAs) and includes the tools and platform SDK for developers, web developers, and designers to create dynamic applications.
  • GlassFish, an enterprise-quality Java EE 5 application server, offers advanced clustering, centralized administration, and best-in-class performance.
  • download the slides


Java Technology Day Israel

iguana.jpg iguana.jpgiguana.jpg
At the Java Technology Day in Israel I gave the following sessions:
  • WSIT Reliability Security and Transactions in Web Services
    • Metro is a high-performance, extensible, easy-to-use web service stack. You can use it for every type of web service, from simple to reliable, secured, and transacted web services that interoperate with .NET services. Metro bundles stable versions of the JAX-WS (Java API for XML Web Services) reference implementation and WSIT (Web Services Interoperability Technology). JAX-WS is a fundamental technology for developing SOAP-based and RESTful Java technology-based web services. WSIT enables secure, reliable interoperability between Java technology-based web services and Microsoft's Windows Communication Foundation.
    • you can download and try out WSIT in this JavaOne HOL: Metro: Try Out Simple and Interoperable Web Services and with these lab instructions.
    • You can read more about some of the example code for this session at
      GlassFish and MySQL, Part 3: Creating a Pet Catalog Web Service
  • MySQL for Developers
    • If you are a developer using MySQL, you should learn enough to take advantage of its strengths, because having an understanding of the database can help you develop better-performing applications. This session talks about MySQL database design and SQL tuning for developers.
    • download or view a screencast of this presentation
  • OpenESB and Connecting Enterprises
    • This session  explains and demonstrates several concrete technologies that make SOA architecture possible - BPEL (Business Process Execution Language), JBI (Java Business Integration) and OpenESB. The part of of BPEL starts with an explanation of the requirements of standardized business process language. The BPEL language is then described using an example. The relationship between BPEL and WSDL is also explained. Finally, BPEL designer and runtime that comes with NetBeans IDE is demonstrated using Travel reservation sample BPEL project. It also explains the motivation of the JBI and OpenESB as a standardized application integration framework in the same way J2EE architecture standardized how enterprise applications are built and deployed. Finally Sun's solution in SOA and application integration space is discussed. Whenever possible, concrete steps of building, deploying and testing SOA applications will be demonstrated step by step.
  • download the slides for all 3

Java Day Turkey

iguana.jpg iguana.jpg iguana.jpg
At the Java Day in Istanbul Turkey I gave the MySQL for Developers session again, see above for more information.




Friday May 01, 2009

Preview of 2 Hands On Labs I am working on for JavaOne


I'm Speaking At JavaOne

I'm working on 2 Hands On Labs for JavaOne this year:
  • Building RIA Dojo and JavaFX™ Pet Catalog Clients for MySQL™ backed RESTful Web Services
  • Developing Real-Time Revolutionary Web Applications, Using Comet and Ajax
You can read the HOL details and download some preview documentation and code below:
  • Session ID:       LAB-6771
  • Session Title:     Building RIA Dojo and JavaFX™ Pet Catalog Clients for MySQL™ backed RESTful Web Services
  • Session Abstract:
    • The goal of the Java™ API for RESTful Web Services (JAX-RS) is to provide a high-level declarative programming model for such services that is easy to use and encourages development according to REST tenets. Services built with this API are deployable with a variety of Web container technologies and benefit from built-in support for best-practice HTTP usage patterns and conventions.
      This Hands-on Lab provides an overview of the JAX-RS API and walks developers through the design process for a sample RESTful service.
      Dojo is an open-source DHTML toolkit written in the JavaScript™ programming language. The new JavaFX™ platform brings rich Internet applications to all the screens of your life.
      In the lab, participants will use the NetBeans™ IDE to rapidly develop JAX-RS, Dojo, and JavaFX applications and then deploy them on the GlassFish™ application server, with Java DB or the MySQL™ database.
  • Speakers:       Carol McDonald, Sun Microsystems, Inc.; Sridhar Reddy, Consultant

You can read more about some of the example code for this HOL at
GlassFish and MySQL, Part 4: Creating a RESTful Web Service and JavaFX Client

You can download a preview (some of the slides, docs, code) for this HOL at
Preview subset of slides, doc, code, for Building RIA Dojo and JavaFX™ Pet Catalog Clients for MySQL™ backed RESTful Web Services

  • Session ID:       LAB-5558
  • Session Title:     Developing Real-Time Revolutionary Web Applications, Using Comet and Ajax
  • Session Abstract:  
    • Join the asynchronous Web revolution! Emerging Ajax techniques -- variously called Ajax Push, Comet, and HTTP streaming -- are bringing revolutionary changes to Web application interactivity, moving the Web into the Participation Age. Because Ajax-based applications are almost becoming the de facto technology for designing Web-based applications, it is more and more important that such applications react on the fly, or in real time, to both client and server events. Aajx can be used to enable the browser to request information from the Web server but does not allow a server to push updates to a browser. Comet solves this problem. It is a technology that enables Web clients and Web servers to communicate asynchronously, enabling real-time operations and functions previously unheard of with traditional Web applications to approach the capabilities of desktop applications.
  • Speakers:       Justin Bolter, Sun Microsystems, Inc.; Doris Chen, Sun Microsystems, Inc.; Carol McDonald, Sun Microsystems, Inc.


You can read more about some of the example code for this HOL at
RESTful Web Services and Comet
You can download a preview (some of the slides, docs, code) for this HOL at
Preview subset of slides, doc, code, for Developing Real-Time Revolutionary Web Applications, Using Comet and Ajax

Duke



Thursday Apr 16, 2009

Developing RESTful Web Services with JAX-RS, Netbeans, Glassfish and MySQL

Developing RESTful Web Services with JAX-RS, Netbeans, Glassfish and MySQL

Yesterday I gave a talk at a the Jacksonville Java Users Group (JAXJUG) on Developing RESTful Web Services with JAX-RS, Netbeans, Glassfish, and MySQL.
Jacksonville-Beach-Ocean-View.jpg


You can dowload the StarOffice presentation here

Developing RESTful Web Services with Netbeans and JAX-RS


Content:
Lightweight RESTful approaches have emerged as a popular alternative to SOAP-based technologies for deployment of services on the Internet.

The goal of the Java API for RESTful Web Services (JAX-RS) is to provide a high-level declarative programming model for such services that is easy to use and encourages development according to REST tenets. Services built with this API are deployable with a variety of Web container technologies and benefit from built-in support for best-practice HTTP usage patterns and conventions.

This talk will provides an overview of the design process for a sample RESTful Pet Catalog service using JAX-RS. It shows how to build 2 sample clients for the Pet Catalog service one using the dojo AJAX framework and one using JavaFX.


You can get more information here:

Here is a link to the PDF slides and recorded Webinar
Developing MySQL-Backed RESTful Web Services with Netbeans and JAX-RS

Here is a link to the Article
GlassFish and MySQL, Part 4: Creating a RESTful Web Service and JavaFX Client

Here is a link to the JavaFX code
RESTful Web Service and JavaFX client code

Here is a link to dojo client explanation and code
RESTful Web Service and dojo client explanation and code





Wednesday Mar 25, 2009

Developing MySQL-Backed Applications with Netbeans and Java RESTful Web Services

Yesterday I gave a webinar which talked about how to leverage the latest version of the Netbeans IDE to develop RESTful Web Services and clients deployed on Glassfish with MySQL. The talk gave an overview of the design process for a sample RESTful Pet Catalog service using JAX-R, and discussed how to build 3 sample clients for the Pet Catalog service,  one using the Dojo AJAX framework , one using Comet and one using JavaFX.

You can download the presentation  here:
Developing MySQL-Backed Applications with Netbeans and Java RESTful Web Services

you can watch  a 7 minute screencast on how to build a RESTful Pet Catalog using JAX-RS and dojo here

RESTful Pet Catalog screencast

You can read more about the example RESTful web service and the JavaFX client for the RESTful web service here:

Glassfish and MySQL part 4

You can read more about the Comet client for the RESTful web service here:
RESTful Web Services and Comet

You can read more about the dojo client for the RESTful web service here:
a RESTful Pet Catalog

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

Dojo – An open-source DHTML toolkit written in JavaScript. The Dojo Toolkit includes many utilities that go beyond Ajax. For example, the dojox.comet module simplifies programming Comet applications.

Comet – Techniques that enable a server to push data to client browsers through an HTTP open line of communication.

Tuesday Mar 10, 2009

Glassfish, MySQL, REST, and JavaFX

This is the fourth article in a series of articles on GlassFish and MySQL.
In Part 4, you'll learn how to create a RESTful web service for the web
application. You'll also examine a JavaFX client for the RESTful web service. As
was the case for Part 3, the web service discussed in Part 4 uses GlassFish,
MySQL, and the Java Persistence API.

Glassfish and MySQL part 4

Saturday Feb 07, 2009

Pet Catalog : JavaFX Example Application


Pet Catalog Photos : JavaFX Example Application

Pet Catalog Photos is a simple JavaFX application that displays pet photos retrieved from a RESTful Pet Catalog app (implemented using JAX-RS) described in an earlier blog entry and in this screencast.  This JavaFX example is a modification of the Interesting Photos : JavaFX Example Application.

catalogclient.jpg


Understanding the Code


Code Sample from: main.fx

// Application User Interface
def stage = Stage {
    title: "Pet Catalog"
    resizable: false
    x: bind stageX with inverse
    y: bind stageY with inverse
    width: stageWidth
    height: stageHeight
    visible: true
    style: StageStyle.TRANSPARENT
    scene: Scene {
        content: Group {
            content: bind stageContent
            clip: Rectangle {
                width: stageWidth
                height: stageHeight
                arcWidth: 20
                arcHeight: 20
            }
        }
        fill: Color.TRANSPARENT
    }
}


Stage is the  top level container window required to display any visible JavaFX objects. The variables title, width and height define the the text that appears on the window's top border and its height and width.
The scene variable defines an instance of the Scene object literal, which sets the area in which you can place the JavaFX objects.
Scene is a drawing surface for graphical content and a container that holds the scene graph nodes. It can be added to Stage, and JavaFX renders everything on a scene.
The scene instance variable has a content variable that is used to hold JavaFX graphical elements and defines the graphical content of the application. Here the content consists of a Group Node . The Group Node has a  content variable which is a sequence of child Nodes that will be rendered in order whenever this Group is rendered. The Group Node has a clip variable which specifies a Rectangle which defines the the clipping shape for this Group Node.

stage5_1_1_1.JPG

The Group Node content variable has a data binding  with stageContent.  Data binding allows creating a direct and immediate relationship between two variables or between a variable and the outcome of a function or an expression.   stageContent  is a sequence of Nodes as shown in the code below.  Node - is an element in a scene graph. The following visual objects are examples of javafx.scene.Node implementations: javafx.scene.image.ImageView, javafx.scene.media.Mediaview, javafx.ext.swing.\*, javafx.scene.shape.\*, and javafx.scene.text.Text. These are leaf nodes, which cannot have a child element.

Code Sample from: main.fx

// Application User Interface
var stageContent: Node[];

stageContent = [
        bgImage, titleBar, nextButton, backButton, closeButton,
        titleText, statusText, thumbImageViewGroup, fullImageView
];

stage4.gif
A grid of ImageView is added to Scene of Stage.

The thumbImageViewGroup variable has a data binding  with thumbImageViews which is a sequence of ThumbImageView which extends ImageView. ImageView is a Node used for painting images loaded with Image class.  The code below shows how the  thumbImageViews sequence is initialized to a  grid of  3 columns and 3 rows of  ThumbImageView .

Code Sample from:  main.fx

var thumbImageViews: ThumbImageView[]; // Thumbnail images
for(col in [0..2]) {
    for(row in [0..2]) {
        def thumbImageView = ThumbImageView {
            x: thumbBaseX + (col \* (thumbSize + thumbSpace))
            y: thumbBaseY + (row \* (thumbSize + thumbSpace))
            fitWidth: thumbSize
            fitHeight: thumbSize
        }
        insert thumbImageView into thumbImageViews;
    }
}
var thumbImageViewGroup = Group {
    content: bind thumbImageViews
}


calling the RESTful  Pet Catalog Web Service 


Information and URLs for pet photos is obtained by performing an HTTP GET request on a RESTful Catalog service by using the JavaFX asynchronous HTTP API (javafx.io.http.HttpRequest).  HttpRequest allows one to specify a location and method and start a HTTP operation with the function enqueue().  The content of the HTTP response can be accessed in the onInput callback function. onInput calls the PhotoPullParser.parse function to parse the XML.The onDone Callback is invoked when the request has finished execution, onDone calls the updateImages() function, explained later, which updates the images displayed in the Photo-Grid. 


Code Sample from: main.fx

function loadImageMetadata() {
    var start=page \* 9;  
    var request: HttpRequest = HttpRequest {

        location: "http://localhost:8080/catalog/resources/items/?start={start}&max=9"
        method: HttpRequest.GET

        onInput: function(input: java.io.InputStream) {                            
             var parser = PhotoPullParser{};
             photos = parser.parse(input);    
        }

        onDone: function() {
             updateImages();
        }
    }
    request.enqueue();
}


The response XML document contains a list of information about available photos. The document contains the following information about each photo:

  • id
  • imagethumburl
  • imageurl
  • server
  • name
  • price
  • productid
  • description
Here is example XML returned from the RESTFul Catalog Service:

 <items uri="http://localhost:8080/catalog/resources/items/">
       <item uri="http://localhost:8080/catalog/resources/items/1/">
           <description>This black and white colored cat is super friendly./description>
           <id>1</id>
           <imagethumburl>http://localhost:8080/catalog/images/anthony-s.jpg</imagethumburl>
           <imageurl>http://localhost:8080/catalog/images/anthony.jpg</imageurl>
           <name>Friendly Cat</name>
           <price>307.10</price>
           <productid>feline01</productid>
       </item>
   ...
   </items>


The response document is parsed by using the JavaFX XML pull parser (javafx.data.pull.PullParser) to extract information about the photos.
The parser supplies a sequence of Events as it process the document under application control. XML and JSON are the two data formats currently supported.  The PullParser can be used with the onEvent callback, which reports the current parse event.  The onEvent callback shown below parses the xml item elements into an instance of the Photo class. When the item END_ELEMENT , </item>, is reached,  the photo
variable is inserted into the photos sequence.

Code Sample from: PhotoPullParser.fx
import javafx.data.pull.PullParser;

public class PhotoPullParser {

  public function parse(input: InputStream): Photo[] {

    // Information about all catalog photos
    var photos: Photo[];
    var photo: Photo;

    // Parse the input data (Photo Metadata) and construct Photo instance
    def parser = PullParser {

        input: input

        onEvent: function(event: Event) {
            if (event.type == PullParser.START_ELEMENT) {
                if(event.qname.name == "item" and event.level == 1) {
                    photo = Photo { };
                }
            } else
            if (event.type == PullParser.END_ELEMENT) {
                if(event.qname.name == "item" and event.level == 1) {
                   insert photo into photos;
                } else
                if(event.qname.name == "id" and event.level == 2) {
                    photo.id = event.text;
                } else
                if(event.qname.name == "name" and event.level == 2) {
                    photo.name = event.text;
                } else
                if(event.qname.name == "imagethumburl" and event.level == 2) {
                    photo.imagethumburl = event.text;
                } else
                if(event.qname.name == "imageurl" and event.level == 2) {
                    photo.imageurl = event.text;
                } else
                if(event.qname.name == "description" and event.level == 2) {
                    photo.description = event.text;
                } else
                if(event.qname.name == "productid" and event.level == 2) {
                    photo.productid = event.text;
                }
            }
        }
    }
    parser.parse();
    return photos;
  }
}

A sequence of photo objects is constructed by parsing the response XML.

Code Sample from: Photo.fx

public class Photo {
    public var id: String;
    public var imagethumburl: String;
    public var imageurl: String;
    public var name: String;
    public var price: String;
    public var description: String;
    public var productid: String;
}



The onDone Callback is invoked when the HttpRequest has finished execution, onDone calls the updateImages() function, shown below.


Code Sample from:  main.fx

// Load image and data specified in given Photo object
function loadImage(photo: Photo, thumbImageView: ThumbImageView): Void {
    thumbImageView.image = Image {
        url: "{photo.imagethumburl}";
        width: thumbSize
        height: thumbSize
        backgroundLoading: true
        placeholder: thumbImageView.image
    };
    thumbImageView.photo = photo;

// Update images displayed in Photo-Grid
function updateImages() {
    for(i in [0..8]) {
        var photoIndex = i;
        loadImage(photos[photoIndex], thumbImageViews[i]);
    }
}

updateImages updates the images displayed in the thumbImageViewGroup by  updating the thumbImageView Image URLs to the photo URLs parsed from the HTTP response. The photos are then fetched and displayed in Stage as a grid. The imagethumburl , imageurl are used to retrieve and then display photos. The ImageView class knows how to retrieve the image using the URL and display it. Once the photo is retrieved, it is displayed in Scene of Stage through the use of data binding.


If the user clicks a thumb photo, the normal photo is loaded and shown.

catalogclientlarge.jpg


When the user clicks a thumb photo, the ThumbImageView onMouseClicked function sets the fullImageView url to the clicked photo's larger image url and sets the fullImageView show variable to true.


Code Sample from:  main.fx

// Initialize fullscreen ImageView
var fullImageView = FullImageView {
    translateX: thumbBaseX
    translateY: thumbBaseY
    visible: false
}

// To display thumb image
class ThumbImageView extends ImageView {

    public override var onMouseClicked = function(e:MouseEvent) {   
      // Load larger image
      fullImageView.image = Image {
         url: "{photo.imageurl}"
         placeholder: image
         backgroundLoading: true
       };
    }  
    fullImageView.show = true;
}

When the fullImageView show variable is set to true, The FullImageView Node's  visible variable is set to true which specifies that this Node and any subnodes should be rendered as part of the scene graph. The  fader() function causes the fullImageView to fade in or out. The FullImageView Node's  opacity variable specifies how opaque (that is, solid) the Node appears. Animation occurs along a timeline, represented by a javafx.animation.Timeline object. Each timeline contains one or more key frames, represented by javafx.animation.KeyFrame objects. The value of the time instance variable, 3s, defines the elapsed time at which the values within the key frame will be set in a single cycle of the Timeline object. The play() method plays the timeline as defined.


Code Sample from:  FullImageView.fx

public class FullImageView extends ImageView {

    public var show = false on replace {
        if(useEffects) {
            fader();
        } else {
visible = show;
        }
    }
    var timeline:Timeline = Timeline {
        rate: bind timelineRate with inverse
        keyFrames: [
            KeyFrame {
                time: 3s
                values: [ opacity => 1.0 tween Interpolator.LINEAR ]
            }
        ]
    };
    function fader() {    
        if(show) {
            timeline.time = 0s;
            timelineRate = 1.0;
opacity = 0.0;
visible = true;
        } else {
            timeline.time = 3s;
            timelineRate = -3.0;
opacity = 1.0;
        }   
        timeline.play();
    }


stage4.gif

Clicking the normal photo again restores the thumb photo grid. The user can navigate to the next or previous set of photos by clicking << and >> arrow buttons.  Clicking the nextButton calls the onNext() function which increments the page number and calls loadImageMetadata();

Code Sample from:  main.fx

// Display next set of photos
var nextButton = ImageButton {
    selectImage: Image {
        url: "{__DIR__}images/next_h.png"
    };        
    onMouseClicked: function(e) {
onNext();
    }
}

// Load image and data specified in given Photo object
function onNext() {
    fullImageView.show = false;
    page++;
    //updateImages();
    loadImageMetadata();
}


Running the code

Netbeans 6.5 has plugins for JavaFX.  If  you don't have Netbeans 6.5  download and install it, then  go to Tools..Plugins and select the JavaFX plugins.  You can also download the JavaFX SDK without Netbeans, but I'm going to focus on using JavaFX with Netbeans.
To start learning JavaFX  you can start off with the doc Creating Your First JavaFX Application and/or with the tutorial  Learning the JavaFX Script Programming Language.

Running the RESTful Catalog service

  1. 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.
  2. Start NetBeans IDE. Click Open Project in the File menu and select the catalog directory you just unzipped.
  3. Start the MySQL or JavaDB database as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the databases node. You should see the MySQL server or JavaDB database in the list of databases.
      databaselist.jpg
    • Right-mouse click on the MySQL or JavaDB server database and select Start.
  4. Create the catalog database as follows:
    • Right-mouse click on the MySQL or JavaDB server database and select Create Database.
    • Enter the database name petcatalog and userid root and password admin. This will open a New Database Connection window. Click O.K. to accept the displayed settings.
  5. Create the tables in the MySQL catalog database as follows:
    • Expand the Drivers node. You should see a driver for the petcatalog database in the list of drivers.
      driverlist.jpg
    • Right-mouse click on the petcatalog driver and select Connect.
    • Right-mouse click on the petcatalog driver and select Execute Command. This will open up a SQL command window.
    • Copy the contents of the catalog.sql file in the catalog directory and paste the contents into the SQL command window.
    • Click the Run SQL icon runsql.jpg (Ctrl+Shift+E) above the SQL command window.
    • Open the  catalog/setup/sun-resources.xml file and verify that the property values it specifies match those of the database you created (jndi datasource, username, password...). For example
      <resources>
        <jdbc-resource  jndi-name="catalog" />
          <property name="User" value="root"/>
          <property name="Password" value="admin"/>
          <property name="serverName" value="localhost"/>
          <property name="portNumber" value="3306"/>
          <property name="databaseName" value="petcatalog"/>
          <property name="URL" value="jdbc:mysql://localhost:3306/petcatalog"/>
      </resources> 
      Edit the property values as necessary to match the database you created .
  6. Build the project as follows:

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

  7. Run the project as follows:

    • Right click the catalog node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display and empty html page at http://localhost:8080/catalog/  (this is the service not the client).

Running the JavaFX Pet Catalog Client

  1. 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:\\catalogclient.
  2. In NetBeans IDE, click Open Project in the File menu and select the catalogclient directory you just unzipped.
  3. Run the project as follows:
    • Right click the catalogclient  node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the Pet Catalog Client.

References



Friday Feb 06, 2009

RESTful Pet Catalog using JAX-RS and dojo

for those interested in REST ,  a 7 minute screencast on how to build a
RESTful Pet Catalog using JAX-RS and dojo

http://www.netbeans.org/kb/docs/websvc/pet-catalog-screencast.html 

http://www.bestechvideos.com/2008/11/11/netbeans-tv-restful-web-services-pet-catalog



Friday Dec 05, 2008

JavaFX RESTful Pet Catalog Client

Pet Catalog Photos : JavaFX Example Application

Pet Catalog Photos is a simple JavaFX application that displays pet photos retrieved from a RESTful Pet Catalog app (implemented using JAX-RS) described in an earlier blog entry and in this screencast.  This JavaFX example is a modification of the Interesting Photos : JavaFX Example Application.

catalogclient.jpg


Understanding the Code

Information and URLs for pet photos is obtained by performing an HTTP GET request  on a RESTful Catalog service by using the JavaFX asynchronous HTTP API (javafx.io.http.HttpRequest). The response document is parsed by using the JavaFX XML pull parser (javafx.data.pull.PullParser) to extract information about the photos. The photos are then fetched and displayed in Stage as a grid. The user can click the thumb image to load the normal image. Clicking the normal image again returns the UI to thumb image view. 

The response XML document contains a list of information about available photos. The document contains the following information about each photo:

  • id
  • imagethumburl
  • imageurl
  • server
  • name
  • price
  • productid
  • description
Here is example XML returned from the RESTFul Catalog Service:
  
 <items uri="http://localhost:8080/catalog/resources/items/">
       <item uri="http://localhost:8080/catalog/resources/items/1/">
           <description>This black and white colored cat is super friendly./description>
           <id>1</id>
           <imagethumburl>http://localhost:8080/catalog/images/anthony-s.jpg</imagethumburl>
           <imageurl>http://localhost:8080/catalog/images/anthony.jpg</imageurl>
           <name>Friendly Cat</name>
           <price>307.10</price>
           <productid>feline01</productid>
       </item>
   ...
   </items>

The imagethumburl , imageurl are used to retrieve and then display photos. The ImageView class knows how to retrieve the image using the URL and display it. Once the photo is retrieved, it is displayed in Scene of Stage through the use of data binding.

A sequence of photo objects is constructed by parsing the response XML. A grid of ImageView is added to Scene of Stage. If the user clicks this thumb photo, the normal photo is loaded and shown. Clicking the normal photo restores the thumb photo grid. The user can navigate to the next or previous set of photos by clicking << and >> arrow buttons.


Running the code

Netbeans 6.5 has plugins for JavaFX.  If  you don't have Netbeans 6.5  download and install it, then  go to Tools..Plugins and select the JavaFX plugins.  You can also download the JavaFX SDK without Netbeans, but I'm going to focus on using JavaFX with Netbeans.
To start learning JavaFX  you can start off with the doc Creating Your First JavaFX Application and/or with the tutorial  Learning the JavaFX Script Programming Language. 

Running the RESTful Catalog service

  1. 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.
  2. Start NetBeans IDE. Click Open Project in the File menu and select the catalog directory you just unzipped.
  3. Start the MySQL database as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the databases node. You should see the MySQL server database in the list of databases.  
      Database list
    • Right-mouse click on the MySQL server database and select Start.
  4. Create the catalog database as follows:
    • Right-mouse click on the MySQL server database and select Create Database.
    • Enter the database name catalog. This will open a New Database Connection window. Click O.K. to accept the displayed settings.
  5. Create the tables in the MySQL catalog database as follows:
    • Expand the Drivers node. You should a driver for the catalog database in the list of drivers.
      Driver list
    • Right-mouse click on the catalog driver and select Connect.
    • Right-mouse click on the catalog driver and select Execute Command. This will open up a SQL command window.
    • Copy the contents of the catalog.sql file in the catalog directory and paste the contents into the SQL command window.
    • Click the Run SQL icon Run SQL icon (Ctrl+Shift+E) above the SQL command window.
    • Open the  catalog/setup/sun-resources.xml file and verify that the property values it specifies match those of the database you created (jndi datasource, username, password...). Edit the property values as necessary.
  6. Build the project as follows:

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

  7. Run the project as follows:

    • Right click the catalog node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display and empty html page at http://localhost:8080/catalog/  (this is the service not the client).

Running the JavaFX Pet Catalog Client

  1. 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:\\catalogclient.
  2. In NetBeans IDE, click Open Project in the File menu and select the catalogclient directory you just unzipped.
  3. Run the project as follows:
    • Right click the catalogclient  node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the Pet Catalog Client.

References


Tuesday Sep 30, 2008

Sleepless in Brazil


Since September 24th I've been speaking in Brazil at JUGs, Universitys, and at Sun Tech Days as part of the September Month of Java in Brazil .

MapBRAZIL-Cities2.jpg


I spoke on September 24  in Maringa to ~500 JUG members/students/professors, September 25 in Toledo to ~ 500,  September 26 in  Xanxere to ~ 200, September 27 in Porto Alegre to ~70, and in Sao Paulo there were ~1000 attendees.   We spoke in a different location each evening which meant going to sleep late and waking up early the next morning to travel to the next location.  The guys organizing this obviously do not value sleep and time to run (I'm a avid runner)  as much as I do !   They also don't have the same conception of safety, our driver was going 90mph on a 2 lane road with oncoming traffic which didn't phase Bruno and Eduardo, whereas I was seriously praying to God for my life !! :)  The attendees in each city were very friendly and enthusiastic which compensated for the difficult schedule  (but next time I will insist on more time to travel between destinations!) .   Also we drove close to the beautiful  Iguaçu_Falls  and we flew through the beautiful Florianópolis  (note to self,  next time make sure to schedule a little time to rest and see noteworthy sites ;) .

During this trip I spoke on:

I learned a little about Brazil in conversations over dinner:
It was good that USA kicked out the Brits before we discovered gold, because the Portuguese took away a lot of Brazil's gold. USA has probably had more economic stability (until recently) because we always had a strong middle class, whereas in Brazil historically there was a big gap between the rich and poor with the wealth concentrated in a small percent of the population, however this has been improving recently
Brazil had really bad inflation during the 1970s, ~ 25% per month !  Brazillians told me they used to take their salary check and buy food for the whole month the same day.  But now the Brazillian inflation is under control, they paid off their debt,  and the economy is doing well. Last year they received more foreign investment than any other country.  
Last year Brazil made a huge oil discovery  which could raise Brazil's petroleum reserves by ~40 percent and boost Brazil into the ranks of the world's major exporters (drill baby drill) .  Brazillian cars are required to run on a gas ethanol  mixture and they have a very cost-effective process to produce ethanol from sugar cane. Brazil's sugar cane-based industry is far more efficient than the U.S. corn-based industry. Sugar cane ethanol has an energy balance 7 times greater than ethanol produced from corn , and Brazil's sugar cane based ethanol industry has not caused food prices to increase.
Bruno told me that he grew up near the amazon forest and used to swim in rivers with piranhas,  he said they don't bite unless you have a cut and are bleeding, can you imagine swimming with these things ?
piran.jpg

Here are some photos from my trip :

IMG_0868_1_1.JPG IMG_0871_1_1.JPGIMG_0878_1_1.JPG IMG_0885_1_1.JPGIMG_0886_1_1.JPG IMG_0888_1_1.JPG



Saturday Sep 20, 2008

RESTful Comet Screencast

Here is a screencast about a Comet application which allows users to watch and chat about a slide show. The Application loads the slide URLs from a RESTful Web Service and then uses dojo bayeux with Grizzly on Glassfish to publish the slides and/or text to all the slideshow subscribers.
You can read more about this application at RESTful Web Services and Comet

Friday Aug 29, 2008

RESTful Web Services and Comet

Rick Palkovic and I have written an article about a Comet application which allows users to watch and chat about a slide show. The Application loads the slide URLs from a RESTful Web Service and then uses dojo bayeux with Grizzly on Glassfish to publish the slides and/or text to all the slideshow subscribers. See RESTful Web Services and Comet. RESTful Web Services and Comet

Wednesday Aug 06, 2008

a RESTful Pet Catalog

a RESTful Pet Catalog


This Sample Pet Store Catalog application shows how to expose a  Catalog  as a RESTful Web Service for remote client applications, and it shows how to code a Dojo client which  gets and displays the Web Service responses in a dynamic Ajax table ( Dojo grid). I re-implemented this Sample Catalog application implemented with JAX-WS on the server side and JSF on the client side which is also available in the Java One Metro hands on lab.

Download the RESTful Pet Catalog Code

Dojo is an open source DHTML toolkit written in JavaScript.

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 Dojo and JAX-RS in a sample Catalog Application

The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.
petcatalog

Quick installation and use of dojo with Netbeans

There are 3 ways to install dojo which you can read about 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.
dojonetproj.JPG

Dojo style sheets

Every page using the dojo Grid needs to import the grid style sheet Grid.css as shown below:

Code Sample from:  index.html

    <style type="text/css">
      /\* tundraGrid.css matches Dijit Tundra style. \*/
      @import "src/dojox/grid/_grid/tundraGrid.css";
      @import "src/dijit/themes/tundra/tundra.css";
      @import "src/dojo/resources/dojo.css";
      @import "src/dojox/grid/_grid/Grid.css";
    </style>



This will load the the CSS files required by the Dojo grid widget, you can just use  dojox/grid/_grid/Grid.css instead of tundraGrid if you don't want the  tundra style. 

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"
           djConfig="isDebug: true, debugAtAllCosts: false,
           parseOnLoad: true">
 </script>




This script element will load the base dojo script which gives you access to all the dojo functionality.

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

Code Sample from:  index.html

 <script type="text/javascript">
   dojo.require("dojox.grid.Grid");
   dojo.require("dojox.grid._data.model");
   dojo.require("dojo.parser");
 </script>


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. The rest of the Java Script for this application is in the file dynamicTable.js.

The Grid Widget

You can use widgets declaratively by using special attributes inside of regular HTML tags, or programmatically through JavaScript.
The dojoType attribute declares a Dojo widget. Below is the declaration of the Grid widget for this applicaton:
Code Sample from:  index.html

<div id="grid" dojoType="dojox.Grid" model="model" structure="layout">
</div>


The model and structure attributes point to the  JavaScript variables for the model and layout structure explained below.

The Grid View

A Dojo grid  is a widget useful for displaying data sets in a table with its own scrollable views.  The dojo grid widget requires a layout. A grid layout is declared as an array of views.  Each view is a group of columns,  declared as an array of arrays. Each array element is an object, the "name" property of the object names the column. The column names will be displayed in the top row of the grid. The code below declares 4 columns: Company, City, State, Zip. This grid layout structure consists of one view as shown  below:

Code Sample from:  dynamicTable.js

formatImage = function(value) {
    if (!value)
        return '&nbsp;';   
        return "<img src='" + value + "'/>";   
};

// Data Grid layout
// A grid view is a group of columns
var view1 = {
            cells: [
        [
            {name: 'Name', field: "name"},
            {name: 'Description', field: "description", width: '200px'},
            {name: 'Photo',field: "imagethumburl", formatter: formatImage, width: '120px'},
            {name: 'Price',field: "price"}
        ]
    ]
};
// a grid layout is an array of views.
var layout = [ view1 ];




The Grid Model

The dojo grid widget requires a data model. The model variable declares the type of Dojo object that the Grid will use for the json data that will be loaded in the grid. There are different options for the model, this example uses the dojox.grid.data.Objects which is a collection of objects to be displayed in the grid.

Code Sample from:  dynamicTable.js

// the model will contain the data to be displayed in the view
model = new dojox.grid.data.Objects(null,null);

function handleResponse(responseObject, ioArgs){
    // set the model object with the returned items list
    model.setData(responseObject.items.item);       
}  

// make request to the items web service
function loadTable(page){
    start = page \* batchSize;
    var targetURL = "resources/items/?start="+ encodeURIComponent(start);   
    dojo.xhrGet({
        url: targetURL,
        handleAs: "json",
        load: handleResponse,
        error: handleError
    });
}

The loadTable function calls   dojo.xhrGet to make an XMLHttpRequest to the items JAX-RS web service specified by the url: parameter. When the response from web service is returned, the callback function  handleResponse specified by load: is called and the response is passed to the callback function in the responseObject. The handleAs  parameter specifies the response data type, handleAs: "json"  means the returned data is of the type JSON (Java Script object notation).
In the   handleResponse callback function,  model.setData is called to populate the Dojo grid  with the data returned from the  the  items JAX-RS web service. Below is an example of a JSON response from the items JAX-RS web service:

Example json data

{"items":
  {"@uri":"http://host/catalog/resources/items/",
   "item":[
     {"@uri":"http://host/catalog/resources/items/1/",
       "name":"Friendly Cat",
      "description":"This black and white colored cat is super friendly.",     
       "id":"1",
       "imageurl":"http://localhost:8080/CatalogService/images/anthony.jpg"},
     {"@uri":"http://host/catalog/resources/items/2/",
       "name":"Fluffy Cat",
       "description":"A great pet for a hair stylist!
       "id":"2",
       "imageurl":"http://localhost:8080/CatalogService/images/bailey.jpg"}
    ]
  }
}


Loading the table

The dojo.addOnLoad function allows you to call a  function after a page has loaded and after Dojo has finished its initilization. This application uses dojo.addOnLoad to call the loadTable() function (which we looked at above)  which calls the  items JAX-RS web service and sets the results in the grid data model.

Code Sample from:  dynamicTable.js

    <script type="text/javascript">
        dojo.addOnLoad(function(){
            loadTable(0);
        });
    </script>


Events for paging

The  "<<"">>" buttons call the next() previous() functions when clicked:

Code Sample from:  index.html

<input type="button" value="<<" onclick="previous();">
</input>
<input type="button" value=">>" onclick="next();">
</input>


The next() function  increments the page number and then calls the loadTable() funtion:

Code Sample from: dynamicTable.js


function next() {
    page =page + 1;
    loadTable(page);
}

function previous() {
    page =page - 1;
    if (page < 0) page = 0;
    loadTable(page);
}


RESTful  Web Services with JAX-RS

The  dojo.xhrGet url: parameter  references the URI  resources/items/ for the items   RESTful web service.  The items 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 items RESTful web service was generated from the item data base table (the sql is in the how to run section). 

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

Code Sample from: ItemsResource.java

// Service URI path "/items/"

@Path("/items/")

public class 
ItemsResource {

  @GET
@ProduceMime("application/json")
    public
ItemsConverter 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 Item e") String query) {
        try {
            ItemsConverter items = new ItemsConverter(
getEntities(start, max, query),
                context.getAbsolutePath(), expandLevel);
            return
items;
        } finally {
            PersistenceService.getInstance().close();
        }
    }


The ItemsResource represents a list of items. The ItemsResource get method returns a list of Item 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 ItemsResource  the URI path is /items/.
  • @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 ItemsConverter class is a JAXB annotated class which is used to marshal a list of Item objects into XML or JSON format.   The getEntities method returns a list of Item 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/catalog/resources/items/?start=0


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

Received:
{"items":
  {"@uri":"http://host/catalog/resources/items/",
   "item":[
     {"@uri":"http://host/catalog/resources/items/1/",
       "name":"Friendly Cat",
      "description":"This black and white colored cat is super friendly.",     
       "id":"1",
       "imageurl":"http://localhost:8080/CatalogService/images/anthony.jpg"},
     {"@uri":"http://host/catalog/resources/items/2/",
       "name":"Fluffy Cat",
       "description":"A great pet for a hair stylist!
       "id":"2",
       "imageurl":"http://localhost:8080/CatalogService/images/bailey.jpg"}
    ]
  }
}


The ItemsConverter class is a JAXB annotated class, used to marshal a list of Item objects into XML or  JSON format.  A snippet of the ItemsConverter class is shown below:


Code Sample from: ItemsConverter.java

@XmlRootElement
public class ItemsConverter {

@XmlElement
    public Collection<ItemConverter> getItem(){
     ...
       return items;
    }
    @XmlAttribute
   public URI getUri() {
        return uri;
    }



Java Persistence Query API

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

Code Sample from: ItemsResource.java

@Path("/items/")

public class 
ItemsResource {

    . . .

    protected Collection<Item> 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 Item entity class which maps to the  CUSTOMER table that stores the item 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: Item.java

@Entity

public class Item implements Serializable {

@Id
    private Long id;

    private String name;
    private String description; 
    private String imageurl; 
    private String state; 
    private BigDecimal price;


    public
Item() { }

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

   . . .

}   




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 items, and a dojo client which  gets and displays the Web Service responses in a dynamic Ajax table.

Configuration of the Application for Netbeans 6.5m1 , Glassfish V2, and MySQL


Running the Sample Code

  1. 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.
  2. Start NetBeans IDE. Click Open Project in the File menu and select the catalog directory you just unzipped.
  3. Start the MySQL database as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the databases node. You should see the MySQL server database in the list of databases.
      Database list
    • Right-mouse click on the MySQL server database and select Start.
  4. Create the petcatalog database as follows:
    • Right-mouse click on the MySQL server database and select Create Database.
    • Enter the database name catalog. This will open a New Database Connection window. Click O.K. to accept the displayed settings.
  5. Create the tables in the MySQL catalog database as follows:
    • Expand the Drivers node. You should a driver for the catalog database in the list of drivers.
      Driver list
    • Right-mouse click on the catalog driver and select Connect.
    • Right-mouse click on the catalog driver and select Execute Command. This will open up a SQL command window.
    • Copy the contents of the createdbmysql.sql file in the catalog directory and paste the contents into the SQL command window.
    • Click the Run SQL icon Run SQL icon (Ctrl+Shift+E) above the SQL command window.
  6. Build the project as follows:

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

  7. Run the project as follows:

    • Right click the catalog 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/catalog/).

For more Information:




Tuesday Jul 29, 2008

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

a Dynamic Ajax table example using dojo 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 Dojo client which  gets and displays the Web Service responses in a dynamic Ajax table ( Dojo grid).

Download the dojo Sample Application Code

Dojo is an open source DHTML toolkit written in JavaScript.

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 Dojo 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.

table.jpg


Quick installation and use of dojo with Netbeans

There are 3 ways to install dojo which you can read about 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.
dojonetproj.JPG

Dojo style sheets

Every page using the dojo Grid needs to import the grid style sheet Grid.css as shown below:

Code Sample from:  index.html

    <style type="text/css">
      /\* tundraGrid.css matches Dijit Tundra style. \*/
      @import "src/dojox/grid/_grid/tundraGrid.css";
      @import "src/dijit/themes/tundra/tundra.css";
      @import "src/dojo/resources/dojo.css";
      @import "src/dojox/grid/_grid/Grid.css";
    </style>



This will load the the CSS files required by the Dojo grid widget, you can just use  dojox/grid/_grid/Grid.css instead of tundraGrid if you don't want the  tundra style. 

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"
           djConfig="isDebug: true, debugAtAllCosts: false,
           parseOnLoad: true">
 </script>




This script element will load the base dojo script which gives you access to all the dojo functionality.

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

Code Sample from:  index.html

 <script type="text/javascript">
   dojo.require("dojox.grid.Grid");
   dojo.require("dojox.grid._data.model");
   dojo.require("dojo.parser");
 </script>


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. The rest of the Java Script for this application is in the file dynamicTable.js.

The Grid Widget

You can use widgets declaratively by using special attributes inside of regular HTML tags, or programmatically through JavaScript.
The dojoType attribute declares a Dojo widget. Below is the declaration of the Grid widget for this applicaton:
Code Sample from:  index.html

<div id="grid" dojoType="dojox.Grid" model="model" structure="layout">
</div>


The model and structure attributes point to the  JavaScript variables for the model and layout structure explained below.

The Grid View

A Dojo grid  is a widget useful for displaying data sets in a table with its own scrollable views.  The dojo grid widget requires a layout. A grid layout is declared as an array of views.  Each view is a group of columns,  declared as an array of arrays. Each array element is an object, the "name" property of the object names the column. The column names will be displayed in the top row of the grid. The code below declares 4 columns: Company, City, State, Zip. This grid layout structure consists of one view as shown  below:

Code Sample from:  dynamicTable.js

// Data Grid layout
// A grid view is a group of columns
var view1 = {
            cells: [
                [
                    {name: 'Company', field: "name"},
                    {name: 'City', field: "city"},
                    {name: 'State',field: "state"},
                    {name: 'Zip',field: "zip"}
                ]
            ]
};
// a grid layout is an array of views.
var layout = [ view1 ];


This grid layout for this example is shown in the figure below (note: how the data for the table gets loaded is explained below).
dojogrid.JPG

The Grid Model

The dojo grid widget requires a data model. The model variable declares the type of Dojo object that the Grid will use for the json data that will be loaded in the grid. There are different options for the model, this example uses the dojox.grid.data.Objects which is a collection of objects to be displayed in the grid.

Code Sample from:  dynamicTable.js


// the model will contain the data to be displayed in the view
model = new dojox.grid.data.Objects(null,null);

function handleResponse(responseObject, ioArgs){
    // set the model object with the returned customers list
    model.setData(responseObject.customers.customer);       
}  

// make request to the customers web service
function loadTable(page){
    start = page \* batchSize;
    var targetURL = "resources/customers/?start="+
                      encodeURIComponent(start);   
    dojo.xhrGet({
        url: targetURL,
        handleAs: "json",
        load: handleResponse,
        error: handleError
    });
}


The loadTable function calls   dojo.xhrGet to make an XMLHttpRequest to the customers JAX-RS web service specified by the url: parameter. When the response from web service is returned, the callback function  handleResponse specified by load: is called and the response is passed to the callback function in the responseObject. The handleAs  parameter specifies the response data type, handleAs: "json"  means the returned data is of the type JSON (Java Script object notation).
In the   handleResponse callback function,  model.setData is called to populate the Dojo grid  with the data returned from the  the  customers JAX-RS web service. Below is an example of a JSON response from the customers JAX-RS web service:

Example json data

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


Loading the table

The dojo.addOnLoad function allows you to call a  function after a page has loaded and after Dojo has finished its initilization. This application uses dojo.addOnLoad to call the loadTable() function (which we looked at above)  which calls the  customers JAX-RS web service and sets the results in the grid data model.

Code Sample from:  dynamicTable.js

    <script type="text/javascript">
        dojo.addOnLoad(function(){
            loadTable(0);
        });
    </script>


Events for paging

The  "<<"">>" buttons call the next() previous() functions when clicked:

Code Sample from:  index.html

<input type="button" value="<<" onclick="previous();">
</input>
<input type="button" value=">>" onclick="next();">
</input>


The next() function  increments the page number and then calls the loadTable() funtion:

Code Sample from: dynamicTable.js


function next() {
    page =page + 1;
    loadTable(page);
}

function previous() {
    page =page - 1;
    if (page < 0) page = 0;
    loadTable(page);
}


RESTful  Web Services with JAX-RS


The  dojo.xhrGet url: parameter  references the URI  resources/customers/ for the customers   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. 

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/dojoRest/resources/customers/?start=0


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

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


The CustomersConverter class is a JAXB annotated class, used to marshal a list of Customer objects into XML or  JSON format.  A snippet of the CustomersConverter class is shown below:


Code Sample from: CustomersConverter.java

@XmlRootElement
public class CustomersConverter {

@XmlElement
    public Collection<CustomerConverter> getCustomer(){
     ...
       return items;
    }
    @XmlAttribute
   public URI getUri() {
        return uri;
    }



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;
    }



}   




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 dojo 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.

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>/dojoRest, 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:\\dojoRest.

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

  3. Build the project as follows:

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

  4. Run the project as follows:

    • Right click the dojoRest 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/dojoRest/).

References:



Friday Jul 18, 2008

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

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:




About

caroljmcdonald

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today