Oracle9iAS Portal Developer Kit
Adding Parameters and Events to Portlets

PDK Release 2 (9.0.2 and later)

Oracle9iAS Portal and the PDK introduce several new concepts - page parameters, public portlet parameters and events - that enable portlet developers to easily write reusable, complex portlets. In this document, portlet developers will learn how to create and use public portlet parameters, portlet events , and private portlet parameters. For a discussion of the fundamental concepts behind parameters and events in Oracle9iAS Portal review the article, A Primer on Portlet Parameters and Events.

The examples in this article demonstrate how to construct the declarations required in provider.xml and the code required in the implementation .jsp files. Note that adding declarations to provider.xml will not automatically generate corresponding .jsp code nor will using the PDK APIs generate entries in provider.xml - the portlet developer must add directly any modifications to the portlet declaration and implementation.

Adding public Portlet Parameters

Adding public portlet parameters involves two steps - adding the public portlet parameter definitions to provider.xml and then making use of the public portlet parameters in the implementation file.

Portlet Declaration - provider.xml

The inputParameter element is used to define public portlet parameters and has the following associated data

- class - required, Java class that manages the public portlet parameter definition, typically oracle.portal.provider.v2.DefaultParameterDefinition.
- name - required, unique within the portlet, and must contain only letters, numbers, and underscores.
- displayName - optional, name displayed to the page designer when wiring page parameters to public portlet parameters.
- description - optional, description of the public portlet parameter.

Each inputParameter is a simple, independent declaration that does not reference any other element in provider.xml nor is referenced by any other such element.

The highlighted section in the following excerpt from the PDK Sample Event Web Provider’s provider.xml declares public portlet parameters for the Public Parameter Portlet:

    <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">

      <id>1</id>

      <name>PublicParameterPortlet</name>

      <title>Public Parameter Portlet</title>

      <description>This is a portlet that declares public portlet parameters.</description>

      <acceptContentType>text/html</acceptContentType>

      <acceptContentType>text/vnd.oracle.mobilexml</acceptContentType>

      <inputParameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

        <name>param1</name>

        <displayName>Input Parameter #1</displayName>

        <description>This is public portlet parameter #1</description>

      </inputParameter>

      <inputParameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

        <name>param2</name>

        <displayName>Input Parameter #2</displayName>

        <description>This is public portlet parameter #2</description>

      </inputParameter>

      ...

    </portlet>

Portlet Implementation

Public portlet parameters are read-only inputs to the portlet. Each public portlet parameter may have zero, one, or many values. Zero values means the public portlet parameter was not mapped by the page designer. When mapped to a page parameter, a public portlet parameter will take on all the values of the page parameter. When mapped to a system or constant value the public portlet parameter will have only one value.

The following code is taken from publicparam.jsp, the implementation file for the Public Parameter Portlet from the PDK Sample Event Web Provider. A table is created that contains all the values for the two public portlet parameters, param1 and param2.
Note the following methods used in this example:

- PortletRenderRequest.getParameterValues retrieves an array of string values given a name.

    <%@page import = "oracle.portal.provider.v2.render.PortletRenderRequest,

                      oracle.portal.provider.v2.http.HttpCommonConstants"

    %>

    <table border=1>

      <tr>

        <th align=left>Parameter Name</th>

        <th align=left>Value</th>

      </tr>

    <%

    PortletRenderRequest portletRequest =

       (PortletRenderRequest)request.getAttribute(HttpCommonConstants.PORTLET_RENDER_REQUEST);

    // The public portlet parameters declared in provider.xml are "param1" and "param2"

    String[] names = { "param1", "param2" };

    // Display values for each of the public portlet

    // parameters "param1" and "param2"

    for ( int i = 0; i < 2; i++ )

    {

      // Get the public portlet parameter values

      String[] values = portletRequest.getParameterValues(names[i]);

      // Display the parameter's values.

      // Each portlet parameter can have 0, 1, or multiple values.

      if ( values == null )

      {

        // Null array indicates no values for this parameter.

    %>

        <tr>

          <td><%= names[i] %></td>

          <td>No values have been submitted yet.</td>

        </tr>

    <%

      }

      else

      {

        // Loop through each of the values and display non-null values on a separate line.

        for ( int j = 0; (values != null) && (j < values.length); j++ )

        {

    %>

          <tr>

            <td><%= names[i] %></td>

            <td><%= values[j] %></td>

          </tr>

    <%

        }

      }

    }

    %>

    </table>

