24 Feb 2013

Dynamic Tree Binding Definition

ADF table component usually requires a tree binding definition in the PageDef file pointing to some iterator binding.  For example a table rendering rows of some VEmp view object would require the following structure in the PageDef file:

    <iterator Binds="VEmp" RangeSize="25" DataControl="AppModuleDataControl"        id="VEmpIterator"/>
    <tree IterBinding="VEmpIterator" id="VEmp">
      <nodeDefinition DefName="com.cs.blog.dyntreebindingdemo.model.VEmp"
          <Item Value="EmployeeId"/>
          <Item Value="FirstName"/>
          <Item Value="LastName"/>
          <Item Value="Email"/>
          <Item Value="PhoneNumber"/>
          <Item Value="HireDate"/>
          <Item Value="JobId"/>
          <Item Value="Salary"/>
          <Item Value="CommissionPct"/>
          <Item Value="ManagerId"/>
          <Item Value="DepartmentId"/>
          <Item Value="CreatedBy"/>
          <Item Value="CreatedDate"/>
          <Item Value="ModifiedBy"/>
          <Item Value="ModifiedDate"/>
          <Item Value="ActionComment"/>
          <Item Value="CreatedBy1"/>

In this post I'm going to show how we can create a tree binding definition and a corresponding iterator binding dynamically at runtime.

Let's consider a managed bean method returning a tree binding definition:

private static final String VO_NAME = "VEmp";
private static final String ITERATOR_NAME = "VEmpIterator";
private static final String TREE_NAME = "VEmp";   
private static final String DATACONTROL_NAME = "AppModuleDataControl";   

public JUCtrlHierBinding getTree() {
    DCBindingContainer dcb = getBindings();

    //May be the VEmp tree binding is already created
    JUCtrlHierBinding chb = (JUCtrlHierBinding)dcb.findCtrlBinding(TREE_NAME);

    if (chb == null) { // if not

        //Looking for the VEmpIterator iterator
        JUIteratorBinding iter =
            (JUIteratorBinding)getIterator(ITERATOR_NAME, VO_NAME);

        //Create and init a tree binding definition
        JUCtrlHierDef hierDef = new FacesCtrlHierDef();
        HashMap initValues = new HashMap();
        initValues.put(JUCtrlHierDef.PNAME_IterBinding, iter.getName());
        JUCtrlHierTypeBinding typeBinding = new JUCtrlHierTypeBinding();
                       new JUCtrlHierTypeBinding[] { typeBinding });

        //Create a tree binding instance
        chb = (JUCtrlHierBinding)hierDef.createControlBinding(dcb);

        //Add the instance to the current binding container
        dcb.addControlBinding(TREE_NAME, chb);
    return chb;

And getIterator method looks for the corresponding iterator binding and creates it if it doesn't exist yet:

public DCIteratorBinding getIterator(String iteratorName, String voName)
  DCBindingContainer dcb = getBindings();

  //It could be created earlier 
  DCIteratorBinding jub = dcb.findIteratorBinding(iteratorName);

  if (jub==null) {// if not
    //Create and init an iterator binding definition
    JUIteratorDef jid = new JUIteratorDef(iteratorName, null, voName, null, 25);
    HashMap initValues = new HashMap();
    initValues.put(JUTags.DataControl , DATACONTROL_NAME);

    //Create an iterator binding instance
    jub = jid.createIterBinding(BindingContext.getCurrent(), dcb);        

    //Add the instance to the current binding container
    dcb.addIteratorBinding(iteratorName, jub);
  return jub;
The readonly table using our dynamic tree binding should look like this:

<af:table rows="#{DynTableBean.tree.rangeSize}"
          emptyText="#{DynTableBean.tree.viewable ? 'No data to display.' : 'Access Denied.'}"
          var="row" rowBandingInterval="0"
          rowSelection="single" id="dc_t1">
  <af:forEach items="#{DynTableBean.tree.attributeDefs}" var="def">
    <af:column headerText="#{DynTableBean.tree.labels[def.name]}" sortable="true"
               sortProperty="#{def.name}" id="dc_c1">
      <af:outputText value="#{row[def.name]}" id="dc_ot1"/>

The technique shown in this post can be easily used to build a declarative component responsible for browsing data of any view object passed to the component as an attribute.

That's it!


  1. Very Useful article. Thank you. I've been struggled out with this issue.
    As well as this, do you know for Updatable table usage which has LOV?
    How to define a list binding and attach it to some column?

    1. You can find an example of a dynamic LOV here:

  2. Another way:


Post Comment