Monday, December 31, 2012

My ADF Sample Apps Live in Oracle Java Cloud

With Oracle Java Cloud available for ADF PS5 deployments, I decided to deploy all my future ADF sample apps from the blog in Oracle Cloud, source code will be provided as well as it was up till now. ADF sample applications live will help to explain and present ADF functionality even better, blog readers will be able to test described functionality straight away and provide feedback without downloading and running on their machines. Currently I'm running trial instance of Oracle Cloud for database and Java, but in future I plan to purchase permanent account - let's see how it will go.

Read more about Oracle Database Cloud and Oracle Java Cloud from official documentation. Oracle Cloud right now supports ADF PS5 with certain limitations, please check documentation - however most of the sample apps will run without issues.

I have deployed in Oracle Java Cloud and tested one of the sample apps from my blog post - Tree Table Component in Oracle ADF. This app renders hierarchical data in different levels of the tree, Master-Detail relationship between two tree tables is implemented as well. Original sample app is deployed with minimal changes described below (datasource name and login config are optimized for Oracle Java Cloud). Here you can download source code for ADF app deployed in Oracle Java Cloud -

This app is deployed for public access, you can open it by clicking here - Tree Components in the Cloud. Sample app will be loaded and you should see two tree tables rendered with hierarchical data from sample HR schema (see URL pointing to Oracle Java Cloud instance):

We can use Oracle Cloud Service Control for Java to see a list of deployed apps - TreeComponentsApp is one of them. You can find here JNDI Location for Data Source, we will use it in Application Module - database. ADF Application Module will be using it to retrieve data from database Oracle Cloud:

We can review ADF performance for deployed apps - AM and ADF Task Flow usage:

You can deploy ADF app directly using Oracle Cloud Service Control for Java, but same is possible from integrated JDeveloper 11g PS5 environment. You should download latest JDeveloper optimized for Oracle Cloud. Apparently Oracle released two JDeveloper versions under the same release number, Oracle Cloud release was made public around October. So, if you have old - remove it and download new one. You should see OCLOUD name in JDeveloper build:

I will describe now, what changes I have made to original ADF sample app in order to be able to deploy it and run in the cloud. Firstly you should change JDBC Data Source name for AM configuration, it must be set to database JNDI name, same as it is defined for us in Oracle Cloud Java. This allows to fetch data from Oracle Cloud for database:

Next Application Server connection pointing to Oracle Cloud Java instance must be defined in JDeveloper. Choose connection type - Oracle Cloud:

Provide connection details as per Oracle Cloud documentation and you are almost done.

Almost - because there is just one additional config - ADF application login method handling. By default ADF app is protected by Oracle Cloud security, but I want to make my ADF sample apps public and accessible to everyone. For this reason, I need to include empty login configuration into web.xml - the rest will be handled by Oracle Cloud and ADF app will be public accessible:

This config was suggested by Oracle Cloud automatically, when I was trying to deploy sample app. Deployer creates optimization suggestions and lists them in the deployment log accessible from JDeveloper:

Thats all about ADF deployment to the cloud - very straightforward. Now few words about database schema in the cloud. As usual - I'm using sample HR schema for my sample ADF apps. You can access Oracle Cloud database instance directly from JDeveloper, read this white paper - Data Movement and the Oracle Database Cloud Service. Data can be imported and exported from JDeveloper. However, there is another quick way to populate Oracle Database Cloud - using SQL scripts. Open Oracle Database Cloud instance and go to SQL Scripts section:

I was using HR schema SQL scripts and generated all required tables and populated data:

HR schema data is in the cloud and ready to be accessed from ADF app deployed in Oracle Java Cloud:

I was testing ADF passivation/activation to see if PS_TXN table is automatically created in Oracle Database Cloud. Yes, table was created automatically - perfect:

Sunday, December 30, 2012

After Commit Call for Centralized Transaction Management

With this post I would like to update sample application from my previous post on this topic - Centralized Transaction Management for ADF Data Control. This previous post was about how to call global commit/rollback operations applied for ADF Data Control, without declaring Commit and Rollback in each and every page definition file. Centralized Commit and Rollback operations are created in fragment template, this allows to reuse the same buttons across different fragments. There is one bit we can use to extend centralized transaction management concept - custom method invocation after successful commit. Based on use case requirements, we may need to invoke iterator refresh after commit, etc.

Updated sample application -, implements after commit call. User is changing data and commits transaction with Save button:

Separate method with after commit logic is invoked, this time it just prints static text:

I will describe implementation steps below. Firstly we should provide our custom after commit method name into fragment template - where transaction is commited. For this purpose you can define new attribute for page template definition:

You can look into provided sample application and find there afterCommit attribute defined, we will pass our custom method name through this attribute:

Now take a look into global commit method itself. Two additional lines were added - retrieve custom after commit method name from page template attribute and invoke it as method expression using JSF API:

Method expression construction method is standard, it constructs method expression for any method signature returning void and without input arguments - this is important, otherwise you will need to update invokeMethodExpression method code to support return and argument types. When method expression is constructed, it invokes referenced method:

We move now to consumer part and open fragment, based on our template - depsEmplsView.jsff:

Select af:pageTemplate tag and open Properties window - you should see our custom afterCommit property included into template properties. Provide custom method name, including backing bean name (no need to specify expression brackets, these will be added automatically):

Make sure such bean is defined in the ADF task flow:

Take a look into method invoked after comment signature - no return value and no arguments:

Monday, December 24, 2012

Conditional Validation in ADF BC

ADF BC offered out of the box business validation support is quite advanced - allows to control validation execution conditionally. Still some functionality is missing - easy configuration for execution order. Now we have entity and attribute level validations, but really this doesn't give any guarantee that entity level validation will not be invoked when attribute value is changed (especially true for ADF table component). In the future ADF versions I would like to have more control over validation execution order and time. This post is to demonstrate what is available now - conditional validation execution. Validation rule can be executed conditionally in ADF BC, for example depending on user security role (based on use case requirement, we may want to skip certain validation for the super user).

Sample application - contains validation rule implemented for Salary attribute value check:

Conditional execution expression for the validation rule is based on Groovy and is accessing ADF security context to evaluate if super user role is granted to the current active user:

If current use is not a super user - validation rule will be invoked.

Don't forget to set AutoSubmit=true on the ADF UI for the field to be validated (this is typical ADF beginners mistake) - otherwise validation will not be displayed immediately after data change:

There are two users (both with welcome1 password) defined in the system, one of them is super user:

Test with super user - redsam1:

Change salary value to be 300, less than 500 - validation is passed for super user:

Test with regular user - redsam2:

Change salary value to be less than 500 - validation is executed for the same Eemployees EO:

Friday, December 21, 2012

Skip Validation for ADF Required Tabs

Tell me - how often it happend to implement such basic layout where required attributes from one Entity are located on the same fragment/page but in different tabs? I guess quite often, this is common requirement. However, is not so obvious how to implement it properly. Most likely you will end up into infinite loop of validation errors for required fields when trying to switch between tabs. I will describe in this post how to implement multiple tabs with required attributes from the same Entity and avoid unexpected validation errors.

Sample application - is based on Employees EO and contains two tabs - Contact and Details. Half of Employees attributes are located under Contact and the rest under Details tab:

Firstly I will show you how it works by default. Press Create button, this will call CreateInsert operation and insert new row (attributes from this row will be initialized blank in both tabs):

Type values for required fields and try to open second tab - Details. Validation errors are displayed for missing attribute values in the second tab. But wait a bit - we want to open Details tab and already getting validation errors? This makes our form unusable:

Let's make first attempt to solve this problem - set Immediate = true for both tabs. In theory this should help, in practice it doesn't. Immediate = true allows to skip validation lifecycle, but as a side effect it prevents Model update and value is not set.  Immediate = true will not solve described issue, but still let's test it - I will show you why Immediate = true doesn't help at all. Select both tabs in JDeveloper:

Set Immediate = true property for both tabs:

Do the same test again - create new record and type required values in the first tab:

Because of Immediate = true - we can open second tab without getting validation errors. Type required values in the second tab and press Save. Validation errors are reported for the required values in the first tab. This is quite a magic, actually not - this happens because of Immediate = true - entered data is not stored on the Model:

Set Immediate = true to be false for both tabs, as it was originally:

Solution will be described now. Open page definition file and select root tag in the structure window:

Go to Properties window and search for SkipValidation property. Set SkipValidation to true:

This allows to prevent such silly validation execution as you saw above. Enter required values in the first tab:

Switch to the second tab - enter required values there. Press Save button to commit transaction - no errors this time:

SkipValidation = true doesn't affect regular ADF validation behavior - if required field value is missing during transaction commit - ADF will stop processing and ask user to provide a values as expected:

Tuesday, December 18, 2012

ADF Mobile - Geo Location Synchronization

Here you can read about ADF Mobile application enabled with geo location features - GPS and Google Maps - ADF Mobile - Geo Location and Google Maps App. I would like to post update for this application where geo location is synchronized automatically, directly updating your position on Google Maps screen. Few minor usability updates are included as well - conditional check for 3G/Wi-Fi network and GPS availability.

Download version 2 for ADF Mobile Geo Location and Google Maps application - This update contains code to check if 3G/Wi-Fi and GPS functionality is available - displayed on UI:

Show button is enabled only if 3G/Wi-Fi connection is available, otherwise Google Maps are unaccessible. Start button is enabled only if GPS is available - location will be calculated only with active GPS signal.

Initial position is retrieved from GPS, this position is displayed on the map:

You don't need to switch back and request position correction - keep Google Maps window open, when GPS data will be recalculated - position will be refreshed and displayed automatically:

Go back to initial position screen, you can review synchronized location coordinates there:

3G/Wi-Fi network status is retrieved from ADF Mobile API directly - deviceScope.hardware.networkStatus:

Similar for GPS signal status - deviceScope.hardware.hasGeolocation:

GPS position synchronization is quite straightforward - method from pageFlowScope bean updates center coordinates:

Property Change Support listener is responsible to push data changes to the UI:

Point location layer from ADF Mobile maps component is mapped directly with pageFlowScope bean coordinates data - this allows to reload location point, when location coordinares are changing: