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!