Pages

Look into your JVM with VisualVM

If you want some more information about your JVM, for example your integrated WLS. There is a very easy tool to use, it’s called VisualVM. You can download it from visualvm.java.net. Extract the .zip file and run the \bin\visualvm.exe.

Once the application is started, on the left you can pick a running java container, for example under Local your WebLogic. If you want, you can add remote hosts as well:


Selecting one opens an overview:


Now if you click the monitor tab, you can get more info about CPU, memory, classes and threads. Below an example of a memory graph:

Don't persist UIComponent state, now with attributes!

In this blogpost I showed how to disable the persistence of a UIComponent, but it was needed to write Java code to check for the specific component and change. In this blog entry I will show a more generic way to do this, with the attribute tag.

On the showDetailItem we define an attribute with a name and value:

        
        
     

The Java code for the addComponentChange method in the PortalComposerChangeManager now looks like this:
  public void addComponentChange(FacesContext context, UIComponent component,
                                 ComponentChange change)
  {
    Map attrs = component.getAttributes();
    String value = (String) attrs.get(NON_PERSIST_STRING);

    if (value != null)
    {
      logger.fine("NonPersist attribute found, we don't persist!");
      return;
    }
    super.addComponentChange(context, component, change);
  }

I defined a static final NON_PERSIST_STRING with the value "nonPersist", like the name of the attribute. If the attribute is found, we don't persist the componentChange.
If you want a more specific approach, you can still check for a specific ComponentChange, in the case of this example, we still check if the ComponentChange matches the value in the attribute (disclosed):
  public void addComponentChange(FacesContext context, UIComponent component,
                                  ComponentChange change)
  {
    Map attrs = component.getAttributes();
    String value = (String) attrs.get(NON_PERSIST_STRING);

    if (value != null)
    {
      if (change instanceof AttributeComponentChange &&
          value.equals(((AttributeComponentChange) change).getAttributeName()))
      { //we check if the attribute value equals the change.
        logger.fine("{0} attribute found; {1} event on {2}, we don’t persist.", new Object[]
            { NON_PERSIST_STRING, value, component.getClass() });
        return;
      }
    }
    super.addComponentChange(context, component, change);
  }

This code can be expanded or changed to check for specific changes according to your needs.
I uploaded a new workspace here, so you can download and browse the source if you want to.

Support for multiple session timeouts


Our use case was that we needed to support different timeouts for different application roles. This because our internal users are using the same application as our external users. There is no default support for this behavior in ADF, but you can achieve this by using a PagePhaseListener.

In our production application we used different settings, but for this example I configured the following web.xml parameters:
 
    3
  
  
    oracle.adf.view.rich.sessionHandling.WARNING_BEFORE_TIMEOUT
    60
  
The session-timeout is set to 3 minutes and we want to show the default ADF warning popup 1 minute before the session expires. In case of a internal user login, the session-timeout parameter get overridden.
This is achieved by creating a PagePhaseListener:
public class PortalPhaseListener implements PagePhaseListener
{
  private static final int INTERNAL_TIMEOUT = 360;

  public void beforePhase(PagePhaseEvent pagePhaseEvent)
  {
    if (pagePhaseEvent.getPhaseId() == JSFLifecycle.JSF_RESTORE_VIEW_ID)
    {
      final ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
      final SecurityContext secCtx = ADFContext.getCurrent().getSecurityContext();     

      if (secCtx.isAuthenticated() && isInternalUser())
      {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) ectx.getRequest();        
        httpServletRequest.getSession().setMaxInactiveInterval(INTERNAL_TIMEOUT);
      }
    }
  }
}
I decided to do this in the restore view phase, first we check if the user is logged on and if the user has the internal role. If both are true, we set the MaxInactiveInterval on the HttpSession.
Now the timeout becomes 6 minutes, meaning that after 5 minutes the default ADF popup will show, informing the user that the session will expire if no activity is shown within the next minute.

The result is a different session timeout for different user roles, you can do this for as many roles as you like, making your timeout settings more flexible. 

Don’t persist UIComponent state in the session


Our use case was as followed: In our WebCenter Portal application we have a tableform layout, with a panelAccordion on the form layout. For other functionality we needed MDS persistence to be on, so we couldn’t disable MDS customizations. A side effect was that the panelAccordion remembered the showDetailItem that was disclosed and reopened the form page on the previously disclosed tab. 

We have the Seeded Customizations enabled, you can do this through the project properties:
 This results in a web.xml entry:
  
    org.apache.myfaces.trinidad.CHANGE_PERSISTENCE
    oracle.adf.view.page.editor.change.ComposerChangeManager
  
Now we can configure our adf-config file to exclude Persist Changes:

However, this doesn’t help you for your current session. We can see in the JavaDoc from the FilteredPersistenceChangeManager, the following documentation:
If the DocumentChange fails through the restriction, the corresponding ComponentChange is persisted to the Session.

