blob: 1ec90b8cf20d338a5f620e8b079d31088e53e30b [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-->
<head>
<link rel="stylesheet" type="text/css" href="../../netbeans.css"
media="screen">
<meta name="author" content="Tinuola Awopetu">
<meta name="keywords"
content="NetBeans IDE, ICEfaces 1.7, NetBeans 6.0.1, CRUD Applications">
<title>Building Collaborative CRUD Applications With ICEfaces and
NetBeans</title>
</head>
<body>
<p><img style="margin-right:10px;width: 180px; height: 69px;" alt="ICEfaces"
src="../../images_www/partners/iceSoft.jpg" align="left"></p>
<h1>Building Collaborative CRUD Applications With ICEfaces and NetBeans</h1>
<br>
<p><em>Published: May 2008</em></p>
<img src="../../images_www/articles/60/netbeans-stamp.gif" class="stamp" width="114" height="114"
alt="Content on this page applies to NetBeans IDE 6.0.1"
title="Content on this page applies to NetBeans IDE 6.0.1">
CRUD-style applications remain the mainstay of enterprise
application development, but more and more, application developers are
looking to add Rich Internet Application (RIA) capabilities into their
development process. <a href="http://www.icefaces.org">ICEfaces</a>
provides a comprehensive development framework for building RIAs using
pure Java techniques based on <a
href="http://java.sun.com/javaee/javaserverfaces/">JavaServer Faces
(JSF)</a>, but beyond RIA features ICEfaces can truly revolutionize
web applications by facilitating real time collaboration using Ajax
Push. The latest ICEfaces 1.7 release includes complete
integration with&nbsp;<a
href="http://download.netbeans.org/netbeans/6.0/final/">NetBeans
6.0.1</a> making it easy to build collaborative RIA-style applications;
<a href="http://glassfish.dev.java.net/">Glassfish</a>
combined
with the Asynchronous Request Processing (ARP) features of <a
href="http://grizzly.dev.java.net/">Grizzly</a> provides the
scalable deployment infrastructure required for push-style web
applications.<span style="font-weight: bold;"></span><br>
<br>
Essentially, CRUD-style applications enable users to interact with
enterprise data, including <span style="font-weight: bold;">C</span>reating,
<span style="font-weight: bold;">R</span>eading, <span
style="font-weight: bold;">U</span>pdating and <span
style="font-weight: bold;">D</span>eleting data, thus the CRUD
acronym. If we apply RIA techniques to a CRUD application, our
primary motivation is to make interactions between user and data more
effective. This might mean providing sortable table headers,
improving data navigation through hierarchical tree representations,
and
enriching master/detail views onto the data. While making the
user interaction with the application more effective is a worthwhile
exercise onto itself, it does nothing to enhance the interactions
between the users of that data. This is where Ajax Push
techniques come into play, as they enable asynchronous real time data
push to the user when data changes. Now, when those changes occur as
the result of one user manipulating the data, all users interested in
that particular data can be instantaneously informed of the
change. Web-based collaboration is the essence of Web 2.0 and
Ajax Push enables it, fundamentally changing what is possible in
web applications and turning dusty old CRUD applications into rich,
interactive, collaboration platforms.<br>
<br>
So what does it take to build collaborative CRUD applications?
In the remainder of this article we will work through a very basic
example using ICEfaces and NetBeans to illustrate how easily attainable
they are. While the example is simplistic, it fully exposes all
the technique you will require to leverage rich ICEfaces features and
Ajax Push all through the NetBeans JSF Visual Design Editor. The
example uses the ICEfaces 1.7, and NetBeans 6.0.1 releases. The
completed NetBeans project can be download from the ICEfaces <a
href="http://www.icefaces.org/main/resources/tutorials.iface">tutorial
page</a> under the <span style="font-style: italic;">IDE Tutorials</span>
tab.<br>
<br>
<h2>Installing the ICEfaces Plugins in NetBeans</h2>
<ol>
<li>Registered ICEfaces community members can download the
ICEfaces/NetBeans integration bundle <a
href="http://www.icefaces.org/main/downloads/os-downloads.iface">here</a>.
The bundle is located under <span style="font-style: italic;">IDE Tool
Integrations &gt; NetBeans</span>, and is called <span
style="font-style: italic;">ICEfaces-1.7.0-Netbeans-6.0.1-modules.zip.
</span>Unpack the bundle somewhere that you can access it from
NetBeans.<br>
</li>
<li>Install the ICEfaces plugins into NetBeans from <span
style="font-style: italic;">Tools &gt; Plugins</span> dialog, using
the <span style="font-style: italic;">Downloaded</span> tab. The <span
style="font-style: italic;">Add Plugins</span> button is used
to select the ICEfaces plugins which are called <span
style="font-style: italic;">com-icesoft-faces-vwp-ide.nbm</span> and <span
style="font-style: italic;">com-icesoft-ide-netbeans-libs-module.nbm</span>.
Once you have selected the plugins, you should see something like this,
and just need to hit the <span style="font-style: italic;">Install</span>
button.</li>
<br>
<img style="width: 653px; height: 341px;"
alt="ICEfaces Plugin Installation"
src="../../images_www/articles/icefaces-crudapps/nb-plugin-install.png"><br>
<br>
</ol>
<span style="font-weight: bold;"></span>
<h2>Creating an ICEfaces Project</h2>
<ol>
<li>Create a new project using <span style="font-style: italic;">File
&gt; New Project</span> wizard, and
select <span style="font-style: italic;">Web &gt; Web Application</span>
for the project type and hit <span style="font-style: italic;">Next
&gt;</span>
button.</li>
<li>Name the project<span style="font-style: italic;">
CollaborativeCRUD</span> and select GlassFish V2
server, and Java EE 5, then hit the <span style="font-style: italic;">Next
&gt;</span> button.</li>
<li>Select the Visual Web ICEfaces framework, as illustrated below,
and hit Finished button.</li>
<li><img style="width: 728px; height: 477px;"
alt="New Web Application"
src="../../images_www/articles/icefaces-crudapps/new-webapp.png"></li>
</ol>
<h2>Connecting an ice:DataTable to a Database Table</h2>
<ol>
<li>In the Visual Design Editor, you see the template for an ICEfaces
page called Page1. Delete the default <span style="font-style: italic;">InputTextarea</span>,
and from the
ICEfaces Palette drag an <span style="font-style: italic;">ice:DataTable</span>
onto the page as illustrated below.</li>
<img style="width: 821px; height: 390px;" alt="Drag DataTable"
src="../../images_www/articles/icefaces-crudapps/datatable-drag.png"><br>
<br>
<li>Next, drag a database table onto the<span
style="font-style: italic;"> ice:DataTable</span>. This
can be done from the <span style="font-style: italic;">Services</span>
tab under <span style="font-style: italic;">Databases</span>, as
illustrated
below. For this example you will use the <span
style="font-style: italic;">Person</span> table, from the <span
style="font-style: italic;">Travel</span> database. Make sure the drag
target is the <span style="font-style: italic;">dataTable</span>
and
not the <span style="font-style: italic;">htmlForm</span>. You
will see that the column data in the <span style="font-style: italic;">ice:DataTable</span>
now reflect
the content of the <span style="font-style: italic;">Person</span>
database table.</li>
<img style="width: 839px; height: 298px;" alt="Drag Person DB"
src="../../images_www/articles/icefaces-crudapps/drag-person-db.png"><br>
<br>
<li>Add a Sortable Header and a Row Selector using the context menu
for the <span style="font-style: italic;">ice:DataTable</span> as
illustrated below.</li>
<img style="width: 876px; height: 388px;" alt="Add Sort Header"
src="../../images_www/articles/icefaces-crudapps/add-sort-header.png"><br>
<br>
<li>When the row selector binding dialog appears, simply accept the
defaults and close, as illustrated below. Later you will use the <span
style="font-style: italic;">rowSelectior1_processAction</span>
listener to implement the editing logic for
selected rows.</li>
<img style="width: 607px; height: 319px;" alt="Row Select Binding"
src="../../images_www/articles/icefaces-crudapps/rowselect-binding.png"><br>
<br>
<li>You can now test that this all works by building the project and
running it. The result, illustrated below, is a sortable table of
the <span style="font-style: italic;">Person</span> database with row
selection, which at this point does
nothing.</li>
<img style="width: 750px; height: 400px;" alt="Run 1"
src="../../images_www/articles/icefaces-crudapps/run-one.png"><br>
</ol>
<br>
<ol>
</ol>
<h2>Implement Simple Data Model To Support Editing</h2>
<ol>
<li>First you need to create a wrapper class for the person
data.<br>
&nbsp;<br>
<span style="font-weight: bold;">package CollaborativeCRUD;</span><br
style="font-weight: bold;">
<br style="font-weight: bold;">
<span style="font-weight: bold;">import java.sql.Timestamp;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">import java.util.TreeMap;</span><br
style="font-weight: bold;">
<br style="font-weight: bold;">
<span style="font-weight: bold;">public class Person {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private Integer
personId;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private String
name;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private String
jobTitle;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private Integer
frequentFlyer;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private
Timestamp lastDateUpdated;</span><br style="font-weight: bold;">
<br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public Integer
getFrequentFlyer() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return frequentFlyer;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setFrequentFlyer(Integer frequentFlyer) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.frequentFlyer = frequentFlyer;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public String
getJobTitle() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return jobTitle;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setJobTitle(String jobTitle) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.jobTitle = jobTitle;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public
Timestamp getLastDateUpdated() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return lastDateUpdated;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setLastDateUpdated(Timestamp lastDateUpdated) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.lastDateUpdated = lastDateUpdated;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public String
getName() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return name;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setName(String name) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.name = name;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public Integer
getPersonId() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return personId;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setPersonId(Integer personId) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.personId = personId;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public Person()
{</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public
Person(Integer personId, String name, String jobTitle, Integer
frequentFlyer, Timestamp lastDateUpdated) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.personId = personId;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.name = name;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.jobTitle = jobTitle;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.frequentFlyer = frequentFlyer;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.lastDateUpdated = lastDateUpdated;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public
Person(TreeMap data) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.personId = (Integer) data.get("PERSON.PERSONID");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.name = (String) data.get("PERSON.NAME");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.jobTitle = (String) data.get("PERSON.JOBTITLE");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.frequentFlyer = (Integer) data.get("PERSON.FREQUENTFLYER");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.lastDateUpdated = (Timestamp) data.get("PERSON.LASTUPDATED");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">}</span><br
style="font-weight: bold;">
<br>
</li>
<li>Next you will establish some state in your page bean to support
editing of the selected row. You need to capture the selected
person,
and maintain a boolean indicating whether editing is disabled.<br>
<br>
public class Page1 extends AbstractPageBean {<br>
&nbsp;&nbsp;&nbsp; // Managed Component Definitions<br>
&nbsp;&nbsp; ...<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private Person
blankPerson = new Person(0, "", "", 0, null);</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private Person
selectedPerson = blankPerson;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private boolean
editDisabled = true;</span><br style="font-weight: bold;">
<br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public boolean
isEditDisabled() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return editDisabled;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setEditDisabled(boolean editDisabled) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.editDisabled = editDisabled;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public Person
getSelectedPerson() {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return selectedPerson;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setSelectedPerson(Person selectedPerson) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.selectedPerson = selectedPerson;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<br>
</li>
<li>Next you need to implement the row selection logic in the action
listener previously defined for this. You need to extract the row
out of the data model associated with the <span
style="font-style: italic;">ice:DataTable</span>, in this case
the <span style="font-style: italic;">dataTableSortableDataModel</span>.
You also need to enable editing
when the row is selected.<br>
<br>
&nbsp;&nbsp;&nbsp; public void
rowSelector1_processAction(RowSelectorEvent rse) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int selectedRowIndex =
rse.getRow();<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
editDisabled = false;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dataTable1SortableDataModel.setRowIndex(selectedRowIndex);</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
selectedPerson = new Person((TreeMap)
dataTable1SortableDataModel.getRowData());</span><br
style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; } <br>
<br>
</li>
<li>Build the project so that the new objects will be available for
binding into the page.<br>
<br>
</li>
</ol>
<h2>Create Editing Form</h2>
<ol>
<li>Add a second <span style="font-style: italic;">ice:Form</span>
by dragging one from the ICEfaces component
palette onto the page. Make sure the new form follows the
existing one, and is not nested inside it. You will also have to resize
the form to accept the editing controls that you will add next.</li>
<li>To keep the example as simple as possible, the editing feature
will display the selected name in an <span style="font-style: italic;">ice:OutputText</span>,
and allow editing
of the job description in an <span style="font-style: italic;">ice:InputText</span>.
Start by dragging an <span style="font-style: italic;">ice:OutputText</span>
onto the
new form. Right click the <span style="font-style: italic;">OutputText</span>
to
display the context menu, and select <span style="font-style: italic;">Bind
To Data</span>. You need to
create the binding <span style="font-style: italic;">#{Page1.selectedPerson.name}</span>
as illustrated below.<br>
<br>
<img style="width: 665px; height: 451px;" alt="Output Text Binding"
src="../../images_www/articles/icefaces-crudapps/output-textbinding.png"><br>
<br>
</li>
<li>Now drag an <span style="font-style: italic;">ice:InputText</span>
onto the form, and create the binding <span style="font-style: italic;">#{Page1.selectedPerson.jobTitle}</span>
in the same manner that you did for
the <span style="font-style: italic;">OutputText</span>. Once
you have done that you will add one
additional binding to enable and disable the <span
style="font-style: italic;">InputText</span>. Again,
right click the <span style="font-style: italic;">InputText</span> and
from the context menu select <span style="font-style: italic;">Property
Bindings</span>. You need to bind the <span style="font-style: italic;">disabled</span>
property to your <span style="font-style: italic;">editDisabled</span>
boolean in the page bean, as illustrated below.</li>
<img style="width: 778px; height: 520px;" alt="Disabled Binding"
src="../../images_www/articles/icefaces-crudapps/disabled-binding.png"><br>
<br>
<li>Finally, drag an <span style="font-style: italic;">ice:CommandButton</span>
onto the form. When you
are done, your page design should look something like illustrated
below. As with the <span style="font-style: italic;">InputText</span>,
you want to bind the <span style="font-style: italic;">CommandButton</span>
<span style="font-style: italic;">disabled</span> property to the <span
style="font-style: italic;">editDisabled</span> boolean with a binding
like <span style="font-style: italic;">disabled=#{Page1.editDisabled}</span>.</li>
<img style="width: 702px; height: 491px;" alt="Form Design View"
src="../../images_www/articles/icefaces-crudapps/formdesign-view.png"><br>
<br>
</ol>
<h2>Add The Editing Logic</h2>
<ol>
<li>Right click the <span style="font-style: italic;">submit</span>
button and from the context menu select <span
style="font-style: italic;">Edit Event Handler &gt;
processAction</span>, which will create the Java code
for the <span style="font-style: italic;">button1_processAction()</span>
event listener in the page bean. You need to add logic to this member
function to persist the data, and
disable editing until the next row selection occurs. To do this
you will use the NetBeans data provider that was established
automatically when you associated the <span style="font-style: italic;">Person</span>
table with the <span style="font-style: italic;">ice:DataTable</span>.
The
code for achieving this is shown below.<br>
<br>
&nbsp;&nbsp;&nbsp; public void button1_processAction(ActionEvent ae) {<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet)
getValue("#{SessionBean1.personRowSet}"));</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
persistPerson(selectedPerson);</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
selectedPerson = blankPerson;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
editDisabled = true;</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
</li>
<li>The logic for persisting a person into the database is
implemented as follows.<br>
<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private void
persistPerson(Person person) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (personDataProvider != null) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
java.util.Date d = new java.util.Date();</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Timestamp ts = new Timestamp(d.getTime());</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean done = false;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
try {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (personDataProvider.getRowCount() &gt; 0) {</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.cursorFirst();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
do {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if
(personDataProvider.getValue("PERSON.PERSONID").equals(person.getPersonId()))
{</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setValue("PERSON.NAME", person.getName());</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setValue("PERSON.JOBTITLE", person.getJobTitle());</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setValue("PERSON.FREQUENTFLYER",
person.getFrequentFlyer());</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setValue("PERSON.LASTUPDATED", ts);</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
done = true;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
} while (!done &amp;&amp; personDataProvider.cursorNext());</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.commitChanges();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
} catch (Exception ex) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
System.out.println("Exception occured: " + ex);</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ex.printStackTrace();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<br>
</li>
<li>One last thing you need to do is ensure that the table view on
the data is refreshed before the render occurs to ensure it is up to
date. This is done in the <span style="font-style: italic;">prerender()</span>
member function as shown
below.<br>
<br>
&nbsp;&nbsp;&nbsp; public void prerender() {<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
try {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CachedRowSet cachedRowSet = (CachedRowSet)
getValue("#{SessionBean1.personRowSet}");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cachedRowSet.execute();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.refresh();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dataTable1SortableDataModel.setWrappedData((javax.sql.rowset.CachedRowSet)
getValue("#{SessionBean1.personRowSet}"));</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
} catch (Exception ex) {</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
System.out.println("Exception occured: " + ex);</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ex.printStackTrace();</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
</li>
<li>You can now build and run the application. When a row is
selected it should look something like this.</li>
<img style="width: 906px; height: 541px;" alt="Run 2"
src="../../images_www/articles/icefaces-crudapps/run-two.png"><br>
<br>
<li>Now try interacting with the application from 2 different browser
clients. You will see that if changes are made in one client,
they are not reflected in the other client until you interact with that
client, at which time the data is updated to reflect the existing
content in the database. Without Ajax Push implemented in this
applications, the client's view onto the data can be stale at any
moment in time.</li>
</ol>
<h2>Add Ajax Push</h2>
<ol>
<li>The Ajax Push infrastructure in ICEfaces is organized under an
application scope bean called <span style="font-style: italic;">RenderManager</span>.
To add this bean
to your application open the <span style="font-style: italic;">faces-config.xml</span>
in XML view in the
editor. Right click an existing managed bean definition and from
the context menu select<span style="font-style: italic;"> JavaServer
Faces &gt; Add Managed Bean</span>, as
illustrated below.</li>
<img style="width: 908px; height: 480px;" alt="Add Managed Bean"
src="../../images_www/articles/icefaces-crudapps/add-managedbean.png"><br>
<br>
<li>Define a managed bean called <span style="font-style: italic;">RenderManager</span>
with the class <span style="font-style: italic;">com.icesoft.faces.async.render.RenderManager</span>
in applications scope as
illustrated below.</li>
<img style="width: 563px; height: 320px;" alt="RenderManager Bean"
src="../../images_www/articles/icefaces-crudapps/render-manager.png"><br>
<br>
<li>This will result in the following code being added to your <span
style="font-style: italic;">faces-config.xml</span>.<br>
<br>
&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-name&gt;RenderManager&lt;/managed-bean-name&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-class&gt;com.icesoft.faces.async.render.RenderManager&lt;/managed-bean-class&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-scope&gt;application&lt;/managed-bean-scope&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br>
<br>
</li>
<li>You will need access to the <span style="font-style: italic;">RenderManager</span>
from your page bean so
add it as a managed property with the following code.<br>
<br>
&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-name&gt;Page1&lt;/managed-bean-name&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-class&gt;CollaborativeCRUD.Page1&lt;/managed-bean-class&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;managed-property&gt;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;property-name&gt;renderManager&lt;/property-name&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;property-class&gt;com.icesoft.faces.async.render.RenderManager&lt;/property-class&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;value&gt;#{renderManager}&lt;/value&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;/managed-property&gt;</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br>
<br>
</li>
<li>Next you need your page bean to implement the <span
style="font-style: italic;">Renderable</span> interface as shown below.<br>
<br>
public class Page1 extends AbstractPageBean<span
style="font-weight: bold;"> implements Renderable</span> {<br>
<br>
Now if you right click the page, and select <span
style="font-style: italic;">Insert Code</span> from the context menu,
you will see a dialog from which you can select <span
style="font-style: italic;">Implement Method</span>. You can now
select the Renderable interface and generated the members as shown
below.</li>
<br>
<img style="width: 434px; height: 195px;" alt="Renderable Methods"
src="../../images_www/articles/icefaces-crudapps/renderable-methods.png"><br>
<br>
<li>Before you complete the implementation, you need to add some
state to your page bean as shown below. You will need access to
the <span style="font-style: italic;">PersistentFacesState</span>, <span
style="font-style: italic;">RenderManager</span>, and an <span
style="font-style: italic;">OnDemandRenderer</span> to hold the list
of <span style="font-style: italic;">Renderables</span> (1 per client
session). The <span style="font-style: italic;">OnDemandRenderer</span>
is a named singleton that will be created by the <span
style="font-style: italic;">RenderManager</span>.<br>
<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private
PersistentFacesState state = null;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private
RenderManager renderManager;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; private
OnDemandRenderer personGroup = null;</span><br
style="font-weight: bold;">
<br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public void
setRenderManager(RenderManager renderManager){</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if(renderManager != null){</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
this.renderManager = renderManager;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personGroup = renderManager.getOnDemandRenderer("personGroup");</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personGroup.add(this);</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; </span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; public
RenderManager getRenderManager(){</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return renderManager;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; }</span><br
style="font-weight: bold;">
<br>
</li>
<li>Make sure the persistentFacesState is initialized in the page
bean init() member.<br>
<br>
&nbsp;&nbsp;&nbsp; public void init() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Perform application
initialization that must complete<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // *after* managed
components are initialized<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO - add your own
initialization code here<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
state = PersistentFacesState.getInstance(); </span><br
style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
</li>
<li>Now you can complete the implementation of the <span
style="font-style: italic;">Renderable</span> interface with the
following code.<br>
<br>
&nbsp;&nbsp;&nbsp; public PersistentFacesState getState() {<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return state;</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; public void renderingException(RenderingException
re) {<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personGroup.remove(this);</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
</li>
<li>Finally, you need to request a render whenever changes are
committed to the database. This is done in the action listener
for the <span style="font-style: italic;">submit</span> button as
shown below.<br>
<br>
&nbsp;&nbsp;&nbsp; public void button1_processAction(ActionEvent ae) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personDataProvider.setCachedRowSet((javax.sql.rowset.CachedRowSet)
getValue("#{SessionBean1.personRowSet}"));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
persistPerson(selectedPerson);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selectedPerson = blankPerson;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; editDisabled = true;<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
personGroup.requestRender();</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp; }<br>
<br>
</li>
<li>You can now build and run the application. If you view it
in two different browsers you should see changes pushed to both when
changes are made to the data. You now have a fully functional
collaborative CRUD application. The application will also work
from multiple windows in the same browser instance, but first you will
need to turn on <span style="font-style: italic;">concurrentDOMViews</span>
in the <span style="font-style: italic;">web.xml</span> as shown below.<br>
<br>
&nbsp;&nbsp;&nbsp; &lt;context-param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;param-name&gt;com.icesoft.faces.concurrentDOMViews&lt;/param-name&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;<span
style="font-weight: bold;">true</span>&lt;/param-value&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;/context-param&gt;<br>
</li>
</ol>
<h2>Configure The Grizzly ARP Engine</h2>
<ol>
<li>The current deployment of the application relies on a standard
Servlet to handle the Ajax Push connection, which is not a scalable
solution. By configuring Grizzly into the deployment you can make
the application scale well for large numbers of concurrent users.
In future releases of ICEfaces, Grizzly configuration will be
automated, but for now there is a bit of manual configuration that you
must do. First you must add the Grizzly Servlet as the first
Servlet in your <span style="font-style: italic;">web.xml</span>, as
shown below.<br>
<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; &lt;servlet&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;servlet-name&gt;Grizzly Push Servlet&lt;/servlet-name&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;servlet-class&gt;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
com.icesoft.faces.webapp.http.servlet.GrizzlyPushServlet</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;/servlet-class&gt;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;load-on-startup&gt; 1 &lt;/load-on-startup&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp; </span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;
&lt;servlet-mapping&gt;</span><br style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;servlet-name&gt;Grizzly Push Servlet&lt;/servlet-name&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;url-pattern&gt;/block/receive-updated-views/*&lt;/url-pattern&gt;</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;
&lt;/servlet-mapping&gt;</span><br style="font-weight: bold;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;servlet-name&gt;Persistent Faces Servlet&lt;/servlet-name&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;servlet-class&gt;com.icesoft.faces.webapp.xmlhttp.PersistentFacesServlet&lt;/servlet-class&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;<br>
<br>
</li>
<li>Next you have to add the <span style="font-style: italic;">cometSupport</span>
property to the http-listener in your Glassfish <span
style="font-style: italic;">domain.xml</span> file. NetBeans can tell
you the location of this file for your installation
from the <span style="font-style: italic;">Services</span> tab under <span
style="font-style: italic;">Servers</span>. Right click the
Glassfish server and select properties from the context menu, and you
will see the directory path to your <span style="font-style: italic;">domain.xml</span>
file as illustrated below. Also, you will need to turn off <span
style="font-style: italic;">Enable HTTP Monitor</span> to see the true
performance of the application.<br>
<br>
<img style="width: 769px; height: 512px;" alt="Glassfish Properties"
src="../../images_www/articles/icefaces-crudapps/glassfish-properties.png"><br>
<br>
Once you have located the <span style="font-style: italic;">domain.xml
</span>file, you need to add the <span style="font-style: italic;">cometSuppor</span>t
property as shown below.<br>
<br>
&lt;http-listener acceptor-threads="1" address="0.0.0.0"
blocking-enabled="false" default-virtual-server="server" enabled="true"
family="inet"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
id="http-listener-1" port="17154" security-enabled="false"
server-name="" xpowered-by="true"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property
name="proxiedProtocols" value="ws/tcp"/&gt;<br>
<span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;property name="cometSupport" value="true"/&gt;</span><br
style="font-weight: bold;">
&lt;/http-listener&gt;<br>
<br>
</li>
<li>Now rebuild the application, and restart the server. The
application is now running with Grizzly configured to handle all the
Ajax Push connections.</li>
</ol>
<h2>Inspiration Time</h2>
You have now completed your first collaborative CRUD application.
While simplistic, the example illustrates all the key concepts required
to build sophisticated collaborative applications with ICEfaces and
NetBeans. Take what you have learned here, and apply your own
inspiration to future application development. You can change the
way your enterprise collaborates, and usher your colleagues and
customers into the Web 2.0 era.<br>
<br>
<div style="text-align: right;"><span style="font-style: italic;">(May
2008)</span> <br>
</div>
<br>
</body>
</html>