Skip to main content

Posts

Showing posts from April, 2011

Modifying the Application Module's JDBC DataSource at run time

In normal scenario, your Application Module(AM) may have a static JDBC data source configured and will be connected to the single data base in all conditions. However there are cases where the application may need to display data from different data bases based on user profile. In today's post, I talk about an example for the above use case. Well, this is not a new topic as such. In fact, this has been discussed previously many times.

1. Dynamic JDBC Credentials example by Steve Muench
2. How To Support Dynamic JDBC Credentials

I'm copying the same solution in a slightly modified form ;)

Programmatically setting DataSource for an Application Module

A bit of theory before get in to the implementation. When a Fusion Web Page is getting rendered, UI controls may try to get data by evaluating the expression set for the value attribute. At this stage binding layer comes in to action, and will identify the underlying data provider(your Application Module) for the the specific attri…

Learning Oracle ADF

Accessing destination View Object using View Link Accessor

When you need to programmatically access the 'child' view object from a 'master' view object by virtue of a view link accessor, you can use the the below API.

ViewObject destVO = originVO.findAttributeDef("View Link Accessor Name").getAccessorVO(originVO);

Example:

ViewObjectImpl deptVO = getDepartmentsView();
ViewObject empVO = deptVO.findAttributeDef("EmployeesView").getAccessorVO(deptVO );

Identifying the source of the request for an LOV

The LOV can be enabled for an attribute of a view object, and the same can be used inside a query panel or in a parameter form.
How do you identify where the LOV is displayed currently, from a View Object?

Well, you can use the following groovy expression 'adf.isCriteriaRow' to achieve the same, which may rerun true if the request is from a model driven af:query component. This is useful if you need to switch between LOV definitions based on where its displayed at run time (e.g: one LOV in search panel and a different one in parameter form for the same attribute).

Please see the following topic in Dev Guide to learn more - How to Specify Multiple LOVs for an LOV-Enabled View Object Attribute

Programmatically refreshing the child nodes of an <af:tree>

There are use cases where you may need to refresh(re-execute the query) the child nodes of a <af:tree> or <af:treeTable> programmatically . In this post I'm discussing a simple implementation for the same.

Query execution for retrieving child nodes

A bit of theory before getting in to the code sample. When you expand top level nodes for the first time, runtime will traverse through the View Link Accessor for the parent Row and identifies the child RowSet/ViewObject and execute the same. The execution of child View Object result in child nodes. When you expand the parent once again, the parent row may find an existing QueryCollection(wrapper object over Rows) with the matching row filter, e.g. say DeptId=10. This existing QC, which already has the filtered list of rows is re-used at this stage. In case you may need to refresh the child RowSet in all cases, you may need to brutally execute the corresponding RowSet. The below shown code snippet executes child Employee…

Using JMS with ADF Business Components

There are use case scenarios where you may need to perform some service calls asynchronously, whose out put does not affect the success or failure of the entire business process. Some examples could be sending SMS notification on successful airline ticket booking or logging business data on data change etc. A possible solution for above case may be queuing the request/data for later process and configuring a listener on this Queue to process them asynchronously. In Java EE world, the Java Messaging Service (JMS) provides basic infrastructure for queuing messages. Interestingly, you can easily enable ADF Business Components to use JMS if your use case demands so. Sounds interesting? then read on... :)

Use case

In this example, I'm populating an 'audit' table whenever user commits the modified Department details. This audit table is updated asynchronously using a Message Driven Bean. The high level flow is depicted in the following diagram.


Download

You can download the samp…

Initializing your Fusion Web Application Parameters at startup

If you need to initialize specific business data during application start up,this post is for you.

Download

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

A glance at the implementation

This example make use of a custom javax.servlet.ServletContextListener for performing the application initialization during deployment. Please see 'view.ContextInitializer' class in the attached sample workspace, which act as the ServletContextListener in this example. btw, check out this post How to work with ServletContextListener if you not familiar with this approach.

This example invokes ApplicationModule and populates the ServletContext attributes from the custom ServletContextListener's ContextInitializer::contextInitialized(...) method. Please note that ADFContext.getCurrent().getApplicationScope() in a web app refers the ServletContext. It means that whatever you set to ServletContext, can be retrieved later by calling ADFConte…

Displaying ClobDomain on a page

There is a default JSF converter(oracle.genericDomain) available for most of the oracle.jbo.domain types( not a new stuff, this has been available since 11.1.1.1.0). The converter-class for 'oracle.genericDomain' is oracle.adfinternal.view.faces.convert.GenericDomainConverter. This precofigured converter comes along with ADF binaries, so you just need to use it wherever required :)

Example :
<af:inputText value="#{bindings.ClobContent.inputValue}" label="#{bindings.ClobContent.hints.label}" converter="oracle.genericDomain" required="#{bindings.ClobContent.hints.mandatory}" columns="#{bindings.ClobContent.hints.displayWidth}" maximumLength="#{bindings.ClobContent.hints.precision}" shortDesc="#{bindings.ClobContent.hints.tooltip}" id="it2" rows="5"> <f:validator binding="#{bindings.ClobContent.validator}"…

Throwing ValidationException from the beforeCommit() logic !

If you have some validation logic added to beforeCommit() of the ApplicationModuleImpl or EntityObjectImpl and you face strange rollback behavior(Entity Objects are losing the modified data) while committing data second time after correcting the validation error, then this post is for you :)

From Developer's Guide....
8.5.2 How to Validate Conditions Related to All Entities of a Given Type

If your beforeCommit() logic can throw a ValidationException, you must set the jbo.txn.handleafterpostexc property to true in your configuration to have the framework automatically handle rolling back the in-memory state of the other entity objects that may have already successfully posted to the database (but not yet been committed) during the current commit cycle.

Java Option : -Djbo.txn.handleafterpostexc=true

Programmatically resetting the <af:query> and search result table

If you want to programmatically reset QueryModel of <af:query> component, you can use the following code snippet in your managed bean.

RichQuery queryComp = getRichQuery(); QueryModel queryModel = queryComp.getModel(); QueryDescriptor queryDescriptor = queryComp.getValue(); queryModel.reset(queryDescriptor); queryComp.refresh(FacesContext.getCurrentInstance());
Along with the above requirement, If you need to reset the contents of result table as well, then call executeEmptyRowSet() on the ViewObject which is wired to the result table.

Download
I'm attaching simple application illustrating the above discussed points. You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS3 + HR Schema]

A glance at the implementation

This example displays a popup with a search panel and result table. The custom popupFetchListener method added for the af:popup component resets the search panel and result table contents before di…