Articles
Java Platform, Enterprise Edition
|
| By Jennifer Ball, January 2007 |
|
| |
| - | Phobos Architecture |
| - | What Is a Phobos Application? |
| - | Using a jMaki Widget in a Phobos Application |
| - | Using the Java Persistence API in a Phobos Application |
| - | Conclusion |
| - | For More Information |
The goal of Project Phobos is to build a lightweight web application framework that runs on the Java platform but allows you to develop your entire application using a scripting language, such as JavaScript. As a result, you can take advantage of the many benefits that scripting languages offer but still leverage the power of the Java platform.
When you develop with Phobos, you will experience the many benefits of using scripting languages. For example,
Phobos gives you what other scripting languages do not: access to the Java Platform, Enterprise Edition (Java EE) stack. As the first article in this series has pointed out, scripting languages and statically typed languages such as the Java programming language have their own strengths. When you use Phobos to create web applications, you can use scripting and Java technology in ways that take advantage of their strengths. And because Phobos runs on the Java EE platform, you can call into components of the Java EE stack. For example, from your Phobos application, you can call into the new and powerful Java Persistence API available as part of the Java EE platform.
Phobos also simplifies development in Ajax, a technology that includes but is not limited to Asynchronous JavaScript and XML. If you have JavaScript on the client, as you do with Ajax, and on the server, as you can with Phobos, you get all all the benefits of having the same scripting language on both the client and the server. This also means that no translation is required between one language on the server and another on the client. In addition, Phobos includes a set of convenience libraries specifically for Ajax, such as the jMaki framework and the Dojo toolkit.
This article first describes the Phobos architecture. It then uses a common calculator example to demonstrate the characteristics of a typical Phobos application. Next, it shows how to incorporate jMaki widgets into your Phobos application. Finally, it describes how to use the Java Persistence API with a Phobos application.
| |
From the Phobos user's perspective, Phobos consists of a set of scripting engines and a set of built-in scripting libraries. The scripting engines are compliant with JSR 223, Scripting for the Java Platform, and each one allows you to use a particular scripting language to develop your application. Currently, Phobos supports the JavaScript and JRuby engines. The scripting libraries add convenience JavaScript functions for performing such common tasks as request dispatching and rendering views, as well as more specialized ones such as integrating Ajax functionality into your application.
The application that you build with the Phobos framework adheres to a specific structure, which encourages building web applications according to the Model-View-Controller (MVC) design pattern. Every Phobos application consists of a set of controllers, a set of views, scripts for serving HTTP requests, and possibly other static content, such as style sheets and images.
Once you have written your application, the flexible Phobos architecture allows you to run it on one of a variety of platforms and in a variety of environments. You can run a Phobos application on the open-source GlassFish server or in any compliant servlet container. Phobos also lets you select a particular environment configuration depending on whether the application is in the development, testing, or production stage. For example, you can enable or disable certain optimizations based on their appropriateness for the current stage of development.
After you have deployed your application, it is live, meaning that you can make changes to the application while it is running and see the results instantaneously. There is no need to compile or redeploy the application.
Let's take a closer look at what a Phobos application looks like.
| |
Every Phobos application includes an
application directory, which in turn includes at least a
controller, a
script, and a
view directory. Figure 1 shows the directory structure of the calculator example, which you can download from this
Phobos samples download page.
Figure 1: Directory Structure of the Calculator Application
|
As you can see from Figure 1, the application directory contains the following subdirectories:
controller directory, you put the scripting code that creates a controller object and defines the functions that are called in response to user actions.
script directory, you can put any extra scripting code you use in the application. In the case of the calculator, the
script directory contains a script file that redirects requests to particular pages of the application.
view directory, you put the files that represent the different pages of the application.
More complicated applications might need additional directories, such as a
static directory, in which you can put static files, such as HTML pages and CSS style sheets. The "
Overview of Phobos" document describes the directory structure in more detail.
As Figure 1 shows, the calculator application contains the following files:
calculator.js file, which instantiates a controller object and invokes the appropriate methods to perform the arithmetic operations and redisplay the result.
index.js file, which dispatches the first request for the application to the controller.
calculator.ejs file, which is an embedded JavaScript file, an HTML file with JavaScript code embedded in it. This file represents the view or page of the application.
When the browser makes the first request for the page, the following happens:
The
index.js file redirects the request to the
/calculator/show URL. The
calculator part of the URL is a controller, and
show is a function of it. The
show function is defined in
calculator.js.
The Phobos runtime creates the
Calculator controller and invokes the
show function.
The
show function sets the initial values of the operands, sets the selected arithmetic operation to
add, and renders the
calculator.ejs view.
The user enters two numbers, selects an operand, and clicks Compute.
When the user clicks Compute, the
compute function of
calculator.js is called by way of an HTTP
POST to the
/calculator/compute URL.
The
compute function does the following:
show function so that
calculator.ejs is re-rendered
The line in
index.jsp that redirects to the URL
/calculator/show is the following, separated to fit on the print-friendly version of this page:
library.httpserver.sendRedirect(
|
This line uses the built-in
httpserver JavaScript library that comes with Phobos to handle the initial request for the application. It invokes the
show function of the
Calculator controller, which renders the view. In the next two sections, we'll look more closely at the calculator example's controller and view, the key parts of the application.
The Controller
Every Phobos application needs at least one controller, which processes requests, makes changes to the model in response to requests, and renders the view. In the case of the calculator, the responsibility of its controller is to render the view, perform the arithmetic operations of the calculator, and pass the results to the view.
The
calculator.js file contained in the application's
controller directory does the work of creating the
Calculator controller object and implementing the controller's functions. The
calculator.js file defines and constructs the
Calculator controller object using the prepackaged
define function :
library.common.define(controller, "calculator", function() {
|
Inside the calculator's
constructor function,
calculator.js defines the two functions implemented by the
Calculator controller object:
show and
compute.
The
show function stores the value of the calculation's result and the selected operation, such as
add, into the session.
It uses the
invocation.session object to save values into the session:
var v = invocation.session.value;
|
As shown in the preceding code, the value of the result is set to zero because this is the first time the page is being requested. The operation is set to a default of
add. Finally, a global variable, called
model, is initialized with these values. Later, you'll see how the page accesses these values and passes them back to the controller.
The last thing the
show function does is to display the page, not by writing HTML directly but by rendering a separate view, represented by
calculator.ejs. It does this by using the
render function from the
view library:
library.view.render("calculator.ejs");
|
Notice that all you need to do is provide the name of the file, as long as you put the file in the appropriate directory.
Phobos is smart enough to know where to find the file. As a result, the
render function resolves to
/application/view/calculator.ejs.
The extension
ejs stands for embedded JavaScript, to signify that the file is an HTML file with JavaScript statements and expressions embedded inside it. When the view is rendered, the embedded code is evaluated at the appropriate time. The next section describes how to create the
calculator.ejs file.
But first, let's go over what the
compute function does. This function gets the values and the operator from the request parameters and uses them to calculate a new result. After doing so, it saves the new values back into the session. Finally, it redirects to the
show function so that the page is re-rendered with the new result. Here is the line, separated to fit on the print-friendly version of this page, that performs the redirect:
library.httpserver.sendFound(
|
Now let's take a look at the view that is actually rendered.
The View
Every web application has a set of pages, or views. Figure 2 shows the view of the calculator application. The user enters numbers in the Current Total and Second Operand fields, selects an operator from the set of radio buttons, and clicks Compute. The application responds by displaying the total in the Current Total field.
Figure 2: Screen Capture of the Calculator Application
|
When developing a Phobos application, you create a view using an embedded JavaScript file. This file is an HTML file with embedded JavaScript statements, and so it is similar to a JavaServer Pages (JSP) technology page with HTML form elements mixed with scripting tags.
Following is the
calculator.ejs file, with formatting tags removed:
<script type="text/javascript">
|
Notice that when the user clicks the Compute button, the action of the form submission is the
compute function, described in the previous section. Recall that the
show and
compute functions saved the values and selected operation into the model variable in session. Here, the
calculator.ejs file uses JavaScript statements to retrieve the value and operation from the model variable. The script tag uses the
<%=model.selectedOp%> statement to retrieve the
selectedOp value in order to select the appropriate selected operation checkbox in the form. The Current Total text field uses the
<%=model.value%> statement to get the calculation's current result.
As this section has shown, the architecture of a typical Phobos application conforms well to the familiar MVC design pattern.
| |
When developing a Phobos web application, you can do anything that you can do with a web application based on JSP technology, and that includes adding Ajax capabilities to your application. Currently, Phobos supports adding
jMaki widgets to a Phobos application. In the future, as Phobos and
Dynamic Faces mature, there might be more synergy between the two.
In the meantime, this section shows you how you can use the jMaki fisheye widget in a Phobos application. Figure 3 showns a screen capture of the bioFisheyeWidget application, which you can download from this Phobos samples download page. This application allows a user to click on a photo to get biographical information about the person in the photo.
Figure 3: Screen Capture of the bioFisheyeWidget Example
|
The first task you must perform to get Phobos and jMaki working together is to download both projects and build them separately, as described in "
Building a Phobos Distribution." After that, to include a jMaki widget into your application, just use the
insert function of the jMaki JavaScript library provided by Phobos in your embedded JavaScript file, as shown here:
<% library.jmaki.insert({component: "dojo.fisheye", args:{items:[
|
The preceding code uses the
insert function to add the fisheye widget to a view. The arguments that you pass to this function are nearly the same as the attributes you would define for the equivalent
ajax tag that you would include in a JSP page. The
component argument tells the function which widget you are inserting into your page. The
args argument identifies an array of icons that are included in the widget along with the properties for each of those icons. One of the properties is
url, which identifies a URL that must be accessed when the user clicks the photo that the icon represents. Each URL points to a view that contains the appropriate biographical information.
To display the view with the biographical information, the view of the bioFisheyeWidget application includes a dcontainer widget that subscribes to a topic that gets the URL and will load it into the page:
<h3><div>
|
This is just one example of how you can use the publish and subscribe feature of jMaki to respond to widget events. See the document " jMaki Glue" to learn how you can write your own topic listeners.
So that's how you include a prewrapped jMaki widget into your application. To include a custom jMaki widget that is not part of the jMaki distribution, you simply add the widget's
component.js,
component.htm, and
component.css files to the
application/static/resources directory of your application.
| |
As this article has mentioned previously, one of the advantages of using Phobos is that you have access to all the great features that the Java EE platform offers. One of the latest ease-of-use features included in Java EE 5 is the Java Persistence API, which provides developers with an object-relational mapping facility for managing relational data in Java technology-based applications.
The Java Persistence API allows you to represent an entity, which is typically a table in a relational database, with a Java class. The API also provides a set of classes for managing these entities:
EntityManager interface defines the methods that are used to interact with the persistence context.
EntityManager API creates and removes persistent entity instances, finds entities by the entity's primary key, and allows queries to be run on entities.
EntityManager instances in an application. This set of entity classes represents the data contained within a single data store.
See chapters 24 through 27 of the Java EE 5 Tutorial for more information on the Java Persistence API.
Phobos provides a persistence JavaScript library that gives you the ability to access data from the views and scripts of your Phobos application using the Java Persistence API. The following simple code is from the jpaExample application, which you can download from this Phobos samples download page. The code shows part of a script file that adds authors to a database and then displays those authors on the page. It represents the simplest way to publish this information in a web page.
response.setStatus(200);
response.setContentType("text/html");
writer = response.getWriter();
...
// Insert some authors.
...
var em;
...
em = library.persistence.getEntityManager("jpaExample1-pu");
...
if (em != undefined) {
// Insert some Authors if none are defined.
var authors =
em.createQuery("select a from Author a").
getResultList().toArray();
if (authors.length==0){
var tx = em.getTransaction();
tx.begin();
var author = new Packages.jpaexample.Author();
author.name =
"Danny Goodman";
//equivalent to author.setName("Danny Goodman");
author.organisation= "O\'Reilly";
em.persist(author);
writer.println("<br><br>created one author named "+ author.name);
var author2 = new Packages.jpaexample.Author();
author2.name= "Paul Wilton";
author2.organisation ="Wrox Press Inc";
em.persist(author2);
writer.println("<br><br>created one author named "+ author2.name);
tx.commit();
}
// List out the Authors that are available.
authors = em.createQuery("select a from Author a").getResultList().toArray();
writer.println("<h3>List of Authors as of "+ java.util.Date() +"</h3>")
writer.println(
"<table><tr><th>Id</th><th>Name</th><th>Organisation</th></tr>");
for (var i in authors) {
var a = authors[i];
writer.println("<tr><td>" + a.authorId
+ "</td><td>" + a.name
+ "</td><td>" + a.organisation
+ "</td></tr>");
}
writer.println("</table>")
}
writer.println("</body></html>");
writer.flush();
|
Figure 4 shows a screen capture of the page generated by this code:
Figure 4: Screen Capture of jpaExample
|
As you can see from the code, the persistence library available with Phobos includes a function to get an
EntityManager instance and store it into a simple JavaScript variable. From this variable, you can get a transaction, persist entities, and create queries in the same way you would if you were working in Java technology code. In addition, the Phobos persistence library can work with entity classes written in the Java programming language, which means that you can introduce entity classes you already have into a Phobos application.
| |
The Phobos web application framework gives you the flexibility of developing a web application with a scripting language but still gives the application access to everything that the Java EE platform provides. As Phobos matures, it will give you a lot more capabilities, including more sophisticated database access and support for REST web services. To keep up-to-date on the progress of Phobos, visit the Project Phobos web site and join the project aliases.
| |
Previous articles in the "New Technologies for Ajax and Web Application Development" series:
| |
Jennifer Ball is a staff writer at Sun Microsystems. She writes about web application technologies that are part of the Java EE platform.