Thursday, November 25, 2010

Executing Javascript in an ADF RC Page from a backing bean method

ADF lets us do some pretty wild things and one of them is the ability to easily inject Javascript into a page from a backing bean method and execute it. For example, from the action assciated with a command button, to run run a simple JavaScript the only code required is
FacesContext fctx = FacesContext.getCurrentInstance();
StringBuilder script = new StringBuilder();
script = script.append("alert('Hello World !');");

As can be seen, the backing bean code for executing java script in an ADF page is very simple and makes use of the ExtendedRenderKitService from the Trinidad codebase. The approach becomes very useful when you need to generate dynamic JavaScript to inject and execute it in a page at runtime.

Monday, November 22, 2010

Executing EL expression for a method from a backing bean

In ADF we use expression language(EL) a lot when developing declaratively. At times though, we need to override or more likely, enhance the default functionality, by wrapping the the out of the box functionality with some extra code. A common case is when you have a button or action that is bound to an operation, on the data control though EL, and you want to invoke a backing bean before executing the binding. Inside the backing bean method,  after doing whatever that needed to be done, to invoke the actual server side functionality you can use the same EL that was bound by creating a method expression and invoking it. So to invoke any operation on the DataControl, like Commit, or Create or CreateInsert, from a backing bean using EL, you can create a helper method like this :
public Object invokeMethodExpression(String expr, Class returnType,
                                       Class[] argTypes, Object[] args)
    FacesContext fc = FacesContext.getCurrentInstance();
    ELContext elctx = fc.getELContext();
    ExpressionFactory elFactory =
    MethodExpression methodExpr =
      elFactory.createMethodExpression(elctx, expr, returnType, argTypes);
    return methodExpr.invoke(elctx, args);

and invoke it like this :
String expr = "#{bindings.CreateInsert.execute}";
    invokeMethodExpression(expr, null, new Class[]{}, null);

The method uses the createMethodExpression method from ExpressionFactory. Read the javadoc to see how to pass arguments to the method.
This way, you can easily wrap the built in operations on a data control with your own custom code.

Monday, November 15, 2010

Printing in ADF, the <af:showPrintablePageBehavior> and showing the browser print dialog

ADF comes with a couple of rather easy to implement options for printing and rendering printable pages. The most obvious one is the <af:showPrintablePageBehavior/>. As the document describes, this renders the page without any command components, and as such will look better on paper. The big drawback however is that this is just the same page rendered differently. What if the actual behavior you need is to open the print dialog of the browser ?
There is a javascript function in the ADF client side API hat you can use to do exactly this. The function is simply self.print() and it opens up the browser's print dialog.

To use the function, just drop an tag into a command button like so :

The corresponding code in your jspx/jsff would be :
<af:commandToolbarButton text="show print dialog" id="ctb2">
    <af:clientListener method="self.print" type="action"/>

And of course you can use the self.print()function insde your own custom java script that ou embed with the af:resource tag. The downside of this approach is that what you see is what you get.
The page is sent to the printer as is, Its not specifically made "printer friendly" by removing CSS and command buttons that the <af:showPrintablePageBehavior/> does .

The <af:showPrintablePageBehavior/> approach would be :
<af:commandToolbarButton text="show printable page" id="ctb1">

Friday, November 5, 2010

Bookmarking Taskflows in ADF / Accessing ADF Taskflows by URLs

The problem

I need to bookmark or deep link a page in an ADF application, either to save a link to the page or share the page by email or other means. Unlike a normal web-app, JSF does not play well with bookmarks, but ADF comes bundled with (somewhat limited)support for doing this. This sort of a requirement is common when we need to include an application link in a generated email report to enable to user to see additional interactive information or to secure the information itself by sending not the report but just a link to it, so that he user will authenticate before accessing the information.

The solution

ADF has bookmark support for pages in the unbounded task flow, so we take a look at how the bookmark attribute works and how to use it. The built in support has limitations in that only pages in the unbounded taskflow can be bookmarked, and at times we would want pages within a bounded taskflow to be bookmark-able, so we take a look at a method for bookmarking/deep-linking a page within a bounded taskflow.

Bookmarking in the unbounded taskflow

The following example of the out-of-the-box support for bookmarking is based on the standard Oracle documentation here.

You start out with a standard app, in this case a page that lists  the departments in the HR schema and a second page that displays the details of  the staff in a given department. We need to make this second page bookmark-able, i.e. we need the ability to directly give a URL with parameters and pull the staff information of the department that we use as the parameter in the URL. The taskflow is simple and is shown below.
click to enlarge

You can download the full example for the complete code, but the essentials of the example are these :
  • The first page lists the depatments table, and the second page gets the staff details for a specific department 
  • The second page is using a sql query (ViewObject) that has the departmentName as a bind parameter.
  • You have the first page(welcome) with the department list(from DEPARTMENTS table in HR schema) displayed on a table, and each row has an <af:commandButton> that has its action attribute set to a navigation rule that directs the flow to the staff details page.
  • The  <af:commandButton> also takes care of passing the parameter to the details page.(code below)
click to enlarge

 Now, for the purpose of the example, the command button has an action listener that is bound to a custom method on the AM that takes the department name as a method parameter and executes the Staff Details VO(this dept name being a bind param for the VO). An <af:setActionListener> sets the dept name corresponding to the button in to a backing bean property. Then in the pageDef for the Department page, an operation binding for the AM method(via DataControl) created and is configured to pickup the backing bean property as a parameter to the AM method. So when the button is clicked: 
  1. The <af:setActionListener>  copies the respective department name to a backing bean property 
  2. Then the actionListener for the button fires executing the method binding, 
  3. The method binding takes the department name from the backing bean property(set in step 1), and uses it as a parameter to the AM method. 
  4. This AM method in turn executes the StaffdetailsVO binding the given department name to it. 
  5. Now the staff details VO contains the staff information for the given department. 
click to enlarge

AM Method - click to enlarge

Then, since the action attribute of the command button was set to a navigation rule to the staff page, the Staff Details page loads displaying the staff VO that has been executed already.
click to enlarge

This is the basic working of the example app. Now for bookmarking, we need the ability to extract the URL parameter from the URL and execute the StaffDetailsVO when loading the Staff Details page. ADF provides exactly this.

In the unbounded taskflow, open the property inspector for the view activity representing the staff detail page(Click on the StaffDetail ViewActivity) and you can see there is a properties section for bookmarking. 
click to enlarge

Here you will see the URL parameter name and value. They basically mean that the framework will take whatever value is in the URL for the given name, and it will populate that value to the destination. The optional method property lets you invoke a custom method after the values have been processed and before the page is loaded to do custom processing, like execute a VO with the param we get  from the URL !      

In this case, name is set to “dept”  and value is set to #{pageFlowScope.deptDetails.departmentName}, which is the departmentName property in the backing bean. So essesntially what the framework does is look at the URL for the parameter named “dept”, take the value for tht parameter and populate the value to the backing bean property . Now we also have a custom method defined as #{pageFlowScope.deptDetails.loadDepartmentDetails} which is a method defined in the backing bean as:

click to enlarge

Since the above method is invoked after processing the parameters, the departmentName property of the backing bean has been set to the value specified by the URL param “dept”. So the call to getDepartment will return the department name that was passed though the URL. The rest is like clockwork, we get the same method binding and execute it. Its worthwhile to note here that the method binding here is created on the Staffdetails page’s pageDef and defaults to the backing bean property departmentName for the department name parameter it needs to execute the Staffdetails VO. So setting the operationBinding parameter manually in this method is not required and is shown for demonstration.

Bookmarking in bounded task-flows
Bounded task-flows are a little bit more tricky and before we dive in to the implementation, consider this: When we say URL accessible, we are essentially saying a publicly available resource reachable by a URL, whereas a bounded taskflow is like a component, which needs a container. So we need a way to make the hidden innards of a bounded taskflow accessible in the form of a URL, with optional parameters. One way to do this to setup/construct the state for a page in the bounded taskflow based on the parameters in the URL that we’ll use. Since pages in bounded taskflows cannot be reached directly(actually they can, but the URL is not human readable and is very snarly) the approach here is to create a "container" page in the unbounded taskflow, and embed our bounded taskflow inside the container as a region. Then we will make that "container" page bookmark-able as described above. This way the clients will always see the "container" page's URL  which would be nice and simple too. The bookmark-able page takes the URL parameters and passes them to to the taskflow as taskflow params and the task flow will be constructed so that it can recreate state based on the input parameters. Bounded taskflows do have a property called URL invoke. This enables the taskflow to be invoked with a URL, and is a good option when you want to expose the whole taskflow to be URL accessible, not just a page within the taskflow. We will not look at this option as we are trying to gain access to a specific page/part of a taskflow without going though the taskflow’s normal flow.

About the example
As the example, we’re going to do the exact same app as before, but time as a bounded taskflow with parameters. In the example, we will see the whole flow implemented, from search and details, and this is not necessary in most cases where you want to make a single page of your application bookmark-able/linkable. This is more of a pattern that I have found that will save time, and keeps code consistent. Develop the whole taskflow as bounded and provide the extra “hooks” to parts of your bounded taskflow from the unbounded one. This way, you can reap all the benefits of a bounded taskflow (like reusability, security), and the taskflow consumer can expose parts of the taskflow as URL accessible.

First we design the bounded taskflow. Since this taskflow takes parameters, the taskflow parameters and properties can be set in the property inspector by clicking on the blank area in the taskflow diagram.
click to enlarge

The taskflow starts with a router which decides which page to see. although this is not required, it demonstrates an approach for structuring task flows that are built for URL accessibility(see the “about the example” box note). The important part is the taskflow parameters, as you can see from the property inspector image above. We’ll see how these parameters are passed to the task flow later on. The router looks at one parameter(viewMode) to decide which page page it wants to show. In the example, it is always the StaffDetails page. Once it determines that the details page is to be loaded, it then invokes a MethodCallActivity, passing the second input parameter, which is the deptName, to the method.
This MethodCallActivity has a page definition/ binding container so that it can invoke the AM method to execute the Deatils VO by passing in the dept Name. To open this pageDef file, right click the MethodCallActivity and choose "Go to Page Definition". Once the VO has been executed, the method call outcome loads the StaffDetails page which simple displays the executed VO as before. To make the page URL accessible, we put a “hook” page in the unbounded taskflow that is Bookmarkable and captures the URL parameters. 
click to enlarge

This page contains the bounded taskflow as a region and passes the URL parameters to the taskflow though the page’s pageDef/binding container.
click to enlarge
Well that's it. You can download the sample workspace with both approaches here:
[Built on Jdev, HR schema]
To run the example
You can run

  •  welcome.jspx file to see bookmarking in unbounded taskflow
Once the page is run, for URL accessibility you can use URLs of the form :

You would also notice that when using "Staff Details" button on the welcome page to navigate to the details page, the URL in the browser contains the parameter. Thats right. The name and value pair that was configured works both ways. When navigating to a bookmark-able page, the URL is constructed based on this name/value pair by evaluating the value and putting it on the URL as a named parameter. Just the way the same value is extracted from the URL.
  • BoundedFlowContainer.jspx for the bounded task flow technique 
The example wont display anything by default, unless you put a deptName named parameter on the URL.
Once the page is run, for the bounded flow you can use the URL of the form :
http://<host>:<port>Bookmarking_with_ADF-ViewController-context-root/faces/BoundedFlowContainer?deptName=IT (or any other dept name)

Saturday, September 11, 2010

Getting the String Value or Item Code of an LOV item instead of its index

The example application can be downloaded here : LOV_example

The problem

When you have an LOV (drop down, radio button group etc.) on the page and you want to get the code or String value of the currently selected item(s) in the backing bean; But calling the getValue() on the component returns the index of the item and not its code or value.

The solution

Create the list items using a for loop around an <f:selectItem> instead of using an <af:selectItems>
Dragging and dropping the VO for the LOV from the data control palette to the page creates the list binding for the LOV in the page definition and sets up the LOV for use. The default behavior of the list binding is to use the <af:selectItems> for the selectable LOV elements, which uses indexes rather than the actual values. So to use the actual values, we circumvent the default behavior my setting up the binding ourselves using a for loop around an <f:selectItem> which lets us control both itemLabel and itemValue as opposed to the <af:selectItems> which does not offer such fine grained control. To do this, instead of dragging the VO to the page, use the component palette to select the LOV type you need (single/multi select list/dropdown) and then manually set the EL to get the individual items. The key here is to avoid using the list binding that JDeveloper creates for you and then use a for loop to create the selectable items in the list with finer control. On the page definition file, create a List binding for the VO you need, in this example, it’s the departmentsVO. From the page, you can iterate through the elements of this VO like below

<af:selectOneChoice label="#{bindings.DepartmentLOV.label}" id="textSingle"
            <af:forEach items="#{bindings.DepartmentLOV.iteratorBinding.allRowsInRange}"
              <f:selectItem id="myItem2" itemLabel="#{row.departmentName}"

Note the use of the <af:forEach> tag. We are not using the JSTL core taglib here, and the items attribute has the EL expression #{bindings.DepartmentLOV.iteratorBinding.allRowsInRange} This EL gives the items in the LOV in a format that’s usable by the <af:forEach> tag. Inside the loop is an <f:selectItem> tag with its label and value set to the values we’d like to see. The itemLabel is displayed on screen, and calling getValue() in the component will return the itemValue. The variable row, of course will be an instance of the DepartmentLOVRowImpl (in this example), so its properties can be accessed with EL as above.
The implementation is slightly different for single/multi select LOVs and what the itemValue is set to, depending on if you want to get the textual value that’s displayed or an LOV code (e.g. get dept no. when choosing the dept name) or some other property in the VO. Note that this works only if you have your VO's VORowImpl class generated/implemented.

Single select LOV

I want to get the string value of the text selected on screen

The following code goes to the page :
<af:selectOneChoice label="#{bindings.DepartmentLOV.label}" id="textSingle"
            <af:forEach items="#{bindings.DepartmentLOV.iteratorBinding.allRowsInRange}"
              <f:selectItem id="myItem2" itemLabel="#{row.departmentName}"

The backing bean method that is fired (can be bound with a valueChangeListener or as in the example, with a command button's action binding, which is not show below but is in the downloadable project code ):
public String getTextValueSingle()
    String value = String.valueOf(getTextLOVSingle().getValue());
    return null;

I want to get the LOV code and not the displayed text

This goes to the page. Notice the <f:selectItem>'s itemValue and itemLabel :
<af:selectOneChoice label="#{bindings.DepartmentLOV.hints.label}"
   <af:forEach items="#{bindings.DepartmentLOV.iteratorBinding.allRowsInRange}"
      <f:selectItem id="myItem3" itemLabel="#{row.departmentName}"
The code for the backing bean is the same :
public String getTextIDValue()
    String value = String.valueOf(getTextIDLOV().getValue());
    return null;

Multi select LOV

I want the display text values

The code for the page is the same expect for the change in the component used(its a multi select LOV)
<af:selectManyChoice label="Label 1" id="smc1"
  <af:forEach items="#{bindings.DepartmentLOV.iteratorBinding.allRowsInRange}"
     <f:selectItem id="myItem4" itemLabel="#{row.departmentName}"

The backing bean code is different here, because the multiselect LOV components return a list of Strings in return to the call to getValue(), as shown below :
public String getTextValueMulti()
    List<String> selected = (List<String>) getTextMultiLOV().getValue();
    String csvValue = "";
    for (String s: selected) // For the example, we're displaying the strings as a comm separated list
      csvValue = csvValue + s + ",";
    return null;

I want to see the LOV codes

The page code, just like the single select example, the <f:selectItem>'s itemValue and itemLabel determine whats displayed on screen and what you get back from a call to getValue()
<af:selectManyChoice label="Label 2" id="smc2"
    <af:forEach items="#{bindings.DepartmentLOV.iteratorBinding.allRowsInRange}"
        <f:selectItem id="myItem5" itemLabel="#{row.departmentName}"
The backing bean code, same as above, except that the list you get back is a list of oracle.jbo.domain.Number, the same type from the VOImpl.

public String getAllIDsSelected()
    List<oracle.jbo.domain.Number> selected =  // IDs are numbers, the type from the VO is preserved.
      (List<oracle.jbo.domain.Number>) getTextIDMultiLOV().getValue();
    String csvValue = "";
    for (oracle.jbo.domain.Number s: selected)
      csvValue = csvValue + s.intValue() + ",";
    return null;
The example application can be downloaded here : LOV_example

Thursday, August 12, 2010

Oracle Database XE on Linux

The Problem

On Linux, (I'm using Ubuntu 10.04 ) disabling autostart of Oracle XE at system boot prevents you from being able to start Oracle XE at all.

If you're installing Oracle XE on say, your personal laptop, hoping to do a bit of hobby like projects, you may not want to enable the DB to start up every time the system boots up. The DB after being installed has a configuration script ( /etc/init.d/oracle-xe configure ) that asks you if you want the DB to start up every time the computer boots up. If you chose not to start it automatically, you may realize that after the reboot, your DB does not seem to start, specifically the listener does not start, so you will be able to connect only through SQL*Plus. At this point, the
/etc/init.d/oracle-xe start
simply does not seem to do anything.

The Solution

Runlevel management.
Install Oracle XE with the 'start at boot time' option enabled or if you already installed with this disabled, enable it.

Enable/Disable Oracle XE database autostart

/etc/init.d/oracle-xe enable
enable autostart
/etc/init.d/oracle-xe disable
disable autostart

Once you have enabled autostart, you can use
and disable oracle-xe from run-levels 2,3,4 and 5. See below 

Thats it ! You're done. Now you can start/stop oracle any time using the following commands :

/etc/init.d/oracle-xe start
Start Oracle XE
/etc/init.d/oracle-xe stop
Strop Oracle XE

The run-levels correspond to the multiuser environment in the Ubuntu and other Debian flavored Linux distributions. Preventing the oracle-xe script from running in this manner is essentially configuring it to run at boot time, but conveniently telling the system to skip running the start up script.

The problem seems to be that Oracle XE uses a second configuration file for its startup scripts that maintain some of these settings. This file can be found in


Within this file you see :
# ORACLE_DBENABLED:'true' means to load the Database at system boot.

If this property is set to false, as it would be if you chose not to run start the DB at boot time, then the /etc/init.d/oracle-xe start does not work. The problem is possibly in the /etc/init.d/oracle-xe script, but this seemed a better solution than debugging and editing the script. Maybe I'll try editing the script one of these days...

Update : I'm told that I should not modify and redistribute the shell script, but if you dont mind getting your hands a bit dirty, take a look at the start() function in the script :
(The problem is that th listener is not started... Hmmm.. anything looking suspicious ?)
status=`ps -ef | grep tns | grep oracle`
        if [ "$status" == "" ]
                if [ -f $ORACLE_HOME/bin/tnslsnr ]
                        echo "Starting Oracle Net Listener."
                        $SU -s /bin/bash $ORACLE_OWNER -c "$LSNR  start" > /dev/null 2>&1

Friday, August 6, 2010

ADF Application with multiple Data Sources or Database connections

The Problem: ADF Application with multiple Data Sources or Database connections.

This is a pretty normal use-case, but can be a bit puzzling to new developers. Most apps have more than one database that they connect to. One way of dealing with this is to hide the fact there are multiple databases under the DB layer through the use of synonyms and DBlinks, but sometimes such access is not possible or desirable.  Here I discuss how to use multiple databases from ADF BC.

Solution: Multiple Root Application Modules

The basic element here is the notion of the Root Application Module. For starters, the Root Application Module defines the transactional context.  You need to create two application Modules, each one connecting to its own Database. You could also connect the very same application module to two different databases if you need to, more on that later.  Nesting one application module inside another to get access to it won’t work as nested application modules share the same root.
So the way to do this is to create a *new* _Root_ Application Module directly from the BC4J configuration. This ensures that the connection associated with that Application module’s configuration is used. The ADF model layer usually takes care of handling instances of you Application Modules, and here, you are doing it manually. This brings some risk, and be careful to release the Application Module after use.

Create Project

Start out by creating one or more model projects in your application. In most cases you’ll only require one project, but if you need to create the ADF BC objects from database tables, you will likely need two projects so you don’t have to switch connections in the same project at design time. The “Connection” you see in the Project Properties > Business Components (click on Business Components) is used only during design time to generate ADF BC objects from a DB. An Application Module’s Configuration(bc4j.xml) defines the connection it uses at run time .

Figure 1
The two model projects will house the Application Modules that connect to the two different Databases.


Once the model projects are created, open the Configuration dialog box for the Application modules. The connection an Application Module uses at runtime is defined in the Application Module’s configuration and not the project properties.


The Manage Configurations dialog lists the Configurations available for that AM. The configuration for an AM encapsulates the parameters for the AM like the connection it uses. The configuration name is important as we’ll later use it to identify a particular named configuration and use that named configuration to create an Application Module instance. To specify the parameters inside the named configuration, select the configuration name, and choose Edit

I’m assuming that a Data Source will be used. If using a JDBC URL, the steps are the same. A valid Data Source name is defined for the first DB and the steps should be repeated the same for the second Application Module connecting to the second DB. These Data sources need to be available at runtime, so either they need to exist in the Application server you are deploying to, or you need to deploy them as part of your application.  I’m using the automatic deployment of DS provided by JDeveloper (this might not be suitable for production) so JDeveloper automatically provides a Data Source entry in this wizard based on the connections defined at the Application or IDE level. These Data sources have name that is the connection name appended with the two letters ‘DS’.   After editing the Data source, you have effectively created a Configuration called DB_One_ServiceLocal  (see screenshot) that uses the Data Source /jdbc/database_1DS  . This configuration can now be used anytime to create a root application module with the configured parameters (like an alternate Data Source ).

A note about Data Sources

See this for how to deploy a Data source manually.
This explains how to make use of JDeveloper’s automatic data source deployment.

Here is where most people get puzzled. After creating two Application Modules, you would be tempted to nest your second application module inside your first. This does not work, as the transaction context is defined for the root application module, and when you nest, the root application module does not change, and so the connection does not change. The connection used is the root Application Module’s connection. The solution is to create a new Root Application Module directly from the named BC4J configuration we created. This being a root application module on its own ensures that the connection associated with that Application module’s configuration is used. 

The Code

The following screenshot shows the classes generated by JDeveloper, nothing out of the ordinary.

The second app module exposes a method on its client interface that the first application module invokes.
Here is the method the second AM exposes on its client interface:
   * Method exposed by this AM to provide the query results from its VO.
   * Since this AM's configuration connects it to the second database,
   * the VO query is executed agaist that DB
   * @return
   public String querySecondDB()  {
      return ((DBTwoVORowImpl) getDBTwoVO().first()).getSampledata();
Now in order for the first application module t access and query the second data base, it creates a new root application module instance of the second application module using the named configuration that connects it to the second database. Once the new root application module instance is obtained, the exposed method is invoked and depending on the scenario, the root application module instance is released. The method used is Configuration. createRootApplicationModule()
public String queryMulipleDBs(){
    String fromDBOne;
    String fromSecondDB;
    fromDBOne = ((DBOneVORowImpl) getDBOneVO().first()).getSampledata();
    // Create new root AppModule from the named Configuration
    DB_Two_Service service =  (DB_Two_Service)Configuration.createRootApplicationModule("", "DB_Two_ServiceLocal");
    // Query the second DB
    fromSecondDB = service.querySecondDB();
    Configuration.releaseRootApplicationModule(service,true); //releases and removes the AppModule
    return "from first DB : " + fromDBOne + " from second DB : " +fromSecondDB;

If you have the queryMulipleDBs() method of the first Application Module exposed on its client interface, you can use the Business components test to validate the whole thing since with 11g, the Business components tester can work with Data sources as well.

A note about multiple Projects and Application Modules

Here we used a separate project and an Application Module to connect to our second DB. This however is a personal preference, I like this because it keeps the code easily readable and separates the artifacts cleanly. The real crux of the technique is an alternative root application module using a particular configuration. So ineffect you could have two ApplicationModules in the same project with thier configurations connecting to two DBs or you could have the same ApplicationModule definition with just an alternative Configuration(that connects to the other DB) and instantiate a new instance of the same ApplicationModule definition as a root AM, with the alternate Configuration using the same code. 
So here we have the first AM instantiating another root instance of itself with another Configuration, one that connects to another DataSource.