mastering oracle adf bindings
TRANSCRIPT
1
About me
3
Ski Route
4
Let’s Go!
5
6
Bindings?
7
Application Layers
8
Layers Interaction
9
Fundamental Theorem of Software Engineering (FTSE)
We can solve any problem by introducing an extra level of
indirec8on.
…except for the problem of too many levels of indirec8on
10
Model Layer
10
ADF Model
12
ADF Model
Why ADF Bindings?
12
• A core part of Oracle ADF • Powered by Oracle • Declara8ve programming
approach • Common UI tasks out-‐of-‐
the-‐box – Naviga8on – Range fetching – State Management • ADF Bindings API
Ski Route
13
UI Component Binding
15
<af:inputText value="#{bindings.FirstName.inputValue}" label="#{bindings.FirstName.hints.label}" required="#{bindings.FirstName.hints.mandatory}" …
EmpViewPageDef.xml
16
ADF Model Artifacts
17
² PageDef.xml ² Binding metadata
² DataBinding.cpx ² Page defini8on map ² Data Controls
² Adfm.xml ² DataBinding.cpx, DataControls.dcx, ² bc4j.xcfg, *.jpx
² Web.xml ² ADFBindingFilter
² ADF libraries
Page Definition File
18
<executables> <iterator DataControl="EmployeesAMDataControl” Binds="VEmployees" RangeSize="25" id="VEmployeesIterator"/> </executables> <bindings> <acributeValues id="EmployeeId” IterBinding="VEmployeesIterator”> <AcrNames> <Item Value="EmployeeId"/> </AcrNames> </acributeValues> <acributeValues id="FirstName” IterBinding="VEmployeesIterator”> <AcrNames> <Item Value="FirstName"/> </AcrNames> </acributeValues> … </bindings>
<af:inputText value="#{bindings.FirstName.inputValue}” label="#{bindings.FirstName.hints.label}"
Page Definition File. Executables
19
² Iterator <iterator> ² Method Iterator <methodIterator>
² Variable Iterator <varaibleIterator> ² Invoke Ac8on <invokeAc8on> ² Page <page> ² Search Region <searchRegion> ² Task Flow <taskFlow> ² Mul8task Flow <mul8TaskFlow>
Page Definition File. Bindings
20
² Ac8on bindings ² Ac8on <ac8on> ² Method ac8on <methodAc8on>
² Value bindings ² Current Row
² Acribute value <acributeValues> ² Boolean value <bucon> ² List <list, listOfValues>
² Row Set ² Tree <tree> ² DVT <graph>
Ski Route
21
22
Binding Context vs Binding Container
23
JSF Lifecycle vs ADF Page Lifecycle
24
Bindings in ADF lifecycle. ADF Binding Filter
25
Bindings in ADF lifecycle. Restore View • Restore View • Apply Request Values • Process valida8ons • Update Model Values • Invoke Applica8on • Render Response
26
Bindings in ADF lifecycle. Restore View • Restore View -‐ Init Context -‐ Prepare Model • …
Binding Container at Prepare Model
27
² Page Parameters ² Task Flow Parameters ² Executables with Refresh=prepareModel
² Iterators, Invoke Ac8ons ² Page Template ² Task Flow bindings
28
Bindings in ADF lifecycle. Render Response • Restore View • Apply Request Values • Process valida8ons • Update Model Values • Invoke Applica8on • Render Response -‐ Prepare render (render Model)
Iterator Refresh Attribute
29
² default (deferred) ² On demand
² always ² Prepare Model,Update Model, Render Model
² ifNeeded ² Prepare Model, Render Model
² never ² prepareModel ² prepareModelifNeeded ² renderModel ² renderModelifNeeded
#{viewScope.reallyNeedToRefresh}
Ski Route
30
Accessing Binding Container
31
public BindingContainer getBindingContainer() { BindingContext bindingContext = BindingContext.getCurrent(); return bindingContext.getCurrentBindingsEntry(); }
² Get Binding Context instance ² Get Current Binding Container
Executing Method Action
32
² Get Operation Binding from Binding Container ² Set up parameters ² Execute ² Check for errors
public void raisePay(Integer employeeId) { BindingContainer bindings = getBindings(); Opera8onBinding op = bindings.getOpera8onBinding("raisePay"); op.getParamsMap().put("employeeId", employeeId); Object result = op.execute(); if (!op.getErrors().isEmpty()) { //Do something with this list of JboExcep8ons List errorList = op.getErrors(); } }
<methodAc8on Ac8on="invokeMethod” MethodName="raisePay” id="raisePay” ...
Accessing Attribute Binding
33
public String getEmailValue() { BindingContainer bindings = getBindings(); AcributeBinding emailBinding = (AcributeBinding) bindings.getControlBinding("Email"); return (String) emailBinding.getInputValue(); }
² Get Binding Container ² Find Attribute Binding by Id ² Return Input Value
<bindings> <acributeValues IterBinding="VEmployeesIterator" id="Email"> <AcrNames> <Item Value="Email"/> </AcrNames> </acributeValues> …
Accessing LOV Binding
34
² Get Binding Container ² Find JUCtrlListBinding by Id ² Get Selected Row ² Return Attribute Value
public String getDepartmentName() { BindingContainer bindings = getBindings(); JUCtrlListBinding lov = (JUCtrlListBinding) bindings.getControlBinding("DepartmentId"); // Get the selected row Row selectedRow = (Row) lov.getSelectedValue(); return (String) selectedRow.getAcribute("DepartmentName"); }
<bindings> <list IterBinding="VEmployeesIterator" Sta8cList="false" DTSupportsMRU="true" SelectItemValueMode="ListObject" Uses="LOV_DepartmentId" id="DepartmentId”/> …
Accessing Iterator Binding
35
² Get Binding Container as DCBindingContainer ² Find DCIteratorBinding by Id ² Execute VO query ² Get Current Row (ViewRowImpl) ² Get View Object Instance
public void workWithIterator() { DCBindingContainer bindings = (DCBindingContainer) getBindings(); DCIteratorBinding iter = bindings.findIteratorBinding("VEmployeesIterator"); //Execute RowSet query iter.executeQuery(); //Get current row Row r = iter.getCurrentRow(); //Get View Object ViewObject vo = iter.getViewObject(); }
<iterator Binds="VEmployees" RangeSize="25" DataControl="EmployeesAMDataControl" id="VEmployeesIterator"/>
Ski Route
36
Composite ADF page
37
38
Composite ADF page
² Everything in one page ² Regions with task flows ² Dynamic declara8ve component
39
Composite ADF page ² Everything in one page
² Regions with task flows ² Dynamic declara8ve component
40
Composite ADF page ² Everything in one page ² Regions with task flows
² Dynamic declara@ve component
Dynamic Declarative Component
41
² Uses Binding Container of the parent page ² Doesn’t have own Binding Container
… <af:gridCell ...> <af:declara8veComponent viewId="/fragments/Approvals.jsff" id="dc1"/> </af:gridCell> ….
<ui:composi8on xmlns:ui="hcp://java.sun.com/jsf/facelets" ... <af:componentDef var="acrs" componentVar="comp"> <af:panelBox text="Approvals" id="pb1"> <af:listView value="#{bindings.Approvals.collec8onModel}" var="item” fetchSize="#{bindings.Approvals.rangeSize}" id="lv1”> …
MainPage.jsf
Approvals.jsff
Bindings for Declarative Component
42
² Create Page Def file for the fragment ² Add mapping to the DataBindings.cpx
<pageMap> <page path="/fragments/Approvals.jsff” usageId="dashboard_view_ApprovalsPageDef"/> </pageMap> <pageDefini8onUsages> <page id="dashboard_view_ApprovalsPageDef" path="com.adfprac8ce.dashboard.view.pageDefs.ApprovalsPageDef"/> </pageDefini8onUsages>
<pageDefini8on id="ApprovalsPageDef" Package="com.adfprac8ce.dashboard.view.pageDefs"> <executables> <iterator Binds="Approvals” id="ApprovalsIterator” … ...
DataBindings.cpx
ApprovalsPageDef.xml
Bindings for Declarative Component
43
² Find or Create BC with findBindingContainerByPath ² Refer to the Backing Bean property public class ApprovalsBean { public BindingContainer getBindings() { BindingContext bc = BindingContext.getCurrent(); return bc.findBindingContainerByPath("/fragments/Approvals.jsff"); } …
<ui:composi8on xmlns:ui="hcp://java.sun.com/jsf/facelets" <c:set var="bindings" value="#{backingBeanScope.ApprovalsBean.bindings}"/> <af:componentDef var="acrs" componentVar="comp"> <af:panelBox text="Approvals" id="pb1"> <af:listView value="#{bindings.Approvals.collec8onModel}" var="item” fetchSize="#{bindings.Approvals.rangeSize}" id="lv1”> …
ApprovalsBean.java
Approvals.jsff
Ski Route
44
Bindings for Adaptive UI
45
Bindings for Dynamic Table
46
<executables> <iterator Binds="#{pageFlowScope.voName}" DataControl=”DynamicDataModelServiceDataControl“ id=”VDynamicIterator"/> </executables>
<bindings> <tree IterBinding="VDynamicIterator" id="VDynamic"> <nodeDefini8on Name="VDynamic0"/> </tree> </bindings>
<af:table rows="#{bindings.VDynamic.rangeSize}" fetchSize="#{bindings.VDynamic.rangeSize}” …
Dynamic Table
47
<af:table rows="#{bindings.VDynamic.rangeSize}" fetchSize="#{bindings.VDynamic.rangeSize}" emptyText="#{bindings.VDynamic.viewable ? 'No data to display.' : 'Access Denied.'}" var="row" rowBandingInterval="0” value="#{bindings.VDynamic.collec8onModel}" selectedRowKeys="#{bindings.VDynamic.collec8onModel.selectedRow}" selec8onListener="#{bindings.VDynamic.collec8onModel.makeCurrent}" rowSelec8on="single" id="t1"> <af:forEach items="#{bindings.VDynamic.acributeDefs}” var="def"> <af:column headerText="#{bindings.VDynamic.labels[def.name]}“ sortable="true" sortProperty="#{def.name}“ id="c2"> <af:outputText value="#{row[def.name]}" id="ot2"/> </af:column> </af:forEach> </af:table>
Bindings for Dynamic Form
48
<executables> <iterator Binds="#{pageFlowScope.voName}" DataControl=”DynamicDataModelServiceDataControl“ id=”VDynamicIterator"/> </executables>
<dynamic:form value="#{bindings.VDynamicIterator}" id="f1"/>
Dynamic Component (12c)
49
<af:iterator id="i1" value="#{bindings.VDynamic.acributesModel.acributes}" var="acr"> <af:dynamicComponent id="d2" acributeModel="#{acr}" value="#{bindings[acr.containerName][acr.name].inputValue}"/> </af:iterator>
<tree IterBinding=”VDynamicIterator" id="VDynamic"> <nodeDefini8on Name="VDynamic0"/> </tree>
Hand Made Dynamic Form
50
² DynamicComponent has limitations ² af:Iterator + af:switcher approach can be used <af:iterator value=”#{bindings.VDynamic.acributesModel.acributes}" var="acr" id="dc_i1"> <af:switcher id="dc_s1" defaultFacet="Default" facetName=”#{bindings[acr.containerName][acr.name].dynamicTypeID}”> <f:facet name="DATE"> <af:inputDate id="dc_id1" label=”#{bindings[acr.containerName][acr.name].label}” value=”#{bindings[acr.containerName][acr.name].inputValue}” shortDesc="#{bindings[acr.containerName][acr.name].tool8p}” /> </f:facet> <f:facet name=”INT”> …
<tree IterBinding="VDynamicterator" id="VDynamic"> <nodeDefini8on Name="VDynamic0"/> </tree>
Ski Route
51
Dynamic Bindings. Why?
52
² DynamicForm is straight forward ² DynamicForm is not good for Facelets ² Jdeveloper 12c is still new ² DynamicComponent has limitations ² Tree bindings might be expensive
² Useful for declarative components
² It’s fun! ² Have to finish the route
<tree IterBinding="VDynamicterator" id="VDynamic"> <nodeDefini8on Name="VDynamic0"/> </tree>
Creating Value Binding
53
² Get Control Definition Factory Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory();
² Create an instance of Control Value Definition (JUCtrlAcrsDef, JUCtrlBoolDef, …) JUCtrlValueDef acrDef = (JUCtrlValueDef) defFactory.createControlDef(BINDING_TYPE); ² Initialize Control Value Definition HashMap initValues = new HashMap(); initValues.put(PARAM_NAME, PARAM_VALUE); acrDef.init(initValues);
² Create an instance of Control Value Binding JUCtrlValueBinding acr = (JUCtrlValueBinding) acrDef.createControlBinding(getBindings());
² Add Control Value Binding to Binding Container getBindings().addControlBinding(acr.getName(), acr);
Dynamic Attribute Value Binding
54
private JUCtrlAcrsBinding createAcrValue(String acrName, String iteratorName) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); JUCtrlAcrsDef acrDef = (JUCtrlAcrsDef) defFactory.createControlDef(DCDefBase.PNAME_TextField); //Ini8alize acribute values binding defini8on HashMap initValues = new HashMap(); initValues.put(DCControlBindingDef.PNAME_IterBinding, iteratorName); initValues.put(ListBindingDef.PNAME_AcrNames, new String[] {acrName}); initValues.put(JUTags.ID, acrName); acrDef.init(initValues); //Create an instance of acribute values binding JUCtrlAcrsBinding acr = (JUCtrlAcrsBinding) acrDef.createControlBinding(getBindings()); //Add the instance to the current binding container getBindings().addControlBinding(acrDef.getName(), acr); return acr; }
Dynamic Attribute Value Binding
55
<af:inputText value="#{BackingBean.accountNo.inputValue}” label="#{BackingBean.accountNo.hints.label}” required="#{BackingBean.accountNo.hints.mandatory}” …
public JUCtrlAcrsBinding getAccountNo() { String acrName = "AccountNo"; DCControlBinding acr = getBindings().findCtrlBinding(acrName); if (acr == null) { acr = createAcrValue(acrName, "VDynamicIterator"); } return (JUCtrlAcrsBinding) acr; }
<acributeValues IterBinding="VDynamicIterator” id="AccountNo"> <AcrNames> <Item Value="AccountNo"/> </AcrNames> </acributeValues>
#{bindings.AccountNo}
Dynamic Boolean (button) Value Binding
56
private JUCtrlBoolBinding createBoolValue(String acrName, String iteratorName) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); JUCtrlBoolDef acrDef = (JUCtrlBoolDef) defFactory.createControlDef(DCDefBase.PNAME_BuIon); HashMap initValues = new HashMap(); initValues.put(DCControlBindingDef.PNAME_IterBinding, iteratorName); initValues.put(ListBindingDef.PNAME_AcrNames, new String[] {acrName}); initValues.put(ListBindingDef.PNAME_ValueList, new String[] {"Y","N"}); … return acr; }
<bucon IterBinding="VDynamicIterator" id="AccountClosed" DTSupportsMRU="false" Sta8cList="true"> <AcrNames> <Item Value="AccountClosed"/> </AcrNames> <ValueList> <Item Value="Y"/> <Item Value="N"/> </ValueList> </bucon>
Dynamic LOV Binding
57
private JUCtrlListBinding createLOV(String acrName, String lovName, String iteratorName) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); JUCtrlValueDef lovDef = (JUCtrlValueDef) defFactory.createControlDef(JUTags.PNAME_listOfValues); HashMap initValues = new HashMap(); initValues.put(DCControlBindingDef.PNAME_IterBinding, iteratorName); initValues.put(ListBindingDef.PNAME_AcrNames, new String[] {acrName}); //Specify LOV name. e.g. “LOV_Currency” initValues.put(ListBindingDef.PNAME_ListServerBindingName, lovName); initValues.put(JUTags.ID, acrName); lovDef.init(initValues); JUCtrlListBinding lov = (JUCtrlListBinding) lovDef.createControlBinding(getBindings()); getBindings().addControlBinding(lovDef.getName(), lov); return lov; }
<listOfValues Sta8cList="false" IterBinding="VDynamicIterator" Uses="LOV_Currency" id="Currency"/>
Dynamic Tree Binding
58
public JUCtrlHierBinding createTree(String treeName, String iteratorName) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); JUCtrlValueDef treeDef = (JUCtrlValueDef) defFactory.createControlDef(DCDefBase.PNAME_Tree); HashMap initValues = new HashMap(); initValues.put(JUTags.ID, treeName); initValues.put(JUCtrlHierDef.PNAME_IterBinding, iteratorName); JUCtrlHierTypeBinding typeBinding = new JUCtrlHierTypeBinding(); initValues.put(JUCtrlHierDef.PNAME_TypeBindings, new JUCtrlHierTypeBinding[] { typeBinding }); treeDef.init(initValues); JUCtrlValueBinding tree = (JUCtrlValueBinding)treeDef.createControlBinding(getBindings()); getBindings().addControlBinding(treeDef.getName(), tree); return (JUCtrlHierBinding) tree; } <tree IterBinding="VDynamicterator"
id="VDynamic"> <nodeDefini8on Name="VDynamic0"/> </tree>
Dynamic Value Binding
59
private JUCtrlValueBinding createBinding(BindingDef bindingDef) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); JUCtrlValueDef valueDef = (JUCtrlValueDef) defFactory.createControlDef(bindingDef.getBindingType()); HashMap initValues = bindingDef.getInitMap(); valueDef.init(initValues); JUCtrlValueBinding binding = (JUCtrlValueBinding) valueDef.createControlBinding(getBindings()); getBindings().addControlBinding(valueDef.getName(), binding); return binding; }
Dynamic Value Binding
60
private class BooleanBindingDef extends BindingDef { @Override public HashMap getInitMap() { HashMap map = new HashMap(); map.put(DCControlBindingDef.PNAME_IterBinding, iteratorName); map.put(ListBindingDef.PNAME_AcrNames, new String[] {acrName}); map.put(ListBindingDef.PNAME_ValueList, new String[] {"Y","N"}); map.put(JUTags.ID, acrName); return map; } @Override public String getBindingType() { return DCDefBase.PNAME_Bucon; } }
Dynamic Iterator Binding
61
public DCIteratorBinding createIterator(String iteratorName, String voName, String dataControlName) { Defini8onFactory defFactory = JUMetaObjectManager.getJUMom().getControlDefFactory(); //Create and init an iterator binding defini8on JUIteratorDef iterDef = (JUIteratorDef)defFactory.createControlDef(DCDefBase.PNAME_Iterator); HashMap initValues = new HashMap(); initValues.put(JUTags.ID, iteratorName); initValues.put(JUTags.DataControl , dataControlName); initValues.put(JUTags.PNAME_VOName , voName); iterDef.init(initValues); //Create an iterator binding instance DCIteratorBinding iter = iterDef.createIterBinding(BindingContext.getCurrent(), getBindings()); //Add the instance to the current binding container getBindings().addIteratorBinding(iteratorName, iter); return iter; }
<iterator Binds="VEmployees" DataControl="AppModuleDataControl" id=“VDynamiciterator"/>
Ski Route
62
63