Tuesday, August 26, 2014

Session Schedule Information OpenWorld 2014 San Francisco

I have received my session schedule information for OpenWorld 2014. This year event is going to be quite busy with three sessions. Below you can check session titles along with times, looking forward to meet you in San Francisco !


Session ID: CON2623
Session Title: Oracle ADF Development and Deployment to Oracle Cloud
Venue / Room: Moscone South - 270
Date and Time: 10/1/14, 15:30 - 16:15

Session ID: CON3745 (together with Danilo Schmiedel)
Session Title: Oracle Mobile Suite and Oracle Adaptive Case Management: A Strong Combination to Empower People
Venue / Room: Moscone West - 3018
Date and Time: 10/1/14, 16:45 - 17:30

Session ID: CON2495
Session Title: Data Caching Strategies for Oracle Mobile Application Framework
Venue / Room: Marriott Marquis - Nob Hill C/D
Date and Time: 10/2/14, 12:00 - 12:45

Sunday, August 24, 2014

Transactional Data Caching for ADF Mobile MAF Application

I have described basic idea for data caching in ADF Mobile MAF application in my previous post - Data Caching Implementation for ADF Mobile MAF Application. Today I would like to extend similar solution to handle transactional data caching. Sample application displays list of tasks, user can update task status and description. These updates will be saved locally, until the next synchronisation time with the server.

Updated sample application with MAF mobile and server side implementations can be downloaded from here - MAFMobileLocalApp_v4.zip. User could select a task on his mobile device:


Update task status and description, these changes are stored locally in SQLite DB, no extra call is done to the Web Service at this time:


Changes for multiple tasks can be synchronised in batch. User could go and change different task without submitting previous changes to the Web Service, update task status:


Finally when user decided to synchronise his changes with the Web Service, he could use refresh option:


When synchronisation happens, we can see activity in the server side log. ADF BC executes update operation for submitted task, update for the first task:


Next is called update for the second task:


MAF task flow is updated for this use case, and is based on the task flow from application described in the previous post. We are not calling Web Service from the task flow method call anymore, this call is done programmatically, during refresh:


Web Service method in ADF BC is updated to check if row exists - if yes, data is updated. If row doesn't exist - no error is thrown, task list will be refreshed and latest changes will be displayed to the user on the mobile device. In the real application, you may inform user about the missing task:


Custom method is exposed as ADF BC Web Service method:


To understand how sample application works on MAF mobile side, we should refer to the task flow diagram. Edited changes are submitted to the local SQLite DB through updateTaskLocal method call. This call invokes Java method, where changes are stored locally in the list of tasks. In addition, record about latest task changes is stored in special table with change history:


We are checking in the change history, if the same task was already updated - if no, we are simply storing task ID. This would allow later during synchronisation to retrieve changed task details and update task first through Web Service, before fetching data. If task was already updated, there is no need to insert task ID again:


During data synchronisation, we are checking if there are any rows changed and stored locally. Only after this check is completed, task list data is refreshed and loaded from Web Service:


Changes for each updated task are synchronized through Web Service. Firstly, task ID is retrieved from changes history table. Using this ID, actual changed are fetched from SQLite DB and sent over Web Service to the server side ADF BC for update. Once all the changes are synchronised, local changes history is cleared:


Web Service call to update data through ADF BC is done programmatically, using MAF mobile helper class AdfmfJavaUtilities. We are constructing list of parameters with names, values and types - invoked method even doesn't need to be defined in the Page Definition, it will be referenced directly from the bindings:

Tuesday, August 19, 2014

Accessing ADF Iterator Binding from Value Change Listener

This is a quick hint about how to access ADF iterator binding from value change listener method. Let's say you have generic value change listener, reusable with any kind of input components and you want to get information about underlying ADF BC View Object structure in that listener. Value Change Listener provides access to UI Component, we should evaluate component expression and look up in the bindings for component binding name.

Here is the sample application - ADFIteratorAccessApp.zip. This applications comes with generic value change listener method implemented in the bean. I'm getting value property expression of input component and translating it into attribute name. With the attribute name, I can search in the binding container for attribute binding. From the attribute binding, is possible to retrieve mapped iterator object, iterator could provide information about ADF BC View Object structure:


It works pretty smooth, when generic value change listener is attached to the input component and user is changing value:


Iterator name is printed from generic value change listener, iterator object is retrieved dynamically through attribute definition mapping to iterator:

Tuesday, August 12, 2014

Data Caching Implementation for ADF Mobile MAF Application

If you are building mobile application with web service call integration, you must take into account data caching strategy. Without data caching, mobile application will try to establish too many connections with the server - this will use a lot of bandwidth and slow down mobile application performance. This post will be focused around the scenario of implementing simple data caching strategy. In my next post, I'm planning to review MAF persistence framework from Steven Davelaar - this framework is powerful and flexible. Simple data caching strategy makes sense for smaller use cases, when we don't need to use additional framework for persistence.

Data caching implementation in the sample application - MAFMobileLocalApp_v3.zip, is based on SQLite database local to the mobile application. The whole idea is pretty straightforward, there is a database and Web Service publishing data. Mobile application is reading and synchronising data through Web Service. Once data is fetched from the Web Service, it is stored in local cache, implemented by SQLite DB. For the subsequent requests, mobile application is going to use a cache, until user will decide when he wants to synchronise data from Web Service:


Sample application implements a Web Service, based on ADF BC module. This Web Service returns Tasks data (SQL script is included with the sample application):


Besides fetching the data, Web Service implements Task update method:


On the mobile application side, use case is implemented with a single Task Flow. Task list displays a list of tasks, user can edit a task and submit changes through Web Service. This change is immediately synchronised with local cache storage. User is able to refresh a list of tasks and synchronise it with a Web Service. During synchronisation it will clear local cache and populate again with the data returned from Web Service:


Data caching logic is handle in TaskDC class, Data Control is generated on top of this class, this makes it available through the bindings layer. Initially we check if cache is empty and load data from the Web Service, for the subsequent requests data is loaded from cache. Unless user wants to synchronise with Web Service and invokes refresh:


There is a method responsible for fetching data from Web Service and translating it to the Task list structure:


Data from cache retrieval is implemented in the separate method, we are querying data from local SQLite database:


When request hits TaskDC Data Control, we are checking if there are any rows in cache. If there are rows, call to Web Service is not made and rows are fetched from cache:


When user is synchronising with the Web Service, cache is cleared up and re-populated with the rows fetched from Web Service:


Update is synchronised with local cache, so there is no need to re-fetch entire data collection from Web Service:


If the local cache is empty and Web Service is invoked to fetch data, we can see this is Web Service log - it executes SQL. Later call to Web Service is not made, data loaded locally from SQLite database:


We can track update operation on the server side as well, Task details are updated using Task Id:


Initial load for the task list, this is what you should see if Web Service and MAF mobile applications runs correctly:


User could open specific task and edit task properties - changing status:


Task description could be modified:


All changes are saved through Web Service call and immediately synchronised with local SQLite database:


Selected task is updated, user is returned back to the list of tasks:


We could simulate data update on the server, lets change status for one of the tasks:


With refresh option invoked, data is synchronised on the mobile application side and local cache gets refreshed:

Thursday, August 7, 2014

ADF Thematic Map in ADF 12c (12.1.3)

ADF Thematic Map component from DVT library was updated in ADF 12c with marker zoom option and area layer styling (ADF 12c (12.1.3) new features). I have decided to check how it works and implemented quick sample application - ThematicMapApp.zip.

I was using world GDP data (SQL script is available together with sample application) and displayed it using ADF Thematic Map. World country borders are hidden on purpose, borders are visible by default:


While zooming, marker points are growing - very useful feature:


Data for thematic map is fetched using SQL based VO. I'm calculating total GDP and taking percentage from total for the country, this allows to scale marker points better:


ADF Thematic Map is configured to support zooming for markers:


Countries area layer is set to be hidden, although data is still gets attached to the countries:


Marker is configured with dynamic scaling, this is how each country gets appropriate marker size, based on its GDP value:


Marker colour property is set to be dynamically calculated in marker Attribute Groups section:

Tuesday, August 5, 2014

Standard ADF BC Passivation/Activation for Transient View Object

If you want to implement transient View Object in ADF BC, you must make sure it will be passivation/activation ready, otherwise you may loose data. There are several ways how to achieve passivation/activation for such View Objects - override passivation/activation lifecycle and handle transient View Object rows programmatically or reinitialise transient View Object rows from Application Module prepareSession method. There is one more solution, I'm going to describe it in this post. It is based on dummy SQL based View Object, designed to to store transient attribute values.

Sample application - ADFTransientVOPassivationApp.zip, implements SQL based View Object with transient attributes. Instead of creating completely programmatic View Object, I have created SQL based with single Id attribute based on SQL expression and added transient attributes. This Id attribute is actually never used, it is there just for only reason - to simulate SQL based View Object. As a key attribute is selected one of the transient attributes:


SQL query doesn't fetch any rows, I'm using it only for a single reason - to simulate SQL based View Object. ADF BC knows how to passivate/activate SQL based View Objects automatically, so I'm going to use this feature and force passivation/activation for all transient attributes created for the same View Object:


Just make sure to select Passivate Including All Transient Values option, this will ensure all transient attributes will be passivates/activated automatically, without any coding intervention:


I'm going to test sample application with AM pooling off, this would simulate passivation/activation behaviour for each request:


On ADF UI side, I'm going to implement a table. To be able to enter rows successfully, for such SQL based View Object with transient attributes, I must enable ChangeEventPolicy = ppr option in Page Definition for the iterator:


Input components must be set with AutoSubmit = true option:


On runtime, when I enter rows, all data gets passivated - you can see this from the log. Three rows are entered, data for all attributes gets passivated/activated automatically: