Andrejus Baranovski

Subscribe to Andrejus Baranovski feed
Blog about Oracle technology
Updated: 3 hours 22 min ago

ADF BC Groovy Expression Security Policy Configuration

Mon, 2017-04-24 13:23
Today I'm going to explain how to configure Groovy expression security policy. This could be helpful, if you dont want to change trustMode property to trusted everywhere across the app, but looking for single configuration point.

My sample app - GroovyPermissionApp.zip, contains bind variable with expression reference pointing towards custom method located in AM implementation class:


JDEV 12.2.1.2 returns compilation error for Groovy expression, can't resolve applicationModule property:


Such kind of checks can be disabled in Model project configuration. Uncheck option for Groovy Expression Type Validation:


JDEV 12.2.1.2 by default creates Groovy expressions in untrusted mode. If you change it to trusted, expression would work OK. However, if your app contains many expressions like this, you may want to ignore trustMode property:


If you run ADF BC tester in JDEV 12.2.1.2, it will show error text in the log for untrusted expression. ADF BC tester will fail to start, if there is any error - we logged this issue with Oracle Support. Property applicationModule can't be resolved, when trustMode is set to untrusted:


To disable this check, we can create new class extending ExprSecurityPolicy class. Override checkProperty method to allow calls to applicationModule property:


This class should be registered in adf-config.xml:


Try to run ADF BC tester again. Error about applicationModule will be gone. This time it will complain about permission error to call getCurrentRegion method:


Method access can be granted by annotation in AM implementation class:


ADF BC tester runs, and returns VO row data:

Production Mobile App with Oracle JET Hybrid in 2 Hours

Wed, 2017-04-12 22:58
Do you want to know a secret, how to build mobile application just in 2 hours? Use Oracle JET Hybrid. Beauty of Oracle JET Hybrid - you can reuse the same source code (HTML and JS) from regular JET application. JET UI is responsive out of the box and this allows to render JET screens from the Web on mobile device without changes.

We were using our JET 3.0.0 production app - Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application and created mobile app version. This process took around 2 hours.

Below I will list steps required to create JET Hybrid mobile app out of existing JET app.

1. Execute sudo npm -g install cordova to add Cordova to JET tooling

2. Execute sudo yo oraclejet:hybrid --platforms=android to create new JET Hybrid application. Windows and iOS are supported as well

3. Copy HTML and JS files from src folder of JET app into src folder of JET Hybrid app. Structure of JET Hybrid app with HTML and JS files:


4. Execute sudo grunt build --platform=android to compile JET Hybrid app

5. Execute sudo grunt serve --platform=android --destination=device to deploy JET Hybrid app to mobile device. If you are deploying to Android, you need to have Android tools installed on your machine

Dashboard screen on mobile device, built with JET data visualization components:


Customer setup screen contains JET search list and various input components with validation:


JET dialog looks good in mobile too, with input number fields:


JET input date component on mobile screen:


JET table with pagination is rendered very well and is easily usable on the small screen:


I should say - we are very happy with JET Hybrid functionality. It allows to reuse JET application code and build mobile app very fast.

Oracle JET 2.2.0 Application Migration to JET 3.0.0 Experience

Wed, 2017-04-12 00:28
I was migrating our production JET app from 2.2.0 to 3.0.0. End-to-end migration process took probably around 1-2 hours - with testing. I think this is quick. JET migration is not hard if you follow developer guide instructions - B Oracle JET v2.x.x to v3.0.0 Tooling Migration.

Migration from 2.2.0 must be done in two steps:

1. Migration to 2.3.0 from 2.2.0

2. Migration to 3.0.0 from 2.3.0

Step 1: Migration to 2.3.0 from 2.2.0

- Execute sudo npm install generator-oraclejet@2.3.0 -g to update Oracle JET to 2.3.0

- Execute sudo yo oraclejet ChBJellyHouseInvoicingJET230 to generate brand new JET 2.3.0 application

- Copy html/js files from existing application src folder into new one

- Update JET version number in index.html:


- Update JET version number and add additional library references (as per JET Developer Guide) in main.js:


- Update same set of libraries and versions in main-release-paths.json:


- Execute sudo grunt build:release to verify in migrated app build process succeeds:


- Execute sudo grunt serve:release to run application:


Step 2: Migration to 3.0.0 from 2.3.0

- Execute sudo npm install generator-oraclejet@3.0.0 -g to update Oracle JET to 3.3.0


- Execute sudo npm uninstall grunt-oraclejet oraclejet-tooling

- Execute sudo npm uninstall grunt-bowercopy --save-dev

- Execute sudo npm install grunt-oraclejet@3.0.0 oraclejet-tooling@3.0.0 --save-dev

- Execute sudo npm install oraclejet@3.0.0 --save

- Execute sudo npm uninstall bower -g to remove Bower, it is not needed anymore from JET 3.0.0

- Remove the following file from your system: scripts/grunt/config/bowercopy.js

- If you have no third-party dependencies remaining in your bower.json file, remove it

- Update JET version number in index.html:


- Update JET version number and add additional library references (as per JET Developer Guide) in main.js:


- Update same set of libraries and versions in main-release-paths.json:


- Execute sudo grunt build:release, most likely you will face error. Same was documented by someone on OTN Forum - v3.0.0 - Error with Grunt build and serve tasks with initConfig() in Gruntfile.js:


- To fix this error, add oraclejet-build.js and oraclejet-serve.js into scripts/grunt/config (you can copy these files from newly generated JET 3.0.0 app):

ADF Multi Task Flow Binding and Tab Order

Sun, 2017-04-09 19:47
I had a post while ago about ADF multi task flow binding and loading dynamic regions - Building Custom UI Shell with ADF 11g R2. In that sample, new region was opened in the first tab position. Meaning tab order was from right to left. It is more natural to have left to right tab opening order. This can be done too, check updated sample app - we need to control disclosed property and add new region to the end of array.

Sample app - MultiTaskFlowApp_TabOrder.zip. Sample app contains four regions that can be opened dynamically. Let's say user opens region Locations:


With improved tab order, next region will be opened in the tab on the right (before it was on the left, in the first position):


Tab closing works in the way. Let's say user wants to close second tab:


When tab with Departments is closed, next tab on the right is opened - Employees tab:


Key thing in implementation for this requirement - disclosed property in dynamic tab:


It calls bean method, where it evaluates current tab to be disclosed. If given tab is matching the value - it will be disclosed. Disclosed property for all other tabs will be reset:


Each time when new tab is loaded, it is loaded to the end of the array. New tab is set to be disclosed:


When user selects tab - currently disclosed tab property is updated too, to make sure info about new disclosed tab is stored:


One more case - tab closure. When tab is closed - next tab is selected, unless current tab was the last one:


When tab is selected programmatically, we update information about current selected tab too:

Workaround for ADF BC View Object Attribute Order Problem in JDeveloper 12c

Thu, 2017-04-06 21:23
I'm sure probably every ADF developer sooner or later faced this issue. When you create VO based on EO, JDEV gives you alphabetically ordered list of attributes. As a result - order of attributes in EO and VO becomes different. While this doesn't influence runtime functionality, it becomes quite annoying for application maintenance. Hard to match attributes between VO and EO, developer need to search through the list to locate attribute he is looking for. But there is a workaround, I will describe it here.

Let's see what the problem first. Assume we have Employees EO, attributes are generated in the same order as DB table columns:


Now if you are using VO creation wizard, list of attributes will be displayed in alphabetic order. This is frustrating:


Without any other choice, developer would select EO attributes and select them in such order as it is listed:


But wait, there is a workaround. Don't select all attributes, instead select only EO item itself. Then use Add button to add entire list of EO attributes:


This time attributes will be added in original order, as the order is set in EO.


Enjoy this small, but useful hint.

Slides from Oracle PaaS Forum 2017 - Oracle JET and ADF BC REST Production Experience with Oracle Java Cloud

Sun, 2017-04-02 01:56
My colleague Florin Marcus (twitter: @FlorinMarcus) was attending and presenting at Oracle PaaS 2017 forum in Split, Crotia last week. He was explaining our production experience with Oracle Java Cloud Service and running Oracle JET/ADF BC REST system on Cloud instance.

