As you know, ADF 11g allows to secure read, update, and delete operations on EO level. However there is no default support for insert operation. Typically, developers will go and set Expression Language statements directly on Web page to enable/disable one or another attribute. While this works, it is not good in terms of maintenance. Today I will describe another approach, where I will override isAttributeUpdateable() method on EO to evaluate security rule on insert. I believe, this approach works better comparing to Expression Language on front end, because it allows to secure Model directly. This is especially good, when you are using same EO's in different forms - no need to implement same security rule again.
Download sample application - ProgrammaticSecurity.zip. This sample is enabled with ADF Security and contains two application roles:
I have defined programmatic security rule inside EO implementation class:
Inside EO implementation class, I override isAttributeUpdateable() method. Security rule is applied only for SALARY attribute and only when current row is in insert mode. If current user is not granted with manager role, SALARY attribute will be rendered as disabled:
On runtime I login with user granted only accountant role. As expected, user can edit SALARY attribute values for current employees:
We click Create button - row is in insert mode. Current user don't have permission to enter new SALARY attribute value, while new employee is not yet in database - attribute is rendered as disabled:
When transaction is commited and new employee data is inserted into database, SALARY attribute becomes editable again:
Tuesday, June 22, 2010
Saturday, June 19, 2010
ADF Regions and Nested Application Modules to Improve Performance
Oracle Fusion application typically includes multiple regions and integrates smaller applications into dashboard for better user experience. Users like this approach, however we should check what are implications for technical side. Today I'm describing different approaches for ADF Regions integration and use of Nested Application Modules.
Download sample application - ADFIntegrationNested.zip. This sample contains multiple Oracle JDeveloper 11g PS2 applications to demonstrate integration functionality together with nested application modules usage.
You will find first application with Employees Model implementation. ADF BC Model is packaged into ADF JAR Library to reuse it inside main application:
Second application is identical to first one and implements Jobs Model functionality. It is packaged into ADF Jar Library as well:
There are two applications two integrate ADF BC Model and use Business Services inside ADF Regions. Why two applications? First integrates ADF JAR's directly into ViewController - means using Application Modules directly from ADF JAR's. Second integrates ADF JAR's into local Model project, Business Services from imported libraries are exposed through local proxy Application Module - this Application Module contains Nested Application Modules from imported libraries.
Application without Nested Application Modules (FIRST) - no Model part implementation:
Application with Nested Application Modules (SECOND) - contains local proxy Application Module, it joins Application Modules from imported libraries into Nested group:
We have two imported libraries, based on Employees and Jobs models:
FIRST application integrates Model libraries directly into ViewController, this means DataControl is available:
You can see two Data Controls available, this basically means we are using two different Application Modules. Application is deployed on WLS under regions context root path:
Now we can test FIRST application, it implements two ADF Regions based on two Application Modules from imported ADF JAR Libraries:
Type any value into Employees and Jobs regions, press Save inside Employees region:
Press Undo inside Jobs region - it works as expected, data from Jobs region is reset to original values and Employees keeps updated values. It happens because we are using two different Application Modules - transactions are managed separately:
While it works good from user perspective, if we check reserved database connections, we will see two of them:
Thats quite logical - we are using two Application Modules, both are present on current page inside of two regions. However, from performance view its not ideal - each user will use two database connections in this case.
How we can improve this and use only one connection even for two ADF Regions working with two Application Modules? We can use Nested Application Modules. When we are importing ADF JAR Libraries, local proxy Application Module can be created to join imported ones into Nested group - check SECOND application:
SECOND application imports ADF JAR libraries with Model implementation for Jobs and Employees into local Model project:
Local proxy Application Module doesn't have any View Object Instances - its empty:
But it contains Application Module Instances - Nested group of modules from imported libraries:
In Data Control we can see now only one local Application Module, it contains nested Application Modules:
Nested Application Modules bring View Object Instances from imported ADF JAR Libraries:
I'm using those View Objects from Nested Application Modules inside ADF Regions.
Important to mention, both Commit and Rollback operations are declared on local Application Module. Since imported ones are nested, Commit and Rollback operations are applied from master Application Module:
Main page contains ADF Faces Dashboard component with both regions for Jobs and Employees:
SECOND application is deployed with nestedregions context root path:
Again two ADF Regions are rendered:
We type into Employees and Jobs, press Save for Employees to commit changes:
Press Undo in Jobs region:
Uncommited data in Jobs is reverted, commited Employees changes remain:
Here is one very critical difference between ADF Region and ADF Page - even we are using Nested Application Modules and Commit operation from master Application Module - it still commits only transaction for current region (specific imported Application Module), which is great. With ADF Page it would commit changes from all Nested Application Modules at once.
Let's take a look into database connection usage, only one database connection is used now - great performance improvement:
As you can see, Nested Application Modules in combination with ADF Regions can be great performance improvement in Oracle Fusion applications.
Thursday, June 10, 2010
Deploying an ADF Secure Application using WLS Console
Quick note about ADF Secure application deployment.
Juan Ruiz from Oracle explains how to deploy ADF Secure application on standalone WLS, using WLS console. Check his blog post - Deploying an ADF Secure Application using WLS Console.
Juan Ruiz from Oracle explains how to deploy ADF Secure application on standalone WLS, using WLS console. Check his blog post - Deploying an ADF Secure Application using WLS Console.
Groovy String Operations in Oracle ADF 11g
Groovy Script support by Oracle ADF 11g gives us good flexibility to operate attribute values and implement business logic. Often you need to parse String type attribute values - it can be easily done using Groovy script directly in ADF BC.
Download sample application - GroovyStringMethods.zip. This sample implements validation rule for Salary attribute:
Validation logic is pretty basic, it compares old and new values, if attribute value was changed - it fails:
Now is interesting part - validation execution rule. Here I'm calling substring() method for String type Salary attribute directly in Groovy script. If JobId of current employee starts with IT, only then validation rule is triggered:
I can use toUpperCase() method as well. Using Groovy, LastName attribute is converted to upper case:
On runtime, String type attributes are successfully parsed, validation rule is invoked and it prints LastName in upper case:
Special thanks for researching this, going to my colleague - Inno from Soweto :)
Download sample application - GroovyStringMethods.zip. This sample implements validation rule for Salary attribute:
Validation logic is pretty basic, it compares old and new values, if attribute value was changed - it fails:
Now is interesting part - validation execution rule. Here I'm calling substring() method for String type Salary attribute directly in Groovy script. If JobId of current employee starts with IT, only then validation rule is triggered:
I can use toUpperCase() method as well. Using Groovy, LastName attribute is converted to upper case:
On runtime, String type attributes are successfully parsed, validation rule is invoked and it prints LastName in upper case:
Special thanks for researching this, going to my colleague - Inno from Soweto :)
Monday, June 7, 2010
LOV Description Text with Groovy
There was a question on ADF EMG group, about LOV description texts. While it is usually recommended to create Association and join description text attribute into VO, sometimes people are looking for different approaches (for one or another reason). Today I will tell you about approach, I recently discovered - to get LOV description text through Groovy script, without joining attribute into VO. With this approach, framework executes fault-in query for description text, directly from EO. This means, instead of one join SQL statement, there will be executed smaller SQL selects for each LOV description, plus main VO. To read more about fault-in queries executed from EO, check Steve Muench blog - Difference Between View Object Select and Entity doSelect() Method.
Download developed sample application - DescriptionAttrGroovy.zip. Make sure you have Association between main Employees EO and EO with description text:
Create new transient attribute - DepartmentName, in Employees EO. Set this attribute value as Expression and provide correct Groovy script - Departments.DepartmentName. This means we will reference DepartmentName directly through Association, without joining it into VO:
Let me repeat myself - its not really recommended approach, I personally prefer to join description attribute into VO, because it allows to run single joined query.
Make sure you set expression recalculation dependency, based on DepartmentId EO attribute:
You need to set Auto Submit = true for the same DepartmentId EO attribute, this is needed to refresh transient DepartmentName attribute:
Set DepartmentName attribute dependency on DepartmentId, everything on EO level still:
This will allow to refresh DepartmentName with correct value, when DepartmentId will be changed.
Model part is implemented at this step, let's drag and drop LOV component along with description text in UI:
We render LOV and description:
Change LOV value, description is retrieved through Groovy expression and updated as well:
Check in the log, ADF BC executes additional SQL fault-in statement, to retrieve new description value:
No Java, No Magic - all works in declarative way.
Download developed sample application - DescriptionAttrGroovy.zip. Make sure you have Association between main Employees EO and EO with description text:
Create new transient attribute - DepartmentName, in Employees EO. Set this attribute value as Expression and provide correct Groovy script - Departments.DepartmentName. This means we will reference DepartmentName directly through Association, without joining it into VO:
Let me repeat myself - its not really recommended approach, I personally prefer to join description attribute into VO, because it allows to run single joined query.
Make sure you set expression recalculation dependency, based on DepartmentId EO attribute:
You need to set Auto Submit = true for the same DepartmentId EO attribute, this is needed to refresh transient DepartmentName attribute:
Set DepartmentName attribute dependency on DepartmentId, everything on EO level still:
This will allow to refresh DepartmentName with correct value, when DepartmentId will be changed.
Model part is implemented at this step, let's drag and drop LOV component along with description text in UI:
We render LOV and description:
Change LOV value, description is retrieved through Groovy expression and updated as well:
Check in the log, ADF BC executes additional SQL fault-in statement, to retrieve new description value:
No Java, No Magic - all works in declarative way.
Saturday, June 5, 2010
ADF 11g Fusion Projector Skin
This week I was reading Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle ADF 11g, and have found new and interesting thing for me - projector skin, see all Oracle ADF Faces Skins. There is special skin for Oracle ADF Faces components, it allows better optimized rendering on projector devices. This is especially important when doing different presentations and demos. When you run this skin on desktop monitor, there is no difference to see, but when running on projector color scheme looks much more contrast.
JDeveloper 11g PS2 bring update for fusion skin, namely fusion-11.1.1.3.0. As per documentation, panelTabbed, navigationPane and panelAccordion components look and feel is improved. Let's run sample application - FusionSkin.zip and see it.
Default JDeveloper 11g PS2 fusion skin:
Now I change it to fusion-11.1.1.3.0 skin available with JDeveloper 11g PS2:
Thats true, panelTabbed and panelAccordion appear much better and lighter. I have noticed, tabs are opening faster as well:
Finally, we have fusion-projector skin - optimized for rendering on projector screens. There is JDeveloper 11g PS2 fix for this skin as well - fusion-11.1.1.3.0-projector:
There is no obvious visual difference when running on desktop monitor, however still you can see that component borders are rendered sharper:
Managers can enjoy ADF 11g presentations and demos without having eye pain ! :)
JDeveloper 11g PS2 bring update for fusion skin, namely fusion-11.1.1.3.0. As per documentation, panelTabbed, navigationPane and panelAccordion components look and feel is improved. Let's run sample application - FusionSkin.zip and see it.
Default JDeveloper 11g PS2 fusion skin:
Now I change it to fusion-11.1.1.3.0 skin available with JDeveloper 11g PS2:
Thats true, panelTabbed and panelAccordion appear much better and lighter. I have noticed, tabs are opening faster as well:
Finally, we have fusion-projector skin - optimized for rendering on projector screens. There is JDeveloper 11g PS2 fix for this skin as well - fusion-11.1.1.3.0-projector:
There is no obvious visual difference when running on desktop monitor, however still you can see that component borders are rendered sharper:
Managers can enjoy ADF 11g presentations and demos without having eye pain ! :)