Tuesday, July 1, 2014

Performance: Filtering Navigation Links in Webcenter Navigation Model

There are two ways to filter navigation links in Webcenter Navigation Model -

1. Resource-Level filtering - This is done by specifying the visible property for a navigation resource which determines whether the resource will be displayed or not at run time. You can also specify EL expression for visible property.



2. Catalog-Level Filtering - This is done by defining the class that implements CatalogDefinitionFilter(oracle.adf.rc.spi.plugin.catalog.CatalogDefinitionFilter).
Implement the api includeInCatalog that takes CatalogElement(Navigation resource) as a parameter. This api called for every resource in NavigationModel. If the api returns true then only resource will be visible in the NavigationModel. So, check the resource id(CatalogElement.getId()) and based on conditions return true or false.

 

Check Oracle Document for more details.

I debugged the code to find out how and when filter conditions are evaluated based on the filtering level.Here are some of the scenarios where we can make it more performant.

Resource Level Filtering


Scenario 1 - 
Visible condition result not changing for a user session

Buseiness Usecase - Based on user type show/hide navigation links. So, on login check the business logic for user type and after that no need to evaluate it again until user logout and new user login.



In Resource Level Filtering visible property is evaluated for each request. So, it's better to call the business logic only once to evaluate the visible condition assuming the visible condition evaluate to same value for a user session.
In this case you can save the result of the visible condition  in session scope variable.Now business logic will be called only once on login and after that it will check the session scope variable.

Implementation :

1. Set the visible property in the navigation model





 2. Create a Managed Bean SessionInfo and register it in adfc-config.xml with session scope.



3. In SessionInfo Bean create a Boolean property financeVisible






Idea here is not to call the logic in getter method of visible property every time. Other way to implement is to set the visible property in the login initialization logic.

Scenario 2 - 
Visible condition result may change based on business logic in a user session.

Business Usecase - For a shopping portal , user can select the departments and on the basis of selected department show/hide some navigation links.

In this case reset the session variable when user select the new department. I found Navigation Model don't refresh even if visible conditions changed. So, refresh the Navigation Model explicitly by invalidating the cache.

Code Snippet to invalidate cache -

SiteStructureContext ctx = SiteStructureContext.getInstance(); 
SiteStructure model = ctx.getDefaultSiteStructure(); 
model.invalidateCache();  
 

Catalog Level Filtering

How and When it is called ? For each navigation resource, CatalogDefinitionFilter.includeInCatalog method is called for every request. 

Scenarios where it can be used

#1 Same visible condition applied to most of the navigation links.

As the includeInCatalog method is called for each resource, it's better to use resource level filtering. But if the same visible condition is used for most of the navigation link then it's better to use Catalog level because in this way code is more readable and mangeable.
For Ex: For a Payments Only User disable all the navigation links except the Payments Page.

Implementation

  public boolean includeInCatalog(CatalogElement catalogElement,
                                  Hashtable hashtable) {
    //Get the user type
    String userType = Util.getUserInfo().getUserType();
    //If user is payment only and the navigation link id is payments page show it
    //otherwise hide it
    if("PaymentsOnly".equals(userType) && catalogElement.getId().equalsIgnoreCase("paymentsPage")){
        return true;

      }
    return false;
  }

No comments:

Post a Comment