Friday, November 17, 2006

Sorting and Paging with EJB Alternatives

A rather clean approach would have been EJB returns a List, Bind the List to Table Component . Thats-it every thing has to work. There are two intresting problems to solve

1) Sorting :- The Table component does its own sorting. It does not use database sorting capabilities nor ejb facilities. Solution is writing TableSorter and bind it to the TableComponent.

2) Paging :- The dataprovider performs the job of paging.  Dataprovider interface provides getRowCount(),getRowKeys(int count, RowKey afterRow). The strait forward approach will be overwrite these methods in the custom dataprovider. But intrestingly the TableComponent has a bug. It always call this method with afterRow=null. As a result we cannot use inbuilt paging features of the Table Component.  Final solution is to write addtional methods in dataprovier to handle paging and call these methods from buttons/links on the webpage.

 

Other options

Using Standard table component : Supports paging ,Does not support sorting, Does not support themes.

Not using Dataprovider : Jsf page still works with out dataprovider. We loose on visual binding of fields with the Table component. The TableLayout screen will not work.

Scope of Dataprovider and Table sorter : Dataprovider can be move to page scope by moving the maxresults and starPosition variables to session. Table Sorter cannot be moved out of session scope.

Desired Solution

NetBeans should some how automatically generate dataprovider, delegate paging and sorting to ejb layer. Table componet has to be- smarter :)

Paging and Sorting in ejb3 Analysis

Netbeans 5.5 VisualWeb Pack is a lovey tool for rapid application development. It is the best solution for your visual development. It lacks few features which are available in its cousin Sun Studio Creator(SJSC). For example in SJSC one can drag an EJB component on to a table. The table automatically re-draws itself to show all the filelds exposed by the draged ejb. I have experimented with Netbeans 5.5 to understand how to use visual development of a web application along with the ejb projects.

The new process is

Create EJB project as usual , Create VisualWeb application

Write a custom Dataprovider  by extending ObjectListDataProvider and Write a Custom Sorter extending TableDataSorter

Handle paging in DataProvider

Handle Sorting in TableDataSorter

Add Dataprovider and TableDataSorter as properties of SessionBean1 , Bind these properties to the table component.

Add Button ui components to your page which will handle the paging events.

I have explaind the detailed process in my previous blog

Sorting and Paging with EJB3

In this article we shall use NetBeans Visual Web Pack 5.5 to create and deploy an ejb3 application along with a web application. The application has two parts. A) An Enterprise application using ejb3 B) A Web application which displays a data grid with sorting and paging. Netbeans has wizards which can manage sorting and paging data bound to a database table. Here we shall see how to achive this features using ejb.
At the end you build a travel web application as shown in the figure

Contents
Prerequisites
Creating Travel EJB application
Creating Entity Classes from Database
Writing StateLess Session Bean
Creating Travel Web Application

Creating DataProvider
Adding Table Component
Binding DataProvider
Creating EjbTableSorter
Binding EjbTableSorter
Adding Paging Buttons


Prerequisites

Before you use this tutorial, you must have the NetBeans 5.5 IDE and Visual Web Pack 5.5 installed on your system. Familiarize yourself with the basic parts of the IDE and read the Getting Started With NetBeans Visual Web Pack 5.5 for an introduction to the Visual Web Pack development environment. All steps in this tutorial are based on the default Visual Web Pack project, which uses the JSF 1.2 and Java EE 5 technologies.

Note: To access the TRAVEL database used in this tutorial, you must configure the IDE to use Sun Java System Application Server 9.0 (also known as GlassFish v1 UR1). For information about installing and configuring the Visual Web Pack and the Sun Java System Application Server, see the NetBeans Visual Web Pack 5.5 Installation Instructions.


