30 Nov 2014

Understanding VO's method getCappedQueryHitCount

In one of my previous posts I explained the getQueryHitCount view object method. The method is typically invoked by the framework when some UI components, such as tables or tree tables, need to investigate the number of iterator rows in order to size their scroll bar. The method hits database with a SQL query calculating the number of rows. For example, if a view object query is "select * from Currency", then the getQueryHitCount will generate the following query "select count(1) from (select * from Currency)".  Off course it has a certain performance impact. Furthermore, in some cases, for example when it comes to programmatically populated view objects, it could be a pretty complicated task to calculate the number of view object rows. Therefore this method is often overridden in order to return -1 instead of performing an expensive query.
So, having done that developers can relax and feel happy since they have prevented the framework from executing needless expensive SQL queries. The application performance improved and everything seemed to be ok.
At some point they came up with an idea to fix one more performance issue. They decided to limit the number of rows to be fetched by any view object in the application. That can be done by specifying the Row Fetch Limit parameter in adf-config.xml:


But unfortunately, having done that, the application slowed down. The log analysis showed that the framework started performing "select count(1) ..." queries again.
If the Row Fetch  Limit is setup, the framework doesn't execute the getQueryHitCount when it needs to get an estimated row count. Instead of that, it invokes the getCappedQueryHitCount VO method. The method has the following signature:

public long getCappedQueryHitCount(ViewRowSetImpl viewRowSet,
           Row[] masterRows, long oldCap, long cap)

The viewRowSet is actually the row set containing the fetched rows, the masterRows is needed to get the parameters in a master-detail scenario, the oldCap  is not used, and the cap is actually the value that prevents the database from scanning all rows while performing a "select count ..." query.
So, in our case the cap is going to be 200 and the method is going to generate the following query:
"select count(1) from (select * from Currency where ROWNUM<=201)".
The framework demonstrates the same behavior and invokes getCappedQueryHitCount rather than
getQueryHitCount when the iterator binding property RowCountThreshold comes with some positive value:

    <iterator Binds="CurrencyView" RangeSize="25"
              DataControl="AppModuleDataControl" id="CurrencyViewIterator"
              RowCountThreshold="200"/>

By default RowCountThreshold = 0. 
So, if we need to avoid that sort of "select count ..." queries as well, we should either override the getCappedQueryHitCount method or set up RowCountThreshold = -1 at the iterator binding level.

That's it!











22 Nov 2014

Populating Dirty Entities while VO execution

As we know entity based view objects don't store the data themselves. The view object rows are backed up by the entity instances stored in the entity cache. When the VO execution process is being performed the framework runs over the fetched result set, creates view object rows, creates blank entity instances for each VO row, populates these entities with the fetched data and adds them to the entity cache.  Very roughly this process can be represented on the following diagram:



But what is going to happen if the entity cache already contains entities being fetched? Furthermore, how is the framework going to perform VO execution if those entities are modified by a user? On one hand users need to get recent data from the datasource, on the other hand the modified and uncommitted data shouldn't be lost. The following diagram shows how this magic works:



When the framework adds a new entity to the entity cache it checks whether there is already an entity with the same primary key in the entity cache. If such entity is found then the framework merges the old entity and the new entity. It is supposed that the new entity contains more recent data and this data should be applied to the old entity attributes. However, the framework doesn't change attributes of the old entity if they contain modified and uncommitted data. Note, in this example the user has changed the first name from John to Frank. On the other hand the last name has been changed in the data source from Stone to Gordon. So, we can see how John Stone turned into Frank Gordon.

One important thing should be mentioned here. When the framework merges modified entities it tries to verify the consistency. In other words it checks whether the dirty entity has not been modified by another user in the datasource. By default it compares values of all entity attributes and if it finds any differences it's going to raise an exception "Another user has changed the row with primary key ...". So, in this particular example we are likely to run into that exception, unless we have explicitly marked which attributes should by checked to verify the consistency. We can do that by setting up the  "Change Indicator" property of the entity attribute. If an entity contains any change indicator attributes then only those attributes participate in the consistency verification process. For sure, in our example we should mark as change indicators some other attributes, but not last name.



Since the old entity in the entity cache contains already updated data, there is no need in the new entity anymore. The view row is backed up now by the old entity and the new entity just becomes garbage which is going to be collected by the GC.

The situation can be more complicated when the user has modified entities, but they are not in the entity cache. This could be possible if the user's application module has been borrowed by another user and all the transactional data has been passivated to the passivation storage. Definitely before VO execution the framework is going to restore and activate all that stuff back. When the framework restores dirty entities from the passivation storage it is able to populate only modified attributes, since  values of those attributes only have been passivated. In order to get values of the rest of the attributes from the datasource the framework invokes findByPrimaryKey method on the entity definition instance. Once a restored entity instance has been prepared in this way it is going to be put in the entity cache. The rest of the process is exactly the same as we have considered already.

That's it!







31 Oct 2014

Showing a Subset of Display Attributes in the Drop-down List with Combo box List of Values

Combo box List of Values (inputComboboxListOfValues) is supposed to be a very popular ADF Faces component for working with LOVs. Frankly speaking, this is my favorite approach when it comes to Lists of Values. In this short post I am going to focus on one feature which is often overlooked by ADF developers. If a LOV is defined by default, for example like this:


Then the framework will render the entire list of display attributes in the drop-down combo box and  in the search dialog. For the search form this is desired in our use-case. Basically, that's why all available attributes are selected. But, definitely, it would be better to show a bit shorter attribute list in the combo box. It is possible to define a subset of attributes to be shown in the drop-down list by using the Show in Combo Box option. We can specify the number of first attributes from the list to be rendered in the combo box:



Having done that, the LOV's behavior becomes more user-friendly.
Combo Box:

Search Dialog:
That's it!

26 Oct 2014

User sessions, Data controls and AM pooling

Recently I was asked an interesting question about application module pooling. As we know AM pool contains application module instances referenced by user sessions, which allows a session to fetch exactly the same AM instance from the pool at the subsequent request.
And if there is more than one root application module in the application, then each of them is going to have its own AM pool:
And how about the situation when the application handles more than one instance of the same root application module. For example any kind of UI Shell application where each tab runs a task flow with isolated data control scope.


In this case a user session references several AM instances in the pool. For this particular example there are going to be four AMs in the pool referenced by one session. One for the menu and three for the tabs.



So the question is how come the framework doesn't mess it all up and knows exactly which AM instance in the pool should be used by each tab. The answer is that an application module instance in the pool is not directly referenced by a user session. Instead of that it is referenced by a SessionCookie object which is unique for each DataControl instance. Since the task flows in the application have been run with isolated data control scope, there is a separate DataControl instance for each of them.


That's it!

30 Sept 2014

Using Java API for WebSockets in JDeveloper 12.1.3

Introduction

The latest release of JDeveloper 12c (12.1.3.0) along with WebLogic Server 12.1.3 came up with some new Java EE 7 features. One of them is support of JSR 356 Java API for WebSockets. Actually the WebSocket Protocol (RFC 6455) has been supported starting from 12.1.2.0 release, but it was based on WebLogic specific implementation of the WebSocket API. Now this proprietary WebLogic Server WebSocket API has been deprecated. However, it is still supported for backward compatibility.

In this post I am going to show an example of using JSR 356 Java API for WebSockets in a simple  ADF application. The use case is about some sailing regatta which takes place in the Tasman Sea. There are three boats participating in the regatta and they are going to cross the Tasman Sea sailing from Australia to New Zealand coast. The goal of the sample application is to monitor the regatta and inform users about how it is going on, showing the positions of the boats on a map.

We're going to declare a WebSocket server endpoint in the application and when a user opens a page a Java script function opens a new WebSocket connection. The application uses a scheduled service which every second updates boats coordinates and sends a message containing new boats positions to all active WebSocket clients. On the client side a Java script function receives the message and adds markers to the Google map according to the GPS coordinates. So, each user, interested in the regatta, is going to see the same updated picture representing the current status of the competition.

WebSocket server endpoint

Let's start with declaring a WebSocket server endpoint. There is a small issue in the current implementation, which probably will be resolved in future releases. The WebSocket endpoints can not be mixed with ADF pages and they should be deployed in a separate WAR file. The easiest way to do that is to create a separate WebSocket project within the application and to declare all necessary endpoints in this project:


This is also important to set up a readable Java EE Web Context Root for the project:


 
The next step is to create a Java class which is going to be a WebSocket end point. So, this is a usual class with a special annotation at the very beginning:

@ServerEndpoint(value = "/message")
public class MessageEndPoint {

    public MessageEndPoint() {
        super();
    }
}

Note, that JDeveloper underlines the annotation with red. We are going to fix the issue by letting JDeveloper configure the project for Web Socket.

Having done that, JDeveloper is going to convert the project into a Web project adding the Web.xml file and add necessary library:

Furthermore, the endpoint class becomes runnable and we can just run it so as to check how it actually works:
In response JDeveloper generates the following URL at which the WebSocket endpoint is available. Note, that the URL contains the project context root (WebSocket) and the value property of the annotation (/message). If everything is ok then when we click the URL, we'll get the "Connected successfuly" information window:


By the way, there is a typo in the message.
And now let's add some implementation to the WebSocket endpoint class. According to the specification a new instance of the MessageEndPoint class is going to be created for each WebSocket connection. In order to hold a bunch of all active WebSocket sessions we're going to use a static queue:

public class MessageEndPoint {
    //A new instance of the MessageEndPoint class 
    //is going to be created for each WebSocket connection
    //This queue contains all active WebSocket sessions
    final static Queue<Session> queue = new ConcurrentLinkedQueue<>(); 

    @OnOpen
     public void open(Session session) {
         queue.add(session);         
     }    

    @OnClose
      public void closedConnection(Session session) {
         queue.remove(session);
      }
      

     @OnError
     public void error(Session session, Throwable t) {
           queue.remove(session);
           t.printStackTrace();
       }


The annotated methods open, closedConnection and error are going to be invoked respectively when a new connection has been established, when it has been closed and when something wrong has happened. As we have done that, we can use some static method to broadcast a text message to all clients:

     public static void broadCastTex(String message) {
        for (Session session : queue) {
            try {
               session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
In our use case we have to notify users with new GPS coordinates of the boats, so we should be able to send via WebSockets something more complex than just text messages.


Sending an object

Basically, a business model of the sample application is represented by two plain Java classes Boat:

public class Boat {
  private final String country;
  private final double startLongitude;
  private final double startLatitude;

  private double longitude;
  private double latitude;
  

  public String getCountry() {
      return country;
  }

  public double getLongitude() {
      return longitude;
  }

  public double getLatitude() {
      return latitude;
  }
  
  public Boat(String country, double longitude, double latitude) {
      this.country = country;
      this.startLongitude = longitude;
      this.startLatitude = latitude;
  }
...

and Regatta:

public class Regatta {
    private final Boat[] participants = new Boat[] {
        new Boat("us", 151.644, -33.86),
        new Boat("ca", 151.344, -34.36),
        new Boat("nz", 151.044, -34.86)
    };
    
    public Boat[] getParticipants() {
        return participants;
    }
...

 
For our use case we're going to send an instance of the Regatta class to the WebSocket clients. The Regatta contains all regatta participants represented by the Boat class instances containing updated GPS coordinates (longitude and latitude). 
This can be done by creating a custom implementation of the Encoder.Text<Regatta> interface, or in other words we're going to create an encoder which can transform a Regatta instance into a text and specify this encoder to be used by the WebSocket endpoint while sending an instance of the Regatta.

public class RegattaTextEncoder implements Encoder.Text<Regatta> {
  @Override
  public void init(EndpointConfig ec) { }

  @Override
  public void destroy() { }


  private JsonObject encodeBoat(Boat boat) throws EncodeException {
      JsonObject jsonBoat = Json.createObjectBuilder()
          .add("country", boat.getCountry())
          .add("longitude", boat.getLongitude())
          .add("latitude" , boat.getLatitude()).build();
       
    return jsonBoat;
   }

  
  @Override
   public String encode(Regatta regatta) throws EncodeException {
      JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();         
    
    
      for (Boat boat : regatta.getParticipants()) {
          arrayBuilder.add(encodeBoat(boat));
      }

      return arrayBuilder.build().toString(); 
   }
      
}

@ServerEndpoint(
  value = "/message",
  encoders = {RegattaTextEncoder.class })
 
Having done that, we can send objects to our clients:

    public static void sendRegatta(Regatta regatta) {
        for (Session session : queue) {
            try {
                session.getBasicRemote().sendObject(regatta);
            } catch (EncodeException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


The RegattaTextEncoder represents a Regatta object as a list of boats using Json notation, so it is going to be something like this:

[{"country":"us","longitude":151.67,"latitude":-33.84},{"country":"ca", ...},{"country":"nz", ...}]


Receiving a message
On the client side we use a Java script function to open a new WebSocket connection:
//Open a new WebSocket connection
//Invoked on page load 
function connectSocket() {  
  websocket = new WebSocket(getWSUri());    
  websocket.onmessage = onMessage;   
}


And when a message arrives, we're going to loop over array of boats and for each boat add a marker on the map:

function onMessage(evt) {
  var boats = JSON.parse(evt.data);
  for (i=0; i<boats.length; i++) {
     markBoat(boats[i]);  
  }   
}

function markBoat(boat) {
  var image = '../resources/images/'+boat.country+'.png';
  var latLng = new google.maps.LatLng(boat.latitude,boat.longitude);  
  
  mark = new google.maps.Marker({
           position: latLng,
           map: map,
           title: boat.country,
           icon: image
        });
}

 
You can learn down here how to integrate Google maps into your applications.

Run the regatta

In order to emulate a live show we use ScheduledExecutorService. Every second we are going to update GPS coordinates and broadcast the update to all subscribers:

private final ScheduledExecutorService scheduler = 
   Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> runHandle;


//Schedule a new regatta on Start button click
public void startRegatta(ActionEvent actionEvent) {

    //Cancel the previous regatta
    if (runHandle != null) {
        runHandle.cancel(false);  
    }            

    runHandle = scheduler.scheduleAtFixedRate(new RegattaRun(), 1, 1, 
                                              TimeUnit.SECONDS); 
}



public class RegattaRun implements Runnable {

    private final static double FINISH_LONGITUDE = 18;
    private final Regatta regatta = new Regatta();


    //Every second update GPS coordinates and broadcast
    //new positions of the boats
    public void run() {            
       regatta.move();
       MessageEndPoint.sendRegatta(regatta);           

       if (regatta.getLongitude() >= FINISH_LONGITUDE) {
           runHandle.cancel(true);       
       }
    }
}


Bet on your boat

And finally, the result of our work looks like this:



The sample application for this post requires JDeveloper 12.1.3. Have fun!

That's it!

28 Sept 2014

Groovy Support for attribute UI hints

In one of my previous posts I showed how we can use Groovy expressions in custom properties of Entity and VO attributes. The technique allows custom property values to be evaluated at runtime and in order to use it we had to assign a Groovy expression to a custom property programmatically as it is not possible to do that declaratively at design time.

There is a new feature in JDeveloper 12.1.3 which allows to declaratively set up Groovy expressions for UI hints of entity and view attributes.  For example the UI hint "Display" of the Returndate attribute is defined as an expression "Roundtrip==Y":  


So, the Returndate attribute is supposed to be displayed only if it is a round trip, and this is achieved by using the visible attribute of the UI component:
<af:inputDate value="#{bindings.Returndate.inputValue}"
              label="#{bindings.Returndate.hints.label}"
              required="#{bindings.Returndate.hints.mandatory}"
              columns="#{bindings.Returndate.hints.displayWidth}"
              shortDesc="#{bindings.Returndate.hints.tooltip}"
              visible="#{bindings.Returndate.hints.DISPLAYHINT}"
              id="id2" partialTriggers="sor1">
 
The sample application for this post requires JDeveloper 12.1.3 and it is available for download here.

That's it!

31 Aug 2014

Really Dynamic Declarative Components

In this short post I am going to focus on ADF dynamic declarative components. I mean a well known ADF tag af:declarativeComponent. It can be used as a pretty convenient way to design a page as a composition of page fragments and components. For example, our page can contain the following code snippet:

 <af:declarativeComponent viewId="PageFragment.jsff" id="dc1">
   <f:facet name="TheFacet">
     <af:button text="button 1" id="b1"/>
   </f:facet>                    
 </af:declarativeComponent>


And the PageFragment.jsff is a usual page fragment like this one:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <af:panelGroupLayout id="pgl1">
    <af:outputText value="This is a page fragment. 
                          You can add your content to the following facet:"
                   id="ot1"/>
    <af:facetRef facetName="TheFacet"/>
  </af:panelGroupLayout>
</jsp:root>


If we need to be able to pass some parameters to a page fragment, we can define the fragment as a component:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:componentDef var="attrs">
  <af:xmlContent>
    <component xmlns="http://xmlns.oracle.com/adf/faces/rich/component">
      <facet>
        <facet-name>TheFacet</facet-name>
      </facet>
      <attribute>
        <attribute-name>Title</attribute-name>
      </attribute>
    </component>
  </af:xmlContent>
  <af:panelGroupLayout id="pgl1">
    <af:outputText value="This is a component #{attrs.Title}.
                          You can add your content to the following facet:" id="ot1"/>
    <af:facetRef facetName="TheFacet"/>
  </af:panelGroupLayout>
 </af:componentDef> 
</jsp:root>

In this example we can pass the value of the Title attribute as it is shown in this code snippet:

<af:declarativeComponent viewId="ComponentFragment.jsff"
                         id="dc2"
                         Title="Buttom Container">                    
   <f:facet name="TheFacet">
        <af:button text="button 2" id="b2"/>
    </f:facet>                    
</af:declarativeComponent>


And the most cool thing about this technique is that viewId attribute can accept not only static strings, but EL expressions as well:

 <af:declarativeComponent viewId="#{TheBean.fragmentViewID}"
                          id="dc1">
   <f:facet name="TheFacet">
     <af:button text="button 1" id="b1"/>
   </f:facet>                    
 </af:declarativeComponent>


public String getFragmentViewID() {
    return "PageFragment.jsff";
}


Actually that's why this construction is called dynamic, and that's why this feature can be considered as a powerful tool for building well structured, flexible and dynamic UI.

That's it!


16 Aug 2014

Entity Level View Accessors

The sign on the View Accessors tab in JDeveloper says "View accessors are used for defining and filtering the data source referenced in list based validation and presented in a list of values". And really, usually we define view accessors for LOVs and, may be, sometimes, for list validators. But besides that view accessors can be used as a convenient way to execute a SQL query while implementing some business logic. Since business logic is concentrated at the entity level and usually is implemented in the EntityImpl class it is convenient to define and work with a view accessor at the entity level.
Let's consider a simple use case. There is a standard Employees entity. In order to implement some business logic we need to calculate an average salary for the employee's job in the employee's department. So, we need to execute the following SQL query:

select AVG(Salary) avg_salary 
from Employees 
where department_id = :departmentid and
      job_id = :jobid

We have defined a view object based on this query (just definition without any instance in AM) and defined a corresponding view accessor in the Employees entity:


For the view objects like this, that are used for some calculations only, it is recommended to setup Forward Only access mode at the Tuning section of the General tab:



JDeveloper generated a getter method for the view accessor in the EmployeesImpl class:
/**
 * Gets the view accessor <code>RowSet</code> VAVGSalary.
 */
public RowSet getVAVGSalary() {
    return (RowSet) getAttributeInternal(VAVGSALARY);
}


And whenever we need to get an updated result of this query in our Java code we can do tho following:

public BigDecimal getCalcAvgSalary() {
    Row r  = getVAVGSalary().first();
    return (r!=null ? (BigDecimal) r.getAttribute(0) : null);         
}
 
This method can be used in a Groovy expression as well. For example as a default value expression of some transient attribute:

That's it!

31 Jul 2014

Popup, Dialog and Input Components

In this post I would like to focus on a very common use case when we have af:popup containing af:dialog with input components inside. There are a couple of pitfalls that we need to watch out for when implementing this use case.
Let's consider a simple example:

<af:popup id="p1" contentDelivery="lazyUncached">
          
  <af:dialog id="d2" title="Dialog" >
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
  </af:dialog>
  
</af:popup>  

The most interesting thing here is the popup's property contentDelivery which is set to lazyUncached. This prevents the popup from caching the submitted input values and forces it to get the values from the model on each request instead of using values from the cache.

Let's make the example a bit more complicated. In the lastName's  setter we are going to throw an exception:

public void setLastName(String lastName) throws Exception {        
    this.lastName = lastName;        
    throw new Exception("This last name is bad");
}

So, obviously if we try to submit the dialog we'll get the following:

The input values can not be submitted to the model and they are going to be stored in the local values of the input components. These local values are not going to be cleaned up even if we press the Cancel button and these values will be used during the subsequence request. In order to prevent this behavior we have to set resetEditableValues property of the popup to whenCanceled. Like this:

<af:popup id="p1" contentDelivery="lazyUncached"
                  resetEditableValues="whenCanceled">

  <af:dialog id="d2" title="Dialog" >
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
  </af:dialog>  
  
</af:popup>  

Let's consider an example of af:dialog with custom buttons:
<af:popup id="p1" contentDelivery="lazyUncached"
                  resetEditableValues="whenCanceled"
                  binding="#{TheBean.popup}">

  <af:dialog id="d2" title="Dialog" type="none">
     <af:inputText value="#{TheBean.firstName}" label="First Name" id="it1"/>
     <af:inputText value="#{TheBean.lastName}" label="Last Name" id="it2"/>
     <f:facet name="buttonBar">
        <af:panelGroupLayout layout="horizontal" id="pgl1">
          <af:button text="Ok" id="b2" 
                     actionListener="#{TheBean.buttonActionListener}"/>
          <af:button text="Cancel" id="b3" immediate="true"
                     actionListener="#{TheBean.buttonActionListener}"/>
        </af:panelGroupLayout>  
     </f:facet>

  </af:dialog>  
  
</af:popup>  


So, there are two custom buttons "Ok" and "Cancel" with the following actionListener:

public void buttonActionListener(ActionEvent actionEvent) {
    getPopup().hide();
}

The resetEditableValues doesn't work in this case and local values of the input components won't be cleaned up when pressing the Cancel button. There are a couple of options to fix this issue.
The first one is to add af:resetListener to the Cancel button:

          <af:button text="Cancel" id="b3" immediate="true"
                     actionListener="#{TheBean.buttonActionListener}">
               <af:resetListener type="action"/>
          </af:button>           

The second option is to cancel the popup instead of just hiding it in the Cancel button action listener:

  <af:button text="Ok" id="b2" 
             actionListener="#{TheBean.buttonActionListener}"/>
  <af:button text="Cancel" id="b3" immediate="true"
             actionListener="#{TheBean.cancelButtonActionListener}"/>


public void cancelButtonActionListener(ActionEvent actionEvent) {
   getPopup().cancel();
}
 
That's it!

26 Jul 2014

Smart Auto-PPR Change Event Policy

There is a common belief among ADF developers that setting the iterator binding change event policy to ppr  is not a good thing in terms of performance because this policy forces the framework to refresh all attribute bindings that are bound to this iterator on each request. That's not true!
The framework refreshes only attributes that have been changed during the request and attributes that depend on the changed attributes.
Let's consider a simple use-case. There is a form:

The iterator's change event policy is set to ppr, which is default in JDeveloper 11gR2 and 12c. The "First Name" and the "Last Name" fields are auto-submitted. The "Full Name" field is going to be calculated by concatenation of the first and last names. So, in the setters of the first and last names we have a corresponding method call:
public void setLastname(String value) {
  setAttributeInternal(LASTNAME, value);

  setFullname(getFirstname() + " " + getLastname());
}


Let's have a look at the response content generated by the framework once the "Last Name" has been inputted:


In response to the modified last name the framework is going to partially refresh only two input components - the last name and the full name. The full name is going to be refreshed because its value has been changed during the request. The rest of the components on the form don't participate in the partial request.

Let's consider a bit more complicated use case.

We are going to show value of the "Title" field as a label of the "Full Name" field on the form:

<af:inputText label="#{bindings.Title.inputValue}"
              value="#{bindings.Fullname.inputValue}" 
              required="#{bindings.Fullname.hints.mandatory}"
              columns="#{bindings.Fullname.hints.displayWidth}"
              maximumLength="#{bindings.Fullname.hints.precision}"
              shortDesc="#{bindings.Fullname.hints.tooltip}" id="itFullName">
</af:inputText>


So, the label of the "Full Name" should be updated every time we make a selection of the title. For sure, the "Title" field is auto-submitted. And let's have a look at the response content:


Despite the value of the "Full Name" has not been changed during the request the input component is going to be refreshed because its label property points to the value of a changed field. And again only these two fields are going to be refreshed during the partial request.

That's it!


30 Jun 2014

Dives into Oracle ADF at ODTUG Kscope14

In this post I would like to thank everyone, who managed to attend my sessions at ODTUG Kscope14 in Seattle, WA.  I was proud to present two deep technical ADF sessions at this exciting event:

Deep Dive into Oracle ADF: Advanced Techniques  and
Hidden Rocks in Oracle ADF: Sailing Directions 

I hope these sessions will help ADF developers to feel themselves more confident while working with Oracle ADF a bit beyond the declarative approach.

That's it!

31 May 2014

Working with Bindings in a Task Flow Finalizer

Sometimes we need to access the business service layer in a task flow finalizer. For example, in order to clean up some resources we have to invoke an application module method in a finalizer. But a task flow finalizer is not an activity, therefore it can't have its own page definition file and we are not able to use the bindings layer in order to invoke the application module method. So, we have to get a reference to the application module instance and work with its methods directly. That's not really cool. This is kind of a rule violation. Let's see what we can do about that.

We're going to manually create a page definition file for the task flow finalizer and we are going to access the binding container in the finalizer method programmatically. So, in order to create a page def file we are going to drag-n-drop the AM method to the task flow diagram as a method call:


Jdeveloper is going to create a page def file for the method call and it's going to register the page def file in the DataBindings.cpx. So, in the DataBindings.cpx we'll have a page map:

 <page path="/WEB-INF/task-flow-definition.xml#task-flow-definition@someAMMethod"
   usageId="com_cs_blog_finalizerbindings_view_task_flow_definition_task_flow_definition_someAMMethodPageDef"/>


Actually we can remove it as we don't need it at all. And we'll have a page definition usage:

 <page id="com_cs_blog_finalizerbindings_view_task_flow_definition_task_flow_definition_someAMMethodPageDef"
   

path="com.cs.blog.finalizerbindings.view.pageDefs.task_flow_definition_task_flow_definition_someAMMethodPageDef"/>

Having done that, we can remove the fake "someAMMethod" method call in the task flow definition.
Now we are ready to implement a managed bean method for the task flow finalizer:
 public void taskFlowFinalizer() {
  //Get the current binding context
  BindingContext bc = BindingContext.getCurrent();
  
  //Find our binding container by name (page id in the DataBindings.cpx)
  DCBindingContainer dcb = 
    bc.findBindingContainer("com_cs_blog_finalizerbindings_view_task_flow_definition_task_flow_definition_someAMMethodPageDef");
  //Execute the method
  OperationBinding oper = dcb.getOperationBinding("someAMMethod");
  oper.execute();       
  }
That's it!

27 May 2014

Entity Level View Accessors

In one of my previous posts I explained what happens behind the scene while working with View Accessors. Usually we define view accessors in the same view object definition where we define lists of values. However, it is also possible to define view accessors at the entity definition level. In that case we can use an entity level view accessor when defining lists of values in the entity based view objects. This is a pretty convenient feature in terms of reusing. So, a proper view accessor  can be defined only once at the entity definition level and it’s going to be available for reusing in all view objects that are based on this entity definition.
But besides convenience, this feature can also be useful in terms of performance. For each view accessor definition the framework at runtime creates an internal lookup VO instance according to the view definition linked to the view accessor. This is shown on the following diagram.


There are two VO definitions on the diagram - VO1 and VO2. Both of them are based on the same entity definition. There are three view accessors on the diagram. Two of them are defined at the view object definition level and the rest one is defined at the entity definition level. All view accessors point to the same lookup view object definition. The framework at runtime is going to create three internal view object instances. One instance per view accessor definition. Note, that lists of values that are based on the entity level view accessor will share the same lookup view object instance, which means they are going to reuse the same query results and share the same query collection cache.
So, view accessors, defined at the entity level can be considered by ADF developers as a promising technique.


That's it!

30 Apr 2014

Enabling and Disabling AM Pooling Programmatically

In this post I am going to show some useful technique that ADF developers and QAs may use in their daily work. I mean the ability to enable and disable application module pooling on-the-fly without redeploying and restarting the application. This can be useful for testing purposes when you are able to quickly enable or disable AM pooling and check how the application works in both cases. There are some issues that you can run into only when the pooling is enabled. So, developing and testing an application with constantly disabled AM pooling doesn't cover all cases.
I believe that not many developers and testers use in their daily life such monster instruments like EM Fusion Middleware Control. Therefore I would propose to include that functionality in the application, certainly for the development and testing purposes only.

In order to implement that nice feature, we have to create our custom implementation of the ApplicationPool interface and register it in the application module configuration. So, our custom ApplicationPool looks like this:
public class CustomApplicationPoolImpl extends ApplicationPoolImpl {
    private boolean amPoolingEnabled = true;
    

    public CustomApplicationPoolImpl() {
        super();
    }

    @Override
    public boolean isAMPoolingEnabled() {
       return amPoolingEnabled;
    }
    

    public void setAmPoolingEnabled(boolean amPoolingEnabled) {
        this.amPoolingEnabled = amPoolingEnabled;
    }
}

It has an overridden method isAmPoolingEnabled which returns a private valriable member amPoolingEnabled.  In order to register this class and make it used by the framework we should go to the application module configuration and specify the class name in the PoolClassName property at the bottom of the properties list:



And when we need to get an instance of our CustomApplicationPoolImpl and setup the value of the amPoolingEnabled variable, we can make use of the oracle.jbo.common.ampool.PoolMgr internal class and do the following:
    public void setAmPooling(boolean value){
       CustomApplicationPoolImpl pool =
          (CustomApplicationPoolImpl)PoolMgr.getInstance().
           getResourcePool("com.cs.blog.ampoolappl.model.AppModuleLocal");

        pool.setAmPoolingEnabled(value);
    }

The sample application for this post requires JDeveloper R2 11.1.2.3.0.

That's it!

26 Apr 2014

Working with the Array Data Type in a Table

In this post I would like to follow up on my previous article about Oracle collection data types and I am going to focus on working with oracle.jbo.domain.Array attributes in af:table component.

So, in my database I have the following SQL type:

create or replace type varchar2_array_type as table of varchar2(200)  

And I've got the following table:

create table testarray (
 SomeField Number,
 ArrValue VARCHAR2_ARRAY_TYPE)

nested table ArrValue store as arrvalue_tab return as value;  

There is an entity in ADF BC model which is based on the testarray table:


The data type of the attribute Arrvalue is oracle.jbo.domain.Array. 

There is a corresponding attribute binding in the binding container:

    <attributeValues IterBinding="VTestarrayIterator" id="Arrvalue">
      <AttrNames>
        <Item Value="Arrvalue"/>
      </AttrNames>
    </attributeValues>
The easiest way to display the value of this attribute could be like this:
<af:table value="#{bindings.Arrvalue.inputValue.array}" var="row" 
          id="t1">
   <af:column sortable="false" headerText="Array Values" id="c1">
      <af:inputText value="#{row}" id="ot3"/>             
   </af:column>
</af:table>
And the result looks pretty nice:

The only problem with this approach is that the table is not updatable. It is read only one.  

The EL expression "#{bindings.Arrvalue.inputValue.array}" is going to invoke the method oracle.jbo.domain.Array.getArray() which returns an immutable Object[] array and all modifications to this array will be lost.

If we need to be able to update the data in the table, we've got to do the following:
  1. Make a copy of the bindings.Arrvalue.inputValue.array
  2. Set this copy as table's value
  3. At the Update Model Values phase wrap the copy back into oracle.jbo.domain.Array and put it to the Arrvalue.inputValue. 

So, we are going to make a copy and keep it in a request scope managed bean:

private Object[] array = null;

private Object[] createArray() {
  JUCtrlValueBinding dcb = getArrayCtrlBinding();
  if (dcb!=null){
      Array arr = (Array) dcb.getInputValue();
      if (arr!=null) {
          array = arr.getArray();
      }          
  }
  return array;
}


public void setArray(Object[] array) {
    this.array = array;
}

public Object[] getArray() {
    return (array == null ? createArray() : array);
}

    
private JUCtrlValueBinding getArrayCtrlBinding() {
  BindingContext bc = BindingContext.getCurrent();
  DCBindingContainer binding = (DCBindingContainer) bc.getCurrentBindingsEntry();
  return (JUCtrlValueBinding ) binding.findCtrlBinding("Arrvalue");
}
 
   
When it comes to using this copy as table's value, we can do the following:
  <af:table value="#{TheBean.array}" var="row" 
            id="t1"
            varStatus="status">
    <af:column sortable="false" headerText="Array Values" id="c1">
       <af:inputText value="#{TheBean.array[status.index]}" id="ot3"/>             
    </af:column>
  </af:table>
 
Note, that we didn't use just #{row} as inputText's value. It wouldn't work, since #{row} would just return an immutable String. Instead of that we used the varStatus table attribute. The EL expression #{TheBean.array[status.index]} makes the framework able to call a corresponding setter method at the Update Model Values phase, so all modifications made in the table will be saved to the TheBean.array.  
 
The last step is to put TheBean.array back into the attribute value at the Update Model Values phase. We can use a fake invisible inputText for that purpose:
<af:inputText value="#{TheBean.dummy}" 
              visible="false" 
              converter="EmptyConverter"
              id="it2"/>

  
This input text should be placed below the table on a page. The beauty of this approach is that the framework will try to update the inputText value on each request. So, the setter method TheBean.setDummy(String dummy) will be invoked on each request at the Update Model Values phase right after the table values have been saved to the TheBean.array. And at this moment we're going to wrap the array into oracle.jbo.domain.Array and put it back to the Arrvalue.inputValue:

public void setDummy(String dummy) {
  getArrayCtrlBinding().setInputValue(new Array(array));   
  array = null;
}
 
The secret of this dummy inputText is hidden in the EmptyConverter:
public class EmptyConverter implements Converter {
 public Object getAsObject(FacesContext facesContext,
                           UIComponent uIComponent, String string) {
     return null;
 }

 public String getAsString(FacesContext facesContext,
                           UIComponent uIComponent, Object object) {
     return null;
 }
}
It emulates that null value has been submitted for this component with the request. On the other hand, the dummy getter always returns a not null value:
 public String getDummy() {
    return DUMMY;
 }   

So, the framework has no option, but to invoke the setDummy method at the Update Model Values phase.

The sample application for this post requires JDeveloper 11.1.1.7.

That's it! 

31 Mar 2014

Groovy Expressions in Custom Attribute Properties

Custom attributes properties is a handy ADF BC feature which is often used in order to add some extra information to the attribute definition. We can use custom attribute properties in our business logic and in the UI as well, referring to the custom properties as to the common attribute hints. These custom properties along with their values can be defined at either View definition level or Entity definition level. So the values of the custom properties are shared across all user sessions, as they are defined at the definition level. But it would be cool, if the values can be evaluated for each usage dynamically at run-time, depending on some context.  Actually, that's possible. We can use Groovy expressions in custom attribute properties.

There is no way to setup a Groovy expression for a custom property at design time, but we can do it easily at run-time.  Let's consider a simple VO for a flight booking form:

   
The Returndate attribute has a custom property Visible. At this point we don't bother about its value. Just because it can't be empty, its value is "Value".
What we need to do is to override the resolveDefObject() method in our custom ViewDef class and  setup a Groovy expression for the Visible property:

public class VFlightBookingDefImpl extends ViewDefImpl {

  @Override
  public void resolveDefObject() {
    super.resolveDefObject();
    AttributeDefImpl attrDef =  (AttributeDefImpl) findAttributeDef("Returndate");          
    attrDef.setPropertyExpression("Visible", "Roundtrip == 'Y'");  
  }
  

The Visible custom property can be used for defining the visible attribute of the inputDate ADF Faces component:
<af:inputDate value="#{bindings.Returndate.inputValue}"
   label="#{bindings.Returndate.hints.label}"
   visible="#{bindings.Returndate.hints.Visible}"


So, the input component for the Returndate attribute is going to be visible only for a round trip flight.


The sample application for this post requires JDeveloper R2.

That's it!


22 Mar 2014

Binding Container Viewable Attribute

In this post I'm going to show how the "viewable" attribute of the binding container can change the ADF controller exception handling behavior.

Let's consider a very simple task flow:


Here we go from the view1 to the view2, calling the badMethod on the way. The badMethod method call, as the name suggests, causes an exception. Always. It invokes a managed bean method:
public String methodCall() {
    BindingContainer bindings = getBindings();
    OperationBinding operationBinding = 
        bindings.getOperationBinding("badServiceMethod");
    operationBinding.execute();
    return "go";
}


The methodCall uses the binding layer in order to invoke the badServiceMethod business service method:
    public void badServiceMethod() {
      throw new JboException("Help!");
    }
 

Since the badServiceMethod is invoked via ADF model using methodAction binding definition, the methodCall method is not going to be interrupted.  The exception is going to be caught and processed by the binding layer and registered with the binding container of the task flow activity.  The badMethod method call has its own binding container, containing the methodAction binding.  After invoking the method call, the controller checks whether the activity's binding container has any exceptions, and if it has then the further control will be passed to the exception handler. This is the exception handler's job to take care about errors. For example, like this:
 public void exceptionHandler() {
    ControllerContext context = ControllerContext.getInstance();
    ViewPortContext currentRootViewPort = context.getCurrentViewPort();

    if (currentRootViewPort.isExceptionPresent()) {
        Exception ex = currentRootViewPort.getExceptionData();
        if (ex != null) {
            FacesContext fc = FacesContext.getCurrentInstance();
            FacesMessage facesMessage =
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                 ex.getMessage(), null);
            fc.addMessage(null, facesMessage);
        }
    }
}
  

 
So, this is the default framework behavior. According to that we'll never reach view2. After the exception has been thrown, we go back to the view1 showing the exception message to the user. This message will be kindly added to the FacesContext by the ExceptionHandler.

The binding container has the "viewable" attribute, which is true by default.  It can be changed in the page definition file:
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
        version="11.1.2.62.76"
        id="task_flow_definition_task_flow_definition_badMethodPageDef"
        Package="com.cs.blog.checkactionexception.view.pageDefs"
        SkipValidation="true" viewable="false"
        >

Note, that "viewable" starts with a lower case letter.

When the ADF binding layer processes an exception it starts with the root binding container and goes down registering the exception for each nested binding container if it is a viewable one.  So switching off the viewable property will prevent the framework from registering an exception for this binding container. That means, that our "Help!" JboException will not be registered for the badMethod's binding container, and the control will not be passed to the ExceptionHandler after invoking the method. The controller will go further to the view2. However, the exception is going to be registered for the parent binding container, containing the task flow. So, the user will see the error message anyway, but at the view2 view activity. Note, that the ExceptionHandler is not going to be invoked  in this case at all.
This behavior is demonstrated across all ADF 11g versions (both R1 and R2) except 11gR1 PS6. In the 11.1.1.7.0 the exception handler is going to be invoked anyway, without bothering whether the binding container causing the exception is viewable or not.  In this case the control flow will not go forward, it's going to stop, and the user will see the error message at the view1 view activity.
 
That's it!




        
  
  
 

28 Feb 2014

Understanding View Accessors

Introduction
In an ADF application a view accessor is considered as an approach to access a view object from another view object or entity object. The view accessors are mostly used to provide result sets for the lists of values. In this post I am going to show how actually the view accessors work, to reveal what's going on behind the scene, to clarify how many internal view object instances are created by the framework and how many row sets are used.


Internal View Object instances
Let's start with easy things. I've got a view object definition VForexTrade representing forex operations on the currency market. It has an attribute Buycurrencyid with a list of values LOV_Buycurrencyid:


It also has an attribute Sellcurrencyid with a list of values LOV_Sellcurrencyid:



There is a view accessor VCurrency1 which is based on VCurrency view definition.

So there are two LOVs referring to the same view accessor.

And there is an application module TestAppModule with an instance of VForexTrade view object definition. The name of this instance is VTodTrade and it represents today trade operations:



This simple structure can be represented in the following table:
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid VCurrency1 VCurrency - true
VTodTrade Sellcurrencyid VCurrency1 VCurrency - true


Since VCurrency1 view accessor doesn't use any shared VO instance, the framework, at run time, is going to create an internal view object instance basing on VCurrency view definition. In this case its name will be like _LOCAL_VIEW_USAGE_VForexTrade_VCurrency1. Note that the name is constructed as a concatenation of view definition names. The VO instance name doesn't matter.

Since the RowLevelBinds property of the view accessor is set to true, the framework, at run time, is going to create a separate non-default row set for each row of the VTodTrade instance. So, the internal view object instance will have a number of row sets like _LOCAL_VIEW_USAGE_VForexTrade_VCurrency1_0, _LOCAL_VIEW_USAGE_VForexTrade_VCurrency1_1,
_LOCAL_VIEW_USAGE_VForexTrade_VCurrency1_2, ...

So, each row in the VTodTrade refers to its own row set providing a list of currencies. But since this list of currencies doesn't really depend on a VTodTrade's row, and VCurrency VO doesn't have any bind variables, all these row sets are backed up by the same query collection. By the first one _LOCAL_VIEW_USAGE_VForexTrade_VCurrency1_0.  That means that the VCurrency's SQL query will be executed only once.  



Let's change this structure a little bit defining a separate view accessor VCurrency2 for the LOV_Sellcurrencyid list of values.
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid VCurrency1 VCurrency - true
VTodTrade Sellcurrencyid VCurrency2 VCurrency - true

In this case, at run time, the framework will create another internal VO instance _LOCAL_VIEW_USAGE_VForexTrade_VCurrency2 for the VCurrency2 view accessor. This instance is going to have its own bunch of row sets _LOCAL_VIEW_USAGE_VForexTrade_VCurrency2_0,
_LOCAL_VIEW_USAGE_VForexTrade_VCurrency2_1,
_LOCAL_VIEW_USAGE_VForexTrade_VCurrency2_2, ... .
All of them are going to be backed up the _LOCAL_VIEW_USAGE_VForexTrade_VCurrency2_0 query collection.



So, here we'll have two executions of the VCurrency's SQL query for both query collections.

Let's switch off  the RowLevelBinds property of our view accessors:
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid VCurrency1 VCurrency - false
VTodTrade Sellcurrencyid VCurrency2 VCurrency - false

In this case the framework will also create two internal VO instances _LOCAL_VIEW_USAGE_VForexTrade_VCurrency1 and _LOCAL_VIEW_USAGE_VForexTrade_VCurrency2. But each of them will have only one default row set to be shared across all rows of the VTodTrade view object instance. However, the VCurrency's SQL query will be executed twice, since each internal VO is going to be backed up by its own query collection.


Alrighty, let's add one more instance of the VForexTrade to the application module.



Our BC model is represented in the following table:
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid VCurrency1 VCurrency - false
VTodTrade Sellcurrencyid VCurrency2 VCurrency - false
VForwardTrade Buycurrencyid VCurrency1 VCurrency - false
VForwardTrade Sellcurrencyid VCurrency2 VCurrency - false

The interesting thing is that nothing is going to be changed, actually. The framework will create the same two internal view object instances with default row sets for each VA definition, and they will be shared by both VTodTrade and VForwardTrade VO instances.






Shared View Object instances

And now let's redefine our view accessors and get them referring to a shared VO instance.
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid SharedModule_VCurrency1 VCurrency VCurrency true
VTodTrade Sellcurrencyid SharedModule_VCurrency2 VCurrency VCurrency true

Since the view accessors refers to a real VO instance from some shared AM, the framework won't create any additional internal view objects. Instead of that, it will create a non-default row set within VCurrency shared VO for each view accessor usage with RowLevelBind set to true. And again, there is no any bind variables in the VCurrency and its result set doesn't depend on a row from which it is used. So, all these created row sets are going to be backed up by a single query collection instance. The behavior is pretty similar for both session and application shared AMs. The difference is that in the case of the session shared AM there will be one VCurrency instance per user session, and in the case of the application shared AM the framework will create only one single instance of VCurreny to be shared across the entire application. Besides that, the query collection of a session shared VO can be destroyed due to the AM recycling process or because of the garbage collection process. That will not happen with an application shared VO instance. There is a different mechanism to clean up query collections of the application shared view objects.



 
If we set the RowLevelBind property to false
VO instance LOV attribute VA VA View definition Shared VO instance Row Level Binds
VTodTrade Buycurrencyid SharedModule_VCurrency1 VCurrency VCurrency false
VTodTrade Sellcurrencyid SharedModule_VCurrency2 VCurrency VCurrency false

The framework will create a single default row set for the VCurrency view object, and this row set is
going to be shared for each view accessor usage across all rows.



That's it!

God Save Ukraine!