Velocity Portlet Actions

Velocity 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 Velocity context 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 Velocity 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 TutorialStockQuoteAction1 extends VelocityPortletAction
{
    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"};
 
protected void buildNormalContext(VelocityPortlet portlet,
                                       Context context,
                                       RunData rundata)
    {
        try
        {
            // Get reference to stock quote web service
            StockQuoteService service = (StockQuoteService)
                  TurbineServices.getInstance().
                      getService(StockQuoteService.SERVICE_NAME);
 
            // Retrieve portlet parameters
            String symbols = PortletConfigState.getParameter(portlet,
                    rundata, SYMBOLS, "IBM,MSFT,ORCL,SUNW");
 
            // Request stock quote(s) from the stock quote web service
            String[] symbolArray = StringUtils.stringToArray(
                                                symbols, ",");
            StockQuote[] quotes = service.fullQuotes(symbolArray);           
 
            // Place appropriate objects in Velocity context
            context.put(QUOTES, quotes);
            context.put(COLUMNS, ALL_COLUMNS);
        }
        catch (Exception e)
        {
            Log.error(e);
        }
    }

The array of stock quotes is put in the context and is made available to the template. The template can then pull out the stock records that it needs, iterating over the array of stock quotes:


        #foreach ($quote in $quotes)
        <tr>
          #entryCell ($quote.Symbol)
          #entryCell ($quote.Price)
          #entryCell ($quote.Change)
          #entryCell ($quote.Volume)
        </tr>
        #end

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

Let?s take a closer look at the VelocityPortletAction 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.