Creating Travel EJB application
  1. Choose File > New Project (Ctrl-Shift-N) from the main menu.
  2. Select Enterprise Application from the Enterprise category and click Next.
  3. Name the project NewsApp and set the server to Sun Java System Application Server.
  4. Set the J2EE Version to Java EE 5, and select Create EJB Module and Create Web Application Module, if unselected.
  5. Project Name = Travel
  6. Select a Project Location
  7. Uncheck create web-application module and Create Client module
  8. Click Finish.
Creating Entity Classes from Database

  1. Right click Travel-ejb project
  2. Select New Entity Classes form Database
  3. Create a new DataSource
  4. Add a datasource
  5. Select Person Database Table (next)
  6. Click Create Persistance Unit
  7. Click Create
  8. Click Finish



































Writing StateLess Session Bean

  1. Right Click Travel-Ejb Project Select New Session Bean
  2. Type EJB Name : Person, Package com.travel.service
  3. Check Remote and Local
  4. Add Two Libraries to Travel-ejb . ToplinkEssentials is already available in netbeans. Dataprovider.jar is in following path C:/Sunnetbeans-5.5/rave2.0/modules/ext
  5. Open PersonBean.java. Right Click anywhere in
  6. the code . Add Business Method . Add following methods
  7. getPersons,getcount
  8. Build Travel

Here is the code of PersonBean.java
/* Returns sorted list of persons, Nomber of objects returned can be controlled by specifying
maxresukts and startposition */
public List getPersons(int startPosition, int maxResult, SortCriteria[] sc) {
String query = "select object(o) from Person as o";
if(sc != null){
query = query + " " + "order by " + " " + "o."+sc[0].getCriteriaKey();
if(!sc[0].isAscending()){
query = query + " desc";
}
}

Query q = em.createQuery(query);
q.setMaxResults(maxResult);
q.setFirstResult(startPosition);
return q.getResultList();
}
/* Count */
public int getCount() {
Query q = em.createQuery("select count(o) from Person as o ");
Long count = (Long)q.getSingleResult();
if(count != null){
return count.intValue();
}
return 0;
}


Creating Travel Web Application
  1. Create a new Visual Web application
  2. Add Travel-ejb in the Libraries of TravelWeb project

Creating DataProvider

  1. Create PersonDP.java
  2. Right Click any where in the code select Enterprise Resources | call Enterprise Bean
  3. Select Person Bean
  4. Add following methods to PersonDP refreshDP,getRowCount,next,previous
  5. Add two properties startPosition and maxresults


/*
* PersonDP.java
* Created on November 16, 2006, 6:10 PM
*/
package dataproviders;

public class PersonDP extends ObjectListDataProvider{
/** Creates a new instance of PersonDP */
public PersonDP() {
/* needed by netbeans editor */

setObjectType(Person.class);
}
/* fetch a fresh list of persons from ejb layer*/
public void refreshDP(){
clearObjectList();
setList(lookupPersonBean().getPersons(getStartPosition(),getMaxresults(),null));
}
/* Fetch sorted list of persons from ejb layer*/
public void refreshDP(SortCriteria[] sc){
clearObjectList();

setList(lookupPersonBean().getPersons(getStartPosition(),getMaxresults(),sc));
}
/* find count */
public int getRowCount() throws DataProviderException {
if(Beans.isDesignTime()){

return 5;
}

return lookupPersonBean().getCount();}
/* controls page size*/
private int maxresults =5;
/* starting row*/
private int startPosition;
public int getMaxresults() {
return maxresults;
}
public void setMaxresults(int maxresults) {
this.maxresults = maxresults;
}
public int getStartPosition() {
return startPosition;

}
public void setStartPosition(int startPosition) {
this.startPosition = startPosition;

refreshDP();
}
public void setLastPosition() {

startPosition = (lookupPersonBean().getCount()/maxresults) * maxresults;
refreshDP();
}
/*move to next page*/
public void next(){
if(startPosition + maxresults <= lookupPersonBean().getCount()){
startPosition = startPosition + maxresults;
}
refreshDP();
}
public void previous(){
if(startPosition < lookupPersonBean().getCount()){
startPosition = startPosition - maxresults;
}
if (startPosition < 0){
startPosition =0;
}
refreshDP();
}
/* Helper for calling ejb service . Created by netbeans*/
private PersonRemote lookupPersonBean() {
try {
Context c = new InitialContext();
return (PersonRemote) c.lookup("java:comp/env/ejb/PersonBean");
}
catch(NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught" ,ne);
throw new RuntimeException(ne);
}
}

Adding Table Component

