Friday, May 29, 2015

Load More Scroll Policy for ADF 12c Table and Range Paging

There is a new scroll policy for the table component in ADF 12c. This new policy is called - load more. I think it gives good potential, it allows to reduce access load on heavy tables. In ADF 11g we are implementing similar approach with RowCountThreshold = -1 setting, this is preventing full scroll at once (How To Disable SELECT COUNT Execution for ADF Table Rendering). Load more is better, it integrates with VO Range Paging and allows to configure maximum number of rows present on the client.

New scroll policy is configurable directly on the ADF UI table component, as a property:


Load more works based on configured Range Size for the iterator in the bindings. In my example, I have set it to be 15, this means there will batches of new rows added in the groups of 15 elements:


One of the key things - new scroll policy works with VO Range Paging, this allows to fetch less rows from DB and improve ADF BC runtime performance:


There is no need to set Range Size, it will be calculated automatically, based on the current set of rows rendered in the table on runtime.

This is how it looks like on UI. User scrolls in the range and is given option to Show More rows. Total number of rows is also visible:


What is good about Load more scroll policy, it doesn't keep all fetched rows. If user want to come back to the first set of rows, he will be given Show More rows option in the top of range - to display previous set of rows:


Below you can see SQL query executed to fetch rows in the current range. This query is based on Range Paging feature and contains range variables:


If I would navigate back in the range and display previous 15 rows:


New SQL query is executed with Range Paging, with different range variables:


What is good about it - SQL query range paging variables are calculated automatically, there is no need to implement any custom logic to keep them in synch.

One extra feature to be described - blockNavigationOnError (also available in ADF 11g). This could be useful feature, if you want to prevent selecting rows in the table, when there is validation error in the current row:


Row selection is blocked, until validation error will be fixed:


Download sample application - ADFTableLoadApp.zip.

Thursday, May 28, 2015

Responsive UI Support in ADF 12.1.3

Responsive UI is a big deal nowadays, when enterprise applications should run on different platforms and devices. Often customers prefer to render simpler functionality screens for mobile devices and give full data entry access only when accessing through regular Web browser on the computer. ADF provides support for this, you can implement responsive UI designs relatively easy, check informative blog post from Shay Shmeltzer - ADF Faces Responsive Design - 12.1.3 Update.

I would suggest to think about responsive UI design from the start, it very much depends on functionality your application offers. It is good idea to start from the template and define facets for various layouts. But this is not only about layouts, you may prefer to render editable forms on large screens and on mobile devices to show only charts for quick overview. I'm going to demonstrate, how you could switch between different regions in ADF UI, depending on current resolution. Download sample application here - ADFResponsiveUIApp.zip.

This is how it works, I'm using iPad simulator, but same would be true for the regular browser display on smaller screen resolutions. Web page displays region with editable columns in horizontal view and same page displays different region with read-only list in vertical view:


Similar to Shay's sample, there is a template implemented with two facets (each for different layout):


Facet visibility is managed through assigned style class, controlled by CSS media query. It checks if screen width is less than 950px and sets narrow layout to be displayed:


Main page is created based on the template. Here I'm inserting both regions into corresponding facets - wide and narrow:


This is editable table in wide view:


This is read-only list in narrow view:

Saturday, May 23, 2015

ADF 11.1.1.9 Goodies - Conveyor Belt Component and Alta UI

It doesn't seem to be announced, but newly released ADF 11.1.1.9 is shipped with Alta UI support. All you need to do, is to set alta skin name in trinidad config file. This enables applications running on ADF 11g platform to leverage new Oracle UI layout and to be prepared for ADF 12c upgrade. Besides Alta UI, there are several new UI components, one of them is Scrollable Bar (ConveyorBelt) - Displaying Components in a Scrollable Bar. This is simple, but quite useful component - I'm going to demonstrate how it works.

Conveyor Belt is able to render elements horizontally or vertically. This is perfect component to render key information, user could select one of the items available on the belt and get more info fetched. This is how it looks like - conveyor of employee pictures with first/last names, rendered in the vertical belt on the left:


If there are more items in the conveyor belt, than could fit into visible UI part - user could scroll (right/left and down/up). Here I scroll down and select another employee, his detail data is displayed in the main section:


As you could notice, UI is displayed using Alta skin. This is configured in trinidad file:


Here is the structure for implemented conveyor belt, items in the conveyor are stamped dynamically through ADF UI iterator component. Java Script client/server listeners are responsible to process item selection and keep detail info in synch for the selected employee:


This is the source code structure for conveyor belt UI implementation, based on the structure from above:


Conveyor item selection is processed in the server listener method, VO current row is set based on the selected key:


If you want to try it yourself, download sample application - ConveyorBeltApp.zip.

Saturday, May 16, 2015

ADF and Two-Way WebSocket Communication Architecture

This post is based on WebSockets and ADF, topic described in the previous post - WebSocket Integration with ADF for PPR Request Monitoring. I would like to look into it from technical architecture perspective and split WebSockets server logic into separate application deployed on WebLogic. WebSocket is two-way (bidirectional) communication channel, this allows to send and received data at the same time. I'm going to demonstrate how it works with my sample application.

It is best to explain how WebSocket works, with a live demo - you can watch recorded screencast. I'm using Twitter stream, you should see how many tweets are coming in for music category. Each tweet location is sent through WebSocket channel to ADF page, where it is rendered on the UI, through Java Script. ADF UI performance is measured in Java Script and logged back to the server through the same WebSocket channel. Tweet locations are coming from the server to ADF UI and ADF UI performance statistics traveling back to the server, at the same time:


I'm pretty amazed, how WebSocket transfers data - you should see how quick output text value is changing in ADF UI.

Download sample application - ADFAltaApp_v5.zip. Below diagram describes the main idea of this example:


There are two applications deployed on WebLogic 12c server. WebSocket server side application is listening for Twitter stream and sends data to the WebSocket client running in ADF UI. Logged performance data in ADF UI is sent back to WebSocket server side application.

Twitter stream handler is implemented as a servlet. It listens for every tweet received for the given topic and invokes WebSocket method to send data to the client:


Data is sent to the client using WebSocket API (library is available out of the box in WebLogic 12c and JDeveloper 12c). Incoming message is handled by another method - processMessage. This method accepts complex type, sent from ADF UI in JSON format:


Make sure to define WAR deployment profile for WebSocket project, this must be deployed as part of EAR. There should be deployment profile set, later referenced from WebSocket client:


WebSocket client runs in Java Script, there is onMessage function to handle incoming data. Here I'm simply setting newly received text as value for the ADF output text component:


ADF output text is empty initially, value is populated on runtime through WebSocket:


WebSocket communication from ADF UI to WebSocket server side is initiated in Java Script. PPR request timing data is written to JSON format and sent over WebSocket channel:

Monday, May 11, 2015

WebSocket Accelerated Live Data Synchronization for MAF

New generation Mobile and Web applications are going to use WebSockets. This is one of the fastest and convenient ways to transfer JSON formatted data from the server to the client and back. Huge advantage - server could initiate data synchronisation request and deliver JSON messages directly to the client. You should read my previous post about detail information how to configure MAF with WebSocket - Oracle MAF and WebSockets Integration - Live Twitter Stream.

In this post I would like to describe, how to integrate further information received through WebSocket with MAF components. I will use MAF Tree Map UI component to display live data for Tweets locations.

Below you could see screen recording - MAF Tree Map is getting refreshed automatically, each time when update through WebSocket channel is being received. This is amazing, how fast data through WebSocket channel is coming. In this test, MAF is handling around 1 update per second, received from WebSocket:


Let's look how it is implement behind the scenes. There is MAF Tree Map UI component, this is regular MAF component to render graph visualisation:


UI component is based on Data Bindings, collection is initialized from Data Control method:


Method handling data update from WebSocket is responsible to update data collection - it invokes helper method, where data collection is re-constructed. Standard Refresh Provider is helping to repaint data displayed on the UI:


Simple and effective. Download sample application - AltaMobileApp_v2.zip.

Thursday, May 7, 2015

Oracle MAF and WebSockets Integration - Live Twitter Stream

Oracle MAF and WebSockets - I will describe how it works together. WebSockets is a protocol providing full-duplex communication channel over a TCP connection. This channel is interactive (communication is both ways) and we can send messages from the server to the client (MAF application running on the device). There is no need to use push notifications, WebSockets provide JSON support and allow to send complex payload data. In a way it competes with REST, however REST is different with request is being initiated by the client. WebSockets data is received automatically - there is no need to trigger any event by the client.

I have implemented sample MAF application with WebSockets integration, you can download it here - AltaMobileApp_v1.zip. Finance screen in the application contains MAF output text component. This component displays latest data received through WebSockets channel. Server side is listening for live Twitter Stream updates and sends each tweet location over WebSockets to the MAF application. See how it works in this screen recording:


WebSockets communication is not blocking MAF application functionality, it runs in the separate thread. User can navigating between MAF screens, run different actions and WebSockets delivers data in parallel.

Sample applications is based on two parts - server side WebSockets implementation with Twitter Stream listener and client side MAF application with WebSockets client.

Twitter Stream is handled with Twitter4J API, JAR's are included with the sample. You would need to provide your own Twitter account details, access keys could be retrieved for your account from Twitter developer portal. Make sure to obtain these keys, before running sample application:


New message from Twitter Stream is received by listener method - onStatus. I'm listening for all the tweets around the world, related to corporate keyword. Once there will be new tweet related to this topic, onStatus listener will be notified. In the listener method, I'm retrieving tweet location and and initiating WebSockets communication:


Method in WebSockets implementation - notifyClient, sends text message to the client (JSON message is supported as well):


Listener for Twitter Stream is started automatically, when application is deployed. This is done through servlet initialisation:


On the client side - MAF application is configured to receive automatic notifications through WebSockets channel. Implementation for WebSockets listener is very similar with the regular ADF Faces - it is done through JavaScript. MAF feature is registered with JavaScript file:


JavaScript contains all required methods for WebSockets communication. Here we open WebSockets channel with connectSocket function and further listen for the new messages/notifications with onMessage method. My goal is to update MAF components with the new data received through WebSockets. For this reason, I'm invoking Java method from onMessage JavaScript function and passing payload data (recently received tweet location):


Invoked Java method - processWebSocketMessage is responsible to update MAF bindings with the new data. Data Bindings class contains standard MAF propertyListener implementation, which ensures data refresh on MAF UI:


MAF output text on the UI displays recent data received through WebSockets channel:

Wednesday, April 29, 2015

SOA & BPM Partner Community Webcast May 8th 16:00 CET

Save the date for the Webcast below - make sure to attend, if you don't want to miss SOA & BPM news.

SOA & BPM Partner Community Webcast May 8th 16:00 CET

Join us for our monthly SOA & BPM Partner Community Webcast. We will give you an update on our SOA Suite 12c, Integration Cloud Service offerings and our community activities.



Speakers:
Vikas Anand
J├╝rgen Kress

Schedule: May 8th 2014 16:00-16:45 CET (Berlin time)

Attendance Information:
Join Webcast or dial in Call ID: 4070776 and Call Passcode: 333111

Austria: +43 (0) 192 865 12
Belgium: +32 (0) 240 105 28
Denmark: +45 327 292 22
Finland: +358 (0) 923 193 923
France: +33 (0) 15760 2222
Germany: +49 (0) 692 222 161 06
Ireland: +353 (0) 124 756 50

Italy: +39 (0) 236 008 198
Netherlands: +31 (0) 207 143 543
Spain: +34 914 143 755
Sweden: +46 (0) 856 619 465
Switzerland: +41 (0) 445 804 003
UK: +44 (0) 208 118 1001
United States: 140 877 440 73
More Local Numbers 
Watch and listen
You can join the Conference by clicking on the link: Join Webcast  (audio will play over your computer speakers or headset). Visit our SOA Partner Community Technology Webcast series here.