Sophisticated UI Development Using ADF Faces

Dr. Paul Dorsey, Dulcian, Inc.

Yalim Gerger, Gerger Consulting

Until recently, high quality user interfaces have been the exclusive domain of client/server applications.  Web application user interfaces have traditionally been slower and of significantly lower quality than their client/server counterparts.  JSP/Struts applications came nowhere near the quality of Oracle Forms or PowerBuilder applications, and things that could be done in C++ or Java (using Swing components) could not even be imagined on the web.  What could be done, took much longer to do than in the client/server environment.

Oracle’s ADF Faces has significantly closed the gap between client server technology and web technology. ADF Faces applications can easily rival Oracle Forms applications, both in quality of the user interface (UI) as well as in performance. 

Perhaps more significant is that the “development gap” has also narrowed. It is now possible to build applications just as quickly in ADF Faces as it was in products such as Oracle Forms.  If developers use a “thick-database” approach and place most of the logic in the database, then applications can actually be built faster than using a traditional client/server-based method.

This paper will describe a complex development effort using ADF Faces. The goal was to build a repository manager similar in scope to the Designer RON. The application required a sophisticated tree control and numerous, complex property screens.  The underlying database was designed using a high level of abstraction and the core of the model was recursive. The application chosen would have been difficult to create in any development environment. 

The Project

The client for whom the application described in this paper was developed is a factory. The order entry process for this factory is very complex.  There are not many products, but each product has dozens of attributes that must be specified as part of the order process. These attributes have various dependencies among them. There are hundreds of business rules to validate/enforce when a customer is submitting a purchase order or asking for a quote. Each product is sufficiently unique that it requires its own dedicated entry form.

 

The customer has two options for placing an order. They can either call a sales representative or go online. If the customer orders through a sales representative, the sales person uses an Oracle Forms application to enter the specifications. If the customer goes online, the customer enters the specifications using a web-based application. Since there are 13 different products, there are 26 different order applications. Thirteen are implemented in Oracle Forms (for internal use by sales representatives) and 13 in ADF JSP/Struts (for web access from customers).

 

The business rules for the applications, both in Oracle Forms and ADF JSP/Struts are exactly the same. To avoid coding the same business rules multiple times, a business rule repository was designed. Order entry applications access this rule repository in real time and execute the business rule logic within it.

 

The rules repository is a 15-table Oracle database that was designed and generated using Dulcian’s BRIM® tool. A repository of this size requires its own user interface to enter and maintain the business rules. Originally the repository manager to maintain the rules repository was built using Oracle Forms and it was functional, but not very intuitive or easy to use.  Since the development team had identified ways in which the design of the repository could be improved, it was decided to upgrade the repository data model and rewrite the repository manager using ADF Faces. The revised data model for the repository is shown in Figure 1. 

Figure 1: Rules Repository Data Model

 

This paper describes the construction of the new Repository Manager application in ADF Faces. It discusses the challenges encountered, mistakes made and solutions found.

The Application: Repository Manager

The Repository Manager is used to enter and maintain the business rules. The UI is similar to the one built using Oracle Forms since there existed 13 applications implemented in Oracle Forms and users were already familiar with this tool. This reduced the amount of training required. All of the business logic can be represented nicely using a subset of Oracle Forms objects such as triggers, fields, blocks etc.

Some extensions and changes to the Oracle Forms UI were needed in order to make use of the repository.  Figure 2 shows the Repository Manager user interface.

Figure 2: Repository Manager user interface

 

This application takes advantage of the sophisticated UI JavaServer Faces components shown here as two tree components.

JavaServer Faces Tree Components

In this application, it was necessary to ensure that the tree component could support all of the required functionality. Before making a decision to use the ADF Faces tree component several other options were evaluated:

1. Pure JavaScript tree running completely on the client machine

2. MyFaces tree component

3. ADF Faces tree

The following criteria were used to evaluate the options:

·         How well does the component integrate with ADF? Are managed beans needed to feed the tree the nodes?

·         How much custom code is needed?

·         How customizable is the component?

·         Does it publish a rich set of events/methods that can be used to alter the behavior look-and-feel of the component?

The first option of the JavaScript tree was eliminated for a number of reasons. The look-and-feel was sub par at best, and there was no out-of the box integration. It would be necessary to develop the beans that would supply the data to the tree and write custom code to synchronize the tree when the users edited repository objects which would affect the node displays or the tree status. Although it was highly customizable, the widget seemed more appropriate for simpler trees with more static data.

The MyFaces tree was a reasonable candidate. Its only true downside was that it did not automatically bind to ADF Business Components.  Since JSF was new to the development team, it did not seem wise to try to integrate MyFaces components.

The ADF Faces tree component is a server-side component, meaning that the tree relies on the middle tier to handle its events and supply its data. It cannot be configured to run only on the client side. (This is not true for the MyFaces tree component). The ADF Faces tree binds seamlessly to ADF Business Components. This tree is also smart enough to detect changes in the rows in the database that it is displaying. Therefore, when the business layer updates a row in the database (through a separate view object/entity that does not bind to the tree) the changes are reflected in the tree with the next rendering. As predicted, the tree state (which nodes are expanded or not) did not always display the tree the way it should when users created a new repository object or changed its display. However the tree state provided methods for customization.

Unfortunately, icon support for the ADF Faces tree nodes was completely missing although a workaround was found to deal with this omission. Another possible problem with this option is that Oracle warns developers about possible performance issues with the tree component. Being a middle tier-driven component with no client side caching makes this a valid warning.

After careful evaluation of the three options, the ADF Faces tree component seemed to be the best solution. The problems that existed with the component were either not relevant to this project or there were suitable workarounds.

 

ADF Tree: Developing the Appropriate Business Components

The tree on the left side of the screen shown in Figure 2 is used for navigation among the various objects in the repository. This tree should be familiar to Oracle Forms Developer users since it has a very similar structure and look-and-feel.

Construction of the tree started with building its model layer objects. After inspecting the JDeveloper Tree Binding Editor, it was observed that once the appropriate hierarchical relationships (view links) are defined in ADF Business Components, the Editor could be used to construct the tree based on these relationships.

There were two different possible approaches for building the model layer for the tree: middle tier-centric and database-centric.

The Middle Tier-Centric Approach

Using this approach, a view object is created for each node type in the tree. The view links represent the foreign key relationships in the database. Approximately 20 view objects were needed, along with the related view links among them. These view links must be referenced in the tree binding.  (Note that the 20 or so viewobjects need to be created anyway so that the application can edit the row in the database.)

This implementation seems rather straightforward at first glance, but it has some serious caveats. If a node that represents a repository object is expanded, other repository objects are not immediately visible. Instead, classifications of them are shown. For example, under an expanded block node, the following groupings are shown: Events (Triggers), Fields, Buttons and Lists. Note that Forms groups the children of a block as triggers and items only.

The ADF Tree does not support the creation of “hard nodes” (for lack of a better term) as shown in Figure 3. Various options for handling this situation were considered including writing separate views in the database for each grouping, or creating view objects that are populated programmatically. To use either of these strategies, it would also be necessary to adopt polymorphic restriction functionality in the tree binding many times, which would add another level complexity to defining the tree. In the final analysis, the workarounds seemed clumsy at best and none of them presented a clear, simple solution for the desired navigation tree.

 

Figure 3: Examples of “Hard Nodes

 

 

The Database-Centric Approach

Using this approach, a database view is created in which each row represents a tree node. The hierarchical structure of the tree is preserved in a recursive relationship in the view. For example, the view has a column named ID as its primary key column. The view has a second column named ID_RFK which recursively references the ID column and is used to determine the parent-child relationships.

This approach required two view objects in the Model layer of the application: one for specifying the root node (The Application Area header) and one for specifying the rest of the tree nodes.

The database-centric approach seemed to be the better choice for the following reasons:

1.        Tree nodes are controlled with just one isolated view.

2.        The number of view objects and view links needed to manage the tree was significantly reduced. Experience shows that modifying BC4J components once they are created can be problematic.

3.        The binding syntax of ADF has been changing with every release. Therefore, the less reliance on it, the easier it will be to upgrade to new versions of ADF.

4.        It just seemed to be a more clever way of defining the tree.

 

The following SQL code is an excerpt of the view used for the tree:

  select 1,

       'Application Area',

       'Header_Apparea',

       '1',

       null,

       null,

       null,

       null,

       'Y'

from dual

 

  union all

 

select aa.ar$apparea_oid,

       aa.name_tx,

       'Apparea',

       ''||rowid,

       null,

       '1',

       null,

       null,

       'N'

from ar$apparea$v aa

 

  union all

 

                         .

                         .

                         .

                        

 

The following code is generated after creating the appropriate model layer objects and dragging and dropping them onto the JSP page:

             

 

JSP Page Code for the Tree Tag

The generated code is simple enough. Later, new components will be added with the nodeStamp facet to allow navigation to the different property screens of repository objects. The following code shows the page definition XML displaying the tree binding.

 

Tree Definition XML

As shown above, JDeveloper generated the binding XML based on the rules entered in the Tree Binding Editor. The only time this XML may need to be edited without using the Tree Binding Editor is when applying the workaround to remove the + sign from the leaf nodes. As of this writing, the developers have not implemented the workaround yet. The blog entry on how to achieve this can be found at the following URL: http://technology.amis.nl/blog/?p=1298

Icons and links will be added to the tree at later stages.

 

Displaying the Property Palette for each Repository Object

The next step in developing the application is to build the various property sheets for each type of repository object: Application Areas, Applications, Blocks, Fields, Lists, Buttons etc.

In this application, the navigation tree is used to locate repository objects. When the user clicks a node in the tree, the property sheet for the selected repository object is displayed on the right.