  1. Open Page1 in TraveWeb project
  2. Drag and drop a Table from Pallet window'
  3. Add a Property to SessionBean1
  4. Name of the property is persondp type PersonDP
  5. Inittialize private PersonDP persondp = new PersonDP();
  6. Clean Build TravelWeb
  7. Clean Build Travel-ejb (dont touch travle project)
  8. Restart Netbeans
  9. Open Page 1
  10. Right Click table component on the page
  11. Select Table Layout

Select persondp in getDataFrom dialog

Set Table Layout Options

Creating EjbTableSorter

  1. Create EjbTableSorter.java
  2. Create a Property ejbTableSorter in SessionBean1
  3. Initialize ejbTableSorter

/*
* EjbTableSorter.java
* Created on November 16, 2006, 6:42 PM

*/
package dataproviders;

import com.sun.data.provider.DataProviderException;
import com.sun.data.provider.RowKey;
import com.sun.data.provider.SortCriteria;
import com.sun.data.provider.TableDataProvider;
import com.sun.data.provider.TableDataSorter;
import java.beans.Beans;
import java.io.Serializable;

import java.util.Locale;

public class EjbTableSorter implements TableDataSorter , Serializable {
/** Creates a new instance of EjbTableSorter */
public EjbTableSorter() {
}

protected SortCriteria sortCriteria[];
protected Locale sortLocale;
/** Creates a new instance of EjbSorter */

public EjbTableSorter(SortCriteria sortCriteria[], Locale sortLoc
ale) {
this.sortCriteria = sortCriteria;
this.sortLocale = sortLocale;
}
public void setSortCriteria(SortCriteria[] sortCriteria) {
this.sortCriteria = sortCriteria;

}

public SortCriteria[] getSortCriteria() {
return sortCriteria;
}

public void setSortLocale(Locale locale) {
this.sortLocale= locale;

}

public Locale getSortLocale() {

return this.sortLocale;
}
/* returns sorted list of keys. Gets frersh sorted list of objects from ejb layer*/
public RowKey[] sort(TableDataProvider provider, RowKey[] rows) throws DataProviderException {
if(!Beans.isDesignTime()){

PersonDP persondp = (PersonDP)provider;
persondp.refreshDP(sortCriteria);
System.err.println(" Executed sort EjbSorter.java");
return persondp.getRowKeys(rows.length,null);

}
return provider.getRowKeys(rows.length,null);
}
}


Binding EjbTableSorter
  1. Open Page1 in Visual editor
  2. Select TableRowGroup1 in the Outline window
  3. Rigth Click TableRowGroup1 | Property Bindings
  4. Select all radio button in Property Bindings
  5. Select TableDataSorter in left pane
  6. Select SessionBean1 | ejbSorter in right pane
  7. close
    Adding Paging Buttons
  8. Open Page1 in visual editor
  9. Drag and drop GropPanel from pallet windows
  10. Drag and drop Button from pallet window on to the GroupPanel 4 of them
  11. Change the text property of each button using property editor
  12. Double click on the <<| Button
  13. Add following line getSessionBean1().getPersondp().setStartPosition(0);
  14. Add following code in each button
  15. getSessionBean1().getPersondp().previous(); getSessionBean1().getPersondp().next(); getSessionBean1().getPersondp().setLastPosition();
  16. Deploy Travel Project
  17. Run TravelWeb
  18. Voila your your webrowser will look like the screen shot we started with . You can sort the table, navigate the pages. Also the sorting can be removed. Also sorting order is retained even while moving to another page.

Wednesday, November 08, 2006

Death of AJAX

well Slow death of AJAX
http://www.mozilla.com/en-US/press/mozilla-2006-11-07.html

Tuesday, November 07, 2006

Jkook Blue Prints for JAVA

Jkook Blue Prints for JAVA(BizSutra)
The Introduction
Software development has been challenging as ever. The irony is it has been repetitive for most of us. Over the years I have developed many software products and written heaps of code. Lets take a case of a simple 'Ledger Application' . The first ledger application I have written is in C. Later learnt that a more stable version in COBOL exists in mainframe world. Next a database bug bit me. The Dbase. Then went on to write it in FoxPro. Then came the Open Systems . Had to write it again in Visual Basic (plus oracle). Long Before which i had the taste of technologies like magic and power builder.
Not very long ago I did it again using LAMP.
Welcome to JAVA. History repeated using Servlets. Later with glorified technologies like jsp, struts ...etc . Today i am writing in EJB 2 and Looking forward to write it in ejb3.

The hope the reader of this blog appreciates that the above memoir is not about a specific product. Its about a group of functional requirements which are being solved using different coding languages and techniques. A closer observation reveals that most of these requirements have never changed. And are not going to change in the future. But irony is most of the programmers approach has been consistent. The 'boringly repetitive approach' in question is freshly design, freshly code, freshly gather requirements, use same old faulty patterns. How many times have to coded user authentication,auditing ?

How do we avoid having to code the same set of functional requirements over all again and again?
This is precisely what this BizSutra for Java is going to provide. Wait a min what about those latest technologies and frame-works aren't they supposed to make your life easier?
Yes they do.But does not solve the problem discussed here. Technology is just one piece of this puzzle. Frame-works provide solutions in isolation. We need an integrated solution addressing most of the business requirements.
Let me explain with an example
Auditing is most common requirement. Say we use ejb for auditing. Then what about undo/redo support. Where is does Authentication/Authorization happen ? Most of the frame works provide solutions which work for both requirements. But in isolation. Each of them has to be coded separately and integrated. The BizSutra proposes a single implementation for both the requirements. The challenge is to identify all such common requirements and bundle them as a single implementation.

Business Application Defined
BizSutras
does not attempt to solve all problems. It should be used to develop Business Applications. Typical Business Applications are Accounting, Banking, Inventory Management, Invoice. These types of applications share a common set of functional requirements ie,
[Authentication , Authorization, Audit, Undo/Redo, Persistence, Maker-Checker, One or Two business work-flows, Bulk Import and Export]

The Deliverable :
A comprehensive set of business functionality.
The technology oriented frame-works provide solutions for a specific set of technical problems.(for example scope of Hibernate is persistence , Scope of Struts is MVC). These capabilities are exposed as services or an api. One has to consume these services appropriately to build a Business Application.
BizSutras provides integrated implementation for all the business function discussed above.

The Complete Guide to Drug Free Teens - A Battle Plan for Parents & Teachers

The Complete Guide to Drug Free Teens - A Battle Plan for Parents & Teachers

Tuesday, October 31, 2006

Comparing and Merging two XML files

Comparing and Merging two XML files

The problem :
I have a xml file conversion program. It converts first.xml to target.xml. I have also written a program to convert target.xml to first.xml.
The problem is to preserve the changes made to target.xml. The user is allowed to edit the target.xml manually. For example he can add an element, modify attributes etc..
The file conversion from first.xml to target.xml is not a one-one conversion. There are scenarios like one element in first.xml is equivalent to 25 elements in the target. Further the first.xml does not capture all attributes and data needed to generate target.xml. So there are lot of values which are defaulted during initial conversion. Hence we need a round trip solution . The system should be able to import target.xml and export target.xml while preserving all changes made in target.xml


The current system
xslt is used to generate target.xml from a given first.xml. Conversion of target.xml to first.xml is again handled by xslt. Does not support round trip. ie current system looses most of the changes made manually. Other technologies used XMLBeans , JSF

The approach
Following are the list of feature needed
a) Export first.xml to target.xml
b) Import target.xml to first.xml

