Previous Page | Next Page

Developing Custom Portlets

Development Steps


Overview: Steps for Developing a Custom Portlet

To create a custom portlet, follow these steps:

  1. Create a portlet deployment descriptor.

    Each portlet that you deploy must be defined in a portlet deployment descriptor. A portlet deployment descriptor is an XML file that provides all of the information that the SAS Information Delivery Portal requires in order to deploy one or more portlets. The file includes information about the portlet's initialization, actions, security settings, and resource paths.

  2. Create display resources files.

    The display resources file contains text strings for the portlet's title and description for use in the portlet's metadata. If you create multiple display resources files for different locales, the SAS Information Delivery Portal uses these files to localize the portlet title and description at the time of deployment, according to the default locale for the SAS Information Delivery Portal.

  3. Develop presentation JSP pages.

    Each portlet must have a JSP page to serve as the presentation component.

  4. Create action classes.

    You can use the resources of the SAS Information Delivery Portal to develop the following types of action classes for your portlets:

    • initializer classes

    • portlet action classes

    • postprocessing classes

    • error handling classes

  5. Implement portlet help.

    If you want to provide customized use instructions for a portlet, you can create an action class with an associated JSP page that contains the help text. When the user clicks a help button in the portlet's title bar, the help appears in a pop-up window.

  6. Create a PAR file to deploy in the SAS Information Delivery Portal.

    To enable automatic deployment of a portlet into the SAS Information Delivery Portal, you must provide a PAR file that contains all of the needed files. A PAR file can contain files for one portlet or for multiple related portlets.

For examples of fully developed portlet code, see Sample Portlets.


Creating a Portlet Deployment Descriptor

For each PAR file that you create for deployment in the SAS Information Delivery Portal, you must create a portlet deployment descriptor. The portlet deployment descriptor is an XML file that provides all of the information that the SAS Information Delivery Portal needs to deploy the portlets that are contained in the PAR file. The portlet deployment descriptor file must be named portlet.xml.

A PAR file, and its associated portlet deployment descriptor, can contain one portlet or it can contain multiple related portlets; there is no limit to the number of portlets that a PAR file and its associated descriptor can contain.

In addition, a PAR file and its associated portlet deployment descriptor can contain local portlets, remote portlets, or a combination of local and remote portlets.

To create a portlet deployment descriptor, use the element tags that are defined in the portlet deployment descriptor document type definition (DTD). You can view the portlet deployment descriptor DTD at SAS-installation-directory\SASInformationDeliveryPortal\4.2\Static\wars\sas.portal\WEB-INF\classes\portlet.dtd.

The following examples show portlet deployment descriptors for a local portlet and a remote portlet. You can use these examples as templates for creating deployment descriptors for your own portlets.

After you create the deployment descriptor file, include it in the PAR file that you create for your portlet or group of portlets. For more information, see Creating a PAR File for Deploying the Portlet in an Application.


Example Deployment Descriptor for a Local Portlet

A local portlet is a portlet that meets the following criteria:

You can use the following example as a template for creating portlet deployment descriptors for your own local portlets.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd"> 
<portlets>

   <local-portlet name="simplejsp" title="SimpleJspPortlet"
         icon="images/ndd.jpg">
      <localized-resources locales="en" />
      <deployment scope="user" autoDeploy="false"
         userCanCreateMore="true">
      </deployment>

      <initializer-type>
         com.sas.portal.portlets.JspPortlet.JspPortletInitializer
      </initializer-type>
   
      <init-param>
         <param-name>display-page</param-name>
         <param-value>simpleJspTest.jsp</param-value>
      </init-param>

      <portlet-path>/sample/portlets</portlet-path>
      <portlet-actions>
         <portlet-action name="display" default="true">
            <type>com.sas.portal.portlets.JspPortlet.JspPortlet</type>
         </portlet-action>
      </portlet-actions>
   </local-portlet> 

</portlets>


Example Deployment Descriptor for a Remote Portlet

Remote portlets are portlets that execute outside of the portal container. You can use remote portlets to incorporate data from external applications into the SAS Information Delivery Portal. When a user interacts with a remote portlet, the remote portlet appears to be the same as a local portlet.

Many of the elements in the portlet deployment descriptor DTD relate only to local portlets. Therefore, a portlet deployment descriptor for a remote portlet requires fewer elements than a descriptor for a local portlet.

You can use this example as a template for creating portlet deployment descriptors for your own remote portlets:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd"> 
<portlets>

   <remote-portlet name="MyRemotePortlet" title="MyRemotePortlet">
      <localized-resources locales="en" />
      <deployment scope="user" autoDeploy="false"
         userCanCreateMore="true">
      </deployment>
      
      <portlet-path>/sample/portlets/remote</portlet-path>
      <portlet-actions>
         <portlet-action name="display" default="true">
            <url>http://d9999.mycompany.com:8080/test.html</url>
         </portlet-action>
      </portlet-actions>
   </remote-portlet> 

</portlets>


Creating Display Resources Files

A display resources file is a file that contains key=value statements to define text strings for a portlet's title and description. You can create display resources files for the following purposes:

If your portlet is deployed in only one locale, then the display resources files can be omitted. The portlet name in the default locale is used.

Note:   The SAS Metadata Repository cannot store multiple localized values for metadata. Therefore, the portlet title and description are translated only into the default locale for the SAS Information Delivery Portal. They cannot be translated based on the user's locale preference.  [cautionend]

If your portlet does not include any display resources files, the portlet deployment mechanism sends a warning message to the server log. The message indicates that no localized title or description can be found.

To create display resources files, follow these steps:

  1. Create a separate file for each language (or each country and language combination) that you need to support. In each file, use key=value statements to define text strings for portlet.title and portlet.description, as in the following examples:

    portlet.title=Welcome Portlet 
    portlet.description=Welcome Portlet

    portlet.title=Portlet de bienvenida 
    portlet.description=Portlet de bienvenida

  2. Name the files as follows:

    • Use the base name portletDisplayResources.properties.

    • If you are creating files for multiple locales, append each file's name with the appropriate locale identifier (for example, portletDisplayResources_en.properties for English, portletDisplayResources_fr.properties for French, and so on). The file for the default locale does not need to have a locale identifier.

  3. Place the files in the /portlet-name/classes directory of the PAR file.

  4. Add the locale identifier for each supported locale to the locales attribute value of the <localized-resources> element in the portlet deployment descriptor (portlet.xml) file.


Creating the Presentation JSP Page

JavaServer Page (JSP) pages are the presentation components of local portlets. Because you can define a local portlet's initialization, actions, security settings, and resource paths in the portlet deployment descriptor, the JSP page does not need to contain this information.

In developing the JSP page, you can use the following tags:

When you create a JSP page for a portlet, the only requirements are the following:


Creating Action Classes

You can use the resources of the SAS Information Delivery Portal to develop the following types of action classes for your local portlets:

The Portlet API includes classes that you can use to create your own action classes for custom portlets. For a summary of these classes, see Using the Portlet API. For detailed information, see SAS Information Delivery Portal API documentation at http://support.sas.com/92api.

Any action classes that you develop must be defined in the portlet's deployment descriptor file and included in the portlet's PAR file. These classes cannot be accessed by the portlet's JSP pages.

Note:   You can also develop classes other than action classes for your portlet and include them in the portlet's PAR file. These classes do not need to be defined in the portlet deployment descriptor file. However, the additional classes can be accessed only by the action classes. They cannot be accessed from the portlet's JSP pages.  [cautionend]


Thread Safety

Portlet actions, like Struts actions, are multithreaded. There is only a single instance of your PortletAction subclass, and you must make your actions thread-safe, as follows:


Creating an Initializer Action Class

When you develop a local portlet, you can implement an initializer class that runs before the portlet is displayed for the first time on a SAS Information Delivery Portal page. The initializer does not execute again if the user interacts with your portlet or with other portlets on the same page. It also does not execute again if the user navigates to another page and then back again. However, the initializer does run again if the user logs off, logs on again, and displays the page that contains the portlet.

Uses for an initializer might include reading initial parameters that are specified in your portlet's deployment descriptor file (portlet.xml) or connecting to an external resource such as a database.

The SAS Information Delivery Portal is delivered with a default initializer class named JspPortletInitializer, which requires a parameter named display-page. The initializer places the value of this parameter in the PortletContext object so that it can be used by the portlet's action class. To pass additional parameters, you would need to create your own initializer class.

When you create an initializer class, ensure that the following steps have been taken:

The com.sas.portal.portlet.PortletInitializerInterface class includes one method named initialize(). The following objects are passed to the initialize() method:

java.util.Properties

contains all of the initial parameters that are specified in your portlet's deployment descriptor. If your portlet's action class or JSP page requires access to these parameters, you should place them in the portlet context object using its setAttribute() method.

com.sas.portal.portlet.PortletContext

provides a getter method for the HttpSession object so that you can access or set session attributes.

The following example shows an initialize() method that places initial parameters into the portlet context:

/**
 * Puts initial properties into the PortletContext object. 
 * These come from the portlet.xml. 
 * @param initProperties a Properties object 
 * @param context the PortletContext for this portlet 
 */ 
public void initialize(Properties initProperties,
      PortletContext context) {
   context.setAttribute("display-page", 
      initProperties.getProperty("display-page"));
   context.setAttribute("image-location", 
      initProperties.getProperty("image-location")); 
}


Creating a Portlet Action Class

When developing a local portlet, you can implement one or more action classes for the portlet. If you use an action class, then the following requirements must be met:


Creating a Postprocessing Action Class

The com.sas.portal.portlet.PostProcessorInterface is available for implementing activity that should occur when a local portlet is no longer on display. Like other parts of the portlet architecture, it must be defined in your deployment descriptor file. You can use the post-processor phase to free resources that you attached to in the portlet initializer. You could also remove HttpSession attributes that were set in the initializer or action. This is especially important to consider because multiple copies of your portlet could exist on other SAS Information Delivery Portal pages or even on the same page.


Creating an Error Handling Action

The com.sas.portal.portlet.ErrorHandlerInterface is available for handling any errors that your local portlets encounter. This interface has one method, which is named service(). The service() method has the same arguments as the service() method of the PortletActionInterface, plus an additional object named Exception.

If you specify an error handler in your portlet deployment descriptor file (portlet.xml), the error handler is called if the portlet action throws an exception. You can direct your error handler to send messages to the server log and to return a URL string representing an error page for the user to view.

If your portlet initializer encounters an exception, the error handler is not called. If you want to ensure that the error handler executes, you can store the exception object in the portlet context. Then, in your action class's service() method, you can get the exception object out of the context and re-throw it. In the following example, this code is put into a method that should be called at the start of the action's service() method:

/**
 * Check the PortletContext for an exception object. If 
 * present, throw it so that the error handler is executed.
 * @param context the PortletContext
 */
private static void errorCheck(PortletContext context)
      throws Exception { 
   Exception e = (Exception) context.getAttribute("PORTLET_EXCEPTION");
   if (e != null) {
      throw e;
   }
}

The following example shows a simple error handler that logs the exception and calls a static error page. The error page supplies a general error message from the portlet's localized resource bundles.

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import com.sas.portal.Logger; 
import com.sas.portal.portlet.PortletContext; 
import com.sas.portal.portlet.ErrorHandlerInterface; 
import com.sas.portal.portlet.NavigationUtil; 

/**
 * Error handler for some portlets.
 * It logs the exception and returns ErrorPage.jsp 
 * for the portlet to display.
 */ 
public class MyErrorHandler implements ErrorHandlerInterface {
   private final String _loggingContext = this.getClass().getName();

   /**
   * Returns the URL for the portlet controller to call. This is the
   * name of the error page JSP.
   * @param request the HttpServletRequest
   * @param response the HttpServeltResponse
   * @param context the PortletContext
   * @param exception the exception thrown by a portlet action
   * @return the URL to call
   */ 
   public String service(HttpServletRequest request, HttpServletResponse 
         response, PortletContext context, Exception thrownException) {

      // Prepare the localized resources for use by the jsp.
      try {
         NavigationUtil.prepareLocalizedResources(
            "com.mycompany.portlets.Resources", request, context);
      }
      catch (java.io.IOException ioe) {
         Logger.error(ioe.getMessage(), _loggingContext, ioe);
      }
      Logger.error(thrownException.getMessage(), _loggingContext,
         thrownException);
      return "ErrorPage.jsp";
   } 
}


Implementing Portlet Help

You can easily implement help for a custom portlet. If you implement help for a portlet, then a help icon appears in the portlet's title bar. When a user clicks the icon, the portlet help appears in a resizable, scrollable window that is by default 400 pixels wide and 200 pixels high, as shown in the following example:

[untitled graphic]

To implement portlet help, use these steps:

  1. Create an action class to display the JSP page for the help (or, if you want, you can use an instance of com.sas.portal.portlet.JspPortlet). The following example shows the code for an example of a custom action class to display portlet help:

    package com.sas.portal.portlets.welcome; 
    
    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletResponse; 
    import com.sas.portal.portlet.HTMLPortletAction; 
    import com.sas.portal.portlet.PortletContext; 
    
    public class HelpAction extends HTMLPortletAction {
       public String service(HttpServletRequest request, 
             HttpServletResponse response, PortletContext context)
             throws Exception {
          return "help.jsp";
       } 
    }

  2. Create a JSP page that contains the help text. The JSP page must have the following characteristics:

    • The JSP page must be an HTML fragment. That is, it must not contain starting and ending <HTML> , <HEAD> , or <BODY> tags.

    • The JSP page must have the filename help.jsp. The example JSP page for the help window that was shown previously consists of the following lines:

      <h1>Portlet Help</h1>
      <p>Portlet ID: <%= pid %></p>
      <p>This is where portlet help would be displayed</p>
  3. In the portlet's deployment descriptor (portlet.xml) file, add a <portlet-action> element for the action class. Set the element's help attribute to true.

The following example of the <portlet-action> element for a portlet uses a custom action to display its help:

<portlet-action name="help" help="true">
   <type>com.sas.portal.portlets.welcome.HelpAction</type> 
</portlet-action>

The following example of a <portlet-action> element for a portlet uses an instance of com.sas.portal.portlet.JspPortlet to display its help:

<portlet-action name="help" help="true"> 
   <type>com.sas.portal.portlet.JspPortlet</type> 
</portlet-action>


Creating a PAR File for Deploying the Portlet in an Application

A PAR file contains all of the files needed in order to deploy a portlet or a group of portlets into the SAS Information Delivery Portal. A single PAR file can contain files for multiple portlets. A PAR file can contain local portlets, remote portlets, or a combination of local and remote portlets.

For correct deployment, the portlet files must be archived in a PAR file using the following directory structure:

/ (root)

contains the portlet deployment descriptor file, which must be named portlet.xml.

/portlet-name

contains associated subdirectories for each portlet that is defined in portlet.xml. The directory name must match the name of the portlet as specified in the name attribute of the <local-portlet> or <remote-portlet> element in portlet.xml.

/portlet-name/classes

contains portlet action classes, other custom classes that are used by the portlet, and display resources files that are used by the portlet. Replicate any package structure as subdirectories of /portlet-name/classes. Portlet action classes (but not other classes) must be defined in the portlet deployment descriptor file (portlet.xml).

/portlet-name/content

contains Web resources used by the portlet, including JSPs, HTML files, and images. Each portlet can have only one content directory. However, the content directory can have an unlimited number of subdirectories.

/portlet-name/lib

contains any custom JAR files that are used by the portlet.

Note:   The scripting facility provided with SAS Information Delivery Portal automates the process of building the PAR file with the necessary directory structure. For more information, see Creating Portlets Using the Testportlet Scripting Facility.  [cautionend]

Previous Page | Next Page | Top of Page