Andrejus Baranovski
New Row Delete for ADF Form (ADF Webinar Follow-Up)
There was a question on ADF Masterclass Webinar (Video: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)) about removing new row from ADF Form. I have a blog post about removing new row from ADF table - Immediately Removing New Row Without Validation in ADF, but one of the Webinar participants was saying the same doesn't work for ADF Form layout component. I promised to double check this and post sample application.
Here you can download sample application - NewRowRemoveApp_v2.zip. So, the main trick is additionally to setting Immediate=true for Delete button, add ADF resetActionListener operation to the same Delete button:

Make sure Immediate=true is set for Delete button, along with ADF resetActionListener:

Add new row, force validation errors by trying to navigate to the next row:

Press Delete button to remove new row, validation errors will be ignored and row will be removed:

For ADF Form component is not enough to set Immediate=true property only, ADF resetActionListener must be added to force form refresh.
Here you can download sample application - NewRowRemoveApp_v2.zip. So, the main trick is additionally to setting Immediate=true for Delete button, add ADF resetActionListener operation to the same Delete button:

Make sure Immediate=true is set for Delete button, along with ADF resetActionListener:

Add new row, force validation errors by trying to navigate to the next row:

Press Delete button to remove new row, validation errors will be ignored and row will be removed:

For ADF Form component is not enough to set Immediate=true property only, ADF resetActionListener must be added to force form refresh.
Grant Ronald and Susan Duncan for ADF Mobile SIG (UKOUG, London, May 21st)
ADF Mobile is one of the hot topics in ADF area currently. If you want to see it in practice and learn about ADF Mobile architecture, I'm sure you should join UKOUG SIG in London on May 21st. Check here for more info and registration link - UKOUG Run Full Day SIG on ADF Mobile.
Grant Ronald and Susan Duncan are well known Oracle speakers, they will host this event. I know there are few seats left, you should hurry to register.
Grant Ronald and Susan Duncan are well known Oracle speakers, they will host this event. I know there are few seats left, you should hurry to register.
Video: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)
I was blogging about ADF for 7 years already, long period. I had a feeling this was a right time to bring it to the next level and have live technical ADF Q&A discussion with blog readers. It went well and I plan to repeat similar session later this year again. Read more here: Webinar: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)
You can watch video recording:
Webinar plan with links to use case descriptions and presented ADF sample apps from the blog:
1. CRUD and LOV performance and validation improvement tricks
- List Range Size - 1 for LOV
(LOVRangePagingFix: http://andrejusb.blogspot.com/2011/12/fix-rowset-is-forward-only-for-adf-bc.html)
- Row Count Threshold -1
(QueryOptimizationTableApp: http://andrejusb.blogspot.com/2012/05/how-to-disable-select-count-execution.html)
- Initial Query Overriden
- Skip Validation
(TabsValidationApp: http://andrejusb.blogspot.com/2012/12/skip-validation-for-adf-required-tabs.html)
(NewRowRemoveApp: http://andrejusb.blogspot.com/2013/01/immediately-removing-new-row-without.html)
- Immediate Validation for table
(AutoPPRApp: http://andrejusb.blogspot.com/2012/09/what-to-do-when-adf-editable-table.html)
- Post Changes
(PostControlApp: http://andrejusb.blogspot.com/2012/12/adf-post-changes-and-plsql-invocation.html)
2. Conditional validation in ADF BC, Entity Cache and View Object Instances
- Conditional
(ConditionalValidationApp: http://andrejusb.blogspot.com/2012/12/conditional-validation-in-adf-bc.html)
- Transaction level
(EOValidationApp: http://andrejusb.blogspot.com/2012/10/transaction-level-adf-bc-entity.html)
- EO Cache
(VOSynchEOCacheApp: http://andrejusb.blogspot.com/2013/05/sharing-data-between-vo-instances-in.html)
3. ADF Table pagination, List View components
- Pagination
(TablePaginationApp_v3: http://andrejusb.blogspot.com/2013/04/how-to-control-adf-table-pagination-on.html)
- List View
(ListViewApp: http://andrejusb.blogspot.com/2013/04/list-view-cool-looking-adf-ps6.html)
4. ADF Mobile login, secured ADF BC Web Services and on-device database access
- Mobile login
(adfmobilelogin: http://andrejusb.blogspot.com/2012/10/adf-mobile-login-functionality.html)
- Secured WS access
(mobilesecuredws: http://andrejusb.blogspot.com/2012/11/adf-mobile-secured-web-service-access.html)
- Master-Detail
(adfmdmobilews: http://andrejusb.blogspot.com/2013/04/master-detail-adf-bc-web-service-for.html)
You can watch video recording:
Webinar plan with links to use case descriptions and presented ADF sample apps from the blog:
1. CRUD and LOV performance and validation improvement tricks
- List Range Size - 1 for LOV
(LOVRangePagingFix: http://andrejusb.blogspot.com/2011/12/fix-rowset-is-forward-only-for-adf-bc.html)
- Row Count Threshold -1
(QueryOptimizationTableApp: http://andrejusb.blogspot.com/2012/05/how-to-disable-select-count-execution.html)
- Initial Query Overriden
- Skip Validation
(TabsValidationApp: http://andrejusb.blogspot.com/2012/12/skip-validation-for-adf-required-tabs.html)
(NewRowRemoveApp: http://andrejusb.blogspot.com/2013/01/immediately-removing-new-row-without.html)
- Immediate Validation for table
(AutoPPRApp: http://andrejusb.blogspot.com/2012/09/what-to-do-when-adf-editable-table.html)
- Post Changes
(PostControlApp: http://andrejusb.blogspot.com/2012/12/adf-post-changes-and-plsql-invocation.html)
2. Conditional validation in ADF BC, Entity Cache and View Object Instances
- Conditional
(ConditionalValidationApp: http://andrejusb.blogspot.com/2012/12/conditional-validation-in-adf-bc.html)
- Transaction level
(EOValidationApp: http://andrejusb.blogspot.com/2012/10/transaction-level-adf-bc-entity.html)
- EO Cache
(VOSynchEOCacheApp: http://andrejusb.blogspot.com/2013/05/sharing-data-between-vo-instances-in.html)
3. ADF Table pagination, List View components
- Pagination
(TablePaginationApp_v3: http://andrejusb.blogspot.com/2013/04/how-to-control-adf-table-pagination-on.html)
- List View
(ListViewApp: http://andrejusb.blogspot.com/2013/04/list-view-cool-looking-adf-ps6.html)
4. ADF Mobile login, secured ADF BC Web Services and on-device database access
- Mobile login
(adfmobilelogin: http://andrejusb.blogspot.com/2012/10/adf-mobile-login-functionality.html)
- Secured WS access
(mobilesecuredws: http://andrejusb.blogspot.com/2012/11/adf-mobile-secured-web-service-access.html)
- Master-Detail
(adfmdmobilews: http://andrejusb.blogspot.com/2013/04/master-detail-adf-bc-web-service-for.html)
Sharing Data Between VO Instances in ADF BC
Probably you already noticed that by default data is shared between VO instances (or even separate VO's) based on the same EO. Newly inserted row into one instance becomes instantly visible from another VO instance. There is a way to control this behavior in ADF, this post is based on excellent Steve Muench source of information - Using the RowQualifies() Method to Fine Tune View Link Consistency Behavior. As Steve says, by default data is shared and you can turn it off either by calling setAssociationConsistent(false) or globally per AM with jbo.viewlink.consistent=false configuration property:

Idea of this post is to go a bit deeper and to show how you control data sharing between VO instances programmatically. For example how to delay new row sharing between VO instances until this row is commited.
Sample application - VOSynchEOCacheApp.zip, contains one EO and one VO for Employees:

There are two VO instances defined in AM out of Employees:

Two fragments are implemented in ADF Controller. First displays data from EmployeesEditView and allows to insert new row. While second displays a table with data from EmployeesListView:

We create now new row in the first fragment:

Navigate to the second fragment with the table. Keep in mind - new row is not commited yet, it is just inserted into EmployeesEditView VO instance. However, as per default behavior data is shared between VO's and this new row is appearing in the list from EmployeesListView VO instance:

In order to control when newly inserted row is shared between VO instances, we can override rowQualifies method from VO Implementation as per Steve Muench suggestion above. We have access to the row and can check row status. In this example row is qualified to be added into rowset if its status is unmodified:

Test now again the same scenario - try to insert new row, but don't commit yet:

Navigate to the second fragment with list data - new row is not added yet as expected:

Go back and save new row:

You can check it will be added to the rowset now and displayed in the list from second VO instance:

Idea of this post is to go a bit deeper and to show how you control data sharing between VO instances programmatically. For example how to delay new row sharing between VO instances until this row is commited.
Sample application - VOSynchEOCacheApp.zip, contains one EO and one VO for Employees:

There are two VO instances defined in AM out of Employees:

Two fragments are implemented in ADF Controller. First displays data from EmployeesEditView and allows to insert new row. While second displays a table with data from EmployeesListView:

We create now new row in the first fragment:

Navigate to the second fragment with the table. Keep in mind - new row is not commited yet, it is just inserted into EmployeesEditView VO instance. However, as per default behavior data is shared between VO's and this new row is appearing in the list from EmployeesListView VO instance:

In order to control when newly inserted row is shared between VO instances, we can override rowQualifies method from VO Implementation as per Steve Muench suggestion above. We have access to the row and can check row status. In this example row is qualified to be added into rowset if its status is unmodified:

Test now again the same scenario - try to insert new row, but don't commit yet:

Navigate to the second fragment with list data - new row is not added yet as expected:

Go back and save new row:

You can check it will be added to the rowset now and displayed in the list from second VO instance:
JDeveloper 11g (11.1.2.4.0) Startup Mystery - JDK 1.6.0_24 Not Supported (1.6.0_35 Required)
New JDeveloper 11g (11.1.2.4.0) on Windows fails to start with embarrassing error after fresh installation, this is known issue and Oracle is fixing it. Seems like Oracle engineers missed it and released JDeveloper 11g (11.1.2.4) with wrong JDK. Once you install JDeveloper 11g (11.1.2.4.0) and try to start it, JDK error is reported - Java version 1.6.0_24 not supported. The minimum version required is 1.6.0_35 and JDEV startup stops, basically unusable:

If you go and check installation contents for JDeveloper 11g (11.1.2.4.0), you will see only JDK 1.6.0_24 packaged. This looks like a mistake to me:

Workaround (until Oracle will fix it in JDeveloper 11g (11.1.2.4.0)) is to install required JDK 1.6.0_35 manually by yourself and point it during JDEV startup:

With manually installed JDK 1.6.0_35 JDEV works:

Still this is quite funny - why JDK 1.6.0_24 would be included if JDEV requires JDK version 1.6.0_35.

If you go and check installation contents for JDeveloper 11g (11.1.2.4.0), you will see only JDK 1.6.0_24 packaged. This looks like a mistake to me:

Workaround (until Oracle will fix it in JDeveloper 11g (11.1.2.4.0)) is to install required JDK 1.6.0_35 manually by yourself and point it during JDEV startup:

With manually installed JDK 1.6.0_35 JDEV works:

Still this is quite funny - why JDK 1.6.0_24 would be included if JDEV requires JDK version 1.6.0_35.
Duplicate Validation Error Message and ADF Bindings
One of the bug requests I was fixing during this week was related to duplicate validation error message display on ADF UI. This was quite annoying to the users - the same validation error message displayed twice:

There was nothing special about this validation rule, as any other validation rule defined on ADF BC Entity Object:

I noticed something strange in Page Definition file. As per screenshot above, ADF UI renders only table component. However, in Page Definition file table binding was defined along with attribute binding for the Salary attribute:

Salary in the table is rendered from table binding, and as additionally we have attribute binding for the same element, this is causing the same validation error message reported twice (one for Salary in the table binding and another for Salary attribute binding):

Make sure not to leave duplicate bindings for the same attributes:

It reports only one validation error message, as expected:
Here you can download sample application with duplicate validation error message, try to fix it as described in this post - ADFValidationErrorApp.zip.

There was nothing special about this validation rule, as any other validation rule defined on ADF BC Entity Object:

I noticed something strange in Page Definition file. As per screenshot above, ADF UI renders only table component. However, in Page Definition file table binding was defined along with attribute binding for the Salary attribute:

Salary in the table is rendered from table binding, and as additionally we have attribute binding for the same element, this is causing the same validation error message reported twice (one for Salary in the table binding and another for Salary attribute binding):

Make sure not to leave duplicate bindings for the same attributes:

It reports only one validation error message, as expected:
Here you can download sample application with duplicate validation error message, try to fix it as described in this post - ADFValidationErrorApp.zip.
Webinar: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I)
I was blogging about ADF for 7 years already, long period. I feel this is a right time to bring it to the next level and have live technical ADF Q&A discussion with blog readers. My idea is to organize live ADF call with you - blog readers, we can repeat similar format session later as well - depends how it goes.
Webinar is scheduled for 2 hours at 7 PM (Central Europe time) on May 14th. Number of virtual seats is limited, registration is done on first come first serve basis. Webinar registration link: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I), Tue, May 14, 2013 7:00 PM - 9:00 PM CEST.
I will be ready with predefined agenda, but we can go off and speak about any ADF related questions. Predefined agenda for this call:
1. CRUD and LOV performance and validation improvement tricks
2. Conditional validation in ADF BC, Entity Cache and View Object Instances
3. ADF Table pagination, List View components
4. ADF Mobile login, secured ADF BC Web Services and on-device database access

Very excited to speak to you - blog readers, let's meet on May 14th at 7 PM (CET).
Webinar is scheduled for 2 hours at 7 PM (Central Europe time) on May 14th. Number of virtual seats is limited, registration is done on first come first serve basis. Webinar registration link: ADF Master Class and ADF Blog Q&A, Andrejus Baranovskis (Part I), Tue, May 14, 2013 7:00 PM - 9:00 PM CEST.
I will be ready with predefined agenda, but we can go off and speak about any ADF related questions. Predefined agenda for this call:
1. CRUD and LOV performance and validation improvement tricks
2. Conditional validation in ADF BC, Entity Cache and View Object Instances
3. ADF Table pagination, List View components
4. ADF Mobile login, secured ADF BC Web Services and on-device database access

Very excited to speak to you - blog readers, let's meet on May 14th at 7 PM (CET).
Master-Detail ADF BC Web Service for ADF Mobile
It seems like a bit unclear for the developers if ADF BC Master-Detail relationship can be reused out of the box through ADF BC Web Service in ADF Mobile. Short answer - yes, it can. In order to prove this I have developed sample application - second level Master-Detail relationship is exposed through ADF BC Web Service and consumed from ADF Mobile screens.
Mobile device in the first screen renders list of departments, second screen brings all employees from selected department and finally third screen brings subordinate employees (managed by). Here is ADF Mobile Task Flow implementation:

Here you can download adfmdmobilews.zip sample application, it contains both parts - server side and mobile client.
First screen brings all departments:

Second screen displays list of employees for selected department, first Master-Detail:

Third screen displays list of subordinates, employees managed by selected employee, second Master-Detail:

ADF BC server side is implemented to support classical ADF BC Master-Detail relationship defined with View Links and registered in Application Module:

ADF BC Web Service is exposed with Master VO instance - DepartmentsView1. This instance is enabled with View Criteria (just to bring entire list of departments), empty parameter values for the View Criteria are accepted:

Something very important now. Based on documentation - 11.2.6 How to Support Nested Processing in Service-Enabled Master-Detail View Objects, you must set SERVICE_PROCESS_CHILDREN property on View Link for the Master-Detail relationship be enabled for ADF BC Web Service. I did this for Department-Employees View Link:

As well as for Employee-Subordinates View Link:

This is about the server side, now we switch to ADF Mobile client. You should know that ADF Mobile client Web Service Data Control is stateless (different from regular ADF BC Data Control), this means current row selection is not preserved when moving from one ADF Mobile page to another. For the Master-Detail relationship to work on ADF Mobile client, we must transfer current Master record key between pages, in Page Flow Scope as for example:

We can drag and drop Master-Detail relationship from Data Control as usual in ADF. Here how we can set correct Master key for Detail relationship:

Data Control method - setCurrentRowWithKey is invoked in the second page (detail for Employees based on Department). We are using old good method from ADF 10g times - invokeAction, in order to call executable method on page load:

The same for the third page, where second level detail is implemented for subordinates. Here we call two methods for setCurrentRowWithKey, one for Departments and second for current manager Employee:

Keep in mind that by default setCurrentRowWithKey will not work, because ADF Mobile Web Service Data Control doesn't inherit key setup from ADF BC. You need to set key attribute for each of Data Control bindings manually, from DataControls.dcx go and edit required binding:

JDeveloper generates definition XML file for the binding, you can set proper key. Even it still displays old key and there is no way to remove it, on runtime only proper key is used:

Key is set manually for Employees binding as well:
Mobile device in the first screen renders list of departments, second screen brings all employees from selected department and finally third screen brings subordinate employees (managed by). Here is ADF Mobile Task Flow implementation:

Here you can download adfmdmobilews.zip sample application, it contains both parts - server side and mobile client.
First screen brings all departments:

Second screen displays list of employees for selected department, first Master-Detail:

Third screen displays list of subordinates, employees managed by selected employee, second Master-Detail:

ADF BC server side is implemented to support classical ADF BC Master-Detail relationship defined with View Links and registered in Application Module:

ADF BC Web Service is exposed with Master VO instance - DepartmentsView1. This instance is enabled with View Criteria (just to bring entire list of departments), empty parameter values for the View Criteria are accepted:

Something very important now. Based on documentation - 11.2.6 How to Support Nested Processing in Service-Enabled Master-Detail View Objects, you must set SERVICE_PROCESS_CHILDREN property on View Link for the Master-Detail relationship be enabled for ADF BC Web Service. I did this for Department-Employees View Link:

As well as for Employee-Subordinates View Link:

This is about the server side, now we switch to ADF Mobile client. You should know that ADF Mobile client Web Service Data Control is stateless (different from regular ADF BC Data Control), this means current row selection is not preserved when moving from one ADF Mobile page to another. For the Master-Detail relationship to work on ADF Mobile client, we must transfer current Master record key between pages, in Page Flow Scope as for example:

We can drag and drop Master-Detail relationship from Data Control as usual in ADF. Here how we can set correct Master key for Detail relationship:

Data Control method - setCurrentRowWithKey is invoked in the second page (detail for Employees based on Department). We are using old good method from ADF 10g times - invokeAction, in order to call executable method on page load:

The same for the third page, where second level detail is implemented for subordinates. Here we call two methods for setCurrentRowWithKey, one for Departments and second for current manager Employee:

Keep in mind that by default setCurrentRowWithKey will not work, because ADF Mobile Web Service Data Control doesn't inherit key setup from ADF BC. You need to set key attribute for each of Data Control bindings manually, from DataControls.dcx go and edit required binding:

JDeveloper generates definition XML file for the binding, you can set proper key. Even it still displays old key and there is no way to remove it, on runtime only proper key is used:

Key is set manually for Employees binding as well:
ADF 11g PS6 Table Pagination and Displaying Selected Row Issue
There was a post about new ADF 11g PS6 feature Table Pagination - ADF 11g PS6 - ADF 10g Table Pagination Feature is Back Finally. I had a question from the reader in the comments, about displaying selected row from the page range other than the first. Reader was saying this doesn't work, indeed I tested it with sample application and it doesn't seem to work. If you plan to implement such use case where display of selected row is important, keep in mind there are related issue in ADF UI table pagination. I will describe them below.
Sample application - TablePaginationApp_v4.zip, contains ADF task flow with two fragments. Single row is selected in the first fragment and we try to display the same row in the table from second fragment:

I will show you first how it works by default. Table is set to display 10 rows per page and we navigate to some row in the next page range:

Press Show Employees button to navigate to the table. Table displays first page range, there is no selected row shown:

You can select manually second page range - you will find selected row there:

This is what blog reader explains in his comment - current row is not displayed.
Let's try to apply one trick and see if it works - DisplayRow = selected for ADF table component:

We test now the same thing - navigate to table of Employees with row selected in other than first range page:

Selected row is displayed now, required page range is loaded automatically from the beginning:

But there is another problem now - you are locked in into current page range. Try to press other range page number, it will be changed - but not data, data remains the same and insist to show selected row:

It seems like we can use table pagination only for such use cases, when there is no need to automatically display selected row. At least until workaround is found.
Sample application - TablePaginationApp_v4.zip, contains ADF task flow with two fragments. Single row is selected in the first fragment and we try to display the same row in the table from second fragment:

I will show you first how it works by default. Table is set to display 10 rows per page and we navigate to some row in the next page range:

Press Show Employees button to navigate to the table. Table displays first page range, there is no selected row shown:

You can select manually second page range - you will find selected row there:

This is what blog reader explains in his comment - current row is not displayed.
Let's try to apply one trick and see if it works - DisplayRow = selected for ADF table component:

We test now the same thing - navigate to table of Employees with row selected in other than first range page:

Selected row is displayed now, required page range is loaded automatically from the beginning:

But there is another problem now - you are locked in into current page range. Try to press other range page number, it will be changed - but not data, data remains the same and insist to show selected row:

It seems like we can use table pagination only for such use cases, when there is no need to automatically display selected row. At least until workaround is found.
Oracle BPM 11g Mobile Worklist with ADF Mobile
I have developed ADF Mobile application to bring BPM worklist tasks to the mobile device - I would like to share concepts of such ADF Mobile application with the community. The whole idea is based on BPM Java API to access BPM Context and get currently assigned tasks for the user, read more here - Lightweight ADF Task Flow for BPM Human Tasks Overview. Once tasks from BPM are queried, they are exposed through ADF BC secured Web Service method. Web Service is consumed from ADF Mobile application through Web Service Data Control - task data is rendered on the mobile device, later user can do callback and send approve/reject actions. Approve/Reject actions will be processed by BPM API on ADF BC secured Web Service side.
ADF Mobile login and secured Web Service call implementation is done based on previous blog - ADF Mobile - Secured Web Service Access.
Here you can see BPM mobile worklist solution high level architecture:

Sample application - BPMMobileWorkListApp.zip, is shipped with three separate JDeveloper applications:
1. ADFBasicAuthApp - server side application to allow login into ADF Mobile application running on the mobile device
2. ADFSecuredService - server side application with access to BPM context and exposed secured Web Service providing list of tasks for the current user
3. ADFMobileSecuredApp - ADF Mobile application with connection to secured ADF BC Web Service, displays BPM mobile worklist
User is provided with login screen for BPM mobile worklist application:

Here we can see standard ADF Worklist task flow running in the Web browser with BPM tasks listed. The same tasks are listed in BPM mobile worklist:

In BPM mobile worklist user can select particular task and view details:

1. ADF BC secured Web Service Implementation
ADF BC secured Web Service is implemented and deployed based on this post - Web Service Interface for ADF BC Application Module in Oracle Fusion 11g.
Web Service method returns List type, each task data is represented with one line in the list. Method is exposed through ADF BC Web Service, return type - List:

Connection to BPM context is established with the username retrieved from ADF Security context, password is static for the simplicity of the example:

Sample application contains logic to access BPM context and retrieve all pending tasks for current user. Tasks are collected and returned as List:

Such Web Service can be tested from Oracle Enterprise Manager, using OWSM policy for secured access. See list of task data returned:

2. ADF Mobile application for BPM mobile worklist
Secured Web Service is consumed in ADF Mobile and Data Control is created:

Data is loaded into mobile device screen through proxy Data Control bean - WorkList, in this bean we do parsing of Web Service data retrieved from MobileService Data Control:

Here is the source code for BPM mobile worklist screen - list of tasks:

Screen to display details of BPM task in ADF Mobile:
ADF Mobile login and secured Web Service call implementation is done based on previous blog - ADF Mobile - Secured Web Service Access.
Here you can see BPM mobile worklist solution high level architecture:

Sample application - BPMMobileWorkListApp.zip, is shipped with three separate JDeveloper applications:
1. ADFBasicAuthApp - server side application to allow login into ADF Mobile application running on the mobile device
2. ADFSecuredService - server side application with access to BPM context and exposed secured Web Service providing list of tasks for the current user
3. ADFMobileSecuredApp - ADF Mobile application with connection to secured ADF BC Web Service, displays BPM mobile worklist
User is provided with login screen for BPM mobile worklist application:

Here we can see standard ADF Worklist task flow running in the Web browser with BPM tasks listed. The same tasks are listed in BPM mobile worklist:

In BPM mobile worklist user can select particular task and view details:

1. ADF BC secured Web Service Implementation
ADF BC secured Web Service is implemented and deployed based on this post - Web Service Interface for ADF BC Application Module in Oracle Fusion 11g.
Web Service method returns List type, each task data is represented with one line in the list. Method is exposed through ADF BC Web Service, return type - List:

Connection to BPM context is established with the username retrieved from ADF Security context, password is static for the simplicity of the example:

Sample application contains logic to access BPM context and retrieve all pending tasks for current user. Tasks are collected and returned as List:

Such Web Service can be tested from Oracle Enterprise Manager, using OWSM policy for secured access. See list of task data returned:

2. ADF Mobile application for BPM mobile worklist
Secured Web Service is consumed in ADF Mobile and Data Control is created:

Data is loaded into mobile device screen through proxy Data Control bean - WorkList, in this bean we do parsing of Web Service data retrieved from MobileService Data Control:

Here is the source code for BPM mobile worklist screen - list of tasks:

Screen to display details of BPM task in ADF Mobile:
BPM 11g R1 Worklist Integration (Hacking Experiment) Into Non-SOA ADF 11g R2 Domain
We all know there are no Oracle SOA/BPM available for ADF 11g R2 platform. In practice it happens to run both environments in parallel - Oracle SOA/BPM 11g R1 for process applications and ADF 11g R2 for ADF applications. Obvious question in such situations - how to access BPM 11g R1 Worklist application from ADF 11g R2 context? Well, this is possible - I will describe in this post how it can be done with some hacks. Keep in mind that officially it is not supported to access BPM 11g R1 Worklist from ADF 11g R2 environment, but if there is such requirement it can be achieved. Previously I was explaining how to run BPM 11g R1 Worklist and Human Task on Non-SOA 11g R1 domain - Running Oracle BPM 11g PS5 Worklist Task Flow and Human Task Form on Non-SOA Domain, today we go one step further and use newer ADF version for Non-SOA domain. But you should know that BPM Worklist is ADF application and really it can run well in ADF 11g R2 context. There are no SOA/BPM libraries for ADF 11g R2 installation, but this is not the issue - we can add and reference SOA/BPM libraries from different 11g R1 domain. There is no need to install complete SOA/BPM 11g R1 domain on that machine where ADF 11g R2 runs - you can copy SOA/BPM libraries package only.
Usually we don't want to deploy and run ADF related applications on the same domain where SOA/BPM is installed. Often ADF and SOA/BPM development is out of synch, this is when we need to make different BPM/SOA and ADF versions talk together.
Here you can download sample application for today post - adf11gr2_bpm.zip. This sample is based on two JDeveloper applications. IntegratedBPMWorklistApp - ADF 11g R2 application with integrated ADF 11g R1 BPM Worklist. EmployeeManagementLab - ADF 11g R1 Human Task ADF UI migrated to ADF 11g R2. BPM process - EmployeeManagement you can download from my previous post - Generic ADF 11g Human Task Handler Concept for Oracle BPM.

Visually this integration between SOA/BPM 11g R1 and ADF 11g R2 looks like this:

BPM process is deployed on SOA/BPM 11g R1 domain. Custom ADF application includes BPM Worklist ADF 11g R1 task flow and runs on ADF 11g R2 domain.
ADF 11g R2 application with integrated BPM Worklist ADF 11g R1 task flow:

Human Task ADF application generated with ADF 11g R1 and migrated to ADF 11g R2 runs on ADF 11g R2 domain:

The same ADF 11g R2 application renders custom ADF screens:

When Human Task is deployed on ADF 11g R2 domain, from the log we can see successful Human Task initialization and registration:

BPM process running on SOA/BPM 11g R1 domain points Human Task URL's to ADF 11g R2 domain:

BPM Worklist task flow is added into ADF 11g R2 custom application and is configured to run in worklist mode. At the end of the day BPM Worklist is ADF 11g R1 application with usage of some additional SOA/BPM libraries - it runs well in ADF 11g R2 context:

Make sure you don't forget to add ADF security permissions for BPM ADF task flows:

Worklist Components tag must be registered - pay attention, it points to the library from SOA/BPM 11g R1 domain.:

There are worklist and task list libraries added into ADF 11g R2 application from SOA/BPM 11g R1 domain:

Shared library - oracle.soa.workflow.wc is installed on ADF 11g R2 domain and must be referenced by custom ADF application with integrated BPM worklist:

You should install on ADF 11g R2 domain 2 worklist related libraries and make sure that WebService Policy Manager library is installed (is needed to communicated to BPM domain securely):

Add Foreign JNDI Provider pointing to the SOA/BPM 11g R1 domain (read more about this from my previous post):

Both applications - custom ADF 11g R2 with BPM Worklist and Human Task are deployed on the same ADF 11g R2 domain:

Ok, we are done with BPM Worklist part.
Let's take a look now into Human Task ADF implementation part ready to run on ADF 11g R2 domain. I simply migrated Human Task application to ADF 11g R2 by opening it in JDeveloper 11g R2:

JSF library is not migrated automatically. You need to remove JSF 1.2 and add JSF 2.0 library manually:

BPM Worklist libraries are added only for compilation, these two libraries are not not deployed:

Configuring ADF 11g R2 environment to run BPM Worklist from 11g R1 is not an easy task, but is doable based on my hacking experiment.
Usually we don't want to deploy and run ADF related applications on the same domain where SOA/BPM is installed. Often ADF and SOA/BPM development is out of synch, this is when we need to make different BPM/SOA and ADF versions talk together.
Here you can download sample application for today post - adf11gr2_bpm.zip. This sample is based on two JDeveloper applications. IntegratedBPMWorklistApp - ADF 11g R2 application with integrated ADF 11g R1 BPM Worklist. EmployeeManagementLab - ADF 11g R1 Human Task ADF UI migrated to ADF 11g R2. BPM process - EmployeeManagement you can download from my previous post - Generic ADF 11g Human Task Handler Concept for Oracle BPM.

Visually this integration between SOA/BPM 11g R1 and ADF 11g R2 looks like this:

BPM process is deployed on SOA/BPM 11g R1 domain. Custom ADF application includes BPM Worklist ADF 11g R1 task flow and runs on ADF 11g R2 domain.
ADF 11g R2 application with integrated BPM Worklist ADF 11g R1 task flow:

Human Task ADF application generated with ADF 11g R1 and migrated to ADF 11g R2 runs on ADF 11g R2 domain:

The same ADF 11g R2 application renders custom ADF screens:

When Human Task is deployed on ADF 11g R2 domain, from the log we can see successful Human Task initialization and registration:

BPM process running on SOA/BPM 11g R1 domain points Human Task URL's to ADF 11g R2 domain:

BPM Worklist task flow is added into ADF 11g R2 custom application and is configured to run in worklist mode. At the end of the day BPM Worklist is ADF 11g R1 application with usage of some additional SOA/BPM libraries - it runs well in ADF 11g R2 context:

Make sure you don't forget to add ADF security permissions for BPM ADF task flows:

Worklist Components tag must be registered - pay attention, it points to the library from SOA/BPM 11g R1 domain.:

There are worklist and task list libraries added into ADF 11g R2 application from SOA/BPM 11g R1 domain:

Shared library - oracle.soa.workflow.wc is installed on ADF 11g R2 domain and must be referenced by custom ADF application with integrated BPM worklist:

You should install on ADF 11g R2 domain 2 worklist related libraries and make sure that WebService Policy Manager library is installed (is needed to communicated to BPM domain securely):

Add Foreign JNDI Provider pointing to the SOA/BPM 11g R1 domain (read more about this from my previous post):

Both applications - custom ADF 11g R2 with BPM Worklist and Human Task are deployed on the same ADF 11g R2 domain:

Ok, we are done with BPM Worklist part.
Let's take a look now into Human Task ADF implementation part ready to run on ADF 11g R2 domain. I simply migrated Human Task application to ADF 11g R2 by opening it in JDeveloper 11g R2:

JSF library is not migrated automatically. You need to remove JSF 1.2 and add JSF 2.0 library manually:

BPM Worklist libraries are added only for compilation, these two libraries are not not deployed:

Configuring ADF 11g R2 environment to run BPM Worklist from 11g R1 is not an easy task, but is doable based on my hacking experiment.
Multiple Files Upload - Unlimited Files Upload in ADF 11g PS6
Among other new components and features available in ADF 11g PS6 - there is one very important. File Upload ADF Faces component was upgraded to support multiple or basically infinite file upload. This is good to see how ADF framework is progressing with each new release, this is another argument why you should use ADF.
I was using sample application - MultipleFileUpload.zip, to test how multiple file upload works. You drag and drop regular ADF Faces input file component:

There is option to set number of rows (number of files in other words) to be rendered by input file component (this number can be changed dynamically on runtime):

Another property that must be set - MaximumFiles. With this property you can specify maximum number of files to be uploaded at once (also can be changed dynamically on runtime):

This is about UI part. Now how to handle multiple files and how to get Input Stream. You can create Action Listener for Upload button and handle multiple files input from such listener:

Important part - if you plan to allow multiple files upload, you should bind ADF Faces input file component the List. In such way, we have access to collection of files user is uploading:

Lastly don't forget to set UsesUpload=true property as usual for the container JSF page on af:form tag:

Set UsesUpload=true property for af:form:

Here how it looks on ADF UI - multiple files are submitted to be uploaded (even file upload progress bar is rendered while file is being loaded):

Status on the server informs about successful multiple files upload:

I was using sample application - MultipleFileUpload.zip, to test how multiple file upload works. You drag and drop regular ADF Faces input file component:

There is option to set number of rows (number of files in other words) to be rendered by input file component (this number can be changed dynamically on runtime):

Another property that must be set - MaximumFiles. With this property you can specify maximum number of files to be uploaded at once (also can be changed dynamically on runtime):

This is about UI part. Now how to handle multiple files and how to get Input Stream. You can create Action Listener for Upload button and handle multiple files input from such listener:

Important part - if you plan to allow multiple files upload, you should bind ADF Faces input file component the List. In such way, we have access to collection of files user is uploading:

Lastly don't forget to set UsesUpload=true property as usual for the container JSF page on af:form tag:

Set UsesUpload=true property for af:form:

Here how it looks on ADF UI - multiple files are submitted to be uploaded (even file upload progress bar is rendered while file is being loaded):

Status on the server informs about successful multiple files upload:

How To Control ADF Table Pagination on Runtime and Do Case Insensitive Search
I decided to update my sample app from previous post - ADF 11g PS6 - ADF 10g Table Pagination Feature is Back Finally with option to change page size dynamically on runtime. Change between scroll and page mode is implemented, plus case insensitive table column filter option is enabled. Updated sample - TablePaginationApp_v3.zip comes with choice list to select page size:

There is button to force page size change, it calls af:setPropertyListener:

Listener is copying selected page size from choice list and sets Range Size in table iterator. Table Fetch Size by default is set to be equal iterator Range Size - this is how we can change dynamically table page size:

FetchSize is equal table iterator Range Size:

Switch between scroll and page modes is implemented in backing bean - changing scroll policy and doing surrounding panel collection PPR:

By default, when table is loaded - 10 rows are displayed:

You can change to 25 rows:

Switch between scroll and page modes from panel collection menu:

Rendering scroll mode now - no option to change page size, all rows are displayed:

This is how we can control table layout.
Let's see how column case insensitive search works - this is just one property change for the af:column tag. Try to search for First Name - "steven":

There will be no results - by default case sensitive search is executed in ADF table:

How to enable case insensitive search for af:column - easy. Select af:column you want to apply case insensitive search:

Set "caseInsensitive" for FilterFeatures property of af:column:

Search again for "steven" - this time result is available:


There is button to force page size change, it calls af:setPropertyListener:

Listener is copying selected page size from choice list and sets Range Size in table iterator. Table Fetch Size by default is set to be equal iterator Range Size - this is how we can change dynamically table page size:

FetchSize is equal table iterator Range Size:

Switch between scroll and page modes is implemented in backing bean - changing scroll policy and doing surrounding panel collection PPR:

By default, when table is loaded - 10 rows are displayed:

You can change to 25 rows:

Switch between scroll and page modes from panel collection menu:

Rendering scroll mode now - no option to change page size, all rows are displayed:

This is how we can control table layout.
Let's see how column case insensitive search works - this is just one property change for the af:column tag. Try to search for First Name - "steven":

There will be no results - by default case sensitive search is executed in ADF table:

How to enable case insensitive search for af:column - easy. Select af:column you want to apply case insensitive search:

Set "caseInsensitive" for FilterFeatures property of af:column:

Search again for "steven" - this time result is available:

List View - Cool Looking ADF PS6 Component for Collections
I'm very excited about ADF PS6 release, it brings new freshness and coolness feeling to ADF. ADF Faces runtime performance seems to be incomparable faster and much more responsive comparing to previous ADF 11g R1 and even ADF 11g R2 releases. This gives good hopes to expect the same improvements in ADF 12c. There is new ADF Faces component introduced - List View. You can think about it as about much more liberal ADF Faces table component. List View renders data collections but there is much more control and flexibility how data collection is presented visually. If you need to render strict tabular data - ADF Faces table is the most suitable, List View is for something less structured. We could achieve up till now similar layout as List View with custom implementation using ADF Faces iterators or for each tags. Of course it is much easier now to use out of the box List View tag - Displaying a Collection in a List.
Here you can see fragment structure for my sample application with List View usage - ListViewApp.zip:

There are two types of List View implemented here - simple and hierarchical one. Simple List View renders collection in a list, there is option to load more rows from the collection on demand. Hierarchical List View renders Department - Employees master detail data:

Simple list is configured with the same property values as regular ADF Faces table:

Collection row is rendered within List View using List Item tag - this is where actual output or input ADF Faces component is implemented:

List View with editable popup functionality - launched from Edit button. Edited data is synchronized with data rendered in List View immediately:

Hierarchical List View is configured with the same properties as regular ADF Faces tree would be configured - pointing to treeModel instead of collectionModel as for the ADF Faces table. There is groupHeaderStamp facet - it allows to render data grouping:

Second level data is rendered under List Item tag:

In the page definition, there is regular tree collection definition as usual:

Hierarchical List View provides really good view of hierarchical data and it renders fast. Here viewing employees by departments:

One more small thing: I noticed in PS6 after session timeout - screen becomes black, looks good:

Here you can see fragment structure for my sample application with List View usage - ListViewApp.zip:

There are two types of List View implemented here - simple and hierarchical one. Simple List View renders collection in a list, there is option to load more rows from the collection on demand. Hierarchical List View renders Department - Employees master detail data:

Simple list is configured with the same property values as regular ADF Faces table:

Collection row is rendered within List View using List Item tag - this is where actual output or input ADF Faces component is implemented:

List View with editable popup functionality - launched from Edit button. Edited data is synchronized with data rendered in List View immediately:

Hierarchical List View is configured with the same properties as regular ADF Faces tree would be configured - pointing to treeModel instead of collectionModel as for the ADF Faces table. There is groupHeaderStamp facet - it allows to render data grouping:

Second level data is rendered under List Item tag:

In the page definition, there is regular tree collection definition as usual:

Hierarchical List View provides really good view of hierarchical data and it renders fast. Here viewing employees by departments:

One more small thing: I noticed in PS6 after session timeout - screen becomes black, looks good:

ADF 11g PS6 - ADF 10g Table Pagination Feature is Back Finally
Do you remember good old feature from ADF 10g - table pagination? So many customer requests I have heard to have it back in 11g and finally in ADF PS6 we have it. Not all good features mean bad, table pagination is perfect example. Some two years back I blogged sample application for custom table pagination like behavior - Oracle ADF 11g Custom Table Pagination.
Table pagination is out of the box in ADF 11g PS6:

Implementation steps are pretty simple. Firstly you should set scrolling policy to Page:

AutoHeightRows must be set to 0 and make sure that FetchSize is equal Range Size. FetchSize property determines how many rows are shows in single table page:

In this example I have set RangeSize = 10, this is how many rows are shown in table page:

Download ADF 11g PS6 sample application - TablePaginationApp.zip.
Update April 3rd, 2013:
Blog reader was asking if table pagination works in plain page - yes it works. Here is updated sample application - TablePaginationApp_v2.zip. Table with pagination is implemented directly inside main page, without any layout wrapping components, just below af:form:

Table pagination is rendered operational and without warnings in Google Chrome:

Work the same in IE:
Table pagination is out of the box in ADF 11g PS6:

Implementation steps are pretty simple. Firstly you should set scrolling policy to Page:

AutoHeightRows must be set to 0 and make sure that FetchSize is equal Range Size. FetchSize property determines how many rows are shows in single table page:

In this example I have set RangeSize = 10, this is how many rows are shown in table page:

Download ADF 11g PS6 sample application - TablePaginationApp.zip.
Update April 3rd, 2013:
Blog reader was asking if table pagination works in plain page - yes it works. Here is updated sample application - TablePaginationApp_v2.zip. Table with pagination is implemented directly inside main page, without any layout wrapping components, just below af:form:

Table pagination is rendered operational and without warnings in Google Chrome:

Work the same in IE:
Red Samurai Performance Audit Tool - Up and Running
It's been some time since we created Red Samurai Performance Audit Tool in August, 2012. This tool was deployed and it was logging all performance related issues in one of the projects, already for 8 months. I thought to share with you how it goes, below you can see the results logged continuously from August, 2012 till now:

As project was growing and becoming more complex, performance was going down. But after complexity reached a peak and we were able to locate performance bottlenecks with audit tool for fixing - performance started to improve in the recent months.

As project was growing and becoming more complex, performance was going down. But after complexity reached a peak and we were able to locate performance bottlenecks with audit tool for fixing - performance started to improve in the recent months.
Oracle University Training - ADF/WebCenter Spaces 11g & BPM Suite 11g Integration
I will teach one more Oracle University training course, this time in Slovakia, Bratislava. Training will be about ADF/BPM/WebCenter integration and is scheduled for November 7th - 8th. You can get more details and registration on Oracle University site.
If you are interested in ADF/BPM integration topic - read my previous blog posts on this topic.
If you are interested in ADF/BPM integration topic - read my previous blog posts on this topic.
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:
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:
Workaround - BPM 11g JDeveloper IDE PS5 Bug for Process ExecData
BPM 11g JDeveloper IDE PS5 bug described in my previous blog - BPM 11g JDeveloper IDE PS5 Bug for Process ExecData can be handled with workaround. Thanks to colleague Danilo Schmiedel who provided workaround. Workaround is pretty simple but effective - refresh BPM project from BPM Project Navigator window. Important here - refresh not from Application Navigator, but from Project Navigator, exactly as you can see on this screenshot:

ExecData object will be accessible again, even after JDeveloper restart:

ExecData object will be accessible again, even after JDeveloper restart:
BPM 11g JDeveloper IDE PS5 Bug for Process ExecData
I was hitting ugly BPM 11g JDeveloper IDE PS5 bug recently. This bug is strange, because is reproduced just after JDeveloper restart for the working process. Imagine you have valid BPM process, everything works well - restart JDeveloper and suddenly BPM process is corrupted. In my specific scenario I was referencing system attribute from BPM execData - execData object is suddenly lost after JDeveloper restart. I don't have solution for this yet, just want to share with you the use case for this BPM 11g JDeveloper IDE PS5 bug.
Sample application (SimpleProcess.zip) contains BPM process with one basic Human Task activity:

When you create Human Task activity - execData object is available in Data Associations:

We can use various system variables from execData, for example taskId. We could assign it to the local process variable:

It works well, until you restart JDeveloper 11g PS5. After the restart - there is an error in Human Task:

As you can see - execData object is not found anymore in BPM process - too strange:

Sample application (SimpleProcess.zip) contains BPM process with one basic Human Task activity:

When you create Human Task activity - execData object is available in Data Associations:

We can use various system variables from execData, for example taskId. We could assign it to the local process variable:

It works well, until you restart JDeveloper 11g PS5. After the restart - there is an error in Human Task:

As you can see - execData object is not found anymore in BPM process - too strange:



