Saturday, December 5, 2009

VIewObject based on 'pivot query'

I have seen few posts in ADF discussion forums asking for solutions to transpose database table rows in to columns. Apparently, this turns out to be s a query related to the underlying RDBMS. Attaching a simple demo application that transforms Employee Table in columnar from as shown below.

[If you use Oracle 11g, pivot operator will help you to achieve the same behavior. The above sample is not using pivot operator]
You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS1 + HR Schema]

Friday, November 27, 2009

Retrieving deleted Entity Objects

I have seen a couple of use cases where developers need to iterate through the deleted Entity Objects and perform validations based on various conditions. Steve shared some pointers, which helped me to find a solution. The following code snippet may help you to identify the deleted entities.

public class EmployeesImpl extends EntityImpl {
    
 public ArrayList<EntityImpl> findDeletedEmployees() {
    ArrayList<EntityImpl> deletedList = 
                              new ArrayList<EntityImpl>();
    Iterator iterator =
            this.getEntityDef().
              getAllEntityInstancesIterator
                        (this.getDBTransaction());
   while (iterator.hasNext()) {
      EmployeesImpl emp = (EmployeesImpl)iterator.next();
       if (emp.getEntityState() 
                       == Entity.STATUS_DELETED) {
          // Keep soft ref. if worried on GC              
          deletedList.add(emp); 
        }
    }
    return deletedList;
  }
   
    // Rest of  your code goes here
 }

Creating a Data Capture Form using EJB + JPA and ADF Binding

Java EE technology stack has been improved tremendously in recent past. However, a closer look at this technology spectrum reveals the visible gap that exists between the UI and Service layers. Core Java EE stack really lacks a smart glue layer that avoids large chunk of boiler plate code used for wiring UI with business data. For a typical Java EE business application, we can say that about 20-25% coding effort is being spent for wiring UI to the data from business services and other common UI manipulations such as synchronizing master-child relations, querying entities and displaying results, navigating between records, invoking actions etc.

Binding the UI with EJB

Is there any matured binding solution available for Java EE technology stack?
Answer is YES, Your friend is ADF binding layer who can really help you to bridge the gap between UI and business service layer.

Seeing is Believing

So let us try building a data capture form using Java EE technology stack with the help of JDeveloper + ADF Binding Layer , and see how this toolset saves you time and effort.

Let us take the classic example of Employee and Department. The use case is to realize a data capture screen for an Employee. UI may look like as shown below



The example below illustrates how JDeveloper help you to build Java EE applications quickly and efficiently.

Setup the application environment

Step 1: Create a new application by choosing Java EE Web Application template.



Please make sure that required libraries are selected in subsequent steps of the same wizard. Click Next and finish the wizard. This wizard automates the 'setup' of the basic application structure (I would say, architecture rather) for you with clear separation between UI and Service Layer. You can see two projects generated at this stage 1. ViewController (UI) 2. Model (Business Services)







Step 2: Create a new Database Connection. This example uses HR schema that comes with Oracle database



Generate entities from tables

Step 3: Select the Model project, right click, and select New from the context menu. From the dialog, select the option for generating 'Entities from Table'. Select DEPARTMENTS and EMPLOYEES tables in the next step and continue the wizard with default values. Click to Finish at the end. Wizard generates Employees and Departments entities and the required configuration files as well, like persistence.xml file.





Define entity validation declaratively

Step 4: ADF Binding layer provides declarative validations support for the enterprise applications. Binding layer also supports, UI hints for entity attributes which can be later leveraged by the view layer to derive the runtime characteristic of UI elements.

Let us define the validation for email of an Employees entity. Open the Employees.xml in design mode, choose attributes tab and select employee attribute. You can see validators section displayed at bottom. Click on the + icon to add validation. Select ‘Regular Expression’ as Rule type. From the 'expression' drop down list, select Email Address. Now go to the failure handling tab and key in the error message.



Define UI Hints

Step 5: UI Hints defines hints for the attribute which can be later used by the view layer to derive the UI characteristics like filed label, length, precision, required flag etc. Select the entity attributes and specify values for Label, Tooltip, Display width, Precision etc using Property Inspector



Generate service layer (session facade)

Step 6: We done with the model part.  Let us go ahead and generate service layer for the model. Select the persistence.xml file (displayed under META-INF folder of Model project), right click and select the option to create Session Facade. Continue the wizard with default options till the end. This generates SessionEJBBean and other supporting files(Local and Remote interfaces and related configurations). SessionEJBBean will contain the basic infrastructural service methods (generated by the wizard, off the shelf) for performing CRUD operations on the containing entities.



Create accessor method for entity

Step 7: This accessor method will be used later, to retrieve the instance of the entity from the client .
Open the SessionEJBBean, write down the method public Employees getEmployees() as shown in the below diagram. Copy the method declaration to Local and Remote interfaces(SessionEJB.java and SessionEJBLocal.java).This method provides the Employees entity instance that backs up the data capture form.


Generate Data Control

Step 8:  Select SessionEJBBean, right click and select Create Data Control option from the menu



Create UI for the application

Step 9: Create a jspx page. Drag and drop the employees method accessor from the Data Control pallet to the jspx file as a Form. Now the form is ready, let us replace the departmentId field with a SelectOneChoice component, see next step.



Step 10: Define List binding for department. Objective is to support the department filed with a SelectOneChoice component. Create List binding by selecting departmentsFindAll method accessor.






pagedefinition entry :

<list ListOperMode="navigation" 
     IterBinding="departmentsFindAllIterator"
     ListIter="departmentsFindAllIterator" id="departmentLOV"></list>
Step 11: Make changes in jspx file to add a <af:selectOneChoice> for department, as shown below.

 <af:selectOneChoice value="#{bindings.departmentId.inputValue}"
          label="#{bindings.departmentId.hints.label}"
          required="#{bindings.departmentId.hints.mandatory}"
          showRequired="#{bindings.departmentId.hints.mandatory}"
          shortDesc="#{bindings.departmentId.hints.label}}"
          id="soc1" valuePassThru="true">
       <af:forEach items="#{bindings.departmentLOV.iteratorBinding.allRowsInRange}"
                    var="li1">
          <af:selectItem id="si2"
                 label="#{li1.dataProvider.departmentName}"
                 value="#{li1.dataProvider.departmentId}"/>
       </af:forEach>
  </af:selectOneChoice>

Persist Enity

Step 12: Drag persistEmployees(Employees employees) method action as command button on the Form. Specify the parameter value as #{bindings.employeesIterator.currentRow.dataProvider}






That’s it, job is done without much effort. Now you can try running the page from JDeveloper. Sample workspace is attached below.

A couple of points:
1. Please note that accessorIterator for the employees needs to be refreshed during each page load. So  added a PageController ,to rexecute the IteratorBinding when page loads.
2. Modified the generated source of SessionEJBBean::persistEmployees(Employees employees) to get the reference of associated Departments.

You can download the sample workspace from here.

[Runs with Oracle JDeveloper 11g R1 PS1 + HR Schema]

Friday, November 20, 2009

Displaying pre-executed query result in a search form

I recently encountered an interesting use case related to Search Binding. Requirement is to display the result of pre executed query in a search form embedded inside a popup dialog. Developer tried executing the query from popupFetchListener, but no success in displaying the search result back on the form. Always search result component comes empty. What has gone wrong here?

Before start seeing the implementation part, let us try to understand the model driven query component's runtime behavior. <af:query> component's binding(search binding) by default, follow 'AutoQuery-or-ClearRowSet' behavior. In simple words, search binding for <af:query> component will try to perform either of the below steps(AutoQuery or ClearRowSet) while rendering the page where the component is embedded.