Making a Generic Public Parameter Receiving Portlet

In the previous example, the Public Parameter Portlet looked up public portlet parameter values using specific names. A more generic way to implement a portlet would be to retrieve all the parameter values passed to a portlet and then to filter out parameters by name.

The following example uses the following methods :

- portletRequest.getPortletDefinition returns a portlet definition object.

- portlet.getInputParameters fetches an array containing all of the portlet's public parameters.

    <%@page import = "oracle.portal.provider.v2.render.PortletRenderRequest,

                      oracle.portal.provider.v2.http.HttpCommonConstants"

    %>

    <table border=1>

      <tr>

        <th align=left>Parameter Name</th>

        <th align=left>Value</th>

      </tr>

    <%

    PortletRenderRequest portletRequest =

       (PortletRenderRequest)request.getAttribute(HttpCommonConstants.PORTLET_RENDER_REQUEST);

    // Get the portlet definition - needed to get the public portlet parameters

    PortletDefinition portlet = portletRequest.getPortletDefinition();

    // Get the public portlet parameters

    ParameterDefinition[] parameters = portlet.getInputParameters();

    // Display all values for each of the public portlet parameters

    for (int currParameter = 0; currParmaeter < parameters.length; currParameter++)

    {

      String name = parameters[currParameter].getName();

      // Get the parameter values

      String[] values = portletRequest.getParameterValues(name);

      // Display the parameter's values.

      if ( values == null )

      {

        // Null array indicates no values for this parameter.

    %>

        <tr>

          <td><%= names[i] %></td>

          <td>No values have been submitted yet.</td>

        </tr>

    <%

      }

      else

      {

        // Loop through each of the values and display non-null values on a separate line.

        for ( int j = 0; (values != null) && (j < values.length); j++ )

        {

    %>

          <tr>

            <td><%= names[i] %></td>

            <td><%= values[j] %></td>

          </tr>

    <%

        }

      }

    }

    %>

    </table>

Adding Events and Event Parameters

Adding events and event parameters involves two steps - adding the event and event parameter definitions to provider.xml and then making use of them in the implementation file.

Portlet Declaration - Provider.xml

The event element is used to define portlet public parameters and has the following associated data

- class - Java class that manages the event definition, typically oracle.portal.provider.v2.DefaultEventDefinition.

- name - required, unique within the portlet, and must contain only letters, numbers, and underscores.

- displayName - optional, name displayed to the page designer.

- description - optional, description of the event.

Each event is a simple, independent declaration that does not reference any other element in provider.xml nor is referenced by any other such element.

Event parameters are very similar in syntax to public portlet parameters with the only difference being that the element is named parameter instead of inputParameter and each parameter element is nested within an owning event element.

The highlighted section in the following excerpt from the PDK Sample Event Web Provider ‘s provider.xml declares events and event parameters for the Event and Parameter Form Portlet:

    <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">

      <id>2</id>

      <name>EventParameterForm</name>

      <title>Event and Parameter Form Portlet</title>

      <shortTitle>Event Parameter Form</shortTitle>

      <description>This portlet demonstrates both how to receive data using public portlet

        parameters and how to use a portlet event and event parameters to send data to a

        page.

      </description>

      ...

      <inputParameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

        <name>Name</name>

        <displayName>Name</displayName>

        <description>User name</description>

      </inputParameter>

      <inputParameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

        <name>Age</name>

        <displayName>Age</displayName>

        <description>User age</description>

      </inputParameter>

      <event class="oracle.portal.provider.v2.DefaultEventDefinition">

        <name>submit</name>

        <description>Use this event to submit the form data to a page</description>

        <parameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

          <name>name</name>

          <displayName>name</displayName>

          <description>Name entered in portlet form</description>

        </parameter>

        <parameter class="oracle.portal.provider.v2.DefaultParameterDefinition">

          <name>age</name>

          <displayName>age</displayName>

          <description>Age entered in portlet form</description>

        </parameter>

      </event>

      <event class="oracle.portal.provider.v2.DefaultEventDefinition">

        <name>cancel</name>

        <description>Use this event to handle cancellation while filling

          out a form</description>

      </event>

        ...

    </portlet>

Portlet Implementation

The following code was extracted from eventform.jsp, the implementation file for the Event and Parameter Portlet from the PDK Sample Event Web Provider. This example demonstrates setting up a form that can fire two events with one of the events having two event parameters.

In this example, a form is built up that has two input fields - name and age. There are two ways to submit the form - pressing one of the Submit or Cancel buttons. Pressing Submit causes the event parameters name and age to take on the values entered into the text fields. Pressing Cancel means that the values entered into the text fields will be lost because there are no event parameters declared for Cancel.

Note the following methods used in this example:

- EventUtils.eventName is used to construct a URL parameter representing the event name.

- EventUtils.eventParameterName is used to construct a URL parameter representing the event parameter name.

- HttpPortletRendererUtil.htmlFormActionLink is used to construct the form action URL. The constant request,PortletRendererUtil.EVENT_LINK indicates that this navigation makes use of portlet events and is not a simple navigation.

- HttpPortletRendererUtil.htmlFormHiddenFields is used to pass system information to Oracle Portal.

    <%@page import="oracle.portal.provider.v2.render.PortletRendererUtil,

                    oracle.portal.provider.v2.render.http.HttpPortletRendererUtil,

                    oracle.portal.provider.v2.event.EventUtils"

    %>

    <%

    // The portlet definition in provider.xml includes the following:

    //    - Portlet parameters "Name" and "Age"

    //    - Event "submit" with event parameters "name" and "age"

    //    - Event "cancel" with no event parameters

    //

    // Note that event and parameter names are case sensitive.

    String eventSubmit    = EventUtils.eventName("submit");

    String eventParamName = EventUtils.eventParameter("name");

    String eventParamAge  = EventUtils.eventParameter("age");

    String eventCancel    = EventUtils.eventName("cancel");

    %>

    This portlet shows how to use portlet events and portlet event parameters

    to send data to a page and how to use public portlet parameters

    to receive page parameter values.

    <!--

      -- Associate the action URL with the form’s action attribute

      -->

    <form method="POST" action="<%= HttpPortletRendererUtil.htmlFormActionLink(request, PortletRendererUtil.EVENT_LINK) %

    >">

    <!--

      -- Oracle Portal uses hidden form fields to pass system information top itself

      -- when a page is redisplayed through a link.

      -->

    <%= HttpPortletRendererUtil.htmlFormHiddenFields(request, PortletRendererUtil.EVENT_LINK) %>

    <table>

      <tr>

        <td> <b>Name :</b> </td>

        <td>

                <input type="text" size="20" name="<%= eventParamName %>" value="">

        </td>

      </tr>

      <tr>

        <td> <b>Age : </b> </td>

        <td>

          <input type="text" size="3" name="<%= eventParamAge %>" value="">

        </td>

      </tr>

    </table>

    <INPUT TYPE=submit name="<%= eventSubmit %>" Value="Submit">

    <INPUT TYPE=submit name="<%= eventCancel %>"  Value="Cancel">

    </form>

Simple links can be also be used for firing portlet events as demonstrated in the following alternative implementation for eventform.jsp. In this example, the event parameters cannot be entered by the user since there is no HTML form. Instead, the event parameters name and age are assigned a page parameter value and a constant value, respectively.

Note the following method used in the implementation

- NameValuePair is used to construct a name/value pair of strings .

- PortletRenderRequest.getRenderContext().getEventURL returns the base URL that must be used to construct an event link.

- PortletRendererUtil.constructLink returns the complete URL required to fire an event including both the base URL and any specified event parameters.

    <%@page import="oracle.portal.provider.v2.render.PortletRenderRequest,

                      oracle.portal.provider.v2.http.HttpCommonConstants,

                      oracle.portal.provider.v2.render.PortletRendererUtil,

                    oracle.portal.provider.v2.event.EventUtils,

                    oracle.portal.utils.v2.NameValuePair"

    %>

    <%

    PortletRenderRequest portletRequest =

      (PortletRenderRequest)request.getAttribute(HttpCommonConstants.PORTLET_RENDER_REQUEST);

    //

    // The portlet definition in provider.xml includes the following:

    // - Portlet parameters "Name" and "Age"

    // - Event "submit" with event parameters "name" and "age"

    // - Event "cancel" with no event parameters

    //

    // Note that event and parameter names are case sensitive.

    //

    String eventSubmit = EventUtils.eventName("submit");

    String eventParamName = EventUtils.eventParameter("name");

    String eventParamAge = EventUtils.eventParameter("age");

    String eventCancel = EventUtils.eventName("cancel");

    // Build up the list of parameters for the "submit" event

    NameValuePair[] eventSubmitParams = new NameValuePair[3];

    // Give the 'name' event parameter the value of the page parameter 'Name'

    if (request.getParameter("Name") == null)

    {

      eventSubmitParams[0] = new NameValuePair(eventParamName, "");

    }

    else

    {

      eventSubmitParams[0] = new NameValuePair(eventParamName, request.getParameter("Name"));

    }

    // Give the 'age' event parameter the constant value '23'

    eventSubmitParams[1] = new NameValuePair(eventParamAge, "23");

    // The event name must be passed as a parameter on the URL

    eventSubmitParams[2] = new NameValuePair(eventSubmit, "");

    // Build up an empty list of parameters for the "cancel" event

    NameValuePair[] eventCancelParams = new NameValuePair[1];

    // The event name must be passed as a parameter on the URL

    eventCancelParams[0] = new NameValuePair(eventCancel, "");

    %>

    This portlet shows how to use portlet events and portlet event parameters

    to send data to a page and how to use public portlet parameters

    to receive page parameter values.

    <a href="<%=PortletRendererUtil.constructLink(portletRequest,

      portletRequest.getRenderContext().getEventURL(), eventSubmitParams, true, true)%>">

    Fire the 'submit' event by clicking on this link

    </a>

    <br>

    <a href="<%=PortletRendererUtil.constructLink(portletRequest,

      portletRequest.getRenderContext().getEventURL(), eventCancelParams, true, true)%>">

    Fire the 'cancel' event by clicking on this link

    </a>

    <br>

Setting the passAllUrlParams Flag

The default behavior in previous versions of Oracle9iAS Portal was for all URL parameters to be passed to all portlets. However, with Oracle9iAS Portal, the default behavior has changed so that a portlet only receives its own public portlet parameters, its own private portlet parameters stripped of any qualification prefix, and the PDK system parameters. The passAllUrlParams flag was added to Oracle9iAS Portal to simplify migration of portlets built using previous versions of Oracle9iAS Portal.

When the value true is specified for the passAllUrlParamselement in a portlet’s declaration in provider.xml, the old style behavior of parameter passing will be performed for that particular portlet - it will receive all URL parameters. The following sample demonstrates how to add this flag to a portlet declaration in provider.xml, in this case the Public Parameter Portlet.

    <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">

      <id>1</id>

      <name>PublicParameterPortlet</name>

      <title>Public Parameter Portlet</title>

      <description>This is a portlet that declares public portlet parameters.</description>

      <passAllUrlParams>true</passAllUrlParams>

    ...

    </portlet>

Review the article, A Primer on Portlet Parameters and Events for more discussion of the passAllUrlParams flag and selective passing of parameters to portlets.

Adding Persistent Private Portlet Parameters

Private portlet parameters are by portlet developers to either maintain state for a portlet, using persistent private portlet parameters, or to enable one-time-only portlet actions, using transient private portlet parameters.

Private portlet parameters are created and used solely in the implementation file. Thus, they do not appear in provider.xml and are not available to the page designer.

The following code example demonstrates how to implement the Record Viewer Portlet that is used as an example in the article, A Primer on Portlet Parameters and Events. In this example, one piece of persistent state information, the current record number, is passed to the portlet when a page is redisplayed. The current record number will be incremented or decremented depending on whether the user presses the Next or the Previous button.

The current record numberis maintained as state by using a qualified private portlet parameterbecause qualified private portlet parameters are preserved when following a link or submitting a form back to the same page (for more discussion of preservation of parameters review the article, A Primer on Portlet Parameters and Events). The qualified private portlet parameter is read in when the page is displayed and is assigned a value each time the form is submitted. Qualified private portlet parameters also solve the problem of name conflicts of private portlet parameters that may occur when using multiple instances of a portlet on a page or instances of different portlets that use the same private portlet parameter name.

Note the following methods used in this example:

- HttpPortletRendererUtil.portletParameter is used to construct a qualified private portlet parameter name to be passed on the form action URL.

- HttpPortletRendererUtil.htmlFormActionLink is used to construct the form action URL. The constant request,PortletRendererUtil.PAGE_LINK indicates that this is a simple navigation back to the same page and does not involve portlet events.

- HttpPortletRendererUtil.htmlFormHiddenFields is used to render system information required by Oracle Portal.

- PortletRenderRequest.getQualifiedParameter is used to get the value of a qualified private portlet parameter given an unqualified name.

    <%@page import="java.util.*, oracle.portal.provider.v2.*" %>

    <%@page import="oracle.portal.provider.v2.http.HttpCommonConstants" %>

    <%@page import="oracle.portal.provider.v2.render.PortletRendererUtil" %>

    <%@page import="oracle.portal.provider.v2.render.PortletRenderRequest" %>

    <%@page import="oracle.portal.provider.v2.render.http.HttpPortletRendererUtil" %>

    <%@ page import="oracle.portal.utils.v2.NameValuePair" %>

    <%

      String textCurrRecord  = "currRecord";

      String paramCurrRecord =

        HttpPortletRendererUtil.portletParameter(request, textCurrRecord);

      PortletRenderRequest portletRequest = (PortletRenderRequest)

        request.getAttribute(HttpCommonConstants.PORTLET_RENDER_REQUEST);

      // Retrieve the current record number passed to the portlet

      int currRecord;

      String submittedCurrRecord = portletRequest.getQualifiedParameter(textCurrRecord);

      if (submittedCurrRecord == null)

      {

        currRecord = 1;

      }

      else

      {

        try

        {

          currRecord = Integer.valueOf(submittedCurrRecord).intValue();

        }

        catch (NumberFormatException e)

        {

          currRecord = 1;

        }

      }

      // Calculate the previous and next values

      int prevRecord = currRecord - 1;

      if (prevRecord < 1)

      {

        prevRecord = 1;

      }

      int nextRecord = currRecord + 1;

    %>

    <b>This portlet shows how to use qualified, persistent

    private parameters to maintain portlet state.</b>

    <br><br>

    <b>Current record: <%=currRecord%></b>

    // The first form handles the previous action

    <form method="POST" action="<%= HttpPortletRendererUtil.htmlFormActionLink(

          request,PortletRendererUtil.PAGE_LINK) %>">

      <%= HttpPortletRendererUtil.htmlFormHiddenFields(

          request,PortletRendererUtil.PAGE_LINK) %>

      <INPUT TYPE="hidden" name="<%=paramCurrRecord%>" value="<%=prevRecord%>" />

      <INPUT TYPE=submit name="Previous" Value="Previous">

    </form>

    // The second form handles the next action

    <form method="POST" action="<%= HttpPortletRendererUtil.htmlFormActionLink(

          request,PortletRendererUtil.PAGE_LINK) %>">

      <%= HttpPortletRendererUtil.htmlFormHiddenFields(

          request,PortletRendererUtil.PAGE_LINK) %>

      <INPUT TYPE="hidden" name="<%=paramCurrRecord%>" value="<%=nextRecord%>" />

      <INPUT TYPE=submit name="Next" Value="Next">

    </form>

Adding Transient Private Portlet Parameters

The following code example demonstrates how to implement the Bank Account Portlet that is used as an example in the article, A Primer on Portlet Parameters and Events. In this example, two pieces of transient state information, the action and the amount of money, are passed to the portlet when the page is redisplayed via a Bank Account Portlet form submission. The action value is used to indicate that a bank account transfer is to be performed immediately. The amount value determines the size of the bank account transfer.

Portlet Declaration - provider.xml

Transient portlet parameters rely on the use of unqualified portlet parameters. If the passAllUrlParams flag is set to true in the portlet declaration in provider.xml the unqualified portlet parameters will be passed to a portlet (along with all other URL parameter values). Setting the passAllUrlParams flag to false, the default value, will cause unqualified portlet parameters to be filtered out and not sent to the portlet.

    <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">

      <id>7</id>

      <name>BankAccount</name>

      <title>Bank Account Portlet</title>

      <description>

        This portlet uses the passAllUrlParams flag and unqualified parameters

        to allow the user to request that a bank account transaction be performed.

      </description>

      <passAllUrlParams>true</passAllUrlParams>

      ...

    </portlet>

Portlet Implementation

Like persistent private portlet parameters, transient private portlet parameters are created and used solely in the implementation file. Thus, they do not appear in provider.xml and are not available to the page designer, however, the passAllUrlParams flag must be set to true so that they are actually sent to a portlet and not filtered out by Oracle9iAS Portal.

The action and amount values are implemented as transient state by using unqualified portlet parameters because unqualified portlet parameters are never preserved when following a link or submitting a form back to the same page (for more discussion of preservation of parameters review the article, A Primer on Parameters and Events). The unqualified portlet parameter is read in when the page is displayed and is assigned a value each time the Bank Account Portlet’s form is submitted. Unqualified portlet parameters leave the onus on the portlet developer to solve the problem of name conflicts of private portlet parameters that may occur when using multiple instances of a portlet on a page or instances of different portlets that use the same private portlet parameter name. This example will work correctly if only one Bank Account Portlet is added to a page. The portlet developer must devise some way of uniquely naming a portlet instance’s unqualified portlet parameters. The only restriction the the portlet developer must observe is that if an unqualified portlet parameter is given the prefix ‘_piref’ then Oracle Portal will recognize it as a qualified private portlet parameter.

Note the following methods used in this example:

- HttpPortletRendererUtil.htmlFormActionLink is used to construct the form action URL. The constant request,PortletRendererUtil.PAGE_LINK indicates that this is a simple navigation back to the same page and does not involve portlet events.

- HttpPortletRendererUtil.htmlFormHiddenFields is used to render system information required by Oracle Portal.

- pRequest.getParameter is used to get the value of a unqualified portlet parameter given an unqualified name.

    <%@page import="java.util.*, oracle.portal.provider.v2.*" %>

    <%@page import="oracle.portal.provider.v2.http.HttpCommonConstants" %>

    <%@page import="oracle.portal.provider.v2.render.PortletRendererUtil" %>

    <%@page import="oracle.portal.provider.v2.render.PortletRenderRequest" %>

    <%@page import="oracle.portal.provider.v2.render.http.HttpPortletRendererUtil" %>

    <%

      String paramAmount = "Amount";

      String paramAction = "Action";

      PortletRenderRequest portletRequest =

     (PortletRenderRequest) request.getAttribute(HttpCommonConstants.PORTLET_RENDER_REQUEST);

    %>

    <b>This portlet shows how to use the passUrlParams flag and

    unqualified, transient parameters to perform a portlet action.</b>

    // The account transfer is performed by submitting the following form

    <form method="POST" action="<%= HttpPortletRendererUtil.htmlFormActionLink(

        request,PortletRendererUtil.PAGE_LINK) %>">

      <%= HttpPortletRendererUtil.htmlFormHiddenFields(request,PortletRendererUtil.PAGE_LINK) %>

      <table>

        <tr>

          <td>

            <b>Amount $</b>

          </td>

          <td>

            <input type="text" size="20" name="<%= paramAmount %>" value="">

          </td>

        </tr>

      </table>

      <br>

      <INPUT TYPE=submit name="<%= paramAction %>" Value="Transfer">

    </form>

    // Parse the inputs to see if a transfer should be performed

    <%

    if (portletRequest.getParameter(paramAction) != null)

    {

      String submittedAmount = portletRequest.getParameter(paramAmount);

      if (submittedAmount == null || submittedAmount.trim().length() == 0)

      {

    %>

        <b>Please specify an amount!</b>

    <%

      }

      else

      {

        try

        {

          double amount = Double.valueOf(submittedAmount).doubleValue();

          if (amount != 0)

          {

    %>

            <b>Successfully transferred $<%=submittedAmount%>.</b>

    <%

          }

        }

        catch (NumberFormatException e)

        {

    %>

          <b>Invalid amount.</b>

    <%

        }

      }

    }

    %>

Revision History:

February 27, 2002