Slides are uploaded on slide share, you can go through and read about real production app built with JET and ADF BC REST running on Oracle Java Cloud. If you are interested in more details - let me know, I could show a demo:



Exciting news from Oracle PaaS Forum 2017 - Red Samurai won award for Outstanding Java Cloud Service Contribution 2017:


This award was received for implementing Oracle JET/ADF BC REST app and running it on Oracle Java Cloud in production. Read more about it - Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application.

Oracle JET Slider in Foreach Loop

Wed, 2017-03-29 13:55
While working in the project last week, I had a question from development team - how to render multiple Oracle JET Slider components in foreach loop. I thought this could be useful tip for other developers too.

You can get JET sample app from GitHub - JETSliderSample.

Take a look into dashboard.js, I have defined array with two elements, containing variables (value property variable must be observable, otherwise it will not receive changed data) required to initialize JET slider. Each array element, defines slider to be rendered in HTML. There is JS function which prints array content, it can be useful to access changed slider values:

HTML implementation contains foreach loop pointing to array from JS module. Each loop element prints JET slider. JET slider properties must be mapped with variables from array elements, otherwise slider would not function (if you are using it inside foreach loop):

This is how UI looks like. Multiple slider components are displayed through foreach loop. User can adjust slider values and print new values in JS function (hitting Submit button):

Oracle JET Tooling Migration from 2.2.0 to 3.0.0

Fri, 2017-03-24 12:35
Oracle JET 3.0.0 was released this week and I decided to migrate my local JET tooling from 2.2.0 to 3.0.0. Oracle JET developer guide provides well documented instructions for migration - B Oracle JET v2.x.x to v3.0.0 Tooling Migration. I was following outlined steps and tooling migration was smooth.

Migration from 2.2.0 to 2.3.0

Clean cache for bower and npm:


Install JET 2.3.0:


Migration from 2.3.0 to 3.0.0

Install JET 3.0.0:


Thats it - in three simple steps tooling was upgraded to 3.0.0.

Now we can create JET 3.0.0 app with Yeoman (follow instructions list in JET Getting Started guide):


I prefer to use NetBeans for JET application development. I already had a post about how to open JET application generated in Yeoman for development in NetBeans - JET Application - Generate with Yeoman - Debug in NetBeans. Let me go through this once again. NetBeans provides handy option to open HTML5/JS with existing sources:


We need to point to source folder, project directory and site root:


Make sure to point start file to index.html, NetBeans will ask this info when you try to run app for the first time:


To be able to run JET 3.0.0 application generated with Yeoman in NetBeans, you would need to copy two folders (create another app directly in NetBeans and copy from there):

1. Copy folder js/libs:


2. Copy folder css/libs:


Later when you build minified version of your app, css/libs folder can be removed:


JET 3.0.0 sample app is running:


In my next post I will explain how migrate existing JET 2.2.0 app to JET 3.0.0.

Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application

Mon, 2017-03-20 00:34
I would like to share our success in Oracle PaaS service - Java Cloud (JCS). We have managed to implement JET/ADF BC REST system in short period of time and deploy it in production running on Oracle JCS. UI is implemented entirely with JET, while back-end REST services are running on top of ADF BC. Secure access is controlled by unique ID managed by server side ADF Security.

Production application implements custom invoice processing logic for startup candy factory/distributor in Lithuania. Oracle Cloud doesn't require administration and provides all mandatory services to run custom application. This is primary reason why decision was made to use Oracle Cloud. In the next phase we are going to implement warehouse management logic, tightly integrated with invoice processing.

JET UI

Home screen displays dashboard with financial data for orders, customers and invoice items:


Menu structure (JET Router) is focused around implemented business logic:

1. Dashboard - statistical data display
2. New Invoice - invoice creation module
3. Template Setup - invoice template setup, to speed up invoice creation
4. Invoice Search - search through all invoices
5. Customer Setup - customer data management
6. Supplier Setup - supplier data management

Invoice Search screen implements form block and results table with pagination. This screen is using a set of JET components, starting from input list to responsive UI:


User have option to select invoice for editing. Various invoice fields can be changed in this screen. UI remains responsive and can be rendered on mobile device or JET Hybrid application - this was one of the key requirements:


Invoice items are edited in JET dialog. This is very convenient approach, JET dialog works really fast and allows to switch from one item to another in a quick way:


