Monday, June 27, 2011

Srini Raman's Blog on JDeveloper and ADF

Keep an eye on this new blog - http://sriniraman.blogspot.com/
Srini works as  Senior Development Manager for JDeveloper IDE team and I'm sure hes planning a lot of new stuffs for you in coming days....Stay tuned !

Saturday, June 25, 2011

Safely storing UIComponent reference in a managed bean

Always it's recommended not to bind the UIComponent with managed bean with higher scopes(view, session, pageFlow, application etc.). There are multiple reasons to justify this suggestion.
1. JSF components are not Serializable, so your managed bean may fail to serialize in high availability mode.
2. Leaving stale references of the component if the bean survives the life of the view/page etc.

If you really want to store a component reference in managed whose scope is higher than request, then there is utility class for your help - ComponentReference . You can take a look at org.apache.myfaces.trinidad.util.ComponentReference API to learn more. I should admit that I was not aware of this one till I learned about this from an application developer ;)

ComponentReference Usage:

private ComponentReference someUICompReference;

public UIComponent getSomeUIComponent(){
   return someUICompReference == null ?
            null : someUICompReference.getComponent();
}

public void setSomeUIComponent(UIComponent component) {
    someUICompReference =
        ComponentReference.newUIComponentReference(component);
}

ComponentReference API Doc says::
  • This class is not thread-safe, since it depends on UIComponent APIs.
  • The passed in UIComponent is required to have an ID
  • The reference will break if the UIComponent is moved between NamingContainers or if any of the ancestor NamingContainers have their IDs changed.
  • The refrence is persistable. However UIComponents are not Serializable and therefore can not be used at any scope longer than request.
Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/10/oracle-adf-real-world-developers-guide.html

Building programmatically managed business components - Part 1

I've noticed quite a lot of queries in the public forum on building programmatic entity object and view objects . Let me share an example on this subject which may help you in implementing such use cases quickly. You can see a sample from Steve as well on this topic - 132.Programmatic View Objects Showing Master/Detail Data. Even my example also follows the same approach, of course with some minor tweaks hare and there :-)

Why do you need programmatic entity and view Objects?

Consider a scenario where you may need to retrieve data from a custom data source (say using third party API for example) and may need to perform some data update later on. While realizing such use cases, you my still want to leverage the declarative development support provided by the JDeveloper for building list of values, entity caching and validation, declarative transaction support etc. Though ADF got binding support for Java services, its not as rich as ADF BC implementation. One possible option is to customize the business components (view object and entity object) to interact with third party data source by overriding its default life cycle methods. Before get in to the implementation, let me take a step back take you through life cycle of entity and view objects.

How does your view object work?

When you run a page with a table, during the 'render response' phase of the view, table may tries to get data  by evaluating the EL associated with value attribute. At this stage the binding layer will identify the underlying view object for the iterator which is bound to the table, and may retrieve the data by executing the view object. The view object execution takes the following steps

Step 1: The view object executes the query by calling executeQueryForCollection(...) and the associate the result with QueryCollection object.
ViewObjectImpl::executeQueryForCollection(java.lang.Object qc,
java.lang.Object[] params,
int noUserParams)


Step 2: Once the query is executed, view object starts the iteration over the result set(collection) obtained at 'Step 1' by calling hasNextForCollection(...) for each element in the collection
ViewObjectImpl::hasNextForCollection(java.lang.Object qc)

Step 3: If step2 (hasNextForCollection) return true, then call createRowFromResultSet(...) to convert the record in to ADF aware form. If the view object is based on entity object, then corresponding entity instance(s) is getting created at this stage. In this case the ViewRowImpl will act as a wrapper over the underlying entity instance. It means that if you do update/delete on ViewRowImpl, that may finally reach underlying entity instance and entity may get added to the transaction listener's dirty list.
ViewObjectImpl::createRowFromResultSet(java.lang.Object iqc,
java.sql.ResultSet resultSet)


Step 4: Repeat Step 2 and 3 for all elements in the result set(till hasNextForCollection returns false). At the end of iteration run time marks 'fetch complete' by calling setFetchCompleteForCollection(...)
ViewObjectImpl::setFetchCompleteForCollection(java.lang.Object qc,
boolean val)


Who is interested in ViewObjectImpl::getQueryHitCount(...)?

Well, some UI components like table, tree etc. which needs paginated data fetch + scrollable behavior may require this information. These folks will call count query first and then may go for view object execution.

Note: If you are building programmatic view object, without any entity back up, its really required to implement ViewObjectImpl::retrieveByKey(ViewRowSetImpl rs,Key key,int maxNumOfRows) to return row for the key from your custom data source. why? Well, when run time fails to find the row in the cache by calling findByKey(), as a next step it will try to invoke retrieveByKey() to retrieve the value by passing Key. Please see 42.1.8 Handling View Object Queries with Primary Keys Defined by Transient Attributes to learn more.

What does happen when you update some data and call commit ?

When you update some row from an entity based view object, actual update happens against the corresponding entity instance(see Step 3 in the above section). Later when you commit transaction, entity  posts changes to database and commit transaction. Let us take look at the steps of the transaction commit cycle for an entity object.

Step 1: While you call commit, transaction manager starts the post cycle for the dirty entities. The first step is to validate the business data by calling validateEntity().
EntityImpl::validateEntity()

Step 2: Then transaction manager calls postChanges() on each dirty row(entity instance). The post changes takes multiple sub tasks to finish the job as copied below.

EntityImpl::postChanges(...) : Initiates a post operation for this Entity Object.
    a) EntityImpl::lock() : Locks the row.
    b) EntityImpl::prepareForDML(...) : A pre-notification for preparing rows for posting to DB.
        If you need to update some dependency columns or custom history columns then this is
        the place to add that logic.
    c) EntityImpl::doDML(...) : Performs INSERT/UPDATE/DELETE processing for the row.

Step 3: Once the data is posted, next step is committing the transaction. The following methods gets executed before and after of transaction commit.

    a) EntityImpl::beforeCommit(...) : Reports that a commit operation has initiated
    b) EntityImpl::afterCommit(...) : Reports that a successful commit operation has occurred

Well, enough theory, time for action ! Let us go ahead and build programmatic entities and view objects. Though this is simple, you may need to pay attention to a couple of  'silly' points to make it working.
Read more...


Building programmatically managed business components - Part 2

Putting in to action

We have seen the basic theory behind the execution of  entity and view objects in the first part of this article. In the second part , let us put the theory in to action.

Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]
Please note this example does not use any API specific to 11.1.2.0 release, so you may be able to reuse the source classes in previous versions also.

A glance at the implementation

This example uses two model objects - Department and Employee. The 'Department' is based on DEPARTMENTS table and it follows usual entity and view object generation steps, whereas Employee is based on custom data source and the steps for generating programmatically managed Employee model object is given below.

Building base classes for your programmatic entity and view objects

While building a programmatic view or entity objects you may need to hook your code to perform CRUD (Create Read Update Delete) operations against the custom data source (as per your use case) by overriding the life cycle methods(by default CRUD is done against database). This example uses generic base classes for doing this job and they are copied below for your reference.


ProgrammaticallyManagedEntityObjectImpl : Abstract entity object which overrides EntityImpl::doDML(...) and related methods.
ProgrammaticallyManagedViewObjectImpl : Abstract view object which overrides ViewObjectImpl::executeQueryForCollection(...) and related methods.
GenericQueryModel : A generic query model class which holds the filtering criteria  for third party services.
GenericRowCollection : A generic data structure to hold the result from the query(data retrieval) execution.
GenericRowData : A generic data structure representing a row in the result set.

Building programmatic entity object

Step 1: Right click the model  project, select New->ADF Business Components-> Entity Objects. You can key in the entity name and leave the default values for the other fields as is, click Next.


Step 2: Add attributes and finish the wizard


Step 3: Select the generated entity object in the editor, go to Java tab and click on edit Java Options. Change the base class for the Entity Object as fmwk.extension.entity.ProgrammaticallyManagedEntityObjectImpl(what we generated initially)
You may need to override ProgrammaticallyManagedEntityObjectImpl::getService() to return GenericDataPersistanceService implementation. Please see Step 4 for the service implementation.

Step 4: Build the business service implementing fmwk.extension.view.GenericDataPersistanceService for updating the data. Please take a look at model.emp.service.MyEmpDataServiceImplementation to get a feel of the implementation.

Building programmatic view object

Step 1: Select the programmatic entity object, right click and then select New Default View Object option from the context menu.


Step 2: Switch to the source mode of the generated view object and set the CustomQuery="true" as shown in the following image. This is very important step as this flag influences the run time to avoid the query execution against data base(which is the default execution path)


Ste 3: Select the generated view object in the editor, go to Java tab and click on edit Java Options. Change the base class for the View Object as fmwk.extension.entity.ProgrammaticallyManagedViewObjectImpl(what we generated initially)


You may need to override ProgrammaticallyManagedViewObjectImpl::getService() to return GenericDataReadServiceInterface implementation. Please see Step 4 for the service implementation.

Step 4: Build the business service to read data by implementing fmwk.extension.view.GenericDataReadService.  Please take a look at model.emp.service.MyEmpDataServiceImplementation to get a feel of the implementation.

Can I reuse this sample source?

Well, the classes what you see in package fmwk.extension.xxx are generic in nature and reusable. If you have similar use cases, then you may need to implement an adapter for your 'data source' calls as shown in model.emp.service.MyEmpDataServiceImplementation. The core run time classes what you see under fmwk.extension.xxx can be reused either as is or with some modifications.

How to run this sample?

This example is based on Department-Employee model. As I said earlier the Department is based on data base table and Employee is programmatically manged. This sample contains three pages illustrating search, update and master-child coordination on programmatic view object.
  • search.jsf - Search page for programmatic view object.
  • masterChild - Master child coordination(Department-Employee) through view link.
  • edit.jsf - Edit page for programmatic entity object.
Learn More ...
There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

Sunday, June 19, 2011

What you may need to know about Target Data Source entry for your tree binding definition?

There are use cases where you may need to refresh different parts of the page when user navigates between table or tree components which uses tree binding. In most of the cases the UI bindings(Target Data Source or TargetIterator) which needs to refreshed may share same Key attributes as your tree or tree table bindings. In such cases you can leverage the declarative support from ADF model to refresh the target iterator through 'Target Data Source' property associated with the tree binding. This topic is documented in Fusion Developers Guide, please see 29.5.4 How to Use the TargetIterator Property

Note: If you have 'TargetIterator' set for tree binding, ADF binding layer will never try to execute the target iterator using the 'Key' attribute(s) of the selected row of the source iterator. Instead the binding layer may simply call setCurrentRowWithKey on the target iterator using the key from the currently selected tree node. It means that, to make this property(Target Data Source entry) working, your target iterator should contain all the elements(of course target can be a super set as well) from source iterator.

Thursday, June 16, 2011

Declarative transaction support for your JPA data model

While playing around with new featured of 11.1.2.0.0 release, noticed an interesting one on data control side - declarative support for building Transactional Data Control for the business services built using JPAs. It looks cool ! There are a couple of points you may need to be aware of when you try this one.

1. Your should not keep 'Auto Commit' option 'true' for Java Service Facade if you need to defer the transaction commit. If this flag is ON, transaction will get committed as part of each service invocation from client.