We also don’t want to persist the changes in the session, so we had to subclass the ComposerChangeManager and override the addComponentChange method:
public class PortalComposerChangeManager extends ComposerChangeManager
{
  /**
   * adf-config.xml still persist in session, @see FilteredPersistenceChangeManager
   * We don't want this for the showDetailItem in the RichPanaelAccordion.
   *
   * @param context the FacesContext.
   * @param component the UIComponent.
   * @param change the ComponentChange.
   */
  @Override
  public void addComponentChange(FacesContext context, UIComponent component,
                                 ComponentChange change)
  {
    if (component instanceof RichShowDetailItem &&
        ((RichShowDetailItem) component).getParent() instanceof RichPanelAccordion &&
        change instanceof AttributeComponentChange &&
        "disclosed".equals(((AttributeComponentChange) change).getAttributeName()))
    {
      logger.fine("ComponentChange; disclosed event on showDetailItem in a RichPanelAccordion, we don’t persist.");
      return;
    }
    super.addComponentChange(context, component, change);
  }
}

This method is called by the framework to persist the component change. We override this method and  check if the component is a RichShowDetailItem in a RichPanelAccordion. If the ComponentChange is also a disclosed event, we don't call the super, so this change doesn't persist.

Since I don’t have my Oracle Cloud Trial anymore, I included a workspace, which reproduces this behavior. 
You can see the difference between the two accordions by changing the web.xml parameter. State is saved in session with the default web.xml param:

    Change Persistence Parameter
    org.apache.myfaces.trinidad.CHANGE_PERSISTENCE
    oracle.adf.view.page.editor.change.ComposerChangeManager
  

You can see the panelAccordion resetting to the first showDetailItem when you change to this parameter: 

    Change Persistence Parameter
    org.apache.myfaces.trinidad.CHANGE_PERSISTENCE
    nl.olrichs.blog.panelmds.portal.view.change.PortalComposerChangeManager
  


All you need to do for reproducing is:
  • Click the button toPanelAccordion.
  • Open a different showDetailItem.
  • Click the back button.
  • Click the button toPanelAccordion again.

Full screen mode with panelSplitters

We had a use case in which the input form needed to have a full screen button. This is accomplished with the help of panelSplitters and javascript. In this example I’ll show how you can create a button that will execute javascript to render the input form in full screen. The page looks like this:


We used 3 panelSplitters in the page setup, in the center is the input area, the other area’s are for menus, helptext, etc. On the top of the center area we have a button bar with several buttons including the full screen button. The button has an clientListener on it to call the javascript:



The javascript code is as followed:
function toggleFullScreenMode(actionEvent)
{
   actionEvent.cancel();
   var panelSplitter1 = actionEvent.getSource().findComponent('::ps1');
   var panelSplitter2 = actionEvent.getSource().findComponent('::ps2');
   var panelSplitter3 = actionEvent.getSource().findComponent('::ps3');
             
   var newMode = !panelSplitter1.getCollapsed() || !panelSplitter2.getCollapsed() || !panelSplitter2.getCollapsed();

   panelSplitter1.setCollapsed(newMode);
   panelSplitter2.setCollapsed(newMode);
   panelSplitter3.setCollapsed(newMode);
}

Now if you click the button, all the panelSplitters will collapse, if you click it again, they will show again.


I’m sad to say the Oracle Cloud Trial expired, so no live demo application this time.

Fancy inputsliders through declarative component

In one of our portals the user can use inputsliders to select different values. We made a fancy inputslider that shows not only a label, but also the minimum value and the maximum value allowed.
Next to the slider we have an inputText where the user can decide to type in the value, on this inputText we have a validator that also checks the min an max value.
The result looks like this:

The declarative component has 4 attributes: minval, maxval, value and label.
The code in the component definition is as followed:

      
        
        
          
        
        
          
        
        
          
        
        
        
          
          
        
      
    
The minvalue and maxvalue attributes are used for the labels, the minimum and maximum attribute on the inputNumberSlider and the validator on the inputText. The label attribute is used as label on the panelLabelAndMessage and the value attribute is used as value for the inputNumberSlider.

To illustrate an example of you easy it is to now use this declarative component I created a bean with five properties:
  public SliderBean()
  {
    lowpoint = 1;
    minval = 25;
    maxval = 75;
    highpoint = 100;
    value = 50;
  }

There are 3 sliders based on this properties, the first one to select the minimum value, the second one to select the maximum value and the last one to select a value.
It is very easy to create a slider based on this declarative component, all the code you need for 3 sliders is this:

      
      
      
    

Off course the page / sliders still need skinning, but you can look and play around with this example.

Get your version number from WebLogic


If you want to show the version of your application (for example in your template), you can get this from WebLogic in a bean. If you use the manifest.mf to set the Weblogic-Application-Version property, you can get this number with the help of the ApplicationVersionUtils. It’s in the package weblogic.application.utils:

 ApplicationVersionUtils.getCurrentVersionId();