Previous Page | Next Page

Sample Portlets

SampleDisplayURL: Editable Portlet


Overview: Steps for Creating the SampleDisplayURL Portlet

The SampleDisplayURL portlet is an example of an editable portlet from which users can create their own portlet instances. The Sample DisplayURL portlet includes classes that enable the user to edit the new portlet instance to point to any URL that returns an HTML fragment.

To create the SampleDisplayURL portlet, follow these steps:

  1. Create the portlet configuration and source directories.

  2. Create the portlet deployment descriptor (portlet.xml).

  3. Create the display pages for the portlet and the editor (Viewer.jsp, Editor.jsp, and Error.jsp).

  4. Create the action classes (Initializer.java, BaseAction.java, DisplayAction.java, EditorAction.java, OKAction.java, CancelAction.java, and ErrorHandler.java).

  5. Create resource bundles to supply user interface text.

  6. Create a title and description for the portlet.

  7. Compile portlet code.

  8. Create the PAR file and deploy and test the portlet.

Note:   Before you begin developing the SampleDisplayURL portlet, ensure that the SAS Metadata Server is running so that metadata can be accessed during the configuration and deployment processes.  [cautionend]


Step 1: Create the Portlet Configuration and Source Directories

Follow these steps to create a source directory structure for building the portlet:

  1. Create a configuration directory for the portlet named SampleDisplayURL under the SAS-configuration-directory/Lev1/CustomAppData directory. This directory is referred to as portlet-configuration-directory in the code and descriptions for this portlet.

  2. Copy the contents of the testportlet directory to theSampleDisplayURL directory.

  3. Create a source code directory for the portlet named Source under the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory. This directory is referred to as portlet-source-directory in the code and descriptions for this portlet.

  4. Edit the custom.properties file in the SampleDisplayURL directory as follows.

    Note:   Be sure to substitute the full pathnames from the steps above in the install.currprod.config.dir= and testportlet.install.dir= argument values.  [cautionend]

    # If you change the value "testportlet", make sure to rename in all properties 
    # here as well as in the custom_config.xml.
    config.currprod.12byte=testportlet
    
    # Change the value of this property to be the name of your web application.
    config.currprod.legalname=URL Display Portlet Sample
    
    # The value of this property should be the location where the configuration 
    # files are placed.  Make sure to change the level directory based on your 
    # installation and make sure to rename testportlet if the value of 
    # config.currprod.12byte changes above.
    install.currprod.config.dir=portlet-configuration-directory
    
    # Do not change the value of this property.  The name might be changed if you 
    # change the value of config.currprod.12byte above.
    webappsrv.testportlet.server=server
    
    # Change the value of this property to be the location of your portlet's source 
    # code and configuration files.  The name might be changed if you change the 
    # value of config.currprod.12byte above.
    testportlet.install.dir=portlet-source-directory
    
    # Change the value of this property to be the name of you par, war, and ear 
    # file.  The name might be changed if you change the value of 
    # config.currprod.12byte above.
    webapp.testportlet.archive.name=sample.displayurl
    
    # Change the value of this property to be the context root of your web 
    # application and the name of the portlet.  The name might be changed if you 
    # change the value of config.currprod.12byte above.
    webapp.testportlet.contextroot=SampleDisplayURL
    
    # Change the value of this property to be the versioned name of your web 
    # application.  This property is only used for remote portlets.  The name might 
    # be changed if you change the value of config.currprod.12byte above.
    webapp.testportlet.display.name=URL Display Portlet Sample

  5. From the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory, run the following configuration script to create the source directory structure for building the portlet:

    cfg createLocalPortletDirectories -Dmetadata.connection.passwd="password"

    For the password value, you must supply the unrestricted user password for your SAS installation.

    Note:   You can specify the password either in clear text or in encoded form. For information about generating the encoded form, see "The PWENCODE Procedure" in Encryption in SAS.  [cautionend]

  6. Review the customconfig.log file in the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory to determine whether any errors occurred.


Step 2: Create the 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 one or more portlets. The following example shows the portlet deployment descriptor file for the SampleDisplayURL portlet. For more information about portlet deployment descriptor files, see Creating a Portlet Deployment Descriptor.

<?xml version="1.0" encoding="UTF-8" ?>

 Note about code
<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd"> 
<portlets>
 Note about code
   <local-portlet name="@webapp.testportlet.contextroot@"
      title="URL Display Portlet Sample"
      editorType="portlet">
      
      <localized-resources locales="en" /> 
 Note about code
      <deployment scope="user" autoDeploy="false" userCanCreateMore="true" />
      
      <initializer-type>
        sample.displayurl.Initializer
      </initializer-type>

      <init-param>
         <param-name>error-page</param-name>
         <param-value>Error.jsp</param-value>
      </init-param>

      <init-param>
         <param-name>display-page</param-name>
         <param-value>Viewer.jsp</param-value>
      </init-param>

      <init-param>
         <param-name>edit-page</param-name>
         <param-value>Editor.jsp</param-value> 
      </init-param>

      <error-handler>
         <type>sample.displayurl.ErrorHandler</type>
      </error-handler>

      <portlet-path>/sample/portlets</portlet-path>
 Note about code
      <portlet-actions>
         <portlet-action name="display" default="true">
            <type>sample.displayurl.DisplayAction</type>
         </portlet-action>
 Note about code
         <portlet-action name="editor" editor="true">
            <type>sample.displayurl.EditorAction</type>
         </portlet-action>
 Note about code
         <portlet-action name="ok" default="false">
            <type>sample.displayurl.OKAction</type>
         </portlet-action>

         <portlet-action name="cancel" default="false">
            <type>sample.displayurl.CancelAction</type>
         </portlet-action>

      </portlet-actions> 
   </local-portlet> 
</portlets>    
      

Store this portlet deployment descriptor source text in a file named portlet.xml.orig in the portlet-source-directory/Configurable/pars/sample.displayurl directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the portlet.xml file.


Step 3: Create the Display Pages for the Portlet and the Editor

The SampleDisplayURL portlet has the following JSP pages:

Viewer.jsp

is the presentation component of the portlet.

Editor.jsp

is the presentation component of the editor action.

Error.jsp

displays messages for errors that occur during the editing process.


Create the Viewer.jsp Page

The following example shows the code for the Viewer JSP page, which is the presentation component of the SampleDisplayURL portlet:

<!-- Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513 --> 
<%@ page language="java" contentType= "text/html; charset=UTF-8" %> 
<%@ page import="com.sas.portal.portlet.PortletContext" %> 
<%@ page import="com.sas.portal.common.PortletConstants" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %> 
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt_rt" %> 

<%
   PortletContext context = (PortletContext) request.getAttribute(
   PortletConstants.CURRENT_PORTLET_CONTEXT );
   String url = (String) context.getAttribute("SampleDisplayURL_DisplayURL");
   
   if ((url == null) || (url.length() == 0)) { 
%> 
<p style="text-align: center;"><fmt:message key="viewer.nourl.txt"/></p> 
<%
   }
   else {
      try { 
%> 
<c_rt:import charEncoding="UTF-8" url="<%= url %>" /> 
<%
      }
      catch (Exception ex) { 
%> 
<p style="text-align: center;">
<fmt_rt:message key="viewer.badurl.fmt">
<fmt_rt:param value="<%= url %>"/>
<fmt_rt:param value="<%= ex.getMessage() %>"/>
</fmt_rt:message> 
</p> 
<%
      }
   } 
%>

Store this JSP code in a file named Viewer.jsp in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/content directory.


Create the Editor.jsp Page

The following example shows the code for the Editor JSP page, which is the presentation component of the editor for the SampleDisplayURL portlet:

<!-- Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513 --> 
<%@ page language="java" contentType= "text/html; charset=UTF-8" %> 
<%@ page import="com.sas.portal.portlet.PortletContext" %> 
<%@ page import="com.sas.portal.common.PortletConstants" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 

<% PortletContext context = (PortletContext) request.getAttribute(
   PortletConstants.CURRENT_PORTLET_CONTEXT ); %> 

<table border="0" cellpadding="2" cellspacing="0" align="center"
 width="100%">
   <tr>
   <td colspan="3"> </td>
   </tr>

   <tr>
   <td> </td>
   <td nowrap align="center"><fmt:message key="editor.task.txt"/></td>
   <td> </td>
   </tr>

   <tr>
   <td colspan="3"> </td>
   </tr>

   <tr>
   <td> </td>
   <td> <table border="0" cellpadding="0" cellspacing="0" align="center">
   <td class="celljustifyright" nowrap>
      <fmt:message key="editor.url.txt"/>
   </td>
   <td> </td>
   <td class="celljustifyleft" nowrap>
      <form method="post" action="<%= context.getAttribute(
         "SampleDisplayURL_EditOkURL") %>">
      <input type="text" name="SampleDisplayURL_DisplayURL"
      value="<%= context.getAttribute("SampleDisplayURL_DisplayURL") %>"
      size="60">
   </td>
   </tr>

   <tr>
   <td colspan="3"> </td>
   </tr>

   <tr>
   <td class="celljustifyright">
      <input class="button" type="submit"
      value="<fmt:message key="editor.action.ok.txt"/>"
      name="submit">
   </form>
   </td>
   <td> </td>
   <td class="celljustifyleft">
      <form method="post" action="<%= context.getAttribute(
      "SampleDisplayURL_EditCancelURL") %>">
      <input class="button" type="submit"
      value="<fmt:message key="editor.action.cancel.txt"/>"
      name="cancel">
      </form>
   </td>
   </tr> 
   
</table>

Store this JSP code in a file named Editor.jsp in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/content directory.


Create the Error.jsp Page

The following example shows the code for the Error JSP page, which displays messages for any errors that occur during the editing process:

<%-- Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513 --%> 
<%@ page language="java" contentType= "text/html; charset=UTF-8" %> 
<%@ page import="com.sas.portal.portlet.PortletContext" %> 
<%@ page import="com.sas.portal.common.PortletConstants" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 

<% PortletContext context = (PortletContext)request.getAttribute(
   PortletConstants.CURRENT_PORTLET_CONTEXT ); %> 

<fmt:message key="error.msg1.txt"/> 
<br /> 
<%= context.getAttribute("Exception_message") %>

Store this JSP code in a file named Error.jsp in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/content directory.


Step 4: Create the Action Classes

The SampleDisplayURL portlet has the following action classes:


Create the Initializer Action Class

The SampleDisplayURL portlet's Initializer action class initializes properties that are used by the other action classes and puts the properties into a PortletContext object. The following example shows the source code for the Initializer class:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

import java.rmi.RemoteException; 
import java.util.Properties; 

import com.sas.portal.Logger; 
import com.sas.portal.portlet.PortletContext; 
import com.sas.portal.portlet.PortletInitializerInterface; 
import com.sas.portal.portlet.configuration.Attribute; 
import com.sas.portal.portlet.configuration.Configuration; 
import com.sas.portal.portlet.configuration.ConfigurationFactory; 

/**
 * This initializes common properties by putting them into a
 * PortletContext object.
 */ 
public class Initializer implements PortletInitializerInterface {

   public Initializer() {
   }
      
   /* Key for the URL String in the PortletContext.*/
   public static final String DISPLAY_URL_KEY =
      "SampleDisplayURL_DisplayURL";
   
   /* PortletContext key for the edit screen Ok button URL */
   public static final String EDIT_OK_URL_KEY =
      "SampleDisplayURL_EditOkURL";
   
   /* PortletContext key for the edit screen Cancel button URL */
   public static final String EDIT_CANCEL_URL_KEY =
      "SampleDisplayURL_EditCancelURL";
   
   /* Key for the PortletException object in the PortletContext  */
   public static final String PORTLET_EXCEPTION_KEY =
      "sasPortletException";
   
   /**
    * 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) {
      
      try {
         // Get the initial URL from the portlet configuration object
         Configuration config = ConfigurationFactory.getConfiguration(
            context);
         Attribute attr = config.getAttribute(
            Initializer.DISPLAY_URL_KEY);
         String url = (attr == null) ? "" : attr.getValue();
         
         context.setAttribute("error-page",
            initProperties.getProperty("error-page"));
         context.setAttribute("display-page",
            initProperties.getProperty("display-page"));
         context.setAttribute("edit-page",
            initProperties.getProperty("edit-page"));
         context.setAttribute(Initializer.DISPLAY_URL_KEY, url);
         
         if (Logger.isDebugEnabled(_loggingContext)){
            Logger.debug("Display portlet URL: " +
            url, _loggingContext);
         }
      }
      
      catch (RemoteException e) {
         context.setAttribute(Initializer.PORTLET_EXCEPTION_KEY, e);
      }
   } 

   private static final long serialVersionUID = 1L;
   private final String _loggingContext = this.getClass().getName();

}

Create a directory named sample under the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source directory, and then create a directory named displayurl under the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample directory. Store the class source code in a file named Initializer.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Create the Base Action Class

The SampleDisplayURL portlet's BaseAction class is a superclass that is extended by the DisplayAction, EditorAction, OkAction, and CancelAction classes. The source code is shown here:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

import com.sas.portal.Logger; 
import com.sas.portal.container.deployment.PortletActionInfoInterface; 
import com.sas.portal.portlet.NavigationUtil; 
import com.sas.portal.portlet.PortletActionInterface; 
import com.sas.portal.portlet.PortletContext; 
import sample.displayurl.Initializer; 
import java.io.IOException;
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public abstract class BaseAction implements PortletActionInterface {

   public BaseAction() {
      _actionInfo = null;
   }
   
   private final String _loggingContext = this.getClass().getName();

   /**
   * This method must be overridden in subclasses. 
   * The subclasses must call super and supply a return value.
   * In this class, the method returns null.
   * 
   * @see com.sas.portal.portlet.PortletActionInterface#service(
   * HttpServletRequest, HttpServletResponse, PortletContext)
   */
   public String service(HttpServletRequest request,
      HttpServletResponse response,
      PortletContext context) throws Exception {

      Logger.debug("started..", _loggingContext);
      response.setContentType("text/html;charset=UTF-8");
      
      // Prepare the localized resources for use by the jsp.
      try {
         NavigationUtil.prepareLocalizedResources(
            "sample.displayurl.res.Resources", 
            request, context);
      }

      catch (java.io.IOException ioe) {
         Logger.error(ioe.getMessage(), _loggingContext, ioe);
      }
      
      return null;
   }
   
   /**
   * @see com.sas.portal.portlet.PortletActionInterface#setInfo(
   * PortletActionInfoInterface)
   */
   public final void setInfo(PortletActionInfoInterface info) {
      _actionInfo = info;
   }
   
   /**
   * @see com.sas.portal.portlet.PortletActionInterface#getInfo()
   */
   public final PortletActionInfoInterface getInfo()
   {
      return _actionInfo;
   }
   
   /**
   * Check the PortletContext for an exception object. If present,
   * throw it to invoke the error handler.
   * @param context the PortletContext
   */
   protected static final void errorCheck(PortletContext context)
      throws Exception {
      Exception e = (Exception)context.getAttribute(
         Initializer.PORTLET_EXCEPTION_KEY); 
      if (e != null)
         throw e;
      else
         return;
   } 

   private static final long serialVersionUID = 1L;
   private PortletActionInfoInterface _actionInfo;
   
}

Store the class source code in a file named BaseAction.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Create the Display Action Class

The DisplayAction class is the default action class for the SampleDisplayURL portlet. This means that the class is invoked before the portlet's JSP page renders. The following example shows the source code for the DisplayAction class:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

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

/**
 * Action class that presents the display page. It sets up the display
 * model then instructs the portlet container to present the display
 * page.
 */ 
public final class DisplayAction extends BaseAction {

   public DisplayAction() {
   }
   
   /**
    * Service the portlet request.
    *
    * @param request the HttpServletRequest
    * @param response the HttpServeltResponse
    * @param context the PortletContext
    * @return the URL to call
    */

   public String service(HttpServletRequest request,
      HttpServletResponse response,
      PortletContext context) throws Exception {
      
      super.service(request, response, context);
      
      // Check whether an initialization error occurred
      errorCheck(context);
      return (String)context.getAttribute("display-page");
   
   } 

   private static final long serialVersionUID = 1L;

}

Store the class source code in a file named DisplayAction.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Create the Editor Action Class

The SampleDisplayURL portlet's EditorAction class is invoked when a user clicks the portlet's Edit icon. The following example shows the source code for the EditorAction class:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

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

/**
 * Action class that presents the edit page. It sets up the edit model
 * then instructs the portlet container to present the edit page.
 */ 
public final class EditorAction extends BaseAction {

   public EditorAction() {
   }

   /**
    * Service the portlet request.
    *
    * @param request the HttpServletRequest
    * @param response the HttpServeltResponse
    * @param context the PortletContext
    * @return the URL to call
    */
   public String service(HttpServletRequest request,
      HttpServletResponse response,
      PortletContext context) throws Exception {

      super.service(request, response, context);
      
      // Create the URLs for the OK and Cancel buttons.
      String url;
      
      url = NavigationUtil.buildBaseURL(context, request,
         "ok");
      context.setAttribute(Initializer.EDIT_OK_URL_KEY, url);
      
      url = NavigationUtil.buildBaseURL(context, request,
         "cancel");
      context.setAttribute(Initializer.EDIT_CANCEL_URL_KEY, url);
      
      context.resetMode();
      
      return (String) context.getAttribute("edit-page");
   } 

   private static final long serialVersionUID = 1L;

}

Store the class source code in a file named EditorAction.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Create the OK and Cancel Action Classes

The SampleDisplayURL portlet's OkAction class is invoked when a user clicks OK in the editor display page. The CancelAction class is invoked when a user clicks Cancel in the editor display page. The following examples show the source code for the OKAction and CancelAction classes:

Code for the OKAction Class

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

import com.sas.portal.Logger; 
import com.sas.portal.portlet.configuration.ConfigurationFactory; 
import com.sas.portal.portlet.configuration.Configuration; 
import com.sas.portal.portlet.PortletContext; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

/**
 * Action class that processes the Ok action from the editor. It
 * persists the user-specified URL, sets up the display model, then
 * instructs the portlet container to present the display page.
 */ 
public final class OKAction extends BaseAction {

   public OKAction() {
   }
   
   /**
    * Service the portlet request.
    *
    * @param request the HttpServletRequest
    * @param response the HttpServeltResponse
    * @param context the PortletContext
    * @return the URL to call
    */
   public String service (HttpServletRequest request,
      HttpServletResponse response,
      PortletContext context) throws Exception {
      
      super.service(request, response, context);
      
      String url = request.getParameter(Initializer.DISPLAY_URL_KEY);
      context.setAttribute(Initializer.DISPLAY_URL_KEY, url);
      
      // Save the URL parameter
      Configuration config = ConfigurationFactory.getConfiguration(
         context);
      config.setAttribute(Initializer.DISPLAY_URL_KEY, url);
      ConfigurationFactory.storeConfiguration(context, config);
      
      if (Logger.isDebugEnabled(_loggingContext)){
         Logger.debug("Display portlet URL: " + url, _loggingContext);
      }
      
      // Back to the default, display, mode
      // context.resetMode();
      
      return (String)context.getAttribute("display-page"); 
   }

   private static final long serialVersionUID = 1L;
   private final String _loggingContext = this.getClass().getName();
   
}

Store the class source code in a file named OKAction.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.

Code for the CancelAction Class

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

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

/**
 * Action class that processes the Cancel action from the editor. It
 * sets up the display model then instructs the portlet container to 
 * present the display page.
 */ 
public final class CancelAction extends BaseAction {

   public CancelAction() {
   }
   
  
   /**   
    * Service the portlet request.
    *
    * @param request the HttpServletRequest
    * @param response the HttpServeltResponse
    * @param context the PortletContext
    * @return the URL to call
    */
   public String service(HttpServletRequest request,
      HttpServletResponse response,
      PortletContext context) throws Exception {
      
      super.service(request, response, context);
      
      // Back to the default, display, mode
      // context.resetMode();
      return (String)context.getAttribute("display-page");
   
   } 
}

Store the class source code in a file named CancelAction.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Create the Error Handler Action Class

The following example shows the source code for the ErrorHandler class:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.
 * All Rights Reserved.
 */ 
package sample.displayurl; 

import com.sas.apps.portal.PortalException; 
import com.sas.portal.Logger; 
import com.sas.portal.portlet.ErrorHandlerInterface; 
import com.sas.portal.portlet.NavigationUtil; 
import com.sas.portal.portlet.PortletContext; 
import java.io.IOException;
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 


/**
 * Error handler for this portlet. It logs the exception and 
 * returns ErrorPage.jsp for the portlet to display.
 */ 
public class ErrorHandler implements ErrorHandlerInterface {

   public ErrorHandler() {
   }

   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(
            "sample.displayurl.Resources",
            request, context);
      }

      catch (java.io.IOException ioe) {
         Logger.error(ioe.getMessage(), _loggingContext, ioe);
      }
   
      // Send error to server log in default locale.
      Logger.error(thrownException.getMessage(), _loggingContext, 
         thrownException);
      
      // Get message in user's locale.
      String msg = null;
      try { 
         PortalException ourException = (PortalException)
         thrownException;
         msg = ourException.getMessage(request.getLocale());
      }
      
      catch (ClassCastException cce){
         msg= "";
      }
      
      if (msg == null) {
         // Prevent showing the word null in a JSP
         msg = "";
      }
      
      // Make msg available for display on error jsp.
      context.setAttribute("Exception_message", msg);
      
      return (String)context.getAttribute("error-page");
   } 

   private static final long serialVersionUID = 1L;

}

Store the class source code in a file named ErrorHandler.java in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory.


Step 5: Create the Resource Bundle

The resource bundles provide translated text that is displayed inside the SampleDisplayURL portlet. The portlet's BaseAction, EditorAction, and ErrorHandler classes call the NavigationUtil.prepareLocalizedResources()method to create a JSTL localization context based on the user's locale preference. This context enables the JSTL tags in the portlet's JSP pages to use the appropriate resource bundle to display text.

Note:   For information about localizing a portlet's title and description, see Creating Display Resources Files.  [cautionend]

The following example shows the resource bundle contents for the SampleDisplayURL portlet:

Note:   If you copy and paste this code, then you must remove any line breaks in the message strings for error.msg1.txt and viewer.nourl.txt.  [cautionend]

# Messages for the SampleDisplayURL portlet 

# NOTE: This is the same message text as found in 
# com.sas.portal.res.Resources.properties. The localized versions 
# from that file can be used here. 
error.msg1.txt=A serious error occurred. Contact the Portal administrator. 

# {0} is a URL. {1} is an exception message. 
viewer.badurl.fmt=Unable to display ''{0}'' because ''{1}''. 
viewer.nourl.txt=No URL has been specified. Please edit the portlet to set a URL. 

editor.task.txt=Enter the URL of the HTML fragment to display. 
editor.url.txt=URL: 

# NOTE: These are the same messages as found in 
# com.sas.portal.res.Resources.properties. The localized versions 
# from that file can be used here. 
editor.action.cancel.txt=Cancel 
editor.action.ok.txt=OK

Create a directory named res under the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl directory. Store the resource bundle text in a file named Resources.properties in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/source/sample/displayurl/res directory.


Step 6: Create a Title and Description for the Portlet

The SampleDisplayURL portlet uses a display resources file to provide a description that is placed in the portlet's metadata for display to users.

You can supply multiple display resources files if you want the SAS Information Delivery Portal to localize the portlet title and description at the time of deployment, according to the default locale for SAS Information Delivery Portal. For more information, see Creating Display Resources Files.

For the SampleDisplayURL portlet, create a display resources file with the following contents:

portlet.title=URL Display Portlet Sample 
portlet.description=Sample portlet that displays the contents of a URL

Store this text in a file named portletDisplayResources.properties in the portlet-source-directory/Static/pars/sample.displayurl/SampleDisplayURL/classes directory.


Step 7: Compile Portlet Code

The action classes that were defined in Step 4 must be compiled before the portlet can be used. SAS 9.2 uses a Versioned JAR Repository to manage the JAR files that ship with SAS products. The testportlet scripting facility integrates with the Versioned JAR Repository by requiring a picklist to define which JAR files are used for compiling the portlet and building the WAR file. If your portlet requires additional JAR files, they must also be added to the picklist.

Follow these steps to compile the SampleDisplayURL portlet:

  1. Create a picklist for this sample portlet. As a starting point, copy the SAS Information Delivery Portal picklist file from the SAS-installation-directory/SASInformationDeliveryPortal/4.2/Picklists/wars/sas.portal directory into the portlet-source-directory/Picklist/pars/sample.displayurl directory.

    Note:   After a SAS maintenance release is applied at your site, you must copy the updated picklist file and repeat the building and deploying of PAR and EAR files for all custom portlets.  [cautionend]

  2. Copy any custom or third-party JAR files that are not defined in the SAS picklist but that are needed to compile the custom portlet into the portlet-source-directory/Static/lib directory. For this sample portlet, you must copy the file named servlet-api.jar that ships with the application server into the portlet-source-directory/Static/lib directory.

  3. From the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory, run the configuration script with the following arguments to compile the Java class:

    cfg compileLocalPortlet -Dmetadata.connection.passwd="password"

    For the password value, you must supply the unrestricted user password for your SAS installation.

    Note:   You can specify the password either in clear text or in encoded form. For information about generating the encoded form, see "The PWENCODE Procedure" in Encryption in SAS.  [cautionend]

  4. Review the customconfig.log file in the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory to determine whether any errors occurred.


Step 8: Create the PAR File and Deploy and Test the Portlet

The last step in developing the SampleDisplayURL portlet is to archive its files into a PAR file and deploy the new portlet. The PAR file includes all of the portlet's supporting files, including the files created in Steps 2 through 7. To create the PAR file and deploy the portlet, follow these steps:

  1. Stop the Web application server on which the SAS Information Delivery Portal is deployed so that development of the new portlet will not affect the running system.

  2. From the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory, run the configuration script with the following arguments:

     cfg buildPortletArchive -Dmetadata.connection.passwd="password"

    For the password value, you must supply the unrestricted user password for your SAS installation.

    Note:   You can specify the password either in clear text or in encoded form. For information about generating the encoded form, see "The PWENCODE Procedure" in Encryption in SAS.  [cautionend]

    The portlet archive file will be created in the SAS-configuration-directory/Lev1/Web/Applications/SASPortlets4.2/Deployed directory with the name sample.displayurl.par.

  3. Review the customconfig.log file in the SAS-configuration-directory/Lev1/CustomAppData/SampleDisplayURL directory to determine whether any errors occurred.

  4. Rebuild the sas.portal4.2.ear file using the SAS Deployment Manager. This step is required because the sas.portal4.2.ear file contains files associated with each portlet.

  5. Manually redeploy the sas.portal4.2.ear file into the Web application server.

  6. Start the Web application server on which the SAS Information Delivery Portal is deployed. The SampleDisplayURL portlet should now be available to the portal.

It is a good practice to deploy new portlets into a staging area (that is, a test installation of the SAS Information Delivery Portal) for verification and testing before deploying them into a production environment.

Previous Page | Next Page | Top of Page