Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 13 hours 47 min ago

ADF 12c Dynamic Forms with ADF BC UI Categories

Tue, 2015-09-01 04:54
ADF 12c offers completely new way to implement UI forms. We can implement dynamic forms, based on static ADF BC components. Such approach could simplify form maintenance - when there will be changes in DB, developer would need to adjust only ADF BC EO/VO structure, without changing anything on UI. Bindings layers could determine data structure dynamically and dictate how to render UI blocks. ADF BC VO provides special metadata option to define how form UI should be rendered - UI Categories. Through categories we could group attributes and this would help to render dynamic UI with separate blocks and proper order.

Using UI Categories is straightforward, add category group and move attributes under the category. Label and tooltip can be defined, this will be a title for UI block:


ADF 12c is using general collection binding for dynamic UI, it doesn't depend on specific attribute binding:


Collection binding is generic, without a list of accessible attributes, it just points to the VO. This means we can change list of attributes registered in the VO at any time:


This is how looks dynamic form generated in ADF 12c. I have customised it a bit, but major part is generated automatically by JDeveloper 12c. There is global iterator over UI Categories, rendered UI blocks. Inner iterator renders UI Category attributes. Each attribute is rendered through ADF 12c dynamic component, this means there is no dependency related to attribute UI implementation (input text, LOV, choice list, etc.) - UI implementation is controlled from attribute UI hints in ADF BC:


It is easier to understand how dynamic form is organised from UI structure view:


This is the result - dynamic form is rendered with two blocks, based on defined UI Categories:


I have customised dynamic form rendering with metadata usage. Buttons are rendered only in the first block, identified by PersonalData:


Block identified by JobData is rendered with maximum 4 rows:


I hope this post will give you some new ideas about robust ADF UI implementation. Download sample application - ADFAltaApp_v7.zip.

Red Samurai ADF Performance Audit Tool v 4.0 - Web Client Request Monitoring and Complete Query Analysis

Thu, 2015-08-27 03:12
I'm excited to announce, we have released a new version of our RSA audit tool. This is a major update after previous version released in February 2015 - Red Samurai ADF Performance Audit Tool v 3.4 - ADF Task Flow Statistics with Oracle DMS Servlet Integration.

It is already 3 years, since initial version - Red Samurai Performance Audit Tool - Runtime Diagnosis for ADF Applications. We are using it for many of our customers to monitor ADF performance in both test and production environments. Many new features were added during these years, more features to come.

RSA Audit v4.0 New Features

1. RSA Audit v4.0 dashboard is supporting ADF 12c and Alta UI look


2. Web Client Request Time monitoring. Supported with ADF 11g and 12c. Generic method tracks request time for all ADF UI components. Logged data can be analysed through ADF UI dashboard or directly in the DB. Request time represents complete time from user action in the browser, until request is completed. This includes real user experience - browser processing time, network time, server side time and ADF BC/DB processing times. Runs in VERBOSE logging mode


3. Detail information about ADF fragment, button or other ADF UI component involved into request is being logged together with request processing time and is accessible from audit dashboard. This helps to identify slow actions spanning from Web Client to DB


4. Information about each request is grouped, this allows to compare differences between multiple requests and identify bottlenecks in the application performance


5. Duplicate Queries. Allows to track all executed VO’s, very helpful to identify redundant VO’s executions. Groups VO executions per ECID, this helps to identify VO’s re-executed multiple times during the same request. Runs in MEDIUM logging mode


6. VO’s executed from the same ECID are automatically highlighted - this simplifies redundant queries analysis


7. Number of duplicate executions of VO’s per ECID is calculated and presented in the table and sunburst chart


8. We calculate top VO’s per AM. This helps to set priorities for SQL tuning and understand heavy used VO’s


9. Sunburst chart displays visual representation of duplicate and top VO’s per AM

Smart Combo Box LOV with Filter

Mon, 2015-08-17 17:47
Combo box LOV with filtering is simple, but effective feature not used often. You should rethink LOV design and apply combo box LOV with filtering where possible. Advantage of such LOV implementation is pretty clear - fast list items access, based on filter criteria. This will reduce number of times required to open LOV popup and improve performance of UI.

LOV VO should implement View Criteria, returning top items to be included into choice list. My example retrieves all jobs with minimum salary greater or equal than 10000. Users will see list items based on this criteria first:


I would recommend to use List UI Hints section of the LOV VO to define LOV UI definition. This will save time when assigning LOV for the attributes, do it once and reuse. I have specified Combo box LOV with filtering based on View Criteria - to include jobs with minimum salary greater than 10000 into initial choice list:


Time is saved when assigning LOV for the attribute - UI Hints are automatically set, based on LOV UI Hints definition:


This is how it looks on UI. Top records are displayed in the choice list, based on applied filter criteria.  All list items can be accessed through More... option:


This is how LOV popup looks by default in ADF 12c. Height is stretched automatically to occupy all possible display height, width is not stretched. Such layout is not good, users don't like it:


LOV popup can be made stretchable with little help of ADF UI CSS. We should use -tr-stretch-search-dialog CSS property to enable LOV popup stretching in ADF 12c (CSS sample is provided with example):


Another important thing to remember about LOV's in ADF 12c - List Range Size property. By default it is being set to -1. This is OK for simple choice lists, where you would like to show all data at once. But not suitable for LOV or combo with LOV, where we don't want to fetch all LOV items at first load:


I would set it to 10, this will populate only visible set of LOV records:


Take a look, how LOV popup window will look after improvements applied - it is stretchable by the user and only initial set of list item records is fetched:


Make sure to use combo LOV with initial filter criteria, to optimise LOV behaviour. Download sample application - SmartComboLOV.zip.

Tabs Layout Support in Alta UI Tablet First Template

Thu, 2015-08-06 07:02
Tablet First Template in ADF 12c is ideal for both tablet and desktop. Combined with Alta UI layout, it offers light and responsive UI experience to the end users. I'm going to describe in this post, how to use ADF Faces Tabs with Alta UI in Table First template. I will show ADF regions are friendly with Web like UI design, without internal scrollbars in the page.

Page can be created referencing Tablet First template with JDeveloper wizard, same as we would use it to create page based on UI Shell template:


Table First template provides multiple facets, Central facet is supposed to contain main content. I'm going to include two ADF Faces UI tab components into central facet. Both tabs will render ADF regions:


Unfortunately it doesn't work properly. Tabs are rendered in the centre of the page:


Luckily there is a fix. We should apply special CSS style class, provided with Oracle WorkBetter Alta UI application - ContentContainerWorkaround. This class must be set for ADF Faces UI panel tabbed component:


After CSS style class fix is applied, tabs are rendered correctly:


I have implemented second tab - Employees Table to test how large ADF UI table renders in Tablet First Template. Table is set with page scroll policy:


ADF region renders table without internal scrollbar, it looks Web style alike:


There are more rows, than can fit into screen. User can scroll down entire page to see the remaining rows. This is especially good for tablet screens, ADF provides really good UI experience:


Download sample application - ADFAltaApp_v2.zip.

Oracle Mobile Cloud Service First Hands-On Experience

Fri, 2015-07-31 12:50
Thanks to SOA Community and Jurgen Kress, I had a chance to play with Oracle MCS (Mobile Cloud Service). This new Oracle product is promoted with full force by Oracle PM team, there is dedicated Youtube channel with videos to watch and learn - Oracle Mobile Platform. Mobile Cloud Service offers mobile enterprise repository to organize and support your mobile development. Mobile backend services, security, connectors, storage and etc. can be defined and managed in MCS. Web Services published in MCS can be monitored to track performance and errors. All this should simplify mobile solutions implementation.

This was my first encounter with MCS and I would like to describe the test I did. MCS UI is implemented with Oracle internal JS framework following Alta UI standard. There are options to monitor and administer MCS instance. I'm more interested in development options:


I will not go through all available options, but only focus on Mobile Backend. Basically we can define a group, where we could include various reusable business logic artefacts (API's). Mainly this will be different Web Service calls. The same Web Service calls can be reused by mobile application developer.

In Mobile Backend section we can edit existing groups or create a new one:


You should think about Mobile Backend as about a group of reusable code artefacts (API's). There is an option to create new API or reuse existing one. I decided to reuse existing API for Incidents registration:


This API implements REST Web Service call to register new incident, also it allows to query information about previously reported incidents. This can be tested directly in MCS environment, we could define sample payload data and simulate Web Service call to register new incident:


Web Service call is successful, we can observe this from the log - new incident is registered and ID is assigned. Same Web Service will be reused from mobile application. With MCS we could monitor Web Service usage, number of invocations, errors, etc. - this makes it easier to manage entire infrastructure for mobile solutions:


To make sure new incident was successfully registered, I could run another REST call for the same Web Service - to get incident information about ID:


Result shows incident data, this means incident was located successfully:


Incidents registration service is registered in API's group, we could edit and test this Web Service online in MCS:


Red Samurai mobile backend service is live - invocation statistics and processing time metrics are aggregated by MCS:

Using Shared AM to Cache and Display Table Data

Wed, 2015-07-29 23:12
This post is based on Steve Muench sample Nr. 156. In my personal opinion, ADF samples implemented by Steve Muench still remain one of the best source of examples and solutions for various ADF use cases. Sample Nr. 156 describes how to use Shared AM to display cached data in UI table. Typically Shared AM's are used to implement cached LOV's (session or application scope). But it could go beyond LOV, based on the use case we could display cached data in the table or form. I have tested this approach with 12c and it works fine.

Download sample application - ADFBCSharedSessionLOVApp.zip. AM is defined with application scope cache level - this means cached data will be available for multiple users:


In order to display cached data on UI and pass it through ADF bindings layer, we need to use Shared AM configuration in bindings:


You should create new Data Control reference entry manually in DataBindings.cpx file. JDeveloper doesn't provide an option to select Shared AM configuration. Simply change configuration property to Shared (HrModuleShared as per my example):


Make sure to use correct Data Control entry for iterator in the Page Definition. Cached table iterator binding should point to shared Data Control configuration:


This is how it looks like on UI - readonly table data is fetched once and cached in application scope cache. Other users will be reusing cached data, without re-fetching it from DB:


Jobs VO is set with AutoRefresh = true property. This turns on DB change notification listener mechanism and keeps VO data in synch, when changes happen in DB. This helps to auto refresh cached VO (read more about it Auto Refresh for ADF BC Cached LOV):


Here is the test. Let's change Job Title attribute value in DB:


Click on any row from Jobs table, or use any buttons (make a new request). Cached VO will be re-executed and new data will be fetched from DB, including latest changes:


You should see in the log, DB change notification was received and VO was re-executed, VO data was re-fetched:

Oracle Process Cloud Application Player

Tue, 2015-07-21 10:12
With Oracle Process Cloud you can forget these days when you was waiting long to deploy BPM process and test Human Task UI. No need to wait anymore, in Oracle Process Cloud you could use Application Player feature, this allows to run the process and test Human Task UI almost instantly.

To demonstrate Application Player functionality, I have implemented basic process of Data Entry for the Claim Handling:


This process is using Web Form in the Start activity to capture data, human activity Claim Expense Review allows to review entered data, before submitting it:


This is how Web Form UI design looks like:


When you build Web Form and arrange UI components, business type is constructed automatically, no need to define anything separately. Business type can be used in the process, without changing it:


Data object variable is assigned to the process activity element through Association dialog in Process Cloud, this is where you can map input/output with business type:


Once process is ready to be tested, all you need to do is to invoke Application Player. Click on Test Application button in the top right corner:


In the Test Application window you should select Play option:


To show how it works, I have recorded a video - see yourself how helpful is Application Player:

Auto Refresh for ADF BC Cached LOV

Thu, 2015-07-16 08:19
You can configure auto refresh for ADF BC cached LOV and this works out of the box, no special coding is needed. My previous post describes how ADF BC session cached LOV behaves - ADF BC Session Cached LOV - Understanding Expire Time. Auto refresh can be configured for both application and session caching. One important thing - auto refresh doesn't work when ADF BC is configured with disconnected mode (ADF BC Tuning with Do Connection Pooling and TXN Disconnect Level). I would guess this is related to DB notification listener, it can't notify about DB changes, when DB connection is being taken from AM.

Make sure to remember to configure AM without disconnected mode. Auto refresh works for both application and session caching levels:


As a reminder - in order to use shared LOV functionality, you must select VO instance for LOV from shared AM configuration. See how it looks in the LOV definition wizard:


Auto refresh functionality is enabled with a single property - AutoRefresh = true. This can be set through VO general properties or directly in the VO source code:


Make sure Disconnect Application Module Upon Release option is not set:


I have overriden VO method processChangeNotification for logging purposes, this method is invoked automatically for VO's set with AutoRefresh = true. No need to code anything here, I'm just logging method invocation:


Let's do a test. First of all, check entries of Job list:


Go to DB and update one of the entries. For example, change Stock Clerk title and commit changes:


Come back to UI and press any button. This will trigger new request and Jobs list shared VO will be notified about DB change to refresh:


Check the list again, you should see changed entry for Stock Clerk:


In the log we can observe a call for change notification, it triggers shared LOV query re-execution and data re-fetch:


See recorded demonstration video, where I show refresh behaviour live:


Download sample application - ADFBCSharedSessionLOVApp.zip.

ADF BC Session Cached LOV - Understanding Expire Time

Sat, 2015-07-11 10:11
ADF BC offers LOV caching feature. There are two caching levels - application and session. With application level enabled, it makes LOV rows available for all users. On contrary for session level LOVs, data is cached for single session only. In this post I will focus on session level LOV's and I'm going to explain when cached data expires and is re-fetched.

You can configure caching level for LOV's in Model.jpx file, open AppModules section and select appropriate caching level for AM. I will be using Session level. Key point to understand - session level caching for LOV is nothing to do with Web user session lifetime. Session here is AM session, and cache remains in memory only until AM session remains assigned to the current user session:


LOV with caching feature is defined a bit differently, List Data Source must be selected from shared AM, other steps are the same:


My sample application implements two different VO's, based on Employees data. Both VO's are using the same cached LOV in session level for Jobs. This helps to make a test and check if cached LOV data expires. When cache is not expired, LOV data cached during first VO initialisation, should be present on the second LOV access. Above is example of Jobs LOV definition for Employees VO and below another example of Jobs LOV definition for Employees By Departments VO:


LOV VO is created with implementation class, where I override createRowFromResultSet method. It helps to track if LOV data was expired and rows were re-fetched:


As I have mentioned earlier, there are two VO's, both using the same cached LOV. On UI I have two different fragments, each located in TF. Call between two TF's is implemented, I'm using two different TF's to simulate Isolated TF behaviour. Isolated TF creates new instance of AM and this clears the cache of LOV on AM session level:


Let's understand how it works. First fragment is loaded, LOV data is fetched and cache is populated:


We can observe in the log, all rows fetched for LOV:


Open second fragment, LOV data is not re-fetched, it will be taken from the cache:


There are no rows fetched reported in the log:


Session cache works correctly for LOV. Now if user invoked Rollback, AM is reset and this indicates end of cache on AM session level, rows will be re-fetched. Try to press Cancel button:


There will be entries in the log, showing information about fetched rows - cache was cleared on Rollback:


Let's do another test with second TF set with Isolated option. When TF is set to be Isolated, it will force new AM instance creation, each time with TF is loaded. Meaning - there will be always new AM session and LOV cache will never be reused. TF is set to be Isolated:


Try to open TF and check LOV:


Differently than before, LOV data will be fetched - new AM instance was created on Isolated TF access and this requires to refill LOV data list:


Download sample application - ADFBCSharedSessionLOVApp.zip.

Oracle Process Cloud Service - SOAP Web Service Integration

Tue, 2015-07-07 09:03
Oracle Process Cloud (https://cloud.oracle.com/process) allows to invoke SOAP services, along with REST services. You can define a library of SOAP services in Oracle Process Cloud application and use them within the process. This helps to integrate with business logic running on premise.

I have implemented regular SOAP service in ADF BC, just to test how it works to invoke it from Process Cloud:


SOAP service method accepts employee ID and checks the status. ADF BC application is deployed on standalone WLS. Make sure to select correct deployment profile, when deploying ADF BC with SOAP on standalone server, otherwise SOAP service reference will be missing in deployed application. You should use ADF BC service deployment profile:


Once SOAP service is deployed, you can access WSDL file through Enterprise Manager. Oracle Process Cloud currently doesn't support direct SOAP references, instead you must provide WSDL file copy for Web Service registration:


Download WSDL file from URL (here is the sample WSDL, I was using for my test - HrModuleService.wsdl). This is how it looks like, it contains SOAP service description:


Here you can see Oracle Process Cloud interface. It looks quite user friendly and functional, this is what I like about it. On the left side, there is menu with different objects - Processes, Web Forms, Web Services, etc.:


To add new SOAP service reference is fairly easy, provide a name and upload WSDL file:


Once service is registered, we can go to the process diagram and select Service component from the palette:


Drag and drop it on the diagram, Implementation section will be opened, where you should specify SOAP service reference to be invoked:


Select Service Call from the list, this allows to invoke SOAP Web Service:


Once option for Service Call will be selected, you will be able to select Web Service reference. I have defined only one service, it is listed in the popup - select it:


Operation field is listing all available methods from the service, select one of the operations to be invoked:


Data associations are available to define correct mapping for the input/output values for the SOAP Web Service call, this can be done through Process Cloud composer window:


If you are interested in Human Task UI implementation in Oracle Process Cloud, read my previous post about REST service integration: Oracle Process Cloud Service - Consuming ADF BC REST Service in Web Form.

Oracle Process Cloud Service - Consuming ADF BC REST Service in Web Form

Sat, 2015-07-04 08:57
With the introduction of Oracle Process Cloud Service (https://cloud.oracle.com/process) there is an option to run your business process in the cloud. You can implement very similar things as it is possible with BPM 12c in JDeveloper, but only in the cloud. There is no option to implement human task UI with ADF, it must be done with Web Forms (light UI forms implementation framework). This is disadvantage, as it will require to externalise complex business logic and access data collections through REST calls, instead of processing it locally in ADF extension. However, this is how it is implemented currently in the BPM cloud version.

This is how it looks - Web Form editor in Process Cloud Service:


You have an option to select specific types from component palette. There are such types as money, email, phone, text. Components are provided with built in validation, checks for valid email address, etc. User who implements a form, needs to drag and drop components one by one (generally it works OK, but sometimes may get stuck and page refresh will be required). Properties section is available to enter details for the selected component.

Cool part about it - we can define business logic rules. For example, to show/hide customer field based on trip type, etc. One of the rules below, shows how REST service can be called inline and REST response is applied for drop-down field. This is pretty simple to fetch data from external REST service and use it for the Web Form component. Just invoke REST service and assign collection to the component supporting array of data:


If REST call requires to pass parameters through URL, this is also possible, see example below - list of cities, based on the selected country in the Web Form:


Web Form works pretty well in Preview mode, it even calls REST services and shows real data. Validation messages for built-in checks are displayed pretty nicely. Here I'm selecting a country from the list populated by REST service:


Based on the selection in the Country drop-down, filtered list for Cities becomes available (another REST call):


Good news - most of the Oracle Process Cloud interface itself is implemented with ADF. Here you can see a section listing all Web Forms available for the current process:


I have implemented REST service for Countries and Cities lists in ADF BC. There are two custom methods in AM implementation, to fetch the data and transform it to the list format:


REST resources are defined through annotations and are configured to produce JSON data, this will allow Oracle Process Cloud to parse such data automatically:


If you are going to check how REST service is implemented in ADF BC, you can run a query in Postman to retrieve a list of all countries from HR schema:


Another query to retrieve a list of cities, by country:


Download sample application, with ADF BC REST service - RestADFBCApp.zip.

Intercepting Table Filter Query and Manipulating VO SQL Statement

Wed, 2015-06-24 13:30
I’m going to describe one non declarative use case. Imagine, if there is a table with filter functionality, you may want to intercept filter items and apply the same for another VO. This another VO should be based on the same DB table, so it could apply criteria items against the table.

Sample application - AdvancedViewCriteriaApp.zip, implements a fragment with table component and a chart. Table component can be filtered, criteria is intercepted and applied for the chart, this one is rendered from different VO with GROUP BY query. Chart stays in synch and displays data according to the criteria filtered in the table:


In the log, I’m printing out intercepted criteria from the table filter:


Chart is rendered from the SQL query below:


Table filter criteria is being intercepted by overridden method buildViewCriteriaClauses. Criteria clause is constructed here, we just need select FilterViewCriteria, the one originating from table filter. We could apply this criteria straight ahead to the VO responsible to bring chart data. However, this would not work - ADF BC would wrap original chart SQL query with SELECT * FROM (…) QRSLT WHERE (table filter criteria). This would not work, because table filter criteria is not present in the original chart SQL statement. To make it work, I’m updating original SQL query for chart data, by updating WHERE clause part:


In the last step, we need to pass bind variable values - the ones user is searching for in table filter. This can be done from another overridden method - bindParametersForCollection. We have access to the applied bind variables in this method. Again, you should check for FilterViewCriteria and extract applied bind variables values. Chart VO will be updated with bind variable definitions created on the fly and assigned with values to search for:


I hope this trick will save some of your time, if you are going to implement something similar - to intercept table filter query and apply it to the another VO, based on same DB table.

Select One Choice with Select Items Tag

Thu, 2015-06-18 08:26
If you need to implement select one choice based on alternative data sources (not based on ADF BC) - you shouldn't use af:forEach inside af:selectOneChoice component. Don't get confused with af:forEach tag, this tag is supposed to generate multiple components and not to iterate over a collection of objects and render HTML for each item. There could be cases, when choice list data will come duplicated, with af:forEach tag applied. I would suggest to construct array of SelectItem objects and return it to the f:selectItems tag to be rendered.

This is how proper af:selectOneChoice definition should look like. Array of items is being rendered in the choice list through f:selectItems tag:


Value property for f:selectItems can be entered manually or through the wizard, when creating af:selectOneChoice - this should point to the custom method, where array of SelectItem objects is constructed:


Custom method could read data from any source and construct array of SelectItem objects. This is the input for f:selectItems tag, it knows how to render a list of choice list items out of it:


This is how it looks on runtime - choice list is working fine, no need to use af:forEach:


Download sample application - CustomSelectListApp.zip.

How To Record ADF Client Side Request Performance Time

Thu, 2015-06-11 00:13
I had a blog post, where I have described how to monitor client side request performance time with Ajax tag (works in ADF 12c) - Monitoring PPR Request Time on ADF UI Client Side. There is effective way to propagate recorded statistics back to the server for history logging using WebSockets - WebSocket Integration with ADF for PPR Request Monitoring. This requires WebSockets integration into project, if project doesn't allow this - there is another way. We could leverage Ajax call to the Java servlet and pass logged statistics data through parameter. I will describe how this can be achieved.

Sample application - ADFAltaApp_v6.zip, implements standard servlet. In the doGet method, I'm accessing parameter and parsing received statistics data. From here we could log data to the DB, so it could be analysed further. Data processing should be executed in the separate thread, not to block servlet execution and return response back to the client. Java in ADF 12c supports asynchronous servlets, however this is not the case with ADF 11g versions (unless you change JVM to 1.7). Parameter processing in the servlet:


On the client side, JavaScript code contains a method to acquire Ajax XmlHttpRequest object. Through this object we can invoke servlet, directly from JavaScript:


In the monitor function (invoked automatically on start and end events for the request) - we are invoking servlet and passing request performance data to log. I'm executing synchronous call, this is done on purpose - asynchronous calls in JavaScript can be lost, if user executes requests fast, portion of the data will be skipped. Synchronous call is made at the end of the request and usually is pretty fast (make sure to log data in the separate servlet thread, not to block execution):


This is how it works. Press Save button - you will see information about request processing time embedded in the top of the page (this is calculated and updated in JavaScript function from above):


Servlet on the server side prints received data to be logged - button ID, request processing time, user info:


Try to invoke another request - navigate back to the previous fragment. Time will be logged and displayed in the top part of the page, same is communicated to the servlet for logging:


Time is being logged on the server side:


I hope described idea will be useful for your own project, where you could measure ADF UI client performance (from button click, until action is done). Ajax tag to catch request start and stop events works only in ADF 12c, but you could do similar thing in ADF 11g with custom JavaScript listeners.

How to Apply New Label Text in MDS Customisation

Thu, 2015-06-04 14:49
It may look simple, but really is not obvious how to apply new label text for the ADF BC attribute or UI component through MDS customisation. It is simple, if such label text already exists in the core bundle. If you need to create new label text in the customisation and use it - this becomes a bit tricky. Well, as usual - I'm going to explain how you could solve such task. You should read more about MDS customisation setup in ADF - MDS Seeded Customization Approach with Empty External Project.

Core application - mds_label_cust.zip, contains one label for First Name VO attribute:


The requirement is to customise core application and add label for the Last Name VO attribute, without changing anything in the core. For this purpose, we need to create different JDEV application - extension, configured with shared library deployment profile. Here you could simply create new properties file. We are going to use this application to deliver additional components for the core. Keep in mind - core application must be configured to use this library. Add label for Last Name VO attribute, in the properties file located in the extension:


Time for the main trick. We could use label directly from any resource bundle in the ADF application. This is accomplished through such expression - reference for the resource bundle and label key:


This code should be part of customisation project, on runtime it will find referenced resource bundle and label key in the resource bundle from extension (see above).

This is how it looks on runtime - label text is taken from resource bundle in extension and applied by customisation:


It sounds more tricky, than it is - just try it.

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

Fri, 2015-05-29 13:19
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.

Responsive UI Support in ADF 12.1.3

Thu, 2015-05-28 10:26
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:

ADF 11.1.1.9 Goodies - Conveyor Belt Component and Alta UI

Sat, 2015-05-23 09:59
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.

ADF and Two-Way WebSocket Communication Architecture

Sat, 2015-05-16 05:02
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: