 |
October 2007 Archives
Adding a Google Map to the Sample JSF Catalog Application
Posted by caroljmcdonald on October 19, 2007 at 02:50 PM | Permalink
| Comments (8)
Adding a Google Map to the Sample JSF Catalog Application
This example demonstrates adding a Map to the Sample
Store Catalog Application using JAX-WS, JSF, EJB 3.0, and Java
using the BluePrints
JSF Google Map Viewer Component.
Download
the Sample Application Code
Explanation of the functionality of the Blueprints JSF Ajax Map
Component in a sample Store Catalog Application
The image below shows the Catalog Item Detail page, which displays a
Store item's details.
When the user clicks on the Seller's Location hyperlink, a Google Map
for the location is displayed as shown below:
Explanation of the usage of the Blueprints JSF Ajax Map Component
in the JSF Catalog Web Service client.
The JSF Store UI is a separate web application which is a JAX-WS
client. To learn more about this App read the Sample
Store Catalog Application using JAX-WS, JSF, EJB 3.0, and Java, and
for more information on
the JSF part of this code see this
previous blog.
However this JSF map component could be added to any JSF client, for
example it could also be added to these sample JSF apps: Sample
Application using JSF, Seam, and Java Persistence APIs on Glassfish,
Sample
Application using JSF, Catalog Facade Stateless Session, and Java
Persistence APIs, Sample
Application using JSF, Spring 2.0, and Java Persistence APIs on
Glassfish.
In the Detail.jsp
web page, the Seller's Location hyperlink is defined as shown below:
Code Sample from: Detail.jsp |
<h:commandLink action="#{MapBean.mapAction}"
value="#{item.item.address.street1},
#{item.item.address.city},
#{item.item.address.state}"/>
|
A JSF commandLink
is used to provide a link to click on to
display a Google map corresponding to the address
displayed by the value
tag. The commandLink
tag represents an HTML hyperlink and is rendered as an HTML <a> element. The
commandLink
tag is used to submit an action event
to the application. This commandLink action
attribute
references a MapBean
ManagedBean which is defined in the
faces-config.xml file:
| Code Sample from: faces-context.xml |
<managed-bean>
<managed-bean-name>MapBean</managed-bean-name>
<managed-bean-class>
sessionpagination.client.MapBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>item</managed-bean-name>
<managed-bean-class>
sessionpagination.client.ItemController
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
|
The MapBean mapAction method
gets the longitude and latitude for the address
and returns the logical outcome
String map, which causes the navigation to go to the map.jsp page.
This MapBean
mapAction method
is defined as shown below:
| Code Sample from: MapBean.java |
import
com.sun.j2ee.blueprints.ui.geocoder.GeoCoder;
import com.sun.j2ee.blueprints.ui.geocoder.GeoPoint;
import com.sun.j2ee.blueprints.ui.mapviewer.MapMarker;
import com.sun.j2ee.blueprints.ui.mapviewer.MapPoint;
import javax.faces.context.FacesContext;
public class MapBean
{
private MapMarker
mapMarker=new MapMarker();
private MapPoint
mapPoint=new MapPoint();
private String location="";
public MapMarker[] getLocations()
{
return new MapMarker[]{this.mapMarker};
}
public String mapAction() {
// get the ItemController
ManagedBean
ItemController
itemController = (ItemController)
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("item");
Address
address =
itemController.getItem().getAddress();
location=address.getStreet1()
+ COMMA + address.getCity()+ COMMA + address.getState() +
COMMA + address.getZip();
return findLocation();
}
public String findLocation()
{
GeoCoder
geoCoder=new
GeoCoder();
// use blueprints
GeoCoder to get points based on location (this uses
Yahoo's map service)
GeoPoint
points[]=geoCoder.geoCode(location);
mapMarker.setLatitude(points[0].getLatitude());
mapMarker.setLongitude(points[0].getLongitude());
mapMarker.setMarkup(points[0].toString();
mapPoint.setLatitude(points[0].getLatitude());
mapPoint.setLongitude(points[0].getLongitude());
return "map";
}
|
In the mapAction
method, the FacesContext is
used to get the ItemController
in order to get the current store Item's
Address.
Then the findLocation is called, which uses the blueprints GeoCoder component. The blueprints GeoCoder
uses the Yahoo map service to verify the entered address and to get the
exact latitude and longitude.
The JavaServer Faces NavigationHandler
matches the logical outcome, map
against the navigation rules in the application configuration resource
file faces-config.xml
to determine which page to access next. In this case, the
JavaServer Faces implementation loads the map.jsp
page after this method returns.
| Code Sample from: faces-config.xml |
<navigation-rule>
<navigation-case>
<from-outcome>map</from-outcome>
<to-view-id>/item/map.jsp</to-view-id>
</navigation-case>
</navigation-rule>
|
In the map.jsp the blueprints
JSF mapViewer
component uses the latitude and longitude to render the Google map :
Code Sample from: Map.jsp
|
<%@taglib prefix="ui"
uri="http://java.sun.com/blueprints/ui/14"
%>
<ui:mapViewer
id="mapViewerx" center="#{MapBean.mapPoint}" info="#{MapBean.mapMarker}"
markers="#{MapBean.locations}"
zoomLevel="4" style="height: 500px;
width: 700px"/>
|
The mapViewer
component uses the MapBean
to provide the necessary information, which was returned from the GeoCoder
component's Yahoo lookup, to render the Google map.
The mapViewer
center attribute is populated by a com.sun.j2ee.blueprints.ui.mapviewer.MapPoint
which is accessed through the MapBean
backing bean. The mapPoint is used
to center the map utilizing the latitude and longitude from the mapPoint.
The mapViewer
info
attribute holds the address string text that is printed in the
information balloon that is shown with the map.
The mapViewer
markers
attribute holds an Array of com.sun.j2ee.blueprints.ui.mapviewer.MapMarker
objects that represent points to be identified on the map.
This example only populates the Array with the first point returned
from the GeoCoder.
See How
to Use the Map Viewer and GeoCoder Components for more information
on this.
Conclusion
This concludes how to add the Blueprints JSF Map Viewer
component to the sample JSF Store UI.
Running the Sample Application on
Glassfish:
- Download
and install GlassFish V2, following the instructions on the download
page. Alternatively you can use Sun Java System Application Server PE
9, Sun's GlassFish distribution.
- Download
and install NetBeans 5.5.1
- Download
the Sample Application Code
- install Glassfish and Netbeans 5.5.1. Then add the
glassfish application server to Netbeans.
To Open and Test Run the sessionpagination Project:
- Open the Netbeans sessionpagination project: In Netbeans under
File Open Project... go to the directory where you unzipped the sample
and select the sessionpagination project.
- If you get a message that says unresolved references, right click
on the project and select Resolve Reference Problems. Use the Resolve
Reference Problems dialog to map the ejb and web
modules to their
project, which are subdirectories beneath the sessionpagination
directory.
- After the references are resolved, right-click the
sessionpagination
project and select Open Required Projects.
- If the web module says unresolved references, right-click the
sessionpagination-Web module and select Resolve
Reference
Problems:
- Browse to the sessionpagination-ejb directory which is a
sub-directory below the sessionpagination directory and select Open
Project
Folder.
- If you don't have any resolve reference problems errors then
ignore those steps.
- Starts the application server, or at least connect to the
database, because the run script for this application will also create
the database tables, and this will fail if the database is not started.
- Right-click the project node and choose Run Project.
The Netbeans IDE starts the application server, builds the application,
and opens the web context page in your browser. This application also
has a local JSF client in the war of the application which will be
displayed.
- To go to the web client Tester
application provided by the
Glassfish Application Server use the url :
http://host:8080/CatalogService/Catalog?Tester. You should see the
tester page. For the getItems operation type in integer the integers 0,
5 as input and click on the getItems button. This will return a list
of items 0 through 5.
To Open and Test Run the sessionpagination-wsclient Project:
- Open the Netbeans sessionpagination-wsclient project: In Netbeans
under File
Open Project... go to the directory where you unzipped the sample and
select the sessionpagination-wsclient project.
- If the sessionpagination-wsclient project says unresolved
references, right-click the libraries node, select add JAR/Folder,
browse to the lib directory under the sessionpagination-wsclient and
add the bp-ui-14.jar, commons-logging-1.1.jar, and the
shale-remoting.jar files.
- Right-click the project node and choose Run Project.
The Netbeans IDE builds the application,
and deploys it.
- When you run the project, your browser should display the opening
page
of the application at http://localhost:8080/sessionpagination-wsclient/
References:
Sample Catalog Application using using JRuby and Rails
Posted by caroljmcdonald on October 10, 2007 at 02:20 PM | Permalink
| Comments (3)
Sample Store Catalog using using JRuby and
Rails
The RRCatalog Sample app demonstrates the usage of JRuby and Rails to
implement pagination of data sets for a Store Catalog.
download RRCatalog sample code
Overview of the Technologies and Frameworks in the Sample Application
Rails is a
Model-View-Controller based framework for the development of
database-backed web applications in Ruby.
JRuby is a 100%
pure-Java
implementation of the Ruby programming language. With JRuby and Rails
you get the advantage that you
can run your web app in a servlet container like Glassfish or
Tomcat.
The Sample Application
The sample application displays an online catalog of pets sold in a pet
store. The image below shows the Catalog Listing page, which allows a
user to
page through a list of items
in a store.
The Model
The Model is your application's persistent business domain objects.
Rails implements the Active
Record design pattern for the model. An ActiveRecord
object
instance represents a row in a database table. The item.rb and
address.rb
classes shown below were
generated by Rails for the items and addresses tables. To learn how to
generate Rails code
with Netbeans 6 see Creating
a
Ruby Weblog in 10 Minutes . After model code
generation you have to
add the relationships. The Item
class has a many-to-one relationship
with the Address
and Contactinfo classes. In Rails belongs_to
is the
many end of a many-to-one relationship, and has_many
is the one
end. In Rails the convention is that the object with the foreign key
belongs to the other object.
Code Sample from: app/models/item.rb
|
class Item
< ActiveRecord::Base
belongs_to
:address
belongs_to :contactinfo
end
|
|
|
Code Sample from: app/models/address.rb
|
class Address
< ActiveRecord::Base
has_many
:item
end
|
|
The Item class is a subclass of the Rails ActiveRecord
Base class. At runtime the Rails framework dynamically adds column
names,
and attributes (with getters and setters) to the Item class for each
column in the corresponding items table. Rails uses default mapping
rules for this to work easily: the item class defaults to
the items table, the address class to the addresses table, the primary
key defaults to id, a foreign key defaults to tablename_id...
SQL Sample for items table
|
CREATE TABLE items (
id VARCHAR(10) NOT NULL,
name VARCHAR(30) NOT NULL,
description VARCHAR(500) NOT NULL,
imageurl VARCHAR(55),
imagethumburl VARCHAR(55),
price DECIMAL(14,2) NOT NULL,
address_id VARCHAR(10) NOT NULL,
contactinfo_id VARCHAR(10) NOT NULL,
primary key (id),
foreign key (address_id) references addresses(id),
foreign key (contactinfo_id) references contactinfos(id)
);
|
The Controller
Controllers handle incoming http requests, interact with the model to
get data and to process requests, invoke the correct view, and
direct domain data to the view for display.
In Rails, http requests are handled by ActionController classes which
are made up
of one or more action methods that are executed on request and then
either render
a template or redirect to another
action. Rails routes requests to the controller action which
corresponds to the URL mapping for the request. In Rails the default
mapping from URL to action method follows this convention: http://host/controller/action/id . For
example the URL
http://host/item/list calls the
list action method in the item controller class
shown below. Note
this code was generated using the Ruby Rails scaffolding support in the
NetBeans 6 IDE. Rails
Scaffolding provides a series of standardized
actions for listing, showing, creating, updating, and destroying
objects of a class. These standardized actions
come with both controller logic and default view templates (I modified
the view templates). The ItemController
list
action renders a view with a paginated list of item objects.
| Code Sample from: app/controllers/item_controller.rb |
class ItemController
< ApplicationController
def index
list
render :action => 'list'
end
def list
@item_pages, @items = paginate
:items, :per_page
=> 10
end
|
The ItemController is
a subclass of ApplicationController
which is
a subclass of the Rails ActionController Base class.
When a URL has a controller but no action (e.g.
http://host/controller/ ), Rails defaults to the
index action. In the ItemController
code the index
action method redirects to the list
action. The list action
method calls the ActionController paginate
method which queries the Item
Active
Record model for pagination. The pagination method creates the @items
instance variable, which is an ordered collection of model objects for
the
current page (at most 10), and a @item_pages
paginator instance, which is a class representing a paginator for an
Active Record collection. The @item_pages and
@items variables
are automatically made available to the list view by the framework.
After executing
code, actions usually render a template in the views directory
corresponding to the name of the controller and action, for example the
list action will render the
app/views/item/list.rthml template.
The View
The view layer generates a web
page, using data from domain objects provided by the controller. In
Rails, the view is rendered using RHTML
, RXML, or RJS. RHTML is HTML with
embedded Ruby code.
Code Sample from: app/views/item/list.rhtml
|
<h2>Listing items</h2>
<%=
link_to 'Previous page', { :page =>
@item_pages.current.previous }
if @item_pages.current.previous %>
<%=
link_to 'Next page', { :page => @item_pages.current.next }
if @item_pages.current.next %>
<table border="1" cellpadding="4" cellspacing="0">
<thead>
<tr>
<th
scope="col">Name</th>
<th
scope="col">photo</th>
<th
scope="col">Price</th>
</tr>
</thead>
<tbody>
<%
for item in @items %>
<tr>
<td>
<%= link_to
%Q{#{item.name}}, :action => 'show', :id => item %>
</td>
<td>
<%= image_tag
item.imagethumburl %>
</td>
<td align="right">
<%=h
item.price %>
</td>
</tr>
<% end %>
</tbody>
</table>
|
The view uses instance variables set by the controller to
access the data it needs to render the rhtml. In the list.rhtml:
<% for
item in @items %>
loops through the objects in the @items instance
variable, which is an ordered collection of Item model
objects, and assigns each Item
model object to the item variable.
<%=
link_to
%Q{#{item.name}}, :action => 'show', :id => item %>
calls the Rails helper method link_to, which
creates an html link to the item/show/id action which will display the
corresponding item details. Rails helpers
are methods that help your view templates generate HTML. For
example this line will generate the following HTML for one item:
<a href="/item/show/1">Friendly Cat</a>
<%=
image_tag
item.imagethumburl %>
calls the Rails helper method image_tag,
which generates an HTML image tag for the
item's
imagethumburl attribute.
<%=h
item.price %>
displays the value of the item 's price attribute.The
Rails h method creates
escaped HTML text.
<%=
link_to 'Previous page',{:page =>
@item_pages.current.previous} if
@item_pages.current.previous %>
creates an html link to the previous
page of items, using the @item_pages
paginator instance, if there is a previous page.
The Show Action Method
In Rails the mapping for the URL http://host/item/show/1 (
http://host/controller/action/id ) to
action method will
route to the show
action method in the ItemController
passing 1 to the method as the id
member of the params parameter
hash. The show
action method of the ItemController class
is shown below. The ItemController
show
action renders a view showing the details of the item object
corresponding to the id parameter.
| Code Sample from: app/controllers/item_controller.rb |
def show
@item =
Item.find(params[:id])
end
|
The show
action method calls the Item
ActiveRecord Base class find method
which queries the items table creating the @item instance
variable corresponding to the item with the attribute id (primary key)
equal to the id
parameter. This is the equivalent of the following sql : select * from items where id='1' .
The @item variable
is automatically made available to the Show view by the framework.
The Show View Template
After executing
code in the action, the show action
renders the app/views/item/show.rthml template. Below is the RHTML for
the item show view :
Code Sample from: app/views/item/show.rhtml
|
<h2> Detail of item</h2>
<table>
<tbody>
<tr>
<td>Name:</td>
<td> <%=h
@item.name%> </td>
</tr>
<tr>
<td>Description:</td>
<td> <%=h
@item.description%> </td>
</tr>
<tr>
<td>Photo:</td>
<td> <%= image_tag
@item.imageurl %> </td>
</tr>
<tr>
<td>Price:</td>
<td> <%=h
@item.price%> </td>
</tr>
<tr>
<td>Seller's Location:</td>
<td>
<%=h
@item.address.city%> ,
<%=h
@item.address.state%>
</td>
</tr>
<tr>
<td>Seller's email:</td>
<td> <%=h
@item.contactinfo.email%> </td>
</tr>
</tbody>
</table>
|
<%=h
@item.description%>
displays the value of the item 's description attribute,
in escaped HTML text.
<%=
image_tag
@item.imageurl %>
generates an HTML
image tag for the item's imageurl
attribute.
<%=h
@item.address.city%>
displays the value of the item's address city attribute,
in escaped HTML text.
The image below shows the resulting page for the url
http://host/item/show/id, which displays the item's details:
Layout Templates
Rails layout templates let you put common html on multiple views (for
example page headers, footers, sidebars). By default layout
templates are in the views layouts directory with a file name
corresponding to the controller. To add a title and parrot image to the
top of the Pet Catalog pages, I put this table in the
app\views\layouts\item.rhtml template:
| Code Sample from: app/views/layouts/item.rhtml |
<table>
<tr>
<td>Pet Catalog</td>
<td><img
src="/images/banner_logo.gif"></td>
</tr>
</table>
|
Conclusion
This concludes the sample application which demonstrates how to work
with JRuby and Rails to page through a list
of Item Model objects
which are retrieved using Item
Controller action methods, and
displayed using Item rhtml View
templates.
Running the Sample Application:
Setting Things Up
- Download
and install NetBeans 6.0 Beta 1. Get the full distribution so you can
get the Java IDE, Ruby and GlassFish.
- Configure JRuby to use the
Derby Database (by default Ruby uses MySQL, but I use Derby
because I like it. If you prefer MySQL, then ignore this , change
the
RRCatalog\config\database.yml file, and add the tables below to your
MySQL db )
- Open the Tools Options dialog to find the location of your
JRuby
interpreter.
- Copy the following jar to your JRuby lib directory:
derbyclient.jar (Tools > Java DB Database > Settings will give
you the location of derbyclient.jar)
Open and Run the Sample code:
- Download the sample
code and extract its contents. You should now see the newly
extracted directory as
<sample_install_dir>/RRCatalog,
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:\RRCatalog.
- Start the NetBeans IDE. Click Open Project in the File menu and
select
the
RRCatalog directory you just unzipped.
- Start the Java DB database as follows:
- Select Java DB Database in the Tools menu.
- Select Start Java DB Server.
- Add a connection to the Java DB database as follows:
- Select the Services Tab on the left.
- Select Databases, Right mouse click and select New Connection.
- In the New DB Connection window:
for Name: select Java DB (Network)
for URL enter: jdbc:derby://localhost:1527/pet-catalog
for username enter: app , for password enter: app
- Create the tables in the pet-catalog database as follows:
- Under Databases, select the connection pet-catalog that you
just created. Right mouse click and select Connect.
- enter the username app and password app.
- Right mouse click on pet-catalog and select Excecute Command.
- In the SQL command window copy paste all the sql text from
the file
<sample_install_dir>/RRCatalog/catalog.sql,
- At the top of the window click on the icon for Run SQL. This
will create all of the tables and data for the application.
- Run the project as follows:
- Right click the
RRCatalog node in the Projects
window.
- Select Run. This will run the Application with the
WEBrick server.
When you run the project, your browser should display the List Items
page
of the Sample Application (at http://localhost:3000/).
Run the Sample code on Glassfish:
- Use the WAR file in
<sample_install_dir>/RRCatalog/RRCatalog.war
or Create a WAR file:
- In the NetBeans IDE, right-select the project, select
Run
Rake Target, war, standalone, create
- Copy the WAR file (
RRCatalog.war) to your
Glassfish installation "domains/domain/autodeploy"
directory.
- Enter the URL http://localhost:8080/RRCatalog/ in
your browser, you should see the display the List Items
page of the Sample Application.
References
|