To achieve this functionality, the following functions had to be implemented:

·         Detect the node that the user clicked on the tree

·         Change the focus of the tree to the clicked node (highlight the selected node)

·         Display the correct property sheet.

 

Detect a click on a node

The nodeStamp facet of the tree component is capable of displaying various JSF Components as shown in the following code:

A commandLink tag was added to the nodeStamp facet and bound to a method named checkTransaction in a managed bean named MyTreeBean. This shows the use of a commandLink inside the nodeStamp facet to detect that the user clicked on a node.

 

Changing the focus in the tree     

To capture which node in the tree is clicked, an attribute named “clickedRowKey” is created in the NavTree bean. (This managed bean stores the actual CoreTree object to which the <af:tree/> is bound, as well as other attributes to control the tree.) The focusRowKey attribute of the af:tree tag was modified in order to read its value from NavTree.clickedRowKey.

The commandLink was already added to the nodeStamp; however, the commandLink is already associated with an actionListener. It is possible to fire multiple actions when a commandLink is clicked using a SetActionListener tag inside the commandLink tag. The method specified in the setActionListener tag will execute before the method specified in the comamndLink as shown here:

 

The setActionListener assigns the rowKey of the node that is clicked to the clickedRowKey property of the NavTree bean, which in turn is accessed by the focusRowKey attribute of the <aftree/> tag.

 

Displaying the correct property sheet

The property sheets resemble the standard edit forms that are created by dragging the corresponding data control from the JDeveloper Data Control Palette and dropping it onto the page. The code shown here is an example of the property sheet definition of a Button

 

 

 

A <af:switcher/> tag  was used to toggle between the property sheets. When a user clicks a node in the tree, the type and ID of the repository object that the node displays are captured. Then the appropriate view object is queried to read the record from the database and the <af:switcher/> tag renders the correct property sheet. Some sample code to demonstrate how this tag works is shown here:

 

 

There are over 15 different types of nodes which display different screens. When a node is clicked, the type of node is stored in a bean property named “clickedNodeType.” Then the value of this property is used in the <af:switcher/> tag to determine which property sheet will be rendered.

Each possible value of the clickedNodeType property is handled in a facet. Facets of the <af:switcher tag/> can be seen as the elseif statements of an if  block. Note that there is no else keyword for the switcher tag.

 

Important Note

One problem encountered in the development of this application that is worthy of note was the size of the JSP page. JSP pages do not function properly after they exceed a certain size (~1300 lines).

This problem was discovered when adding facets to the switcher tag. With the increasing number of facets, the JSP file became too big for the compiler to handle.

The workaround was to divide the page into multiple pages using jsp;include tags. In this case, new JSP pages were created for each property sheet and added to the main page using JSP include tags as shown here:

 

 

This completed the steps to be able to display the desired screen when a node is clicked by the user.

Conclusions

Dealing with ADF Faces is not without its challenges.  There are still significant bugs and workarounds that need to be accommodated.  However, it is possible to build applications that are as rich as anything built using Oracle Forms. The result is a nicer looking application that takes no longer to create than it would have taken to build in Forms. 

Adopting a thick database approach seems to be the critical success factor for using this technology, both from a performance perspective as well as for minimizing development costs.

This project demonstrated that we could successfully use ADF Faces for web development.  Given a choice of technologies to build a standard OLTP system, we would choose ADF Faces.

ADF Faces is still nowhere near rich enough to support the kind of development possible with C++ or thick-client Java/Swing.  Our web development environment of choice for the richest of applications (such as graphical data modeling or process flow tools) is Macromedia Flash.  But for the applications built using Oracle Forms, that development environment can now safely be replaced with that of ADF Faces.

 

About the Authors

Dr. Paul Dorsey is the founder and president of Dulcian, Inc. an Oracle consulting firm specializing in business rules and web based application development. He is the chief architect of Dulcian's Business Rules Information Manager (BRIM®) tool. Paul is the co-author of seven Oracle Press books on Designer, Database Design, Developer, and JDeveloper, which have been translated into nine languages as well as the Wiley Press book PL/SQL for Dummies.  Paul is an Oracle Fusion Middleware Regional Director. He is President Emeritus of NYOUG, a Contributing Editor of the International Oracle User Group’s SELECT Journal.  In 2003, Dr. Dorsey was honored by ODTUG as volunteer of the year, in 2001 by IOUG as volunteer of the year and by Oracle as one of the six initial honorary Oracle 9i Certified Masters.  Paul is also the founder and Chairperson of the ODTUG Symposium, currently in its eighth year.

 

Yalim K. Gerger is the founder and president of Gerger Consulting, a consulting firm specializing in J2EE application development using Oracle, ADF, JSF and Struts. Yalim has over seven years of experience in various technologies such as Oracle Database, Oracle Forms Developer, Oracle ADF, Struts, JSF, Java and FLEX. He has worked for various government and leading private industry institutions and completed various projects using these technologies.