Saturday, May 29, 2010

Use Case: View Criteria Conditionally Query-able Attribute

Today I will talk about specific use case - how to reuse the same ADF Task Flow with View Criteria for different scenarios. Generally, it is quite clear how to do this, however I will point on several tips and tricks. Hopefully, it will help you to implement stable design easier and with less effort.

Download sample application - Central part of this application is Employees ADF Task Flow:

It contains Router activity, two Method Calls and region. Based on task flow parameter value, router navigates to specific Method Call, where View Criteria is reset and applied. If task flow input parameter is not null, Employees are filtered by Department:

I should mention, that View Criteria contains hidden criteria item to filter by DepartmentId - this item is set to be rendered never:

Render Mode = Never is used for DepartmentId item, because the same View Criteria is implemented as Query component on the page and also I'm using it programmatically to filter by DepartmentId attribute. However, I don't want to render criteria item, I'm using for programmatic filtering.

Let's assume, Use Case is implemented and we are testing it. Default dynamic region for Locations is loaded:

I'm using menu, to navigate and open Employees dynamic region. Once its opened, I switch Query component to Advanced mode and expand Add Fields list. I can see DepartmentId attribute in the list, which is correct - it is valid to filter employees by department in this case:

Let's go back to Locations region, and select any of available locations:

Press Departments button, to open Locations summary screen, with all corresponding departments listed below. We select one of the departments and press Employees button:

At that time, Employees ADF Task Flow is opened with Department parameter value. Router activity navigates and filters employees by department - Query component block is conditionally disclosed:

Repeat the same steps, and open Add Fields list for Employees criteria being in Advanced mode. You will see DepartmentId attribute available in the list. This is incorrect from the user point of view. We want to see employees only from selected department, it will be invalid to search by DepartmentId in this case:

If user really wants to search by DepartmentId, he should open Employees region from the main menu. How we can prevent this and guarantee correct funcationality? Answer is simple - using conditionally queryable attribute. You already saw Method Calls in Employees ADF Task Flow, lets take a bit closer look. Both Method Calls have return values, return value is used to enable conditional expression for Query component Disclosed property:

Both Method Calls are invoking custom methods from Application Module Implementation class:

Here are those methods, key part of today Use Case:

First method is filtering Employees by DepartmentId, second is resetting View Criteria to initial state. View Criteria is reset, auto execution mode is set, bind variable initialized and finally View Criteria is applied. There is one more very important thing - changeAttributeQueryable(String, Boolean) method. This method makes DepartmentId attribute queryable or not - depending from where it is invoked. If we reset View Criteria and enter in default mode - attribute is queryable, otherwise its not. Method that controls attribute queryable property is implemented in Employees View Object Implementation class:

To enable/disable queryable property programmatically, we simply can use setQueriable(Boolean) method from ViewAttributeDefImpl:

We are testing again, and opening filtered Employees region by selected Department:

DepartmentId attribute is not available in Add Fields list anymore, its what we need:

If Employees region is opened now directly from the main menu:

DepartmentId will be present now in Add Fields list. Thats correct, because View Criteria was reset and we can search employees by any department:

Wednesday, May 26, 2010

Migrating Security Policies from Development to Standalone WLS 11g

While ago I was working on ADF security deployment to standalone WebLogic server - Practical ADF Security Deployment on WebLogic Server. It was still first 11g production release, and we had problems with automated security policies migration during deployment. Problems were solved using policies migration scripts from Steve Muench article - Simplified ADF 11g Application Credential and Policy Migration to Standalone WebLogic Servers. Its worth to mention, with latest JDeveloper 11g PS2 and WebLogic release, security policies are migrated during deployment process automatically - WLS system-jazn-data.xml is updated without running additional scripts. However, it happens we need to update system-jazn-data.xml with new policies, without whole application redeployment. For this purpose, similarly as in Steve article, we can use WLST command - migrateSecurityStore.

If you will run Steve scripts on latest Oracle Fusion release - you will see that some parts need to be updated (build.xml should contain updated references to JPS libraries, jps-config.xml should be updated with new system-jazn-data.xml location in fmwconfig folder). Main goal of my today post is to describe how you can apply migrateSecurityStore command and migrate security policies from development environment (or any other) into test/production WLS environment.

I'm using sample jazn-data.xml from this application - There is one simple security policy defined for index page:

Application role is mapped to specific Enterprise role:

In order to use migrateSecurityStore command, you will need to define jps-config.xml file, where you will point to source jazn-data.xml and to destination system-jazn-data.xml:

More about this file structure, please read in Oracle FMW Security Guide - Section In my case, I have created jps-config.xml file inside WLS domain folder structure, I have copied source jazn-data.xml manually.

In order to execute WLST command, we will need to run WLST.cmd script. Make sure, you are using WLST.cmd script from oracle_common folder, otherwise it will not recognize ADF related WLST commands:

When WLST is running, you can execute migrateSecurityStore command. This WLST command can be run offline, this means no need to have running WLS server. Make sure you specify jps-config.xml file, source and destination contexts correctly, as it is defined in jps-config.xml:

And here we go, security policies are magically migrated to WLS system-jazn-data.xml and ready to be used:

Next step, make sure WLS server is connected to Active Directory service, where WLS can find users with correct Enterprise roles. Or for test purpose, define these users and roles in WLS embedded security realm.