2. ADF binding layer will never request the EntityManager to manage your entities at run time. So its your responsibility to associate your detached entities with PersistenceContext by calling EntityManager::persist(...) or EntityManager.merge(...) through generated wrapper method from the service facade.

Generating Transactional Data Control for your Java Service Facade

If you are new to EJB and never used ADF binding support to build UI for JPA entities, then please see this post first - Creating a Data Capture Form using EJB + JPA and ADF Binding. In this post I'm not covering the preliminary steps for generating JPA. Once you generate the JPA model, next step is to build service layer. This can be achieved by either using Java Services Facade or Session Bean. In this post I'm focusing on Java Service Facade. Please note if you build service facade built using stateful session bean also got similar support what we discuss here.

In 11.1.2.0.0 release, the wizard for building Java Service Facade is more intelligent than before ;) The detailed steps for building Transactional Data Control for your Java Service Facade is given below.

1. Right click the model project, from the context menu select -> New -> EJB. Then from the Items list select Java Service Facade. The IDE will display a Java Service Facade creation wizard for you. In the first step, you may need to select 'Application Managed' Transactional Option. You can keep the default options as is for the rest and finish the wizard.


2. Now select the generated JavaServiceFacade class, right click and select Create Data Control option. You may get a window as shown below. Select all three options.
and click OK. This action will modify your class to implement the selected interfaces and generate necessary code to support the contracts set by the interfaces.


API doc says,
TransactionalDataControl : This interface is to be implementated by DataControls that supports transaction.
UpdateableDataControl : This interface is to be implemented by DataControls that support an updateable or mutable business service.
ManagedDataControl: This interface is implemented by data controls that needs to have each request demarcated by beginRequest/endRequest pair, so that request level initialization and cleanup processing is possible

You may notice that the data control pallet in your JDeveloper displays Commit and Rollback operations for your transactional data control. Your data control is really smart now. If you have any bounded task flow using this data control, then you can rely on declarative transaction mechanism available with the task flows to commit your business data.


Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

A glance at the implementation

This example is built using JPA entities and the Java Service Facade implementing oracle.binding.TransactionalDataControl. The Departments entity holds a status flag(Enum) to keep track of the modification status. The view controller project contains a dept-task-flow comprising a view activity - dept.jsf . The dept view uses the JavaServiceFacade as data provider. The task flow's transaction is controlled declaratively. Please note that merging modified entities with PersistenceContext is done programmatically from the view.DeptBean::doSave() method.

How to run this sample?

Run main.jsf and click on 'Show Departments', this action will take you to dept-task-flow.
Edit few records and click on Save. The save action is mapped to task flow return. This action commits the EntityTransaction by leveraging declarative transaction management support provided by the bounded task flow.

Saturday, June 11, 2011

Globally setting the change event policy for all data bindings

The 11.1.2.0.0 release of ADF has added a new configuration entry in adf-config.xml file to globally set the default change event policy for the all iterators in the application. Of course, developers can override the default setting at each binding level.


 <adf-config xmlns="http://xmlns.oracle.com/adf/config"   
 ...  
  <adf-adfm-config xmlns="http://xmlns.oracle.com/adfm/config">  
   <defaults changeEventPolicy="ppr" useBindVarsForViewCriteriaLiterals="true"/>  

Wednesday, June 8, 2011

Creating Task Flow bindings on the fly

A very common demand from the community was support for adding regions at run time. The good news is that 11.1.2 release has support for adding regions dynamically which is now well supported by a task flow binding layer as well. Wow...excited? Please see
21.10 Configuring a Page To Render an Unknown Number of Regions in developers fusion developers guide to learn more about this topic. Let me give you a quick overview on the implementation. Its very easy.


1. Build the logic to return TaskFlowBindingAttributes list for dynamic task flows

First step is to build a managed bean to hold your business logic for building list of oracle.adf.controller.binding.TaskFlowBindingAttributes as shown in the following code snippet.

 private List<TaskFlowBindingAttributes> taskFlowBindings = new ArrayList<TaskFlowBindingAttributes>();  
   
 public void buidTaskflowBindings(){  
   
  TaskFlowBindingAttributes tfBindAttr1 = new TaskFlowBindingAttributes();  
  tfBindAttr1.setId("region1");  
  tfBindAttr1.setTaskFlowId(new TaskFlowId("/WEB-INF/dept-task-flow-definition.xml", "dept-task-flow-definition"));  
  taskFlowBindings.add(tfBindAttr1);  
    
  TaskFlowBindingAttributes tfBindAttr2 = new TaskFlowBindingAttributes();  
  tfBindAttr2.setId("region2");  
  tfBindAttr2.setTaskFlowId(new TaskFlowId("/WEB-INF/emp-task-flow-definition.xml", "emp-task-flow-definition"));  
  tfBindAttr2.setParametersMap("#{pageFlowScope.MyBean.parameterMap}");  
  taskFlowBindings.add(tfBindAttr2);  
 }  
   
 public List<TaskFlowBindingAttributes> getTaskFlowBindings() {  
  return taskFlowBindings;  
 }  
   

2. Generate the executable entry for multi task flow in the page definition file

Switch to the binding tab of your page, click on the '+' icon under the Executables section to generate the binding for multiTaskFlow. Please see the following image.


You may need to key in a unique identifier for the <multiTaskFlow> entry, and a value for taskFlowList as well. The taskFlowList will take an EL expression that returns the list of TaskFlowBindingAttributes at run time. In our case the method getTaskFlowBindings() returns the list(please refer this method in above code snippet).

Note: The multi task flow binding (multiTaskFlow) in the page definition identifies a list of bounded task flows used in the ADF region.

  <multiTaskFlow id="multiRegion1"   
  taskFlowList="#{pageFlowScope.MyBean.taskFlowBindings}"  
  xmlns="http://xmlns.oracle.com/adf/controller/binding" activation="deferred"/>  


3. Build the UI to host regions at run time

The last step is building the UI to host regions at run time. This example uses af:forEach for adding regions at run time as shown in the following page snippet.

 <af:forEach var="tf" items="#{bindings.multiRegion1.taskFlowBindingList}">  
  <af:region value="#{tf.regionModel}" id="reg#{tf.name}"/>  
 </af:forEach>  


Notes(from Fusion Developers Guide):

  • Limit the number of ADF regions that you create in a page to 10.
  • Each task flow binding inherits attributes defined for the multi task flow binding unless you override this behavior using the methods exposed by TaskFlowBindingAttributes.
  • Each task flow binding inherits parameters defined in the multi task flow binding in addition to those defined using the parametersMap property.

Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

A glance at the implementation

Run the main.jsf page and click on the 'Display More Taskflows' button.
You may notice that two task flows are getting added on the screen when you click on the button.


Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html



Tuesday, June 7, 2011

The Release 2 (11.1.2) of Oracle JDeveloper and Application Development Framework Now Available

The 11.1.2 release of JDeveloper and ADF is available now. This is a very promising release and I'm sure you will really love using this smart tool.

Friday, June 3, 2011

Call custom JavaScript method during component initialization

If you need to invoke custom Java Script method during some specific UI(ADF Faces) component initialization, then this post is for you. Idea is to use ClientListenerSet::addBehavior(javax.el.ValueExpression) to associate a deferred value expression (referring a JavaScript method) with the UI component, which will be evaluated later when DOM is rendered on the page. Thanks to Gary Van Matre who shared this idea in an internal discussion forum

public void setSomeInputField(RichInputText inpField) {
this.inputField = inpField;
ClientListenerSet clientListenerSet = inputField.getClientListeners();
if (clientListenerSet == null) {
clientListenerSet = new ClientListenerSet();
clientListenerSet.addBehavior("new CustomCompBehavior()");
inputField.setClientListeners(clientListenerSet);
}
}

Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS4(11.1.1.5.0)]

Oracle OpenWorld 2011 Suggest-a-Session

If you missed the general public call for papers, don’t worry! You have another opportunity to get included in this year’s event.
You can either suggest a session or vote for one - Rich Enterprise Application Development...

Read More....

Why does programmatic refresh fail for child table when the parent table has immediate=true?

Story so far...
There is a master table with immediate=true and a custom selectionListener. An editable(clickToEdit) child table needs to be refreshed programmatically from master table's custom selectionListener.

  <af:table id="masterTabl" immediate="true"   
    selectionListener="#{MyBean.customSelectionHandlerForParentTable}" ...  
  <af:table id="childTabl" partialTriggers="::masterTabl"   
    editingMode="clickToEdit" ...  
  public void customSelectionHandlerForParentTable(SelectionEvent selectionEvent) {  
   RichTable childTable = getChildTable();  
   refreshChildTableCollectionModel()  
   RequestContext.getCurrentInstance().addPartialTarget(childTable);  
  }  

Now the fun starts...Though everything looks perfect, child table fails to reflect the refreshed CollectioModel (which is updated from the SelectionEvent of master table). Child table just repaints the previously submitted values from UI as is, not the updated model :(

What goes wrong here?

Well, a variant of this specific case has been discussed in one of my previous post -Reset the content of a web page. Let me explain few basic concepts from the perspective of the above use case.

What does happen when you set immediate="true" on a component?

When you keep immediate="true" for a UI component, the normal JSF life cycle for that component gets short circuited as explained in the following section. btw, please see this topic 'Life Cycle of a JSF Page' if you are not familiar with JSF life cycle concept as such.


• What happens when you set immediate="true" set on an ActionSource(e.g. af:commandButton) component?

The ActionEvent for this component is normally delivered in 'Invoke Application Phase'. When immediate is set true the ActionEvent delivery is moved up to the 'Apply Request Values Phase'. An ActionEvent always results in 'renderResponse' being called implicitly in the default ActionListener whether or not an "action" is attached.

• What happens when you set immediate="true" on an EditableValueHolder(e.g. af:inputText) component?

The validation and valueChangeEvent for this component usually take place in the 'Process Validations Phase'. When immediate is true the component's value will be converted and validated in the 'Apply Request Values Phase', and ValueChangeEvents will be delivered in that phase as well. Please note that framework is not going to skip any lifecycle phase even if you keep immediate=true. You may need to call FacesContext::renderResponse() if you really want to by pass the rest of the phases from the listener.

How does 'component renderer' treat submitted value of the component?

Each UI component has local cache value. When you submit a form, submitted value gets assigned to this localValue at the end of 'Process Validations Phase', 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.

Enough theory, let me answer the question now :)

Solution

In the above use case when you select a parent row, the submitted content contains other editable fields from the form as well(including the child table's editable fields too). As you have immediate="true" set for parent table, SelectionEvent gets fired as part of Apply Request Values Phase. If you 'blindly' refresh the CollectionModel for the child table at this stage, it does not really help you because the 'submitted form' holds set of editable components and they are lined up to go through normal JSF life cycle phases. JSF runtime will use values of these submitted fields for model update later point, which may even override the the model changes done by you in the early phase of life cycle. Apparently, solution for the above use case is to clear the submitted values from the components which needs to be refreshed with updated model. For input UI components (such as af:inputText), you can call UIInput::resetValue() on each component to clear the submitted value. For stamped components like af:table, you are supposed to call resetStampState(). Now your custom selection listener for parent table may look like as shown in the following code snippet.

  public void customSelectionHandlerForParentTable(SelectionEvent selectionEvent) {  
   RichTable childTable = getChildTable();  
   childTable.resetStampState();  
   refreshChildTableCollectionModel()  
   RequestContext.getCurrentInstance().addPartialTarget(childTable);  
  }  



Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html