Development process - Oracle Developer Cloud Service

Application was developed using Oracle Developer Cloud Service. We think Agile boards/sprints defined in DevCS are really helpful. Offered functionality simplifies task management/monitoring process and you can see the progress in the sprint:


DevCS provides Git source control repository, agile board and issue tracking. It also gives you Build Automation. We were using Build Automation to re-build changes committed in ADF BC REST repository:


After build process completes - there is a an option to redeploy latest EAR package directly to JCS. This helps to save time, no need to repeat redeployment routine steps yourself each time when new build completes:


Application Structure

Application is divided into two parts (two separate deployments): ADF BC REST and JET UI implementation.

ADF BC REST implements back-end REST services and provides authentication/authorisation control. We are using regular ADF BC development, together with REST interface provided out of the box starting from ADF 12.2.1:


JET UI application is following modular architecture approach. Each use case is implemented in separate module. Common logic (REST service definition, etc.) is moved out into controller modules. Client side business logic is implemented in JET module JavaScript functions and rendered with JET UI components:


Oracle Cloud Deployment

We are using Oracle Java Cloud Service instance to run both ADF BC REST app and JET. ADF can't be deployed to Oracle Application Container Cloud service, but you can host JET from Java Cloud. For this reason it was more sense for us to use only Java Cloud and run both server side and host client side from the same instance.

Both demo and prod environments run from the same Cloud instance, targeted to different Managed Servers (to simplify maintenance):


If we take a look into application runtime statistics, ADF BC REST application mainly executes ADF REST servlet (to produce REST request response), our custom PDF servlet and ADF authentication servlet to execute session logout:


JET wrapper application doesn't run any server side logic, it simply return JET application content to the client - only File Servlet is invoked in operation:


Performance

JET runs on client side, there are much less server side calls comparing to ADF Faces application. In this example we change invoice status to Submitted. In result several REST calls are executed, each running below 100 ms. and transferring just a bit of info. Key difference between JET and ADF Faces - REST call doesnt block client functionality. REST call may execute asynchronously and user can continue to work with the application:


In the example below, we navigate to invoice list screen. Invoice MAR-36 status was changed to submitted, invoice line data is re-fetched to display up-to date information in the table for particular row. Invoice row data is re-fetched below 100 ms.:


Let's check navigation in the table. We navigate to the last page. REST request is completed in around 100 ms., and it returns only a set of rows for the last page:


When user log's our from JET application, we execute request for adfAuthentication servlet with parameter logout=true. This allows to close ADF BC REST session on the server side:


Summary

1. JET UI and ADF BC REST server side can be used in production system

2. JET UI and ADF BC REST runs great on Oracle Java Cloud

3. Oracle Developer Cloud Service is useful for JET and ADF development

Significant Improvement for WebLogic Start-Up Time on macOS Sierra

Tue, 2017-03-14 11:59
I have faced really slow WebLogic start-up times after upgrade to recent versions of macOS Sierra. It turns out to be common problem related to JVM start-up on macOS systems, nothing to do with WebLogic itself. Solution is to register mapping between 127.0.0.1 and your computer name in hosts file, read more on Stack Overflow - Jvm takes a long time to resolve ip-address for localhost. This issue seems to appear with newer JVMs.

Originally WebLogic was starting up in 157 seconds:


After config was applied in hosts file, start-up time improved a lot, it is 24 seconds now:


Changes in hosts file - 127.0.0.1 was mapped with my computer name, along with localhost. Same applies for ::1 mapping:


You can get computer name in System Preferences -> Sharing:


Hope this hint will be useful for those developers, who are working on macOS.

Improved Display for Empty Field Values in ADF Form

Sun, 2017-03-12 04:39
I had a task in the project, to improve display for empty field in ADF form. By default, if there is no row data in the result - all input text entries in ADF form will be hidden, user will see only labels. This is not ideal, most of time users would prefer to see disabled input text boxes instead.

In this example below, on purpose I search for non existing value and this causing form below to become empty. First Name field shows example with disabled text box, the way we want it to be displayed. All other fields display only label - default way:


Let's see how First Name field is changed to be rendered as disabled, when there is no data. I have changed EL for value property. Instead of pointing directly to the binding inputValue (when expression points to standard inputValue and when there is no data - field is rendered as read-only), I point to proxy method in my custom bean. Method is generic and it accepts field name as variable:


Disabled property is changed to return true, when primary key value is empty - this would happen when there are no rows in the result:


No need to change any other properties.

Proxy method is implemented in the bean. This implementation allows to pass parameter to the getter. Parameter - attribute name. Using parameter we are reading value from the bindings. If value is empty - NULL is returned, this makes field empty, but not read-only. When user is changing value - we need to update binding - this is done in put method. Here we get two values from EL - attribute name and actual new value. Think about it as about HashMap element:


With this generic method, there is no need to define separate getters/setters for each UI field. You only need to provide attribute name in EL expression:


Now form is displayed with empty disabled boxes, when there is no result:


When results are available - from displays and allows to edit data:


Download sample application - ADFDataEntryUIApp.zip.

Oracle Java Cloud - How to Create Access Rule for Managed Server

Tue, 2017-03-07 11:40
When you get fresh instance of Oracle Java Cloud, you are assigned with one admin and one managed server. If there is requirement to host multiple environments - demo, production, etc. - one managed server is not enough. Is better to run different environments on dedicated managed servers, this would simplify maintenance. WebLogic 12.2.1.2 partitions are not supported yet for Fusion Middleware, so only choice we have right now - different managed servers per environment.

In this short post, I will describe how to enable access to newly created managed server in Oracle Java Cloud. I have created RedSamuraiProd managed server with port 9075 in our Oracle Java Cloud service instance:


To allow access to port 9075, I need to define new access rule. This can be done through Cloud instance control, select Access Rules from the menu:


In Access Rules section, create new rule. Import here is to specify PUBLIc-INTERNET for source, WLS_MANAGED_SERVER for destination and port for managed server:


Once rule is created, managed server starts to be accessible from the internet. So simple and it works!

Oracle Java Cloud Upgrade to 12.2.1.2

Wed, 2017-03-01 11:51
We finished upgrade of our production Oracle Java Cloud instance to 12.2.1.2. This allows us to use new ADF BC REST features (16.5.2 What You May Need to Know About Versioning the ADF REST Framework).

Upgrade to newer version in Oracle Cloud is similar to on-premise upgrade. We need to create new service instance for software release 12.2.1.2 and later re-deploy our app, re-configure data source and setup security mappings:


12.2.1.2 instance is created in same way as it was before:


Instance is created in three simple steps, last step is just to review configuration:


Give it some 10 minutes to initialize:


And 12.2.1.2 environment is initialized - very simple and much more easier than to configure it by yourself on premise:


We can verify in Cloud EM - JRF 12.2.1.2 is installed, this means it includes full ADF 12.2.1.2 support:

Simple Way to Export Your Data from Oracle Cloud

Mon, 2017-02-27 02:05
You should not get stuck in the Cloud. There are various options to create Oracle Cloud backup, but is very important to keep a local copy of your data. One of the simplest options to create a local copy of data from the Oracle Cloud - use Oracle SQL Developer.

Define Oracle Cloud DB connection in SQL Developer (the same as regular DB connection):


Use Database Export utility from Oracle SQL Developer:


Allows to export schema DDL, together with data (various formats, SQL INSERT statements one of them):


You can choose from long list of DB objects to export, this includes indexes, triggers, constraints, tables, etc.:


In my use case I select all objects to export (except PS_TXN):


There is option to filter exported data, again I will export all data:


Schema structure along with data is exported successfully:

ADF Editable Table - Recommendation For Data Entry Optimization

Fri, 2017-02-17 11:33
I will explain data entry use case related to ADF table. Specifically I will talk about a bit more complex case, when some columns in the table are set with AutoSubmit=true, to force values to be submitted to the server on change. This can be required when validation rule must be processed on value change or there are dependent re-calculated fields in the same row.

If you are using AutoSubmit=true columns in ADF table, it is easy to start loosing values from columns with AutoSubmit=false. Really? Yes - only, if table iterator is set with ChangeEventPolicy=ppr.

Let's do an experiment. First Name column field is set with AutoSubmit=true:


Iterator is set with ChangeEventPolicy = ppr:


Enter value for Last Name, field with AutoSubmit=false:


Change value for First Name, field with AutoSubmit=true and tab away:


Previously entered value for Last Name will be lost and focus will move to table header. Two bad things happened at once. First Name is set with AutoSubmit=true, this means it send value from this field in PPR request, and since table iterator is set with ChangeEventPolicy=ppr, in response it is refreshing table with data from the server. Obviously Last Name new value wasn't sent to server yet (AutoSubmit=false) and ChangeEventPolicy=ppr is reloading values on the client with whatever values are on the server. Technically this is not a bug, but is a critical bug from user perspective - loosing data.

If you have AutoSubmit=true columns in the table, make sure to set ChangeEventPolicy=none for iterator:


This time after changing value with AutoSubmit=true - other field values stay on the client and focus moves nicely to the next field:


When data is saved - changed from both fields are submitted to the DB:


Download sample application - GroovyADFApp_v3.zip.

Setting Invalid Fields for the UI in ADF BC Groovy

Tue, 2017-02-07 10:23
What if you have entity level validation rule and want to attach validation error message to specific field. By default this is not possible - all entity level validation error messages are displayed in the popup and are not attached to the fields (differently than attribute level validation rule messages).

Apparently there is a way to achieve such requirement with Groovy expression, this can be executed from entity level validation - adf.error.addAttribute('Salary'). In addAttribute you need to provide attribute name which will be assigned with the error. Complete expression for entity validator:


Result displayed on UI - validation error message is assigned to the field, which was changed:


Download sample application - GroovyADFApp_v2.zip.

ADF 12c New Groovy API to Work with View Object Methods

Fri, 2017-02-03 04:01
I have interesting topic to share - new Groovy API in ADF to work with View Object, apply View Criteria, execute it. I have discovered it while experimenting with new features and functionality in ADF 12c. Starting from ADF 12.2.1, we have an option to code Groovy in separate file with extension .bcs - ADF BC Groovy Improvements in ADF 12.2.1. This makes sense especially with this new Groovy API - it is more convenient to code/maintain more complex Groovy logic in separate file. As Oracle docs say - Groovy runs faster when it is coded in separate .bcs file, probably there is no need to parse XML to extract and execute expression.

Sample application - GroovyADFApp.zip, contains Groovy implementation for Employees EO:


There is validation rule for Salary attribute coded in Groovy:


Let's take a look into Groovy method, we can open it in .bcs file - for more convenient to review/edit:


1. Method newView gets instance of Jobs VO, within Employees EO context. To get instance of VO with newView, it needs to be defined for programmatic access. This can be done in Model.jpx file, Groovy section.


2. Method copyNamedViewCriteria returns instance of predefined View Criteria. You need to set property ExtAllowUntrustedScriptAccess=true for View Criteria to be accessible in Groovy:


3. Method setViewVariable allows to set value for bind variable from VO. As a rule, bind variable must be assigned with ExtAllowUntrustedScriptAccess=true to be accessible in Groovy.

Let's see how it works on runtime. First it gets VO instance, applies bind variable value and then executes VO. Based on predefined logic, if row is returned - validation is successful:


When validation fails - message is returned:


This Groovy API can be useful when you need to access VO and execute logic directly from Groovy script, without coding Java method.

Contextual Event API Improvements in ADF 12.2.1.x

Sun, 2017-01-29 08:43
ADF 12.2.1.x brings improved API support for Contextual Event implementation - this should simplify Contextual Event usage. Now Contextual Events can be produced without referencing ActionEvent or SelectionEvent, also there is no need to define Data Control to implement Contextual Event handler. Read more in ADF 12.2.1.x documentation - 46.4 Creating Contextual Events Using Managed Beans. I will provide example and explanation how to use these improvements.

Download sample application - ContextualEventApp.zip. This sample is based on two isolated ADF regions - table and chart. When row is changed in the table, through table selection listener method I generate Contextual Event with Job Id payload and send it over, event is consumed in chart region and it allows to refresh chart by key:


Row is changed in the table - new Contextual Event is produced and consumed - chart is refreshed:


We should check in the log - it prints what happens from event initialization to consumption. This gives useful info to debug Contextual Event flow:


Let's jump into code of event producer - method for table row selection (JSFUtils helper method allows to execute table row selection event programmatically, just before producing Contextual Event, this allows to access information about current row). Event is constructed without any event definition in the bindings, directly using method action and event dispatcher API - we can pass payload information directly - no need to describe it in the definition (this is advantage, as sometimes payload definition expression could execute too late and payload could be empty):


Method action definition doesn't represent any real method, it contains event name and acts as helper for event producer:


Consumer region contains Contextual Event handler mapping - it specifies event name and handler info (this is same as before). There is no need to define handler through data control anymore. Method action points directly to the bean method, through instance name. Payload value is sent through using paramVal name and ${data.payLoad} expression:


Consumer receives payload and re-executes VO:

SQL Bind Variable Support in ADF BC REST

Sun, 2017-01-22 10:14
Is not that obvious from Oracle ADF BC REST developer guide how to provide value for bind variable defined directly in the View Object SQL statement. I did research around this and would like to post few hints to make your life easier, if you have same requirement - pass values from REST request to View Object required bind variables. This topic is especially useful, when you want to reuse existing ADF BC implementation for ADF BC REST access.

We are going to use View Object Row Finder. Oracle ADF BC REST developer guide explains how to use Row Finder with View Criteria. In our case we have different situation -  we would like to use Row Finder for required bind variables, referenced directly in SQL statement.

You can't define Row Finder without View Criteria. First trick is to define empty View Criteria, just to be able to define Row Finder - we are not going to use View Criteria functionality, our bind variables are referenced directly in SQL WHERE clause:


Once Row Finder is defined, you are going to see bind variables listed. Keep in mind - this doesn't means bind variables are referenced by Row Finder, they are just listed for possible use. Now main trick - go and define some dummy expression for each bind variable you want to use in REST request (make sure to uncheck - Save expression to groovy file):


This action would generate Groovy expression for each bind variable and list these bind variables under Row Finder. Go to source of View Object to see the structure:


Now remove Groovy expressions assigned to each bind variable - we don't need them, keep only bind variable names assigned to Row Finder:


Visually in the wizard is going to look like there are no changes made - but we keep bind variables under Row Finder tag now:


Bind variables are included directly into SQL statement WHERE clause:


ADF BC REST service is defined in regular way, no special tips here:


This is how REST call looks like: Departments?finder=RESTFilter;depNameVar=IT.locIdVar=1700. We include Row Finder name and two bind variables with values:


In the background we could check ADF BC log, where it prints SQL statement with both bind variables assigned with values:


Download and browse sample application ADFBCRestApp from my GitHub repository - jetcrud.

Multi Language Support in Oracle JET

Wed, 2017-01-18 09:30
There is great post from Geertjan Wielenga about Translating Oracle JET Applications. If you want to introduce multi language support into JET app - this is great place to start reading from. We are building production Oracle Cloud app with ADF BC REST and JET. This app requires multi language support - English and Lithuanian. I will describe below how we integrated multi language into various areas in the app.

Download or browse through sample application in GitHub repo - JETPlaygroundApp.

In JET we could set default language in index page html root tag. By default it is set to en-US, but it can be set to lt-LT for Lithuanian language or any other language:


Translation texts are located in message bundles. There is one default message bundle for English and translations are located in sub folders. English bundle:


Lithuanian bundle with translations for the same message keys:


Multi language bundle support must be registered in main.js (bundle file name can be anything):


Values for all labels/texts must be defined as observables and initialised from JET translation API by passing message key - this will bring default text:


When language is changed, we need to update observable values and reset language value in HTML tag. I'm changing menu labels as well by re-configuring JET router:


On UI in index.html message key is referenced directly from observable variable:


We can access message key defined in appController from individual JET module UI through $parent. For example, I'm using dueDate message key in incidents module:


Same message key is reused in another module - customers:


This is how language switch looks on UI - language change is available in preferences:


When we switch to Lithuanian language - texts are changed (the ones assigned with translatable messages):


Menu labels are also changes, JET Router is reset:


Labels are change in built-in JET components - such as date. Though is not translated completely for Lithuanian language (Today text remains in English):

Pages