Wednesday, February 4, 2015

Creating ADF Tree Table Programatically, ArrayList cannot be cast to JUCtrlHierBinding

ADF tree table can easily be created using POJO as data source in the way described in these blogs Blog1, Blog2

But if you try to access data of that tree from a managed bean, you get java.util.ArrayList cannot be cast to oracle.jbo.uicli.binding.JUCtrlHierBinding exception. And this error is caused because the tree data is not being accessed through the ADF binding layer. To resolve this issue, instead of using a POJO class we need to use a POJO Data Control as the ADF model for tree data

Here is the updated way of creating tree table based on POJO data:

- Create an Employee class
public class Employee {
 private String name;
 private String location;
 private List<Employee> directs;

 public Employee(String name, String loc, List<Employee> directs){
    this.name = name;
    this.location = loc;
    this.directs =  directs;
  }
  public String getName() {
    return name;
  }
  public String getLocation() {
    return location;
  }
  public List<Employee> getDirects() {
    return directs;
  }
}

- Create an EmployeeBean Class
public class EmployeeBean {
    private List<Employee> allEmployees;
    public EmployeeBean() {
        super();
    }
    public void setAllEmployees(List<Employee> allEmployees) {
        this.allEmployees = allEmployees;
    }

    public List<Employee> getAllEmployees() {
        List<Employee> directList = new ArrayList<Employee>(); 
        directList.add(new Employee("Ken", "New York", new ArrayList<Employee>()));
        Employee manager1 = new Employee("John", "London", directList);
        directList= new ArrayList<Employee>();
        directList.add(new Employee("Ramesh", "London", new ArrayList<Employee>()));
        Employee manager2 = new Employee("Ravi", "Bangalore",directList);
        directList= new ArrayList<Employee>();
        directList.add(new Employee("Rakesh", "Pune", new ArrayList<Employee>()));
        Employee manager3 = new Employee("Raju", "Pune",  directList);

        allEmployees = new ArrayList<Employee>();
        allEmployees.add(manager1);
        allEmployees.add(manager2);
        allEmployees.add(manager3);
        return allEmployees;
    }
}


- Right click on EmployeeBean class and select 'Create Data Control'. This will create an EmployeeBean data control that can be used to create the tree table.
- Drag and drop allEmployees from EmployeeBean data control on to the page as a tree component.

Now, you can access tree data without any issues

Assigning default search values for LOV Search and Select popup

Values for search attributes on LOV Search and Select popup can be preset using a launchPopupListener method

<af:inputComboboxListOfValues id="inpClv2"
    popupTitle="Search and Select: #{bindings.StateProvince.hints.label}"
    value="#{bindings.StateProvince.inputValue}"
    label="#{bindings.StateProvince.hints.label}"
    model="#{bindings.StateProvince.listOfValuesModel}"
    required="#{bindings.StateProvince.hints.mandatory}"
    columns="#{bindings.StateProvince.hints.displayWidth}"
    shortDesc="#{bindings.StateProvince.hints.tooltip}"
    launchPopupListener="#{backingBeanScope.lovBean.stateLaunchPopupListener}"> 
</af:inputComboboxListOfValues>


Suppose if we want to preset CountryId in Search and Select popup for State LOV, the launchPopupListener code will look like:
public void stateLaunchPopupListener(LaunchPopupEvent launchPopupEvent)
{
    UIXInputPopup lovComponent = (UIXInputPopup)launchPopupEvent.getSource();
    ListOfValuesModel model = lovComponent.getModel();
    if (model != null)
    {          
        QueryDescriptor queryDesc = model.getQueryDescriptor();
        ConjunctionCriterion conCrit = queryDesc.getConjunctionCriterion();
        List<Criterion> criterionList = conCrit.getCriterionList();
        for (Criterion criterion: criterionList)
        {
            AttributeDescriptor attrDesc = ((AttributeCriterion) criterion).getAttribute();
            if (attrDesc.getName().equalsIgnoreCase("CountryId")) 
            {
                List values = ((AttributeCriterion) criterion).getValues();
                values.set(0, "US"); 
            }
        }
    }           

}