Thursday, October 27, 2016

ADF Regions and Shared Data Control Bindings Use Case

While teaching ADF trainings and talking to ADF developers, often I can see people think about ADF bindings as about some mistery and try to avoid using full potential of ADF Data Control. I would like to give simple, but practical example in this post, which describes how to use ADF bindings and access these bindings across different ADF regions.

This diagram shows how sample application ( is implemented:

There are two regions (task flows), both are configured with Shared Data Control (means they will share same AM instance). Employees region could change current row. From Jobs region we can access bindings updated in Employees (Email attribute in this case).

Two regions are rendered side by side. I can move to different row in Employees and press button Set Current. This will set displayed row as current:

Current row in Employees region is set through custom method:

Button in Jobs region - Show Employee displays Email value from Employees region. Such functionality can be important, when you need to implement data exchange functionality between regions. Simply rely on ADF bindings in Shared Data Control - this would work:

Main page contains both regions:

Email field value is set in Employees region, through ADF bindings:

Binding attribute for Email is defined in Page Definition and attached to Data Control:

Make sure TF is set to default Shared transaction, otherwise changes in the ADF bindings values will not be visible outside of current task flow/region:

Email attribute is referenced through the binding in Jobs region:

You must include Email attribute binding into Jobs region page definition. Its value will be automatically set to the one from Employees region:

Hopefully this will explain how powerful ADF bindings are.

Tuesday, October 18, 2016

Oracle JET Example - Implementing Editable Collection Table

Oracle JET allows to implement inline editable tables. User can double click row or press Enter to switch to edit mode. Use Esc to switch back to readonly mode. With F2 can toggle between editable and readonly. Check it yourself in JET cookbook Editable Collection Table to see how it works.

I have followed instructions from the cookbook and implemented editable JET table on top of ADF BC REST service. Row with key 201 is switched to edit mode:

When we exit edit mode, event is handled in JavaScript and changed row is printed to the log. Here we can collect all changed rows into array and submit to the server all at once or we can fire individual REST calls per each changed row - depends on implementation:

To handle row edit, table must be set with editMode: 'rowEdit' property:

Row template property must be defined to render different HTML elements in readonly and editable modes. This property can be initialized dinamically with different template name retrieved from function:

Based on row edit mode, function returns template name:

Readonly template renders output texts, editable template renders input texts:

Changed row data is logged by ojbeforeroweditend listener function:

Download sample application -

Saturday, October 15, 2016

JDeveloper Bug and Workaround - Wrong Instance Name for Method Action Binding

After upgrade to JDeveloper I have noticed issue related to Method Action binding instance name. This is not ADF bug, but JDeveloper bug. JDeveloper sets incorrect name for Method Action binding instance name.

If you are going to create custom method in VO/AM and expose it through interface to be called in bindings layer - there will be similar error as below on runtime:

Source of this error is in the method binding definition:

Go to page definition source view and you will find instance name highlighted with warning. JDeveloper is able to recognize invalid expression, but still it generates it. ADF runtime quality is improved, but can't say the same about JDeveloper IDE. Oracle focus is on Cloud, but still there is a lot to do to improve development tools quality:

Expression must be replaced manually to correct one (the one previous JDeveloper version used to generate) - data.DataControlName.VOInstanceName:

With correct expression for instance name, custom method is invoked correctly without error:

Download sample application -

Thursday, October 6, 2016

Oracle JET and ADF BC REST Security Integration Approach

I have promised to atendee of my OOW'16 session (Building Enterprise-Grade Mobile Apps with Oracle JET and Cordova [CON5731]) to post a blog about ADF BC REST security and integration with Oracle JET. This post is to demonstrate how we could reuse cookie ID generated by ADF BC REST Web session for REST requests from JET.

First thing first, here you can download source code - This archive contains ADF BC REST application and JET source code (you need to copy it into your local JET application).

Take a look first into JET login form. This is where we collect username/password and call login function. One important detail - invalidComponentTracker, this allows to report required validation error, when user hits login button with empty username or password:

Here is the login function in JET. If there are no validation errors, it executes POST against ADF BC REST service custom method. In response we could return user info, preferences, etc. This is the only one request where we are using username/password. Key point of this request is to get JSESSIONID from ADF BC REST server, so we could use it for subsequent requests, without sending username/password again. This is similar concept to ADF Faces, it is also using JSESSIONID to track web user and HTTP session on the server. If login is successful, we are reading custom parameter from response with JSESSIONID value. JET router is updated to render different menu structure after login:

Custom response parameter is populated on the server in Filter class. On authentication request this parameter is set once:

ADF BC REST application is enabled with standard ADF Security:

This is how it works. Login form in JET:

Login is successful with redsam/welcome1 user. Two tabs are rendered - Home and People. Home tab displays chart with employees:

We should dive deeper and check what happens with REST communication. POST method in response gets custom parameter with JSESSIONID value, if authentication is successful based on Authorization header parameter:

Chart data in Home tab is retrieved through GET method and this method is not using Authorization header anymore. It calls REST method using JSESSIONID in URL. JESSIONID must be before URL parameters:

Home tab is implemented with JET chart component:

JSESSIONID is included into REST call URL through getURL method, which is referenced by JET collection:

People tab implements table with pagination support:

Same approach is applied in People tab. JSESSIONID is appended into URL through getURL method, before URL parameters:

People UI with paginated table in JET:

REST request URL contains JSESSIONID:

Tuesday, September 27, 2016

BPM Worklist API and Custom ADF Application

I have updated my sample app with BPM API usage in ADF application to Originally this was developed with ADF/BPM - Dynamic ADF Buttons Solution for Oracle BPM Outcomes. There are several changes in BPM libraries usage. I will describe it all step by step.

Download sample application - This archive contains both BPM and ADF app. BPM process implements two roles - request holiday and approve holiday:

Main goal of such use case - we don't want to use out of the box Oracle Worklist app, but prefer to develop our own business logic and manage BPM process from custom ADF app through BPM API. It is important to initialize Workflow context one time during login, this can be heavy operation and we should not call it each time when BPM API is invoked:

I'm using authenticateOnBehalfOf method. This allows to use admin user as a proxy for business user connection. Once Workflow context is established, we can get BPM context to use it for BPM API calls, all this is done during login into ADF app:

Assigned tasks are fetched through Workflow context:

We can initiate new task through BPM API in our custom ADF app:

There is a way to generate buttons to control task actions dynamically. Buttons can be generated on top of task outcomes list obtained from BPM API:

Task action can be executed with payload info, this allows to pass correct info to the next step in the process:

Let's see how it works. User can start new BPM task from ADF:

When task is submitted to approval, manager is assigned task to approve or reject holiday request. Buttons are generated dynamically based on task outcomes:

To double check executed flow from BPM API in ADF we can review it in EM control:

ADF application must import BPM API JARs to be able to compile Java code. In ADF it is enough to import BPM Services JARs:

There is no need to package these JARs into application archive, these should be referenced for compile time only:

Tuesday, September 20, 2016

Slides Available - End-to-End Cloud: Oracle Java Cloud, Oracle Mobile Cloud Service, Oracle MAF, and Oracle JET [CON2388]

I have completed my OOW'16 session [CON2388] today. For those of you who could not attend it, check slides online (I will post sample code later, read more about the session here):

Saturday, September 17, 2016

Dynamic Flying Dashboard UI in ADF

I took my old sample application implemented in 2010 - Dynamic Flying Dashboard UI Shell and upgraded it to recent ADF It runs pretty well, without major changes - this proves ADF migration between releases can be smooth (well, not always in practice - but let's be positive).

I have recorded gif to give you an impression how it runs and how UI switch works in ADF UI panel dashboard component:

There are four blocks in the dashboard, user can remove each of the blocks or select predefined group of blocks:

It is possible to maximize selected block to occupy more space:

Some of the blocks can be minimized and only a subset of blocks will be displayed:

Such functionality is implemented with out of the box ADF UI components - af:panelStretchLayout, af:panelSplitter and af:panelDashboard. Depending on selection, block is minimized, displayed or maximized:

Toolbar items (minimize, maximize and restore) are implemented in the separate JSF container and reused in the main page:

Hopefully you will find such use case interesting and will have a chance to apply in the project. Download sample application -