Parameter Styles Architecture

Parameter styles have been implemented using the Turbine module mechanism. For those of you not familiar with Turbine, modules are webapp resources (screens, actions, layouts, navigations, etc) which may be loaded dynamically based on a predefined module search path.

A Portlet parameter is defined in a registry entry as having a custom presentation style by setting its type attribute to "style" and then adding parameter-style tag to define the style name and any style options.

Popup Calendar Date Style

In the example below, we have a widget named "date" whose style is "PopupCalendar", and the style format string is "mm/dd/yyyy".

<parameter name="date" value="" type="style" hidden="false">
    <meta-info>
        <title>Date</title>
        <description>Date with popup calendar. Format pattern: mm/dd/yyyy
        </description>
    </meta-info>
    <parameter-style name="PopupCalendar">
        <style-option name="format" value="mmm-d-yyyy"/>
    </parameter-style>
</parameter>

Velocity Parameter Style

In the example below, we have a widget named "password" whose style is "VelocityParameterPresentationStyle". This is a very flexible parameter style, which allows you to reuse a velocity template to format the presentation of your widget. Alternatively, you could skip the template attribute and set the name to "Password.vm" which would automatically default to VelocityParameterPResentationStyle. Velocity Parameter Style templates should be placed in the Jetspeed deployment under /WEB-INF/templates/vm/parameters/html (for HTML portlets). Similarly, WML portlets would be found under /WEB-INF/templates/vm/parameters/wml. The resolution of portlet templates is based on several configuration files and a resolution algorithm. See the section on Template Resolution for more details.

<parameter name="password" value="secret" type="style" hidden="false">
	<parameter-style name="VelocityParameterPresentationStyle" template="Password.vm"/>
</parameter>
Velocity Parameter Style

JSP Parameter Style

In the example below, we have a widget named "password" whose style is "JSPParameterPresentationStyle". This is a very flexible parameter style, which allows you to reuse a JSP template to format the presentation of your widget. JSP Parameter Style templates should be placed in the Jetspeed deployment under /WEB-INF/templates/jsp/parameters/html (for HTML portlets). Similarly, WML portlets would be found under /WEB-INF/templates/jsp/parameters/wml. The resolution of portlet templates is based on several configuration files and a resolution algorithm. See the section on Template Resolution for more details.

<parameter name="password" value="secret" type="style" hidden="false">
	<parameter-style name="JspParameterPresentationStyle" template="Password.jsp"/>
</parameter>
JSP Parameter Style

Stock Quote Example

## InputWithHelp.vm
#set ($src = $parms.get("src")) ## Retrieve the "src" parameter from the $parms map
<input type="text" name="$name" value="$value" size="30" disabled>
<img src="$src" alt="Info" #foreach($event in $events.keySet()) $event="$events.get($event)"#end>

<parameter name="about" value="About Bluesunrise Stock Quote Web Service" type="style" hidden="false">
			<parameter-style name="InputWithHelp.vm">
				<style-option name="src" value="images/info.gif"/>
				<style-option name="javascript.onclick" value="alert('For additional info on the stock quote web service contact info@bluesunrise')"/>
			</parameter-style>
</parameter>

package com.bluesunrise.jportal.modules.actions.portlets;

// Turbine stuff
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
import org.apache.turbine.services.TurbineServices;

// Velocity Stuff
import org.apache.velocity.context.Context;

// Jetspeed stuff
import org.apache.jetspeed.portal.portlets.VelocityPortlet;
import org.apache.jetspeed.webservices.finance.stockmarket.StockQuoteService;
import org.apache.jetspeed.webservices.finance.stockmarket.StockQuote;
import org.apache.jetspeed.util.PortletConfigState;
import org.apache.jetspeed.util.StringUtils;

/**
 * This action sets up the template context for retrieving stock quotes.
 *
 */

public class TutorialStockQuoteAction extends VelocityPortletAction
{
private static final String SYMBOLS = "symbols";
private static final String COLUMNS = "columns";
private static final String SORT = "sort";
private static final String QUOTES = "quotes";
private static final String[] ALL_COLUMNS = {"Symbol","Price","Change","Volume"};
private static final String SELECTED_COLUMNS = "selected-columns";1

/**
 * Build the normal state content for this portlet.
 *
 * @param portlet The velocity-based portlet that is being built.
 * @param context The velocity context for this request.
 * @param rundata The turbine rundata context for this request.
 */

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");
       String columns = PortletConfigState.getParameter(portlet, rundata, COLUMNS, StringUtils.arrayToString(ALL_COLUMNS, ","));2
       String[] selectedColumnsArray = StringUtils.stringToArray(columns, ",");3
       String sort = PortletConfigState.getParameter(portlet, rundata, SYMBOLS, "Symbol");4

        // 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(SELECTED_COLUMNS, selectedColumnsArray);5
       context.put(COLUMNS, columns);6
    }
    catch (Exception e)
    {
        Log.error(e);
    }
}

So far the changes are related to stock quote column selection:

  • 1. The SELECTED_COLUMN will be placed in the Velocity context as list of selected column headings.
  • 2. The columns variable will hold user customized value of columns selected for display. Please note the usage of PortletConfigState.getParameter() method to retrieve the value of COLUMNS from user's PSML.
  • 3. Here we convert columns which is in a comma-delimited format to a string array selectedColumnsArray.
  • 4. For the sake of example, we can also retrieve a custom sort setting. We will not be implementing the actual sort though.
  • 5. The selectedColumnsArray is placed in the Velocity context so the template can use it as headings.
  • 6. The columns is placed in the Velocity context so the template can determine which stock quote fields to dsiplay.

Next, here's a modified Velocity template tutorial-stock-quote.vm used to display the stock quotes:

## tutorial-stock-quote.vm
<table>
    <tr>
        <td>
            <table border="true" cellspacing="1" cellpadding="3">
                <tr>
                    #foreach ($column in $selected-columns)
                        #headerCell ($column)
                    #end
                </tr>

                #foreach ($quote in $quotes)
                <tr>
                    #if ($columns.indexOf("Symbol") >= 0) #entryCell ($quote.Symbol) #end
                    #if ($columns.indexOf("Price") >= 0) #entryCell ($quote.Price) #end
                    #if ($columns.indexOf("Change") >= 0) #entryCell ($quote.Change) #end
                    #if ($columns.indexOf("Volume") >= 0) #entryCell ($quote.Volume) #end
                </tr>
                #end
            </table>
        </td>
    </tr>
</table>

<portlet-entry name="TutorialStockQuote" hidden="false" type="ref" parent="Velocity" application="false">
    <meta-info>
        <title>Tutorial Stock Portfolio with parameter styles</title>
        <description>Tutorial Stock Portfolio Portlet with parameter styles</description>
    </meta-info>
    <parameter name="template" value="tutorial-stock-quote2" hidden="true"/>
    <parameter name="action" value="portlets.TutorialStockQuoteAction2" hidden="true"/>
    <parameter name="sort" value="Symbol" type="style" hidden="false" cachedOnName="true" cachedOnValue="true">
        <meta-info>
            <title>Sort</title>
	       <description>Column to sort by</description>
        </meta-info>
        <parameter-style name="ListBox">
            <style-option name="items" value="Symbol,Volume,PChange"/>
        </parameter-style>
    </parameter>
    <parameter name="columns" value="Symbol,Quote,Date,Time,Change,PChange,Open,High,Low,Volume" type="style" hidden="false" cachedOnName="true" cachedOnValue="true">
        <meta-info>
            <title>Columns</title>
            <description>Columns to display</description>
        </meta-info>
        <parameter-style name="CheckBoxGroup">
            <style-option name="items" value="Symbol,Quote,Date,Time,Change,PChange,Open,High,Low,Volume"/>
            <style-option name="layout" value="$eastwest"/>
        </parameter-style>
    </parameter>
    <parameter name="symbols" value="MSFT,ORCL,SUNW,EMC,INTU" type="style" hidden="false" cachedOnName="true" cachedOnValue="true">
        <meta-info>
            <title>Symbols</title>
            <description>List of comma-separated stock symbols</description>
        </meta-info>
        <parameter-style name="TextArea"/>
    </parameter>
    <parameter name="About" value="About Stock Quote Web Service" type="style" hidden="false">
        <parameter-style name="InputWithHelp.vm">
            <style-option name="src" value="images/info.gif"/>
            <style-option name="javascript:onclick" value="alert('For additional contact info@bluesunrise.com')"/>
        </parameter-style>
    </parameter>
    <media-type ref="html"/>
    <category group="Jetspeed">tutorial</category>
</portlet-entry>