Inside WSRP
Pages: 1, 2, 3, 4, 5

Using Backing Files

WebLogic Portal Producer supports the use of backing files on portlets. However, the nature of WSRP and the fact that portlets are remote imposes certain restrictions.

Let's first look at backing files. The purpose of backing files is to implement business logic at certain points in a portlet's invocation cycle. Let's add the following backing file to the search portlet.

public class SearchBacking implements JspBacking
{
    public void init(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
    {
    }

    public boolean handlePostbackData(HttpServletRequest httpRequest, 
        HttpServletResponse httpResponse)
    {
        // Some logic
        return false;
    }

    public boolean preRender(HttpServletRequest httpRequest, 
        HttpServletResponse httpResponse)
    {
        // Some logic
        return true;
    }

    public void dispose() 
    {
    }
}

When you attach a backing file to a local portlet, WebLogic Portal framework invokes all the methods on this class using the same HTTP request and response objects in the following order:

  • init()
  • handlePostbackData()
  • preRender()
  • dispose()

However, when the portlet is deployed on a Producer and invoked via WSRP, WebLogic Portal Producer preserves the lifecycle order but may execute the lifecycle methods using different pairs of HttpServletRequest and HttpServletResponse objects. The methods that the Producer executes depend on the Consumer's request, as listed below:

  • getMarkup: init(), preRender() and dispose()
  • performBlockingAction: init(), handlePostbackData(), and dispose()
  • handleEvents: init(), any event handler method, and dispose()

So, when a Consumer sends a performBlockingRequest, and then sends a getMarkup request to a Producer for a portlet with a backing file, the Producer invokes the backing file methods in the following order:

  • performBlockingInteraction: init(), handlePostbackData(), preRender(), and dispose(). The Producer invokes the preRender() only when it decides to return the portlet's markup as part of performBlockingInteractionResponse.
  • getMarkup: init(), preRender(), and dispose().

If you are monitoring the backing files lifecycle method execution from an end user's point of view, you will notice that some methods are called twice. This difference arises due to the remote nature of the portlet and the WSRP protocol.

Tip: If you are using backing files on a Producer, do not assume that the same HttpServletRequest and HttpServletResponse are used to invoke all backing file lifecycle methods. If your portlets need to carry state from one lifecycle method to another, store such data in the Producer's HTTP session.

Note that backing files used on the remote portlet on the Consumer side do not share these restrictions.

Accessing Portal Framework APIs

Portlets deployed on a WebLogic Portal Producer can access certain portal framework APIs and JSP tags at runtime. Here are some of the most common APIs portlets use.

  • PortletPresentationContext : Portlets can access this context whenever the Producer is rendering a portlet. In the case of the search portlet, the Page Flow can access the PortletPresentationContext during the begin action and in the Page Flow JSPs.

  • PortletBackingContext : Portlets can access this context in actions, backing files, and in JSPs. However, portlets can change window state, mode, and preferences only during action processing. Note that the begin action of Page Flows are executed during rendering and therefore cannot modify window state, mode, or portlet preferences.

These classes do not support any Consumer-specific methods and throw UnsupportedOperationExceptions when invoked. For example, the following code snippet would fail to execute on a Producer.

PortletPresentationContext ctx = 
    PortletPresentationContext.getPortletPresentationContext(httpRequest);
PagePresentationContext pageCtx = 
    ctx.getPagePresentationContext(); // Throws UnsupportedOperationException

In this code snippet, the portlet is trying to access data about the page on the Consumer. Note that the WebLogic Portal Producer does not have access to any of the portal artifacts rendered by the Consumer. If your portlets require access to such information, you can deploy backing files on the Consumer side for remote portlets, where backing files can get access to such portal artifacts.

Tip: It is a good practice to build portlets to be independent of any portal artifacts, including other portlets. By introducing any such dependencies, your portlets remain tightly coupled to the portal and cannot take advantage of the decoupling offered by WSRP. Another reason to avoid depending on portal artifacts is interoperability. Not all Consumer implementations may have the notion of a page.

Portlet Preferences and Registration

The purpose of portlet preferences is to let portlet developers and administrators declaratively associate and manage properties of portlets. You can associate preferences with any portlet using WebLogic Workshop or WebLogic Portal administration tools. In this section, I will only discuss how remote portlets can take advantage of portlet preferences. For more information on what preferences are and how they can be used, refer to the article Portlet Preferences.

In WebLogic Portal's WSRP implementation, the Producer hosts and manages portlet preferences, and allows Consumers to manage those preferences using the Portlet Management interface of WSRP. For instance, if you view/modify portlet preferences of a remote portlet using WebLogic Portal Admin Tools, the Consumer uses the Portlet Management interface to fetch/modify preferences from the Producer. In most cases, portlet developers need not be concerned with using this interface directly. To learn more about this interface, refer to the WSRP 1.0 Primer (see References below).

Another way of viewing/modifying portlet preferences is by using the javax.portlet.PortletPreferences object. Portlets can get an instance of this object either using the Java Portlet API (for JSR 168-compliant portlets), or PortletPresentationContext and PortletBackingContext (for other types of portlets). This object offers methods to access and modify portlet preferences. When a portlet modifies portlet preferences for the first time, WebLogic Portal clones the portlet (therefore creating a new portlet instance), and associates the modified preferences with the cloned instance. However, a WSRP Producer can allow portlets to change preferences only when the Consumer allows such cloning.

If you are using portlet preferences for remote portlets, note the following:

  • Portlets are not allowed to make persistent state changes during rendering. The store() method on the javax.portlet.PortletPreferences throws an IllegalStateException if a portlet calls the store() method during the render phase of a portlet (that is, during the execution of the getMarkup operation).

  • If you are using a remote portlet via a file-based portal (that is, via a .portal file), or if the user accessing the portlet is anonymous, WebLogic Portal Consumer does not allow any kind of customization, including changes to portlet preferences. To indicate that Producers should not allow portlets to modify preferences, the Consumer sends a value of readOnly for the portletStateChange element in the performBlockingInteraction request.

  • If the instance of a remote portlet is shared among several users, WebLogic Portal Consumer sends a value of cloneBeforeWrite for the portletStateChange element. This value indicates to the Producer that it must clone the portlet before making changes to preferences. If a portlet does indeed modify preferences, the Producer returns a new portletHandle to the Consumer. This new portletHandle replaces the original portletHandle.

  • On subsequent requests, the Consumer sends a value of readWrite indicating that the Producer can allow portlets to modify preferences.

As you can see from this list, Producers can create new portlet instances when portlets modify portlet preferences. As more and more users from different Consumers begin to customize portlets by modifying portlet preferences, the Producer may end up creating several portlet instances. What happens if the Consumer suddenly decides not use the Producer? The instances will remain forever on the Producer. In order to prevent this, you can use the registration interface.

WSRP 1.0 specifies a registration interface to allow Consumers to register with Producers. Although the WSRP 1.0 Specification does not speculate on possible use cases for using registration, it does set certain rules on how Consumers and Producers should behave when a Producer supports registration. The registration interface includes three operations:

  • register(), to allow Consumers to register with the Producer
  • modifyRegistration(), to allow Consumers to modify an existing registration
  • deregister(), to allow Consumers to terminate a registration

Tip: If your portlets use portlet preferences, consider keeping Portlet Management and Registration interfaces enabled. These two interfaces are enabled by default for complex producers. If your portlets do not use portlet preferences, you can disable these two interfaces. Refer to WebLogic Portal documentation for configuration details.

When a Producer supports registration, Consumers must register with the Producer before accessing any portlets. Once registered, the Producer returns a registrationHandle to the Consumer. The Consumer is then required to supply this handle on all future requests until deregistration.

When the WebLogic Portal Producer is set up to require registration, it stores INSTANCE_IDs of cloned portlets against the Consumer's registrationHandle. Therefore, the Producer keeps track of which Consumer caused the creation of which portlet instance. When a Consumer sends a deregister() request, the Producer removes all the instances created for that Consumer.

Note that other WSRP Producer implementations may or may not support the notion of portlet preferences.

Summary

My primary goal in this article was to provide insight into some key concepts and implementation details of WSRP support in WebLogic Portal. When you are building portlets, consider following the guidelines listed in this article. These guidelines will ensure that your portlets will be more WSRP-friendly.

This is by no means an exhaustive coverage of WSRP or its implementation. Refer to the list of references at the end of this article to learn more about WSRP and using WSRP with WebLogic Portal.

Acknowledgements

I would like to thank Adam Bruce and Nathan Lipke for their review and comments.

References

Subbu Allamaraju is the driver behind portal federation, and in recent years, focusing on portal-related standards such as JSR286, JSR301 and WSRP.