JSP Portlet Actions

JSP Portlet Actions are Java classes, they are where you put your controlling logic for your code. Here you will do any backend processing necessary to retrieve or store dynamic information, and then populate the JSP request attributes with your model so that the template may display the dynamic content.

First, let?s look at the code for the TutorialStockQuoteAction8. This portlet retrieves stock quotes from a web service. There is only one method in this JSP portlet action, the buildNormalContext method. The StockQuoteService comes with the Jetspeed deployment. It returns an array of StockQuote objects when you ask for a quote on a array of stock symbols.


public class TutorialStockQuoteAction8 extends JspPortletAction
{
    private static final String SYMBOLS = "symbols";
    private static final String COLUMNS = "columns";
    private static final String QUOTES = "quotes";
    private static final String[] ALL_COLUMNS = {"Symbol","Price","Change","Volume"};

 
    /**
     * Build the normal state content for this portlet.
     *
     * @param portlet The jsp-based portlet that is being built.
     * @param rundata The turbine rundata context for this request.
     */
    protected void buildNormalContext(Portlet portlet,
                                      RunData rundata)
    {
        try
        {
            // Get reference to stock quote web service
            StockQuoteService service = (StockQuoteService) TurbineServices.getInstance().
                getService(StockQuoteService.SERVICE_NAME);

            // Retrieve portlet parameters
            String symbols = (String) PortletSessionState.getAttributeWithFallback(portlet, rundata, SYMBOLS);

            // Request stock quote(s) from the stock quote web service
            String[] symbolArray = StringUtils.stringToArray(symbols, ",");
            StockQuote[] quotes = service.fullQuotes(symbolArray);           

            // Place appropriate objects in jsp context
            rundata.getRequest().setAttribute(QUOTES, quotes);
            rundata.getRequest().setAttribute(COLUMNS, ALL_COLUMNS);
        }
        catch (Exception e)
        {
            Log.error(e);
        }
    }
}


The above example is very similar to the one used in Tutorial 7 with the exception that it allows the user to temporarily specify stock quote symbols without having to customize. Note that the symbols are retrieved by the portlet action as follows:


String symbols = (String) PortletSessionState.getAttributeWithFallback(portlet, rundata, SYMBOLS);

The above method call retrieves value of the symbols parameter using the following algorithm:

  • 1. If the parameter is present in the request, get it from there and store it in the session, otherwise,
  • 2. If the parameter is present in the session, get it from the session, otherwise,
  • 3. If the parameter is present in portlet instance attributes (values defined for the portlet in user psml), get it from there, otherwise,
  • 4. Get if from the portlet configuration (values defined for the portlet in registry)

So when the user "overrides" the stock symbols using the input field provided within the body of the portlet, the portlet will temporarily display stock quotes for those symbols until:

  • 1. The user logs of and logs back in
  • 2. The user clicks the ?Get Quotes? button with empty input field
  • 3. The user customizes the portlet

Now, let?s take a closer look at the JspPortletAction class, and see how the processAction phase is nicely handled for you by inheriting from this class. There are three important methods than you can implement in your velocity action. Remember from section 6.2 on the Portlet Life Cycle, the processAction phase occurs before the render phase. So the following methods will be called before the template is processed, allowing for you to cleanly populate the JSP request attributes first, depending on the portlet mode.

MethodPortlet Mode
BuildNormalContextView
buildConfigureContextCustomize (Edit)
buildMaximizedContentMaximize

Using this approach you can easily customize your portlet to generate different content depending on the mode of the request. Often, the maximize content is the same as the normal context. In the default implementation of buildConfigureContext, the normal context is called. You can override this method to specially handle maximize mode. The buildConfigureContext is available if you want to provide your own customization as we will do further on in this chapter. To go with the default portal customizer provided by Jetspeed, just don?t override this method.