At a concept level the import solution can be modeled as follows
Retain the current convertion logic ( ie, extract as much as data needed for first.xml)
Generate a delta of changes.
Use the delta and merge it with the target.xml generated in export process

Activities planned
1) Identify appropriate Java based solutions
2) Evaluate each solution
3) Design the final solution
4) Implement the solution

Solutions evaluated
1) XSLT
2) XMLBeans
3) JAXB
4) XMLUnit
5) The "3DM" XML 3-way Merging and Differencing Tool
6) DOM
7) X-Diff
8) XML Diff and Merge Tool(Alpha works)

The initial though process is to generate the target.xml. Compare it with the one used during import. (instead of storing the delta store the whole document) . Copy/overwrite/ignore the delta to the newly generated target.xml. Hence I started evaluating various options available to deeply compare the xml tree. Features needed are
a) Compare the whole document
b) Compare the elements selectively
c) Comprision has to be smart enough to ignore -- spaces, return characters, alteration of sequences, changes in positions of attributes etc..

1) XSLT --- very complex . There are couple of code fragments available out there. But I felt it was too complex to understand and maintain. Also xsl tends to be too lengthy.
2) XMLBeans -- There are two methods defined in XMLObject compareTo( Object) and compareValue(XMLObject) .
compareTo
public int compareTo(Object obj)
Impelements the Comparable interface by comparing two simple xml values based on their standard XML schema ordering. Throws a ClassCastException if no standard ordering applies, or if the two values are incomparable within a partial order.

compareValue
public int compareValue(XmlObject obj)
This comparison method is similar to compareTo, but rather than throwing a ClassCastException when two values are incomparable, it returns the number 2. The result codes are -1 if this object is less than obj, 1 if this object is greater than obj, zero if the objects are equal, and 2 if the objects are incomparable.

There is also an implementation availble in XMLObjectBase.java. This method does not work. I downloaded the source code and trid to fix it. I was not going any where. One of the response from bea says that these methods can handle ony simple type( what ever it is) and need developers to code for handling schema based comparision.

3) JAXB
The story with jaxb is almost the same as xml beans. The interfaces have compareTo(Object ) . But there is no implementation.
4) XMLUnit
Comparing xml files is very easy in XMLUnit
Diff myDiff = new Diff(controlDocument, testDocument); XML Unit can identify similar, identical and also print all differences found with element name and attribute names. The limitation is the API is built around DOM ie, it works with org.w3c.dom.Document which represents the whole xml document. XML Unit does not support our B requrement
5) The "3DM" XML 3-way Merging and Differencing Tool
This project is still in alpha
6) DOM
DOM 3 has defined the behaviour for isEqualNode(). I tried the default parser in JDK 1.5 and also Xerces-J-bin.2.8.1. In either case it throws an exception saying DOM 3 implementation needed. Even Oracle parser has DOM 3 but i wonder if they have implemented isEqualNode(). The conclution is DOM 3 isEqualNode() is not yet there
7) X-Diff
No files released
8) XML Diff and Merge Tool(Alpha works)
This seems to be targeted to GUI applications . Not suitable for our requirements.

Conclusion
It seems comparing XML is still an under developed technology. This raises few more questions.
What happened to the do any thing and do in anywhere promise of XML. Or is this impression I got coz my exploration is limited to java world.
How does mature technologies like RDBMS handle this kind of requirements.
After-all RDBMS does handle these problems. The solution in RDBMS world are much simpler. It does not have deeply nested hierarchies. So these type of requirements are handled by manual coding. Probably we will not need sophisticated tools as in XML world.

After this exercise I had changed my approach. The new approach is use manual coding. I used XMLBeans as binding framework. Manipulate each element as java objects appropriately to handle the export and import functions.