Showing posts with label Reports. Show all posts
Showing posts with label Reports. Show all posts

Friday, December 27, 2013

ADF Dynamic ADF BC - Surviving Passivation/Activation Events

ADF dynamic ADF BC and dynamic ADF UI implementation is useful functionality and is required almost in every larger project. Primary area where this functionality is applied - report parameters screens, instead of building hundreds of static report parameter screens for every report, we can build one dynamic and regenerate required ADF BC objects structure, together with dynamic ADF UI. Here you can read my previous post for the same topic - ADF Generator for Dynamic ADF BC and ADF UI - Recreate. Today post provides improved sample application with added support for ADF dynamic functionality working in passivation/activation event scenario.

Download updated sample application - ADFDynamicReportUI_v4.zip. Previous sample application contained one dummy VO - DynamicView:


This VO was replaced on runtime with real dynamic VO, created programmatically in HrModule class. This didn't worked in stress test environment, simulated by disabling AM pooling:


Null pointer exception for ADF dynamic form - activation event was failing:


It was failing, because on activation, ADF runtime was trying to activate original dummy VO - not the one we have substituted programmatically:


In theory it should work to remove dummy VO and change it with programmatic one, but really it fails on activation event:


Solution is pretty simple for this - we can get rid of dummy VO completely and rely directly on VO instance created programmatically on runtime. There is no need to define dummy VO in AM Data Model:


There is no need to have dummy VO either:


As there is no dummy VO anymore, no need to remove it's instance. We can simply create new programmatic VO instance with given name:


In page definition we should reference VO instance by the same name, obviously it will be highlighted as design time error - as there is no such VO instance defined statically, but this will work on runtime:


There are few additional improvements to survive passivation/activation events better - I will list them all below:

1. Non editable primary key - you should add primary key attribute and hide it to be non editable


2. If there is no default value for the attribute, it can be marked as not selected in query and there will be no need to include it into SQL statement


3. Not specifically related to passivation/activation - but for dependent LOV's, we need to set AutoSubmit=true for the parent attribute:


Dependent attribute should be set with backward dependency, this will reset attribute value automatically, when parent attribute value is changed:


4. SQL statement includes only selected attributes, where default value is set:


5. Dynamic VO doesn't passivate and activate correctly by default. We need to passivate and activate such VO manually. Standard method for passivation should be overridden, we can read current row attribute values and passivate them:


Standard method for activation should be overridden, to activate and set values to the current row attributes back:


6. If there are LOV's created dynamically, all such LOV's must be assigned with primary key:


Here you can see how it works on UI. Let's select Location Id, based on selected value LOV for Department Id is filtered and returns 50:


If you change Location Id, Department Id will be cleared automatically and user could select new Department Id value corresponding to the currently selected Location Id:

Saturday, November 16, 2013

Creating ADF BC View Object Instances On The Fly

This post is to describe such use case, where we have a set of common Entity Objects and want to handle View Objects and UI dynamically. This is common use case for simpler screens, usually common Entity Objects are provided from the library, but instead of creating hundreds of similar View Objects and UI fragments - we can handle such screens in generic way, by creating View Object instances programmatically and later using them through dynamic iterator.

Sample application - ADFDynamicReportUI_v3.zip is based on my previous post - ADF Generator for Dynamic ADF BC and ADF UI - Recreate. This sample is utilising ADF BC API for ViewDefImpl, VO instances are created and registered on the fly using this API.

There are two EO's created in the sample application:


Custom method is defined in Application Module implementation class - constructVOInstance, this method is used to create VO instances programmatically:


Here you can see how VO instances are created and registered:


We pass as a parameter - EO name, based on this name for VO is constructed. We check if VO with the same name already is registered, if not - VO will be created from EO. There is no need to set attributes one by one for VO, we can get all attributes directly from EO. SQL statement is created by API, based on EO information. Finally - create VO instance, based on VO definition, this will expose it to the Data Control and we could access it later on runtime from bindings. VO name is returned by the method, this is used later in the page definition to supply dynamic reference to the iterator.

Dynamic reference of the VO instance is defined in the page definition, I'm getting it from Page Flow Scope (initialized through Method Call activity calling dynamic VO construction method):


UI table is rendered with the help of ADF dynamic table component, this is pretty easy part:


Before actual UI fragment with the table is opened, we call Method Call activity and invoke dynamic VO construction method exposed through AM client interface - this allows to prepare current VO instance based on passed EO name parameter:


EO name parameter is defined as required on the task flow level, rendering UI fragment with dynamic table:


For the test purposes, I have created simple main page and passing parameters for Employees and Departments having two different regions. In real use cases, this can be changed by loading the same region and passing different EO name from menu model:


Here what we can see on UI - first tab brings dynamic VO instance for Employees:


Second tab brings another dynamic VO instance, reusing the same UI - this time for Departments:

Wednesday, March 27, 2013

ADF Generator for Dynamic ADF BC and ADF UI - Recreate

Last year in November, I was blogging about ADF generator for dynamic ADF BC and ADF UI. This approach allows to generate ADF BC from metadata and draw ADF UI dynamically based on ADF BC structure. You can read more about it here. This approach works without issues. However, if you want to change dynamic ADF BC and redraw ADF UI while staying on the same fragment or page, there is special trick to recreate dynamic iterator declared in Page Definition. This trick is described in Duncan Mills blog - Refresh Problems using Adaptive Bindings, I will apply it to my sample app posted here.

Without this trick applied, if you try to change ADF BC dynamic VO - there will be error generated from ADF bindings:


Sample application - ADFDynamicReportUI_v2.zip, works better with the workaround applied. Just before ADF BC dynamic VO is changed, ADF bindings iterator is refreshed - this allows to reload ADF View based on changed ADF BC VO:


Iterator is defined in Page Definition, this is regular static iterator created out of predefined VO (later dynamically initialized, see my previous blog mentioned above). There is not table or attribute bindings, because I'm using ADF dynamic form component on the ADF UI:


Dynamic VO is constructed in AM Implementation class, based on parameter - different VO structure is created:


Different SQL statement is created:


It works now to switch to different VO structure - see the checkbox coming as part of recreated VO:

Wednesday, November 14, 2012

ADF Generator for Dynamic ADF BC and ADF UI

Often we implement solutions to automate ADF development, based on custom metadata stored in database. This is common requirement especially for reporting systems, where screens have very similar layout, just number of UI components differ. Reporting systems require parameters capture screens, each report may have different set of parameters. Instead of building separate ADF UI screen for each report - we can build only one, but dynamic. I will describe how we can achieve this with detail sample application.

I have presented this topic on OOW - OOW'12: Oracle ADF Implementations Around the Globe: Best Practices. It was promised by me to post a blog post with sample application - ADFDynamicReportUI.zip.

This sample consists four dynamic elements:

1. Dynamic VO
2. Two dynamic LOV's
3. Dynamic ADF UI Form


There is one proxy VO (read here about proxy VO concept - Proxy ViewObject and Dynamic Editable UI in ADF). This VO gets substituted by dynamic VO on runtime. I'm using this VO to be able to define iterator reference in page definition:


AM offers Client Interface method, this method is invoked from ADF Controller and is the main method responsible for dynamic structure construction:


First thing what this method does - dynamic VO creation along with the attribute creation. Select statement is defined from Dual, aliases for each of the attributes with default values are included (this typically will be retrieved from metadata). We have option to set different properties for the attribute - type, label, mandatory flag, etc.:


Next - LOV View Objects are created along with View Accessors. You should notice that second LOV is created with bind variable (Departments LOV will be filtered based on Location ID). All of this is done dynamically and can be based on custom metadata:


Sequence of the steps is important. LOV mapping with main VO attributes must be done after all View Accessors are defined. Here we map LOV's with attributes and also set LOV display type (Combo, LOV):


Last step - proxy VO is substituted with our dynamic VO:


Take a look now into helper method for LOV View Object creation. If SQL statement contains bind variable, you must set LOV View Object binding style to be BINDING_STYLE_ORACLE_NAME - otherwise will get error on runtime, related to bind variable index. If there are any bind variables, all of them must be defined:


There is another helper method, where View Accessors are defined. If LOV have bind variables, View Accessor bound attributes must be defined here. LOV metadata is constructed here also:


LOV metadata helper method constructs LOV representation:


Dynamic ADF BC code is invoked from ADF Controller, before fragment is accessed - through the custom method invocation:


On ADF UI we are using standard ADF component for dynamic UI - Dynamic Form:


This component is very good, because it doesn't require static attribute mapping in page definition, it allows to render dynamic ADF UI directly from iterator defined in page definition:


We can get parameters from UI easily, by accessing iterator from page definition:


Here you can see how dynamic ADF UI is rendered from dynamic ADF BC. Even validation is enforced, also choice list and LOV UI components are displayed:


Department Id is dependent on Location Id, change Location Id value:


Department Id LOV will be filtered by Location Id bind variable:


All this is generated dynamically from bottom to top:


Values are access and printed in the managed bean, from current row retrieved through the iterator: