Sunday, November 7, 2010

ADF UI - Getting all pagedef attributes of a particular VO iterator programatically (find transients among them as well :) )

This might be rare requirement to get handle on pagedef attributes of a particular VO iterator. But, it would be quite useful for some scenarios like when you want to get the values of attributes of a particular iterator present in the current jsff page (not each and every VO attribute) and compare them with the original values to know if the user has changed the attribute through the UI. It would be waste of effort to check all VO attributes if they're changed as the user can only change the attributes present in the UI jsff pages.

But, it's not as easy as getting a reference to bindings (DCBindingContainer) and call the method getAttributeBindngs() on it. Even though it returns all the pagedef attribute bindings, they'll include attributes of all VO iterators in the pagedef. The tricky part is to get attributes of only a particular VO iterator in the pagedef. Here, in this post, I'll explain how to do that.

I did some research and wrote the a method to retrieve all the pagedef attributes of the VO iterator specified by 'VOName' as a parameter. This method also has the logic to find out the transient attributes present the VO. This would be quite useful when you want to find out the transient attributes of a VOIterator in the pagedef and to do logic on them (like skipping them for comparision, etc.,).

Method code in the bean:
public void storePageDefAttrs(String VOName) { DCBindingContainer binding = (DCBindingContainer)ADFUtil.evaluateEL("#{bindings}"); //getting the attribute bindings in the pagedef, it'll contain all pagedef attribute bindings of all VO iterators in pagedef List attrBindings = binding.getAttributeBindings(); //getting iterator for attribute bindings Iterator itr = attrBindings.iterator(); //getting the current row for the VOName ViewRowImpl row = (ViewRowImpl)ADFUtil.evaluateEL("#{bindings." + VOName + "Iterator.currentRow}"); //pageDefAttrs will store pageDef attribute names for the given VO specified by 'VOName' List pageDefAttrs = new ArrayList(); //transientAttrs will store trasient attribute names added in the pagedef for the given VO specified by 'VOName' List transientAttrs = new ArrayList(); //iterating through all attribute bindings while (itr.hasNext()) { AttributeBinding attrBinding = (AttributeBinding)itr.next(); //getting the attribute name String attrName = attrBinding.getName(); //getting the iterator binding for the attribute DCIteratorBinding attrIterBinding = (DCIteratorBinding)ADFUtil.evaluateEL("#{bindings." + attrName + ".iteratorBinding}"); //getting the iterator name for the iterator binding String attrIterBidningName = attrIterBinding.getVOName(); //checking if this attribute's iterator name is equal to the passed VOName if (VOName.equals(attrIterBidningName)) { //if the attributes' iterator name is equal to passed VOName, this attributes belongs to the VO specified by 'VOName'. So adding it to pageDefAttrs. pageDefAttrs.add(attrName); //getting the attribute index int attrIndex = row.getAttributeIndexOf(attrName); //getting the view attribute definition ViewAttributeDefImpl vDef = (ViewAttributeDefImpl)row.getViewDef().getAttributeDef(attrIndex); //checking if it's a transient attribute. boolean transientPageDefAttr = (vDef.getEntityAttributeDef() == null) || (vDef.getEntityAttributeDef().getColumnName() == null); //if it's transient, adding it to transientAttrs list if (transientPageDefAttr) { transientAttrs.add(attrName); } } } //stroing the pagedef attribute names and transient attribute names for the given VOName in the pageFlowScope variables. ADFUtil.setEL("#{pageFlowScope.pageDefAttrs}", pageDefAttrs); ADFUtil.setEL("#{pageFlowScope.trasientPageDefAttrs}", transientAttrs); }

The above code is self explanatory from the comments inline. It takes 'VOName' as a parameter and finally stores all pagedef attributes(including transients) for that VO in the ArrayList 'pageDefAttrs'. It'll also store transient attributes of the VO in the ArrayList 'transientAttrs'.

I devloped a sample application that prints the all attributes and transient attributes present in the pagedef. When you download and run the application, it'll open a search page. Search for a record and select one row and click on 'Edit' button. Now, you'll goto edit page and when you click on 'Show Pagedef Attributes' button, it'll print all attributes as well as the transient attributes present in the pagedef.

Attributes in EmpDeptVO definition:

Attributes in DeptVO definition:


Pagedef file containing some of the attributes from EmpDeptVO and DeptVO:
<?xml version="1.0" encoding="UTF-8" ?> <pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="11.1.1.56.60" id="EditEmployeePageDef" Package="com.demo.fragments"> <parameters/> <executables> <variableIterator id="variables"/> <iterator Binds="EmpDeptVO" RangeSize="25" DataControl="DemoAMDataControl" id="EmpDeptVOIterator"/> <iterator Binds="DeptVO" RangeSize="25" DataControl="DemoAMDataControl" id="DeptVOIterator"/> </executables> <bindings> <attributeValues IterBinding="EmpDeptVOIterator" id="Ename"> <AttrNames> <Item Value="Ename"/> </AttrNames> </attributeValues> <attributeValues IterBinding="EmpDeptVOIterator" id="Job"> <AttrNames> <Item Value="Job"/> </AttrNames> </attributeValues> <attributeValues IterBinding="EmpDeptVOIterator" id="Loc"> <AttrNames> <Item Value="Loc"/> </AttrNames> </attributeValues> <attributeValues IterBinding="EmpDeptVOIterator" id="Mgr"> <AttrNames> <Item Value="Mgr"/> </AttrNames> </attributeValues> <attributeValues IterBinding="DeptVOIterator" id="Dname"> <AttrNames> <Item Value="Dname"/> </AttrNames> </attributeValues> <attributeValues IterBinding="DeptVOIterator" id="Loc1"> <AttrNames> <Item Value="Loc"/> </AttrNames> </attributeValues> <attributeValues IterBinding="EmpDeptVOIterator" id="attribute1"> <AttrNames> <Item Value="attribute1"/> </AttrNames> </attributeValues> <attributeValues IterBinding="EmpDeptVOIterator" id="attribute2"> <AttrNames> <Item Value="attribute2"/> </AttrNames> </attributeValues> </bindings> </pageDefinition>



Ouptput attributes on running the sample application:


So, from the above screen shot you can see our method printed the EmpDeptVO's attributes and transient attributes present in the pagdef correctly.

Enjoy :) !

PS: In case, if you're aware of better approach than the above one, please share with me too. Thank you :)

1 comment:

  1. Hi Murali,

    I basically want to store the selected row on a table that has a backing bean. Any time i navigate away from the page and come back , i loose the selected row, reason being that the table is bound to a class with a backing bean scope. If i bind the table to a pageflow scope bean it works fine and i dont need to store the value.

    I want to know the right approach to do it instead of having to bind the whole table to a pageflow scope bean.

    Thanks
    -pradipc@gmail.com

    ReplyDelete

Related Posts with Thumbnails