Ah, almost forgot - make sure you have restarted WebLogic, before trying to test if it works.

Saturday, May 22, 2010

Yes-No Check Box in Query Criteria

There are several posts on internet where it is described how to implement Yes-No (Y-N) type check box using ADF Faces boolean check box component. However, when you want to use Yes-No check box in Query Criteria, there is one additional trick should be applied - I will explain it today.

Download sample application - In order to run this sample, you need to create additional column in Regions table from HR schema. Make sure you name this column correctly - YES_NO:

For demonstration purpose, I have created static View Object to bring Yes-No values LOV:

Next, I have defined Choice List type LOV for YesNo attribute:

For the same YesNo attribute, make sure that Check Box is specified as Control Type attribute. This will render Check Box in JSF page:

On runtime, YesNo attribute is rendered in Query Criteria and table column:

While it works well, it is not working in Query Criteria. The problem is that Query Criteria block is applying true/false for check box, even it is based on Yes-No LOV component in the Model. Then of course, it is trying to query database with true/false values - and result set is empty, because it expects Y or N.

In order to fix this, make sure you have defined Bind Variable for YesNo attribute in View Criteria:

And we need to create View Object Implementation class, where ADF BC executeQuery() method will be overriden:

This method is accessing View Criteria row and retrieving YesNo criteria attribute value. Retrieved value is compared to true and and Bind Variable value is set to Y. Otherwise, if YesNo criteria attribute value is not equal true, we set Bind Variable value to NULL - this will return all rows:

Querying only those rows with Y:

All rows:

Friday, May 21, 2010

Oracle Podcast about Oracle WebCenter Suite 11g Implementation

Learn how Oracle WebCenter Suite provides an out-of-the-box centralized information system for King Khalid University. Hear from Oracle Specialized partner, Red Samurai, as they describe how King Khalid University is using Oracle WebCenter Spaces to create an integrated collaboration platform, where they use Enterprise 2.0 services such as blogs, wikis and discussion forums to share knowledge and communicate with others. You can download it from Oracle Fusion Middleware twitter, or directly.

Oracle OpenWorld 2010 - Developing Large Oracle ADF 11g Applications

My session (S313355 - Developing Large Oracle Application Development Framework 11g Applications) is accepted for Oracle OpenWorld 2010 in San Francisco. This session will be based on customer case from one of my current projects.

Oracle Application Development Framework (ADF) is an end-to-end development framework that offers unparalleled productivity for application developers.

This session will show how data passivation and activation should be managed in large applications and demonstrated different UI Shell templates for separate Oracle ADF applications integration. Based on personal experience from retail industry projects, the speaker will describe how Oracle ADF applications can be tuned for the best runtime performance and show how developers can apply Oracle ADF architecture best practices. There will also be multiple demos about Oracle ADF Task Flows and Libraries usage for application integration and reusability.

Tuesday, May 18, 2010

Differences of Handling JboException in Oracle ADF

Today I will talk more about best practices, not about technical problems. From what I saw, especially new ADF developers, frequently are experiencing problems with handling JboExceptions. Its not about how to throw JboException, but about how to invoke method that throws it.

Download sample application - This sample implements two approaches about how to call custom method from the Model layer. Custom method is simple, it just throws JboException in both cases:

Method that I'm calling from managed bean, is implemented and exposed through Application Module client interface:

It simply throws JboException:

This custom method is declared in Page Definition Bindings, to make it available for the client:

Now most important part of this blog - how we invoke custom method defined in Application Module implementation class:

First function calls custom method correctly - through bindings. In case of JboException in that custom method, framework will raise error popup automatically.

Second function is accessing Application Module Implementation class directly, bypassing bindings layer. In this case, if developer forgets to catch thrown JboException - server error will appear and application will be broken.

So, always call custom methods from Application Module interface through bindings layer.

Sunday, May 16, 2010

Implementing Confirmation Choice List

Today I will tell you, how I was playing with choice list component, when implementing value change confirmation functionality. Requirement is simple - we have Yes, No choice list and when user is changing from No to Yes, we show confirmation screen. If OK is selected by the user, Yes value is accepted. If Cancel was pressed, we need to reset choice list back to No automatically.

Download sample application - This sample implements static View Object with Yes and No values:

There is transient Authorized attribute, it is implemented with Yes, No choice list:

If user selects Yes:

When Yes value is selected, application renders confirmation dialog:

You can see, Yes value is selected in the background. If user click on Cancel button, choice list value is reset back to No:

In other case, if user clicks on OK:

Yes value is accepted:

From development point of view, in order to enable such functionality, you need to set AutoSubmit=true and define ValueChangeListener for choice list attribute. This will allow us to track value change event and raise confirmation popup. Another important thing, choice list should have PartialTrigger from popup component. This means choice list will be refreshed, after popup cancel event:

The main logic is in value change listener method:

The trick is, that we need to change value back to No from popup cancel listener. And, when value is changed in popup cancel listener, framework is recognizing it as second value change event and invoking value change listener method again and again. The main problem is, that in this case - even value change listener is invoked, newValue inside value change listener method is not set correctly to that one assigned in popup cancel listener. We need to enable additional attribute in Page Definition, where we will be able to store value change tracking values - AuthorizedAttr:

You can see, there some magic code implemented in value change listener method. Hope it will be useful, if you will face similar requirement as mine.