AutoQuery : <af:query> component follows model driven rendering approach. Obviously the ViewCriteria defined in the ViewObject, decides query component's runtime behavior. If the ViewCriteria has Query Automatically flag set to true, then runtime will apply the ViewCriteria and execute query when <af:query> component is being rendered. And the search results will be displayed in the specified component.

ClearRowSet : If the AutoQuery is not performed (i.e Query Automatically flag is set false for the ViewCriteria), then search binding clears the row set related to its iterator. User will be presented with empty search results component.

More details on this topic can be found in Fusion Developer's Guide for Oracle Application Development Framework 27 Creating ADF Databound Search Forms

Now, let us go back to the use case that we were discussing initially, it is clear that we need to override 'AutoQuery-or-ClearRowSet' behaviour of the search binding in order to display the result of the pre executed query. Good news is that, ADF binding layer has support for this kind of use case scenario 'out of the box'. A search binding's InitialQueryOverridden property controls whether it should suppress its initial AutoQuery-or-ClearRowSet behavior the first time the search binding is used in a page flow. If InitialQueryOverridden is true, then all valid values, including true, false, or a boolean-valued EL expression, are suppressed. The default value is false. So keeping this flag ‘true’ is enough to achieve the above mentioned use case. This property can be located in your page definition file, inside < searchRegion >.


Please go through Fusion Developer's Guide Chapter 27.2.4 How to Set Default Search Binding Behavior to know more.

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS1 + HR Schema]

Sunday, November 8, 2009

Accessing web tier variable values from the business components in a groovy way

Groovy is an amazing dynamic language with lots of unnoticed features. One feature that I like most is the dynamism that can be introduced to an enterprise application at runtime. To know more about the groovy support in ADF, please go through this white paper : Introduction to Groovy

This 'dynamism' fits pretty well for an ADF based application in many scenarios. However, there are few cases where this feature is being used in a non groovy way :)

Accessing web layer data from business components

Rule of thumb for designing a system is that client layer can  depend upon your business service layer, not the other way around. This provides more flexibility and extensibility to the system. Your build tool (say for e.g.: maven) may also expect a unidirectional dependency, to resolve dependencies without getting into infinite loops.

However, there are some use cases where EntityObjects or ViewObjects needs to be initialized with values from the client side(web tier).
Consider a typical example where web tier keeps an 'activity id' in a PageFlowScoped memory variable - 'activityFlowId'. The same value may needs to be accessed from the Service Layer of the application. Let us explore few possible approaches for this specific case, and pros and cons with each one as well.

In this specific use case, the requirement is to access this PageFlowScoped variable from a ViewObject, in order to initialize a specific transient attribute. A very common approach being followed by is to make use of the oracle.adf.share.ADFContext class that has set of APIs exposed for accessing the 'scoped variables' of the web layer. Even groovy expression can be used to achieve the above said functionality in a declarative way. Below image shows the groovy expression that being used for the same.


Groovy expression:
adf.context.expressionEvaluator.evaluate
('#pageFlowScope.activityFlowId}')

Drawback of accessing PageFlowScoped variable direcly from business service layer

1. Your business service layer starts losing the core principles like extensibility and reusability. In the above case, business service depends on the client layer which is not considered as a good design as we are losing the clear separation between view and business service layers.
2. If you follow Test Driven Development methodology, the above implementation may fail when you try to test business service layer independently (web container is missing here)

A better (recommended) approach for the above use case, which is free from the above mentioned drawbacks is detailed below

Step1: Expose a custom method on the business service layer (Application Module) that accepts the required parameter
Step 2: View layer is supposed to pass the desired information by invoking the above method. The information can be saved in a hash table obtained from session.getUserData(). ADF has groovy support to access the value from this data structure.

The 'custom method' exposed in the Application Module may look like as below
public void setAtivityFlowIdId(String activityFlowId) {
   this.getSession().getUserData().put("activityFlowId", activityFlowId);
}

The value stored in the 'session user data' can be referenced from EntityObjects and ViewObjects using groovy expression, declaratively. Below image shows how the groovy expression can be used for accessing the userSession value.
(Steps: Select Attribute of ViewObject -> Click Edit -> Select Expression -> key in value)



Groovy expression:
adf.userSession.userData.activityFlowId

Apparently, the second approach let you to unit test your service layer independently and avoids the dependency to the view layer.

[ Many thanks to Steve Muench who pointed out some flaws in the initial version of the same blog post! ]
You can download the sample workspace from here.

Sunday, October 18, 2009

Entity Object based on a PL/SQL Package API

A simple demo application that uses Entity Object based on the Stored Procedure is attached here.
More details can be found in Developer's Guide, section 37.5 Basing an Entity Object on a PL/SQL Package

PS: Unzip the attachment and run the script(StoredProcedureExample/script) to set up the required DB objects for running this demo

Friday, October 16, 2009

Reset the content of a web page

Resetting the page contents or undoing the changes made by a user is a very common use case scenario in Rich Internet Applications. The 'reset action' should skip all validations defined on the current page and page contents needs to restored from the underlying data layer. Some of the web frameworks support this feature out of the box. Let me try explaining possible ways to reset a page when developing applications using ADFFaces.

1. <af:resetButton>

As the name suggests, af:resetButton resets the contents of a form. Please note that developer doesn't have much control here as he/she might not be able to bind any action method with this built in reset button.
<af:resetButton  text="ResetButton" id="rb1"/>
2. <af:resetActionListener>

This tag is usually bound to an action source like command button to reset all submitted values whenever an action is triggered. Obviously this gives more control to the developer as the action sources like command button can be optionally bound to an action method through the Expression Language(EL). Please note that, you may need to keep immediate="true" for the command button ( for the action source ) to skip the validations while implementing the reset/cancel behavior.
  
<af:commandButton text="Cancel with resetAction" id="cb2"  immediate="true"   
     partialSubmit="true"
     actionListener="#{SomeBean.cancelBusinessAction}">
     <af:resetActionListener/>
</af:commandButton>

Why do we need to reset submitted values?

Each component has local cache value. When you submit a form, submitted value gets assigned to this localValue at the end of 'PROCESS VALIDATIONS' pahse, and thereafter submitted value is set as null. During the RENDER RESPONSE, first consult the local value property of this component. If non-null return it. If null, see if we have a ValueExpression for the value property. UIInput::resetValue() reset the submitted value that would force the rendering logic to take the value from the model/binding layer.

3. Custom Reset Implementation

So far so good, but in some scenarios developers may need to dirty their hands a bit to get the job done - where the declarative 'reset' support is missing. I noticed a rare use case scenario recently, that calls for custom reset implementation. There master-detail data is displayed in tabular form and user is allowed to edit one master record (and it's children as well) at a time, then save that record and proceed to next. In case user decided to navigate to next record without saving current record, then current changes needs to be cancelled. Though use case is bit odd one, adding this feature is pretty simple. All we need to is override the default selectionListener and from this custom method, parse the component tree and call reset on each element.
Code Snippet:
   
 public void customSelectionHandler(SelectionEvent selectionEvent) {

     UIComponent source = (UIComponent)selectionEvent.getSource();
     UIComponent uiComp = _getRootToReset(source);
     _resetChildren(uiComp);
     EL.invokeMethod(
     "#{bindings.DepartmentsView11.collectionModel.makeCurrent}",
     SelectionEvent.class, selectionEvent);
}
   

On a related note, I would suggest you to look at the source of org.apache.myfaces.trinidadinternal.taglib.listener.ResetActionListener, that may help you to understand the 'reset' concept much better. (Even the below given sample application just tries to reuse the same reset logic from ResetActionListener class).

You can download the sample workspace from here.