SAS 4.2 Information Delivery Portal User manual

SAS 4.2 Information Delivery Portal User manual
Add to My manuals

Below you will find brief information for SAS Information Delivery Portal 4.2. This manual describes how to develop custom portlets for the SAS Information Delivery Portal. Portlets are the information display components of the SAS Information Delivery Portal. Custom portlets allow you to integrate custom applications into the portal, enhancing its functionality.

advertisement

Assistant Bot

Need help? Our chatbot has already read the manual and is ready to assist you. Feel free to ask any questions about the device, but providing details will make the conversation more productive.

SAS Information Delivery Portal 4.2 User Manual | Manualzz

Developing Portlets for the

SAS

®

Information Delivery

Portal 4.2

The correct bibliographic citation for this manual is as follows: SAS Institute Inc. 2010.

Developing Portlets for the SAS

® Information Delivery Portal 4.2. Cary, NC: SAS Institute

Inc.

Developing Portlets for the SAS

®

Information Delivery Portal 4.2

Copyright © 2010, SAS Institute Inc., Cary, NC, USA

All rights reserved. Produced in the United States of America.

For a hard-copy book: No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, or otherwise, without the prior written permission of the publisher, SAS

Institute Inc.

For a Web download or e-book: Your use of this publication shall be governed by the terms established by the vendor at the time you acquire this publication.

U.S. Government Restricted Rights Notice. Use, duplication, or disclosure of this software and related documentation by the U.S. government is subject to the Agreement with SAS Institute and the restrictions set forth in FAR 52.227-19 Commercial Computer

Software-Restricted Rights (June 1987).

SAS Institute Inc., SAS Campus Drive, Cary, North Carolina 27513.

1st electronic book, March 2010

SAS ® Publishing provides a complete selection of books and electronic products to help customers use SAS software to its fullest potential. For more information about our e-books, e-learning products, CDs, and hard-copy books, visit the SAS Publishing Web site at support.sas.com/publishing or call 1-800-727-3228.

SAS ® and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries.

® indicates USA registration.

Other brand and product names are registered trademarks or trademarks of their respective companies.

Contents

Chapter 1

4 Developing Custom Portlets

1

Introduction to Portlet Development

1

Options for Implementing Portlets

2

Development Environments

3

Development Steps

3

Chapter 2

4 Hints and Tips for Creating Custom Portlets

15

Overview

15

Avoiding Namespace Problems

15

Bundling Multiple Portlets into a Single PAR File

16

Testing Portlets

16

Obtaining a User and Session Context

16

Obtaining the User’s Name

17

Obtaining the User’s Locale

17

Chapter 3

4 Using the Portlet API

19

Overview

19

Class Reference

19

Chapter 4

4 Sample Portlets

21

Overview: Sample Portlets

22

Creating Portlets Using the Testportlet Scripting Facility

22

SampleWelcome: Localized Display Portlet

24

SampleForm: Interactive Form Portlet

32

SampleDisplayURL: Editable Portlet

40

SampleRemote: Remote Portlet

58

Appendix 1

4 Moving Existing Custom Portlets to SAS Information Delivery Portal

4.2

75

Overview

75

Java Package Changes

75

JAR File Changes

75

Smart Object Changes

76

Remote Portlet API Changes

76

Index

79

iv

C H A P T E R

1

Developing Custom Portlets

Introduction to Portlet Development

1

Options for Implementing Portlets

2

Development Environments

3

Development Steps

3

Overview: Steps for Developing a Custom Portlet

3

Creating a Portlet Deployment Descriptor

4

Example Deployment Descriptor for a Local Portlet

4

Example Deployment Descriptor for a Remote Portlet

5

Creating Display Resources Files

6

Creating the Presentation JSP Page

7

Creating Action Classes

8

Thread Safety

8

Creating an Initializer Action Class

8

Creating a Portlet Action Class

9

Creating a Postprocessing Action Class

10

Creating an Error Handling Action

10

Implementing Portlet Help

11

Creating a PAR File for Deploying the Portlet in an Application

13

Introduction to Portlet Development

Portlets are the information display components of the SAS Information Delivery

Portal. A portlet can process requests from the user and generate dynamic content such as report lists, alerts, workflow notifications, or performance metrics. In addition to a set of standard portlets, the SAS Information Delivery Portal provides a framework that enables you to develop and deploy custom portlets that meet your organization’s needs. This framework, which is based on the open-source Struts architecture and conforms to industry-standard Model-View-Controller (Model 2) design patterns, provides the following:

3 an execution environment that allows portlets to execute in the portlet container, in the same way that servlets execute in the servlet container. The SAS

Information Delivery Portal processes all HTTP requests for portlets, while the session and state information are maintained and shared among portlet actions and across requests.

3

3 support for portlets running remotely in other Web technology frameworks, with the option to pass the session and state information to these portlets.

simplified portlet deployment through the use of the following:

3 a portlet deployment descriptor, which is an XML file that specifies the portlet’s actions as well as initialization, path, and access control information.

1

2 Options for Implementing Portlets

4 Chapter 1

3 a portlet archive (PAR) file, which includes all of the elements needed to deploy a portlet or series of portlets, including the portlet deployment descriptor, JavaServer Pages (JSP) files, custom Java classes, and associated resources (such as images, resource bundles, and HTML files).

3

3 a set of action and initializer classes, which reduce the need for developing custom programs. These classes perform many commonly used functions, such as displaying the JSP page that is specified in the portlet deployment descriptor.

access to SAS custom tags and to tags in the Struts development framework to simplify development of JSP pages for your portlets.

Portlets that are created with the framework provided in the SAS Information

Delivery Portal have a standard appearance, which includes a title bar that contains icons that link to portlet actions, as shown in the following examples:

Options for Implementing Portlets

The action and initializer classes included in the SAS Information Delivery Portal are designed to handle a portlet’s basic function of displaying a single JSP page.

However, to meet specialized needs you can do the following:

3 write one or more Java classes that implement the com.sas.portal.portlet.PortletActionInterface. Alternatively, you can extend the provided com.sas.portal.portlet.HTMLPortletAction class to obtain a basic implementation of the interface.

3 write Java classes that implement the PortletInitializerInterface,

ErrorHandlerInterface, or PostProcessorInterface in the com.sas.portal.portlet

package in order to meet more specialized requirements.

4 Overview: Steps for Developing a Custom Portlet

3

For more information, see Chapter 3, “Using the Portlet API,” on page 19 and

Chapter 4, “Sample Portlets,” on page 21.

Development Environments

You can create Java classes, JSP pages, and other supporting files to implement portlets using any Java integrated development environment (IDE). However, SAS

AppDev Studio software provides templates for creating common types of portlets. For more information about SAS AppDev Studio software, see http://support.sas.com/

rnd/appdev/

.

In addition to interactive development environments, SAS Information Delivery

Portal provides a scripting facility for building portlets. To use the scripting facility, you place source files for portlet components in designated directories and execute a configuration script to generate the archive files required to deploy portlets. The use of the scripting facility is illustrated in Chapter 4, “Sample Portlets,” on page 21.

Development Steps

Overview: Steps for Developing a Custom Portlet

To create a custom portlet, follow these steps:

1

Create a portlet deployment descriptor.

2

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.

Create display resources files.

3

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.

Develop presentation JSP pages.

4

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

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:

3

3 initializer classes portlet action classes

3

3 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

4 Creating a Portlet Deployment Descriptor

4 Chapter 1

6

user clicks a help button in the portlet’s title bar, the help appears in a pop-up window.

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 Chapter 4, “Sample Portlets,” on page 21.

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” on page 13.

Example Deployment Descriptor for a Local Portlet

3

3

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

The portlet is deployed within the SAS Information Delivery Portal.

The portlet executes inside the portlet container.

3

3

The portlet consumes the computing resources (for example, CPU, memory, and disk storage) of the server machine on which the portal container runs.

The portlet can include resources such as Web pages, images, resource bundles, and Java classes that are deployed inside the SAS Information Delivery Portal.

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" />

4 Creating a Portlet Deployment Descriptor

5

<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>

6 Creating Display Resources Files

4 Chapter 1

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:

3 to specify a description for your portlet. If you do not provide a display resources file, the SAS Information Delivery Portal uses the portlet’s name to create a default description.

Note:

The <local-portlet> and <remote-portlet> elements of the portlet deployment descriptor contain a description attribute. However, this description is only for internal documentation purposes. It is not displayed to users.

4

3 to enable the SAS Information Delivery Portal to localize the portlet title and description at the time of deployment, according to the default locale for the SAS

Information Delivery Portal. When the portlet is first deployed, the deployment process determines which locale to use. Based on this locale, the deployment process uses the title and description from the appropriate display resources file to create metadata and register the portlet in the SAS Metadata Repository. The following rules apply:

3

For editable portlets, the portlet name that is displayed in the drop-down list of portlet selections is localized based on the browser locale when the user first logs into the portal.

Note:

The locale does not apply to new portlet instances created from the template because the user enters an explicit name and description that are stored in metadata for the portlet instance.

4

3

For portlets with user scope and the autoDeploy="true" attribute in the deployment descriptor, the browser locale when the user first logs into the portal determines which display resources file is selected to provide the title and description for the portlet.

3

For portlets with group scope and the autoDeploy="true" attribute in the deployment descriptor, the locale used to start the Web application server determines which display resources file is selected to provide the title and description for the portlet. Starting the Web application server with one locale specified and then starting it again with a different locale specified will result in two instances of the portlet.

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.

4

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:

4 Creating the Presentation JSP Page

7

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

2

Name the files as follows:

3

3

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

4

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

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:

3 tags from the JSP Standard Tag Libraries (JSTL).

3 tags from the Struts tag libraries.

3

SAS custom tags, which are available if your site has licensed SAS AppDev Studio software in addition to the SAS Information Delivery Portal. For information about these tags, see the SAS Custom Tags Reference page on the AppDev Studio

Developer’s Site at http://support.sas.com/rnd/appdev.

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

3

The JSP page must be an HTML fragment:

3

The page must not contain starting and ending <HTML>, <HEAD>, or <BODY> tags.

3

The page must be able to be displayed inside a table cell in an HTML document.

3

If the JSP page includes custom tags from a tag library, you must include a taglib directive before the first use of a tag from that library. For the JSTL format tag library, use the following taglib directive:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

3

You must include a UTF-8 directive if you want the JSP page to provide full support for internationalization. This directive causes all user input to be encoded in the 8-bit Unicode Transformation Format, which supports all of the world’s languages, including those that use non-Latin1 characters.

Note:

The SAS Information Delivery Portal supplies this directive when it displays portlets on a portal page. However, you must supply the directive to ensure correct internationalization when your portlet is displayed from the Search

8 Creating Action Classes

4 Chapter 1

Results panel. You should consider making your portlet actions extend the

HTMLPortletAction class, because that class supplies the directive.

4

The syntax for the UTF-8 directive is:

<%@ page contentType= "text/html; charset=UTF-8"%>

3

The JSP cannot import Java classes from the portlet’s PAR file.

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:

3

3

3

3

Initializer classes

Portlet action classes

Postprocessing classes

Error handling classes

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 Chapter 3, “Using the Portlet

API,” on page 19. 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.

4

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:

3

3

You cannot use class properties to share values between member methods.

If you use member methods, be sure to pass all values through the method’s signature. The signature passes all values through the thread-safe stack.

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.

4 Creating Action Classes

9

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

3

3

The class must be specified in the <initializer-type> element of the portlet’s deployment descriptor file (portlet.xml).

The class must implement com.sas.portal.portlet.PortletInitializerInterface.

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:

3

You must specify the class in your portlet deployment descriptor file (portlet.xml).

3

3

The class must implement com.sas.portal.portlet.PortletActionInterface.

The class can extend DefaultPortletAction or HTMLPortletAction in com.sas.portal.portlet. The DefaultPortletAction and HTMLPortletAction contain two simple methods for setting and getting an instance of com.sas.portal.portlet.PortletActionInfoInterface, as shown in the following example: public void setInfo(PortletActionInfoInterface pai) {

_actionInfo = pai;

} public PortletActionInfoInterface getInfo() { return _actionInfo;

}

The primary method, named service(), runs every time the action is executed.

For the portlet’s display action, that occurs before the portlet is displayed and

10 Creating Action Classes

4 Chapter 1 every time the portlet is redisplayed. For example, it runs after a user interacts with the portlet or with a different portlet on the same page.

The service() method is provided with the HttpServletRequest,

HttpServletResponse, and PortletContext objects. From the PortletContext object, you can obtain the HttpSession object, which provides access to many important servlet objects.

Your service() method must return a string representing a valid URL for the portlet. Typically, the URL is the name of the portlet’s JSP page. If your initializer places the display-page property of the portlet deployment descriptor file into the

PortletContext object, then you can obtain the URL as in the following example:

String url = (String) context.getAttribute("display-page");

If user interaction with your portlet requires a different URL string, then you can return that URL instead.

The service() method can handle any type of exception subclass that is thrown by code within your action. If your portlet action needs to throw an exception, then you can use the portlet error handler. For more information, see “Creating an

Error Handling Action” on page 10.

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) {

4 Implementing Portlet Help

11

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:

12 Implementing Portlet Help

4 Chapter 1

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:

3

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

3

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>

4 Creating a PAR File for Deploying the Portlet in an Application

13

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” on page 22.

4

14

C H A P T E R

2

Hints and Tips for Creating

Custom Portlets

Overview

15

Avoiding Namespace Problems

15

Bundling Multiple Portlets into a Single PAR File

16

Testing Portlets

16

Obtaining a User and Session Context

16

Obtaining a Local User and Session Context

17

Obtaining a Remote User and Session Context

17

Obtaining the User’s Name

17

Obtaining the User’s Locale

17

Overview

3

3

3

3

3

3

This chapter provides tips and best practices for developing portlets, including the following: avoiding namespace problems bundling multiple portlets into a single PAR file testing portlets obtaining a user or session context obtaining the user’s name obtaining the user’s locale

Note:

The code samples in this chapter require that you include the appropriate import statements at the top of your program. Here are some examples: import com.sas.preferences.SASProfileInterface; import com.sas.services.information.metadata.PersonInterface; import com.sas.services.session.SessionContextInterface; import com.sas.services.user.UserContextInterface; import com.sas.services.user.UserServiceInterface;

4

Avoiding Namespace Problems

The portlet namespace consists of the path (with underscores in place of slashes) and the portlet’s name. For example, a portlet with the name simpleJSP and a path of /mycompany/portlets would be deployed as _mycompany_portlets_simpleJSP.

To avoid namespace problems, do the following:

15

16 Bundling Multiple Portlets into a Single PAR File

4 Chapter 2

3

3

Use a standard naming convention for portlet paths.

Avoid using the _SAS namespace.

Bundling Multiple Portlets into a Single PAR File

When you need to deploy multiple portlets, define the portlets in a single portlet deployment descriptor (portlet.xml) file and bundle the portlets into a single portlet archive (PAR) file if it is feasible to do so. This practice improves performance, since only one PAR file needs to be opened and only one portlet descriptor file needs to be read.

Testing Portlets

To test and debug a local portlet that you have developed, deploy it into a staging area (that is, a test installation of the SAS Information Delivery Portal). After the portlet has been verified and tested, deploy it into the production environment.

For remote portlets, test and debug the Web application that is called by the portlet by using the application’s direct URL. After the application has been verified and tested, deploy the remote portlet into the SAS Information Delivery Portal’s production environment.

Obtaining a User and Session Context

The SAS Foundation Services user context and session context provide a mechanism for managing information while a user is authenticated to the SAS Intelligence

Platform middle tier. For details about using SAS Foundation Services, see the class documentation at http://support.sas.com/92api.

A local portlet has access to the SAS Information Delivery Portal’s local user and session context. By using the local user and session context that is shared with the portal, all Java objects created when accessing SAS Foundation Services will be local objects and will be shared by the portal and the portlets.

A remote portlet is implemented as a separate Web application and does not have access to the SAS Information Delivery Portal’s local user and session context. A remote user and session context are available to the remote portlet to support single sign-on and passing information from the portal to the remote portlet.

The remote contexts should be used when the remote portlet does not make extensive use of SAS Foundation Services, as illustrated in “SampleRemote: Remote Portlet” on page 58. If more extensive use of SAS Foundation Services is required, the remote portlet should have its own local user and session context. One reason for creating a local user and session context for a remote portlet is to improve efficiency. Java calls will then be local to the Web application’s JVM rather than directed to remote services.

Another reason for creating a local user and session context for a remote portlet is to improve scalability. A Web application can run in a load-balanced cluster, but there can be only one instance of the remote services application. In addition, the remote contexts are limited to accessing the repositories that are defined in the remote services deployment. Because additional repositories might be defined in the local services deployment, you should use the local session context whenever possible. The process of developing a remote portlet with its own local user and session context requires additional portlet configuration files. Additional metadata must also be created. This document does not include a sample that illustrates these additional steps.

4 Obtaining the User’s Locale

17

The preferred ways to obtain the user and session contexts are from the HttpSession.

The easiest way to obtain the HttpSession in portlet code is from the request, as in the following example:

HttpSession session = request.getSession();

If the request is not available, the HttpSession can also be obtained from the portlet context, as in the following example:

HttpSession session = portletContext.getHttpSession();

Obtaining a Local User and Session Context

The following example obtains both the local user and session contexts from the

HttpSession:

UserContextInterface userContext =

(UserContextInterface)session.getAttribute(CommonKeys.USER_CONTEXT);

SessionContextInterface sessionContext =

(SessionContextInterface)session.getAttribute(CommonKeys.SESSION_CONTEXT);

Obtaining a Remote User and Session Context

The following example obtains both the remote user and session contexts from the

HttpSession:

UserContextInterface userContext =

(UserContextInterface)session.getAttribute(CommonKeys.REMOTE_USER_CONTEXT);

SessionContextInterface sessionContext =

(SessionContextInterface)session.getAttribute(

CommonKeys.REMOTE_SESSION_CONTEXT);

Obtaining the User’s Name

In a portlet initializer or action class, you can obtain the display name of the user that is logged on from the user context. For information about obtaining the user context, see “Obtaining a User and Session Context” on page 16.

IdentityInterface aPerson = userContext.getPerson();

String name = aPerson.getDisplayName();

Obtaining the User’s Locale

In a portlet initializer or action class, you can obtain the user’s locale from the user context. For information about obtaining the user context, see “Obtaining a User and

Session Context” on page 16.

The following code obtains the SAS profile from the user context and then obtains the locale from the instance of the SASProfileInterface:

ProfileInterface profile = userContext.getProfile();

SASProfileInterface sasProfile =

(com.sas.preferences.SASProfileInterface)profile.getProfile("SAS");

18 Obtaining the User’s Locale

4 Chapter 2

Locale locale = sasProfile.getLocale();

Note:

The locale is null if no value was available from the SAS profile. In this case, use the HttpServletRequest.getLocale() method instead.

4

C H A P T E R

3

Using the Portlet API

Overview

19

Class Reference

19

Overview

The Portlet API provides access to classes that provide the SAS Information Delivery

Portal’s navigation and request processing functions. For detailed information about the API, see the class documentation at http://support.sas.com/92api.

Class Reference

The following classes are of particular usefulness in creating custom portlets: com.sas.portal.portlet.DefaultPortletAction

Extend this class in order to create your own portlet actions. For more information, see “Creating a Portlet Action Class” on page 9.

com.sas.portal.portlet.ErrorHandlerInterface

Use this interface to handle errors that your portlet encounters. For more information, see “Creating an Error Handling Action” on page 10.

com.sas.portal.portlet.HTMLPortletAction

Extend this class in order to create your own portlet actions. For more information, see “Creating a Portlet Action Class” on page 9. Possible uses include the following:

3 correctly displaying non-Latin1 character sets when a portlet is displayed in preview mode. For an example of this use, see “Step 4: Create the Action

Class” on page 28.

3 preparing URLs for actions within an interactive form JSP and populating a

JavaBean with parameters from a JSP form. For an example of these uses, see “Step 4: Create the Action Class” on page 36.

com.sas.portal.portlet.PortletContext

Use this interface to obtain a local or remote session context, which you can use to pass information from one portlet to another. For examples, see “Obtaining a User and Session Context” on page 16.

com.sas.portal.portlet.NavigationUtil

Use this class to do the following:

3 create URLs for buttons on your JSP pages (for example, OK and Cancel).

19

20 Class Reference

4 Chapter 3

3 obtain a portlet’s resource bundles in order to create a localization context for your portlet’s JSP page.

com.sas.portal.portlet.PortletActionInterface

Use this interface to develop an action class for your portlet. For more information, see “Creating a Portlet Action Class” on page 9 and “Step 4: Create the Action Class” on page 28.

com.sas.portal.portlet.PortletInitializerInterface

Use this interface to develop an initializer class, which runs before your portlet is displayed for the first time on a portal page. Possible uses include

3 reading initial parameters that are specified in your portlet’s deployment descriptor file (portlet.xml).

3 connecting to an external resource such as a database. For more information, see “Creating an Initializer Action Class” on page 8.

com.sas.portal.portlet.PostProcessorInterface

Use this interface to develop a postprocessor class that runs when your portlet is no longer displayed. Possible uses include the following:

3

3 freeing resources that were used in the portlet initializer.

removing HttpSession attributes that were set in the portlet initializer or portlet action. This is especially important to consider because multiple copies of your portlet could exist on other portal pages or even on the same page.

For more information, see “Creating a Postprocessing Action Class” on page 10.

C H A P T E R

4

Sample Portlets

Overview: Sample Portlets

22

Creating Portlets Using the Testportlet Scripting Facility

22

SampleWelcome: Localized Display Portlet

24

Overview: Steps for Creating the SampleWelcome Portlet

24

Step 1: Create the Portlet Configuration and Source Directories

25

Step 2: Create the Portlet Deployment Descriptor

26

Step 3: Create the Display Page

28

Step 4: Create the Action Class

28

Step 5: Create the Resource Bundles

30

Step 6: Create Translated Titles and Descriptions

30

Step 7: Compile Portlet Code

30

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

31

SampleForm: Interactive Form Portlet

32

Overview: Steps for Creating the SampleForm Portlet

32

Step 1: Create the Portlet Configuration and Source Directories

32

Step 2: Create the Portlet Deployment Descriptor

34

Step 3: Create the Display Page

35

Step 4: Create the Action Class

36

Step 5: Create a JavaBean to Return User Input

37

Step 6: Create a Title and Description for the Portlet

38

Step 7: Compile Portlet Code

39

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

39

SampleDisplayURL: Editable Portlet

40

Overview: Steps for Creating the SampleDisplayURL Portlet

40

Step 1: Create the Portlet Configuration and Source Directories

40

Step 2: Create the Portlet Deployment Descriptor

42

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

44

Create the Viewer.jsp Page

44

Create the Editor.jsp Page

45

Create the Error.jsp Page

46

Step 4: Create the Action Classes

46

Create the Initializer Action Class

47

Create the Base Action Class

48

Create the Display Action Class

50

Create the Editor Action Class

51

Create the OK and Cancel Action Classes

52

Create the Error Handler Action Class

54

Step 5: Create the Resource Bundle

56

Step 6: Create a Title and Description for the Portlet

57

Step 7: Compile Portlet Code

57

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

58

21

22 Overview: Sample Portlets

4 Chapter 4

SampleRemote: Remote Portlet

58

Overview: Steps for Creating the SampleRemote Portlet

58

Step 1: Create the Portlet Configuration and Source Directories

59

Step 2: Create the Enterprise Application Deployment Descriptor

60

Step 3: Create the Web Application Deployment Descriptor

61

Step 4: Create the Spring Framework Configuration File

64

Step 5: Create the Display Pages for the Web Application

65

Create the Viewer.jsp Page

65

Create the Editor.jsp Page

66

Create the Error.jsp Page

67

Create the Help.jsp Page

67

Step 6: Create the Controller Servlet Class

68

Step 7: Create the Portlet Deployment Descriptor

71

Step 8: Create a Title and Description for the Portlet

73

Step 9: Compile the Remote Portlet

73

Step 10: Create the EAR and PAR Files and Deploy and Test the Portlet

74

Overview: Sample Portlets

This chapter includes complete code for portlet deployment descriptors, JSP pages, resource files, and action classes as applicable for the following sample portlets:

SampleWelcome is a simple display portlet that has no interactive capabilities. Because it is internationalized, it displays text in the user’s locale (language and country) preference.

SampleForm is an interactive form portlet that accepts free-form input and displays it back to the user.

SampleDisplayURL is a portlet from which users can create their own portlet instances that display

HTML content from any URL. It is a simplified version of the standard

DisplayURL portlet template that is delivered with the SAS Information Delivery

Portal. This sample provides an edit mode that enables users to specify the URL to display.

SampleRemote is a remote portlet that executes a Web application that displays the name of the user who is logged on to the SAS Information Delivery Portal. The portlet also displays text that can be edited by the user.

For detailed information about a specific portlet development task, see “Development

Steps” on page 3.

Creating Portlets Using the Testportlet Scripting Facility

The examples in this chapter use the portlet development scripting facility provided with the SAS Information Delivery Portal. The files for this facility can be found in the

SAS-configuration-directory/Lev1/CustomAppData/testportlet directory. The scripting facility should be used for portlet development because it provides a process that integrates your custom portlets with the SAS 9.2 Versioned JAR Repository.

4 Creating Portlets Using the Testportlet Scripting Facility

23

The following steps provide an overview of creating a portlet using the scripting facility. The instructions for creating the sample portlets in this chapter include detailed examples of using the scripting facility.

Note:

Before you begin developing a custom portlet, ensure that the SAS Metadata

Server is running so that metadata can be accessed during the configuration and deployment processes.

4

1

Create a configuration directory for the portlet under the

SAS-configuration-directory/Lev1/CustomAppData/ directory. Use the portlet name for the configuration directory name. The following rules apply to the portlet name and configuration directory structure:

3

3

3

Neither portlet names nor their paths can contain spaces.

The portlet name must match the name of the portlet that is specified in the name attribute of the <local-portlet> or <remote-portlet> element in the portlet deployment descriptor (portlet.xml) file.

The portlet name must be unique.

2

3

4

5

Copy the contents of the testportlet directory to the new portlet configuration directory.

Create a source directory for the code associated with the portlet. This directory is referred to in subsequent instructions as the portlet source directory.

Edit the custom.properties file in the portlet configuration directory to specify the portlet name and title and the locations for the configuration and source files.

Run the configuration script, cfg, to create the source directory structure for building the portlet.

Note:

After running the script, review the customconfig.log file for errors. This file will be located in the directory where the script was run.

4

For local portlets, the following source directory structure is created:

portlet-source-directory/Configurable/pars/archive-name

portlet-source-directory/Picklists/pars/archive-name

portlet-source-directory/Static/lib

portlet-source-directory/Static/pars/archive-name/context-root/content

portlet-source-directory/Static/pars/archive-name/context-root/source

portlet-source-directory/Static/pars/archive-name/context-root/classes

For remote portlets, the following source directory structure is created:

portlet-source-directory/Configurable/ears/archive-name/META-INF

portlet-source-directory/Configurable/pars/archive-name

portlet-source-directory/Configurable/wars/archive-name/WEB-INF

portlet-source-directory/Picklists/wars/archive-name

portlet-source-directory/Static/lib

portlet-source-directory/Static/ears/archive-name/META-INF

portlet-source-directory/Static/pars/archive-name/context-root/classes

portlet-source-directory/Static/wars/archive-name/jsp

portlet-source-directory/Static/wars/archive-name/source

portlet-source-directory/Static/wars/archive-name/WEB-INF/classes

portlet-source-directory/Static/wars/archive-name/WEB-INF/spring-config

The /Configurable and /Static directory hierarchies are used to store the files needed to create PAR, EAR, and WAR files for the portlet, in the same directory structure as the PAR, EAR, and WAR files themselves. The

/Configurable

hierarchy is used for files in which values are substituted from the portlet configuration file when the portlet is built. The /Static hierarchy is

24 SampleWelcome: Localized Display Portlet

4 Chapter 4

6

7

used for files that do not require substitution. The /Picklists directory hierarchy is used to store picklist files that specify which of the JAR files from the SAS

Versioned JAR Repository need to be included in the portlet. The /Static/lib directory is used to store additional JAR files needed at compile time.

Load source files for portlet components into the source directory structure.

Create a picklist file to tell the portlet which of the JAR files from the SAS

Versioned JAR Repository need to be included in the portlet.

8

9

Note:

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

4

Add other JAR files to the project.

Run the configuration script to compile Java classes.

Note:

After running the script, review the customconfig.log file for errors. This file is located in the directory where the script was run.

4

10

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

11

Run the configuration script to build the appropriate archive files for the portlet.

This step will create a PAR file in the SAS Information Delivery Portal’s Exploded and Deployed portlet directories. For remote portlets, it will also create the remote portlet Web application.

Note:

After running the script, review the customconfig.log file for errors. This file is located in the directory where the script was run.

4

12

For remote portlets only: Run the configuration script to deploy the Web application EAR file to the Web application server.

Note:

After running the script, review the customconfig.log file for errors. This file is located in the directory where the script was run.

4

13

Rebuild the sas.portal4.2.ear file using the SAS Deployment Manager and redeploy the EAR file.

Note:

If your SAS installation uses restrictive policy files, you might need to update the files to provide appropriate permissions for the portlet.

4

14

Start the application server where the SAS Information Delivery Portal is deployed. The custom portlet should now be available to the portal.

Note:

In order to use the scripting facility, you must have the unrestricted user password for your SAS installation.

4

SampleWelcome: Localized Display Portlet

Overview: Steps for Creating the SampleWelcome Portlet

The SampleWelcome portlet displays localized text using the user’s locale (language and country) preference and is not interactive. The SampleWelcome portlet is a local portlet that runs inside the portlet container.

To create the SampleWelcome portlet, follow these steps:

1

Create the portlet configuration and source directories.

2

3

Create the portlet deployment descriptor (portlet.xml).

Create the display page (Welcome.jsp).

4 Step 1: Create the Portlet Configuration and Source Directories

25

4

5

6

7

8

Create the actions class (WelcomeAction.java).

Create resource bundles to support different locales.

Create translated portlet titles and descriptions to support different locales.

Compile portlet code.

Create the PAR file and deploy and test the portlet.

Note:

Before you begin developing the SampleWelcome portlet, ensure that the SAS

Metadata Server is running so that metadata can be accessed during the configuration and deployment processes.

4

Step 1: Create the Portlet Configuration and Source Directories

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

1

Create a configuration directory for the portlet named SampleWelcome 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

3

4

Copy the contents of the testportlet directory into this new SampleWelcome directory.

Create a source code directory for the portlet named Source under the

SAS-configuration-directory/Lev1/CustomAppData/SampleWelcome directory.

This directory is referred to as portlet-source-directory in the code and descriptions for this portlet.

Edit the custom.properties file in the SampleWelcome 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.

4

# 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=Welcome 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

26 Step 2: Create the Portlet Deployment Descriptor

4 Chapter 4

# 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.welcome

# 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=SampleWelcome

# 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=Welcome Portlet Sample

5

From the SAS-configuration-directory/Lev1/CustomAppData/SampleWelcome directory, run the configuration script with the following arguments 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.

6

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.

4

Review the customconfig.log file that was created in the

SAS-configuration-directory/Lev1/CustomAppData/SampleWelcome 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 contents of the portlet deployment descriptor file for the

SampleWelcome portlet. For more information about portlet deployment descriptor files, see “Creating a Portlet Deployment Descriptor” on page 4.

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

The DOCTYPE statement must be present in the descriptor file in order for the portlet to run.

However, the document type definition (DTD) does not need to be accessible at the URL that the statement specifies.

If you want to look at the portlet.dtd file, you can find it in the portal installation directory in the path portal/WEB-INF. For example, on a Windows system, the DTD is located at the following path: SAS-installation-directory/SASInformationDeliveryPortal/4.2/Static/

wars/sas.portal/WEB-INF/classes/portlet.dtd

.

<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd">

<portlets>

4 Step 2: Create the Portlet Deployment Descriptor

27

The

<local-portlet>

element assigns the name to the portlet. The name cannot contain spaces. The portlet identifier, which consists of the portlet path (defined in the

<portlet-path>

element) together with the portlet name, must be unique within the SAS Information Delivery

Portal. This example uses the testportlet scripting facility to build the portlet, which will replace @webapp.testportlet.contextroot@ with the literal name SampleWelcome.

<local-portlet name="@webapp.testportlet.contextroot@" title="Welcome Portlet Sample">

The

<localized-resources>

element lists the locales that the portlet supports. Display resource files must be provided for each of these locales.

<localized-resources locales="de,en" />

The

<deployment>

element specifies that all users can create new instances of this portlet.

<deployment scope="user" autoDeploy="false" userCanCreateMore="true" />

Because the SampleWelcome portlet does not need its own initializer class, the default portlet initializer (JspPortletInitializer) is specified. This class 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. The value of the parameter is the name of the

SampleWelcome portlet’s JSP page, named Welcome.jsp.

Note:

The default initializer passes only the display-page parameter. To pass additional parameters, you need to create your own initializer class. For more information, see “Creating an Initializer Action Class” on page 8.

4

<initializer-type> com.sas.portal.portlets.JspPortlet.JspPortletInitializer

</initializer-type>

<init-param>

<param-name>display-page</param-name>

<param-value>Welcome.jsp</param-value>

</init-param>

The

<portlet-path>

element specifies the directory location in which the portlet is deployed.

The portlet identifier, which consists of the portlet path together with the portlet name (defined in the

local-portlet

element), must be unique within the SAS Information Delivery Portal.

For example, Orion Star Sports & Outdoors could have two SampleWelcome portlets if different paths are specified for each (as in /OrionStar/Sales/SampleWelcome and /OrionStar/

Purchasing/SampleWelcome

).

<portlet-path>/sample/portlets</portlet-path>

To provide for internationalization of the text that appears inside the portlet border, the

SampleWelcome portlet has its own action class, named WelcomeAction. The name of the class is specified in the

<type>

subelement of the

<portlet-action>

element.

<portlet-actions>

<portlet-action name="display" default="true">

<type>sample.welcome.WelcomeAction</type>

</portlet-action>

</portlet-actions>

</local-portlet>

28 Step 3: Create the Display Page

4 Chapter 4

</portlets>

Store this portlet deployment descriptor source text in a file named

portlet.xml.orig

in the portlet-source-directory/Configurable/pars/

sample.welcome

directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the portlet.xml file.

Step 3: Create the Display Page

JSP pages are the presentation components of portlets. The following example shows the source code for the SampleWelcome portlet’s JSP page. For more information about portlet display pages, see “Creating the Presentation JSP Page” on page 7.

<%-- Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513 --%>

The following line contains the

UTF-8

directive, which is required for internationalization. This directive causes all user input to be encoded in the 8-bit Unicode Transformation Format, which supports all of the world’s languages including those that use character sets other than Latin1.

<%@ page language="java" contentType= "text/html; charset=UTF-8" %>

The following line contains the

taglib

directive for the JSP Standard Tag Library (JSTL) formatting tags. The directive must appear before the first use of these tags.

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

The following lines use JSTL formatting tags to display text. The

key

attribute is used to obtain the appropriate text from the resource bundle that most closely matches the user’s locale preference. The SAS Information Delivery Portal makes the user’s locale available to these tags.

<fmt:message key="welcome.msg1.txt"/>

<br>

<fmt:message key="welcome.msg2.txt"/>

Store this JSP code in a file named Welcome.jsp in the portlet-source-directory/

Static/pars/sample.welcome/SampleWelcome/content

directory.

Step 4: Create the Action Class

The SampleWelcome portlet has its own action class, WelcomeAction, which provides support for localizing messages. This class extends com.sas.portal.portlet.HTMLPortletAction, which contains code to correctly display character sets other than Latin1 when the SAS Information Delivery Portal displays the portlet in preview mode.

The following example shows the source code for the WelcomeAction class. For more information about action classes, see “Creating Action Classes” on page 8.

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.

* All Rights Reserved.

*/ package sample.welcome; import com.sas.portal.portlet.HTMLPortletAction; import com.sas.portal.portlet.NavigationUtil; import com.sas.portal.portlet.PortletContext; import javax.servlet.http.HttpServletRequest;

4 Step 4: Create the Action Class

29

import javax.servlet.http.HttpServletResponse;

/**

* Action for the SampleWelcome Portlet. This prepares the localized resource

* bundles for use by the JSTL tags within the portlet’s JSP.

* @version 1

*/ public final class WelcomeAction extends HTMLPortletAction { public WelcomeAction() {

}

/**

* Configure the JSTL localization context for use in the SampleWelcome

* portlet. Returns the value of "display-page" from the portlet’s

* XML descriptor.

*

* @param request The HttpServletRequest associated with the method

* invocation

* @param response HttpServletResponse associated with the method

* invocation

* @param context PortletContext mapped to the request path

*

* @return java.lang.String - representing a valid URL.

*/ public String service(HttpServletRequest request,

HttpServletResponse response,

PortletContext context) throws Exception {

In the following code, the NavigationUtil method uses the portlet’s classloader to obtain the portlet’s resource bundle. Using this bundle and the locale of the current user, it creates a new

JSTL localization context. The localization context is made available to the portlet’s JSP page with request scope.

super.service(request, response, context);

NavigationUtil.prepareLocalizedResources(

"sample.welcome.res.Resources", request, context);

}

// This comes from the portlet.xml.

String url = (String) context.getAttribute("display-page"); return url; private static final long serialVersionUID = 1L;

}

Create a directory named sample under the portlet-source-directory/Static/pars/

sample.welcome/SampleWelcome/source

directory, and then create a directory named

welcome

under the portlet-source-directory/Static/pars/sample.welcome/

SampleWelcome/source/sample

directory. Store the class source code in a file named

WelcomeAction.java

in the portlet-source-directory/Static/pars/sample.welcome/

SampleWelcome/source/sample/welcome

directory.

30 Step 5: Create the Resource Bundles

4 Chapter 4

Step 5: Create the Resource Bundles

Resource bundles provide translated text that is displayed inside the SampleWelcome portlet. The portlet’s WelcomeAction.class calls the

NavigationUtil.prepareLocalizedResources() method to create a JSTL localization context based on the user’s locale preference. This context enables the JSTL tags in

Welcome.jsp to use the appropriate resource bundle to display the text.

Note:

For information about localizing the portlet’s title and description, see “Step

6: Create Translated Titles and Descriptions” on page 30.

4

Create the following resource files for the SampleWelcome portlet:

Resources_de.properties (for German)

# This is where you put key/value pairs for message strings that need to

# be localized.

## These are the messages for the Welcome portlet welcome.msg1.txt=Willkommen bei SAS Information Delivery Portal.

welcome.msg2.txt=Schauen Sie sich um!

Resources_en.properties (for English)

# This is where you put key/value pairs for message strings that need to

# be localized.

## These are the messages for the SampleWelcome portlet welcome.msg1.txt=Welcome to the SAS Information Delivery Portal.

welcome.msg2.txt=Take a look around!

Create a directory named res under the portlet-source-directory/Static/pars/

sample.welcome/SampleWelcome/source/sample/welcome

directory. Store these resource bundles in files named Resources_de.properties and

Resources_en.properties

in the portlet-source-directory/Static/pars/

sample.welcome/SampleWelcome/source/sample/welcome/res

directory.

Step 6: Create Translated Titles and Descriptions

Translated titles and descriptions for the SampleWelcome portlet are stored in display resource files. See “Creating Display Resources Files” on page 6 for more information about display resource files.

The following display resource files are required for the SampleWelcome portlet: portletDisplayResources_de.properties (for German) portlet.title=Begrungs-Portlet Muster portlet.description=Begrungs-Portlet Muster portletDisplayResources_en.properties (for English) portlet.title=Welcome Portlet Sample portlet.description=Welcome Portlet Sample

Store these files with the specified names in the portlet-source-directory/Static/

pars/sample.welcome/SampleWelcome/classes

directory.

Step 7: Compile Portlet Code

The action class that was 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

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

31

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 SampleWelcome 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.welcome 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.

4

2

Copy the file named servlet-api.jar that ships with the application server into the portlet-source-directory/Static/lib directory.

3

Note:

The portlet-source-directory/Static/lib directory is where you store any custom or third-party JAR files that are not defined in the SAS picklist but that are needed to compile the custom portlet.

4

From the SAS-configuration-directory/Lev1/CustomAppData/SampleWelcome 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.

4

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.

4

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleWelcome

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 SampleWelcome 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

2

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.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleWelcome 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.

4

32 SampleForm: Interactive Form Portlet

4 Chapter 4

5

6

3

4

The portlet archive file will be created in the SAS-configuration-directory/Lev1/

Web/Applications/SASPortlets4.2/Deployed

directory with the name

sample.welcome.par

.

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleWelcome

directory to determine whether any errors occurred.

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.

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

Start the Web application server on which the SAS Information Delivery Portal is deployed. The SampleWelcome 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.

SampleForm: Interactive Form Portlet

Overview: Steps for Creating the SampleForm Portlet

The SampleForm portlet is an interactive portlet that accepts free-form input from the user. When the user clicks Submit Form, the portlet displays the entered text back to the user.

SampleForm is a local portlet that runs inside the portlet container. It was developed using a JavaBean, which places values in the PortletContext object so that the values are available to the JSP page. The HttpServletRequestor HttpSession object could be used for this purpose. However, the PortletContext object is unique to the portlet and is not shared with other processes. Therefore, using it avoids collisions that could cause attribute values to be overwritten.

To create the SampleForm portlet, follow these steps:

1

2

Create the portlet configuration and source directories.

Create the portlet deployment descriptor (portlet.xml).

3

4

5

6

7

8

Create the display page (SampleForm.jsp).

Create the action class (DisplayAction.java).

Create a JavaBean to return user input (ExampleBean.java).

Create a title and description for the portlet.

Compile portlet code.

Create the PAR file and deploy and test the portlet.

Note:

Before you begin developing the SampleForm portlet, ensure that the SAS

Metadata Server is running so that metadata can be accessed during the configuration and deployment processes.

4

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 SampleForm under the

SAS-configuration-directory/Lev1/CustomAppData directory. This directory is

4 Step 1: Create the Portlet Configuration and Source Directories

33

2

3

4

referred to as portlet-configuration-directory in the code and descriptions for this portlet.

Copy the contents of the testportlet directory to the SampleForm directory.

Create a source code directory for the portlet named Source under the

SAS-configuration-directory/Lev1/CustomAppData/SampleForm directory. This directory is referred to as portlet-source-directory in the code and descriptions for this portlet.

Edit the custom.properties file in the SampleForm 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.

4

# 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=Form 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.form

# 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=SampleForm

# 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=Form Portlet Sample

5

From the SAS-configuration-directory/Lev1/CustomAppData/SampleForm directory, run the following configuration script to create the source directory structure for building the portlet: cfg createLocalPortletDirectories -Dmetadata.connection.passwd="password"

34 Step 2: Create the Portlet Deployment Descriptor

4 Chapter 4

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

SAS installation.

6

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.

4

Review the customconfig.log file that was created in the

SAS-configuration-directory/Lev1/CustomAppData/SampleForm 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 contents of the portlet deployment descriptor file for the

SampleForm portlet. For more information about portlet deployment descriptor files, see “Creating a Portlet Deployment Descriptor” on page 4.

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

The DOCTYPE statement must be present in the descriptor file in order for the portlet to run.

However, the DTD does not need to be accessible at the URL that the statement specifies.

<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd">

<portlets>

The

<local-portlet>

element assigns the name SampleForm to the portlet. The name cannot contain spaces. The portlet identifier, which consists of the portlet path (defined in the

<portlet-path>

element) together with the portlet name, must be unique within the SAS

Information Delivery Portal.

<local-portlet name="@webapp.testportlet.contextroot@" title="Form Portlet Sample">

<localized-resources locales="en" />

The

<deployment>

element specifies that all users can create new instances of this portlet.

<deployment scope="user" autoDeploy="false" userCanCreateMore="true" />

Because no initializer class is specified, the SampleForm portlet uses the default initializer,

JspPortletInitializer. This initializer requires a page name as a parameter. The SampleForm portlet has its own JSP page named SampleForm.jsp.

<init-param>

<param-name>display-page</param-name>

<param-value>SampleForm.jsp</param-value>

</init-param>

The

<portlet-path>

element specifies the directory location in which the portlet will be deployed. The portlet identifier, which consists of the portlet path together with the portlet name (defined in the

<local-portlet>

element), must be unique within the SAS Information

Delivery Portal.

<portlet-path>/sample/portlets</portlet-path>

4 Step 3: Create the Display Page

35

To provide its interactive functionality, the SampleForm portlet has its own action class, named

DisplayAction. The name of the class is specified in the

type

subelement of the

<portlet-action>

element.

<portlet-actions>

<portlet-action name="display" default="true">

<type>sample.form.DisplayAction</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.form directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the portlet.xml file.

Step 3: Create the Display Page

JSP pages are the presentation components of portlets. The following example shows the code for the SampleForm portlet’s display page. This JSP page uses SAS custom tags, which require a license for SAS AppDev Studio software. For more information, see “Creating the Presentation JSP Page” on page 7. If SAS AppDev Studio software is not licensed at your site, you must substitute equivalent HTML or JSP coding instead.

<%-- Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513 --%>

<%@ page language="java" import="com.sas.portal.portlet.PortletContext, com.sas.portal.common.PortletConstants" contentType="text/html;charset=UTF-8" %>

<%@taglib uri="http://www.sas.com/taglib/sas" prefix="sas"%>

<%-- This portlet echoes user input back to the portlet display. --%>

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

%>

<sas:Form id="form" name="form" method="POST" action="<%= (String) context.getAttribute(\"formExample_baseURL\")%>">

<table border="0">

<tr>

<td align="right">Enter a value:</td>

<td><sas:TextEntry id="userInput" /></td>

</tr>

<tr>

<td align="right">You typed:</td>

<td><%=(String) context.getAttribute("formExample_userInput") %></td>

</tr>

36 Step 4: Create the Action Class

4 Chapter 4

</table>

<sas:PushButton id="submit" text="Submit Form" type="submit" />

</sas:Form>

Store this JSP code in a file named SampleForm.jsp in the portlet-source-directory/

Static/pars/sample.welcome/SampleWelcome/content

directory.

Step 4: Create the Action Class

The SampleForm portlet has its own action class, DisplayAction. The following example shows the source code for the DisplayAction class. For more information, see

“Creating Action Classes” on page 8.

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.

* All Rights Reserved.

*/ package sample.form; import java.util.Enumeration; import java.util.HashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; import com.sas.portal.portlet.HTMLPortletAction; import com.sas.portal.portlet.NavigationUtil; import com.sas.portal.portlet.PortletContext;

/**

* Action for the Form Example Portlet. This prepares the URL

* that is assigned to the form’s action within the portlet’s JSP.

* It also populates a bean with the parameters from the JSP form.

*

*/ public final class DisplayAction extends HTMLPortletAction { public DisplayAction() {

}

/**

* Prepare the URL for the form used in the portlet.

* Returns the value of "SampleForm.jsp".

*

* @param request The HtppServletRequest associated with the

* method invocation

* @param response HttpServletResponse associated with the

* method invocation

* @param context PortletContext mapped to the request path

*

* @return java.lang.String - representing a valid

4 Step 5: Create a JavaBean to Return User Input

37

* URL.

*/ public String service(HttpServletRequest request,

HttpServletResponse response, PortletContext context) throws Exception{ super.service(request, response, context);

// Prepare the base URL for setting on the form in the JSP.

// The "display" is the value used in portlet.xml for this

// action.

String baseURL = NavigationUtil.buildBaseURL(context, request,

"display"); context.setAttribute("formExample_baseURL", baseURL);

// Make a new ExampleBean. Alternatively, this could be made

// once in the portlet initializer class, then you manage

// its properties in the action.

ExampleBean bean = new ExampleBean();

// The BeanUtils class populates any bean with all the

// parameters from the form.

HashMap map = new HashMap();

Enumeration names = request.getParameterNames(); while (names.hasMoreElements()) {

String name = (String) names.nextElement(); map.put(name, request.getParameterValues(name));

}

BeanUtils.populate(bean, map);

// Put the userInput into the portlet context so we can get it out

// in the JSP.

context.setAttribute("formExample_userInput", bean.getUserInput());

} return "SampleForm.jsp"; private static final long serialVersionUID = 1L;

}

Create a directory named sample under the portlet-source-directory/Static/pars/

sample.form/SampleForm/source

directory, and then create a directory named form under the portlet-sourcedirectory/Static/pars/sample.form/SampleForm/source/

sample

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

form

directory.

Step 5: Create a JavaBean to Return User Input

The SampleForm portlet uses a JavaBean to place values in the PortletContext object so that the values are available to the JSP page.

38 Step 6: Create a Title and Description for the Portlet

4 Chapter 4

The HttpServletRequestor HttpSession object could be used for this purpose.

However, the PortletContext object is unique to the portlet and is not shared with other processes. Therefore, using it avoids collisions that could cause attribute values to be overwritten.

The following example shows the source code for the JavaBean:

/** Copyright (c) 2009 by SAS Institute Inc., Cary, NC 27513.

* All Rights Reserved.

*/ package sample.form; public final class ExampleBean {

/**

* Sets the user’s input to this property. If input

* is null, it is changed to "" so that getUserInput()

* never returns null.

*

* @param input

*/ public void setUserInput(String input) { if (input == null) { input = "";

} this.input = input;

}

/**

* Returns the user’s input or "".

*

* @return String

*/ public String getUserInput() { return input;

} private String input = "";

}

Store the source code for the JavaBean in a file named ExampleBean.java in the

portlet-source-directory/Static/pars/sample.form/SampleForm/source/sample/

form

directory.

Step 6: Create a Title and Description for the Portlet

The title and description for the SampleForm portlet are stored in a display resource file. See “Creating Display Resources Files” on page 6 for more information about display resource files.

Create the following display resource file for the SampleForm portlet: portlet.title=Form Portlet Sample portlet.description=Form Portlet Sample

Store this text in a file named portletDisplayResources.properties in the

portlet-source-directory/Static/pars/sample.form/SampleForm/classes directory.

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

39

Step 7: Compile Portlet Code

The action class that was defined in Step 4 and the JavaBean that was defined in

Step 5 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 SampleForm 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.form 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.

4

2

3

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.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleForm 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.

4

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.

4

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleForm

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 SampleForm 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

2

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.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleForm 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.

40 SampleDisplayURL: Editable Portlet

4 Chapter 4

3

4

5

6

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.

4

The portlet archive file is created in the SAS-configuration-directory/Lev1/Web/

Applications/SASPortlets4.2/Deployed

directory with the name

sample.form.par

.

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleForm

directory to determine whether any errors occurred.

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.

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

Start the Web application server on which the SAS Information Delivery Portal is deployed. The SampleForm 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.

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.

7

8

2

3

4

5

6

Create the portlet deployment descriptor (portlet.xml).

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

Error.jsp).

Create the action classes (Initializer.java, BaseAction.java, DisplayAction.java,

EditorAction.java, OKAction.java, CancelAction.java, and ErrorHandler.java).

Create resource bundles to supply user interface text.

Create a title and description for the portlet.

Compile portlet code.

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.

4

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

4 Step 1: Create the Portlet Configuration and Source Directories

41

2

3

4

referred to as portlet-configuration-directory in the code and descriptions for this portlet.

Copy the contents of the testportlet directory to theSampleDisplayURL directory.

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.

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.

4

# 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:

42 Step 2: Create the Portlet Deployment Descriptor

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

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

SAS installation.

6

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.

4

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” on page 4.

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

The DOCTYPE statement must be present in the descriptor file in order for the portlet to run.

However, the DTD does not need to be accessible at the URL that the statement specifies.

<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd">

<portlets>

In the

<local-portlet>

element, the value of the

title

attribute specifies the new portlet type that is displayed to users in the Create a New Portlet dialog box.

The attribute value editorType="portlet" indicates that portlets created from the template are editable. When this attribute value is specified, a portlet action with the attribute value

editor="true"

must also be specified. Otherwise, the portlet deployer sends a warning to the server log and does not deploy the portlet.

Note:

Add the word Sample to the name and title in order to distinguish this portlet from the URL Display portlet that is delivered with the portal.

4

<local-portlet name="@webapp.testportlet.contextroot@" title="URL Display Portlet Sample" editorType="portlet">

<localized-resources locales="en" />

The

<deployment>

element specifies that all portal users can create new instances of the portlet.

<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>

4 Step 2: Create the Portlet Deployment Descriptor

43

</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>

The following

<portlet-action>

element specifies the action class DisplayAction. The attribute value default="true" indicates that this is the default action class, which means that the class is invoked before the portlet’s JSP renders.

<portlet-actions>

<portlet-action name="display" default="true">

<type>sample.displayurl.DisplayAction</type>

</portlet-action>

The following

<portlet-action>

element specifies the action class EditorAction. The attribute value editor="true" indicates that this action is invoked when a user clicks the portlet’s

Edit

icon.

<portlet-action name="editor" editor="true">

<type>sample.displayurl.EditorAction</type>

</portlet-action>

The following

<portlet-action>

elements specify the action classes that are invoked when the user clicks

OK

and

Cancel

in the editor display page.

<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.

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

4 Chapter 4

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>

<%

}

}

%>

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

45

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">

46 Step 4: Create the Action Classes

4 Chapter 4

<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:

3

Initializer

3

BaseAction

3

DisplayAction

3

EditorAction

3

OKAction and CancelAction

3

ErrorHandler

4 Step 4: Create the Action Classes

47

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 {

48 Step 4: Create the Action Classes

4 Chapter 4

// 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;

4 Step 4: Create the Action Classes

49

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;

50 Step 4: Create the Action Classes

4 Chapter 4

}

/**

* 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

4 Step 4: Create the Action Classes

51

* @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

52 Step 4: Create the Action Classes

4 Chapter 4

*/ 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:

Example Code 4.1

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.

4 Step 4: Create the Action Classes

53

*/ 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.

Example Code 4.2

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;

54 Step 4: Create the Action Classes

4 Chapter 4 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;

4 Step 4: Create the Action Classes

55

/**

* 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= "";

}

56 Step 5: Create the Resource Bundle

4 Chapter 4 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” on page 6.

4

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.

4

# 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

4 Step 7: Compile Portlet Code

57

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” on page 6.

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.

4

2

3

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.

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.

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

4 Chapter 4

4

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.

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

2

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.

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.

5

6

3

4

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.

4

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

.

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleDisplayURL

directory to determine whether any errors occurred.

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.

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

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.

SampleRemote: Remote Portlet

Overview: Steps for Creating the SampleRemote Portlet

SampleRemote is a remote portlet that calls a Web application. The Web application displays the string Hello user, where user is the name of the user who is logged on to the SAS Information Delivery Portal. It also displays text that the user can edit.

To create the SampleRemote portlet, follow these steps:

4 Step 1: Create the Portlet Configuration and Source Directories

59

3

4

1

2

5

Create portlet configuration and source directories.

Create the enterprise application deployment descriptor (application.xml).

Create the Web application deployment descriptor (web.xml).

Create the Spring framework configuration file (infrastructure-config.xml).

Create the display pages for the Web application (Viewer.jsp, Editor.jsp, Error.jsp, and Help.jsp).

Create the controller servlet class (ControllerServlet.java).

6

7

8

Create the portlet deployment descriptor (portlet.xml).

Create a title and description for the portlet.

9

Compile the remote portlet.

10

Create the EAR and PAR files and deploy and test the portlet.

Note:

Before you begin developing the SampleRemote portlet, ensure that the SAS

Metadata Server is running so that metadata can be accessed during the configuration and deployment processes.

4

Step 1: Create the Portlet Configuration and Source Directories

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

1

2

Create a configuration directory for the portlet named SampleRemote 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.

Copy the contents of the testportlet directory to the SampleRemote directory.

3

4

Create a source code directory for the portlet named Source under the

SAS-configuration-directory/Lev1/CustomAppData/SampleRemote directory. This directory is referred to as portlet-source-directory in the code and descriptions for this portlet.

Edit the custom.properties file in the SampleRemote 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.

4

# 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=Remote 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=port-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

60 Step 2: Create the Enterprise Application Deployment Descriptor

4 Chapter 4

# 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.remote

# 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=SampleRemote

# 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=Remote Portlet Sample

5

From the SAS-configuration-directory/Lev1/CustomAppData/SampleRemote directory, run the following configuration script to create the source directory structure for building the portlet: cfg createRemotePortletDirectories -Dmetadata.connection.passwd="password"

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

SAS installation.

6

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.

4

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleRemote

directory to determine whether any errors occurred.

Step 2: Create the Enterprise Application Deployment Descriptor

Java Enterprise (J2EE) applications are deployed in the form of enterprise archive

(EAR) files. An enterprise application deployment descriptor file describes the Web projects and other components that comprise an EAR file. The following example shows the contents of the enterprise application deployment descriptor file for the

SampleRemote portlet:

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

<application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" version="1.4">

<display-name>@webapp.testportlet.contextroot@</display-name>

<description>@webapp.testportlet.display.name@</description>

<module>

<web>

<web-uri>@[email protected]</web-uri>

<context-root>@webapp.testportlet.contextroot@</context-root>

4 Step 3: Create the Web Application Deployment Descriptor

61

</web>

</module>

</application>

Store this text in a file named application.xml.orig in the

portlet-source-directory/Configurable/ears/sample.remote/META-INF directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the application.xml file.

The EAR file must also contain a manifest file that specifies information about the files packaged in the EAR. The SampleRemote portlet uses the following manifest file:

Manifest-Version: 1.0

Ant-Version: Apache Ant 1.7.0

Created-By: 1.5.0_12-b04 (Sun Microsystems Inc.)

Store this text in a file named MANIFEST.MF in the portlet-source-directory/Static/

ears/sample.remote/META-INF

directory.

Note:

This file is placed in the /Static directory hierarchy rather than the /

Configurable

directory hierarchy because no substitution is required.

4

Step 3: Create the Web Application Deployment Descriptor

The Web application deployment descriptor is an XML file that describes the Web application’s initialization parameters, servlets, and other components. The following example shows the contents of the deployment descriptor file for the SampleRemote portlet’s Web application. For more information about creating Web application deployment descriptors, see the documentation for your servlet container.

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

<web-app id="@webapp.testportlet.contextroot@" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/spring-config/infrastructure-config.xml</param-value>

</context-param>

<context-param>

<param-name>locatorFactorySelector</param-name>

<param-value>classpath:beanRefContext.xml</param-value>

</context-param>

<context-param>

<param-name>parentContextKey</param-name>

<param-value>config.context</param-value>

</context-param>

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>com.sas.servlet.filters.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

62 Step 3: Create the Web Application Deployment Descriptor

4 Chapter 4

<filter>

<filter-name>PortletSecurityFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy

</filter-class>

<init-param>

<param-name>targetBeanName</param-name>

<param-value>portletSecurityFilter</param-value>

</init-param>

<init-param>

<param-name>targetFilterLifecycle</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>trusted.url</param-name>

<param-value>Logoff</param-value>

</init-param>

</filter>

<filter>

<filter-name>WIPPlatformServicesFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy

</filter-class>

<init-param>

<param-name>targetBeanName</param-name>

<param-value>platformServicesFilter</param-value>

</init-param>

<init-param>

<param-name>targetFilterLifecycle</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter>

<filter-name>RemotePortletFilter</filter-name>

<filter-class>com.sas.portal.portlet.remote.RemotePortletFilter

</filter-class>

<init-param>

<param-name>allow-webapp-mode</param-name>

<param-value>false</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>PortletSecurityFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>WIPPlatformServicesFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>RemotePortletFilter</filter-name>

4 Step 3: Create the Web Application Deployment Descriptor

63

<url-pattern>/*</url-pattern>

</filter-mapping>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<listener>

<listener-class>com.sas.common.components.SpringComponentFacade

</listener-class>

</listener>

<servlet>

<servlet-name>logoff</servlet-name>

<servlet-class>com.sas.svcs.webapp.servlet.DelegatingServletProxy

</servlet-class>

<init-param>

<param-name>targetBeanName</param-name>

<param-value>logoffServlet</param-value>

</init-param>

</servlet>

<servlet>

<servlet-name>ControllerServlet</servlet-name>

<servlet-class>sample.remote.ControllerServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>logoff</servlet-name>

<url-pattern>/Logoff</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>ControllerServlet</servlet-name>

<url-pattern>/Controller</url-pattern>

</servlet-mapping>

<session-config>

<session-timeout>30</session-timeout>

</session-config>

</web-app>

Store this Web application deployment descriptor source text in a file named

web.xml.orig

in the portlet-source-directory/Configurable/wars/sample.remote/

WEB-INF

directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the web.xml file.

The following files provide additional settings for Web application servers. For more information about configuring Web application servers, see SAS Intelligence Platform:

Web Application Administration Guide.

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

<jboss-web>

<security-domain>java:/jaas/PFS</security-domain>

<context-root>@webapp.testportlet.contextroot@</context-root>

</jboss-web>

64 Step 4: Create the Spring Framework Configuration File

4 Chapter 4

Store this text in a file named jboss-web.xml.orig in the portlet-source-directory/

Configurable/wars/sample.remote/WEB-INF

directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the jboss-web.xml

file.

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

<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<jsp-descriptor>

<jsp-param>

<param-name>page-check-seconds</param-name>

<param-value>-1</param-value>

</jsp-param>

</jsp-descriptor>

<container-descriptor>

<servlet-reload-check-secs>-1</servlet-reload-check-secs>

<prefer-web-inf-classes>true</prefer-web-inf-classes>

</container-descriptor>

<context-root>@webapp.testportlet.contextroot@</context-root>

</weblogic-web-app>

Store this text in a file named weblogic-web.xml.orig in the

portlet-source-directory/Configurable/wars/sample.remote/WEB-INF directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the weblogic-web.xml file.

Step 4: Create the Spring Framework Configuration File

The Web application for the SampleRemote portlet uses the open-source Spring J2EE application development framework. An infrastructure configuration file defines the

Spring framework components that are used in the application. The following example shows the infrastructure configuration file for the SampleRemote portlet. For more information about the Spring framework, see http://www.springsource.org.

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

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<!-- Public ids provided as a part of these files are: sas.framework.commons.jar: configurationService, urlGenerator sas.framework.themes.jar: themeService sas.svcs.mail.client.jar: mailService sas.svcs.directives.client.jar: directivesService sas.svcs.security.client.jar: authenticationService, userValidationService sas.svcs.userinfo.client.jar: userInfoService sas.svcs.status.client.jar: capabilityVerification, systemValidationService

Each of these depends on an id defined elsewhere for sas.svcs.cache.

-->

<import resource="classpath*:META-INF/wip-services-client-config.xml" />

<import resource="classpath*:META-INF/spring-config/aop-config.xml" />

<import resource="classpath*:META-INF/spring-config/data-config.xml" />

<import resource="classpath*:META-INF/spring-config/webapp-config.xml" />

<import resource="classpath*:META-INF/spring-config/presentation-config.xml" />

4 Step 5: Create the Display Pages for the Web Application

65

<import resource="classpath*:META-INF/spring-config/jps-config.xml" />

<import resource="classpath*:META-INF/spring-config/portlet-config.xml" />

</beans>

Store this text in a file named infrastructure-config.xml in the

portlet-source-directory/Static/wars/sample.remote/WEB-INF/spring-config directory.

Step 5: Create the Display Pages for the Web Application

The Web application for the SampleRemote 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.

Help.jsp

displays help information for the portlet.

Create the Viewer.jsp Page

The following example shows the code for the Viewer JSP page, which is the presentation component of the SampleRemote 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.NavigationUtil" %>

<%@ page import="com.sas.portal.portlet.RemotePortletContext" %>

<%@ page import="com.sas.portal.portlet.remote.RemotePortletToolkitUtil" %>

<%@ page import="com.sas.services.user.UserContextInterface" %>

<%@ page import="com.sas.web.keys.CommonKeys" %>

<%@ page import="com.sas.webapp.contextsharing.WebappContextParams" %>

<%@ page import="sample.remote.ControllerServlet" %>

<% try {

// Get the Remote User Context Information

UserContextInterface uc =

(UserContextInterface) session.getAttribute(CommonKeys.REMOTE_USER_CONTEXT);

// Determine the Display Name of the user (Remote User Context).

String user = uc.getPerson().getDisplayName();

%>

RemotePortletContext pcontext =

RemotePortletToolkitUtil.getRemotePortletContext(request);

String pid = pcontext.getId();

String param_name = "sample.param." + pid;

String param_value = (request.getParameter(param_name) == null) ?

"" : "checked";

String submiturl = NavigationUtil.buildBaseURL(pcontext, request, "formsubmit");

<p>This remote portlet supports view mode, edit mode,and help mode.</p>

66 Step 5: Create the Display Pages for the Web Application

4 Chapter 4

<p>Hello <%= user %>.</p>

<p>Data value: <%= session.getAttribute(ControllerServlet.DATA_KEY1 + pid) %></p>

<form method="post" action="<%= submiturl %>">

<input name="<%= param_name %>" type="checkbox" <%= param_value %> />

<%= param_name %>

<br />

<button type="submit">Submit</button>

</form>

<%

} catch (Throwable thr1) { thr1.printStackTrace();

}

%>

Store this JSP code in a file named Viewer.jsp in the portlet-source-directory/

Static/wars/sample.remote/jsp

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 SampleRemote portlet:

<%@ page language="java" contentType="text/html; charset=UTF-8" %>

<%@ page import="com.sas.portal.portlet.RemotePortletContext" %>

<%@ page import="com.sas.portal.portlet.remote.RemotePortletToolkitUtil" %>

<%@ page import="sample.remote.ControllerServlet" %>

<%

%>

RemotePortletContext pcontext =

RemotePortletToolkitUtil.getRemotePortletContext(request);

String pid = pcontext.getId();

<table border="0" cellpadding="2" cellspacing="0" align="center" width="100%">

<tr>

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

</tr>

<tr>

<td> </td>

<td nowrap align="center">Edit Page</td>

<td> </td>

</tr>

<tr>

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

</tr>

<tr>

<form method="post" action="<%= request.getAttribute(ControllerServlet.EDIT_OK) %>" accept-charset="UTF-8">

<td> </td>

<td> <table border="0" cellpadding="0" cellspacing="0" align="center">

<tr>

4 Step 5: Create the Display Pages for the Web Application

67

<td class="celljustifyright" nowrap>Input:</td>

<td> </td>

<td class="celljustifyleft" nowrap>

<input type="text" name="<%= ControllerServlet.EDIT_FIELD1 %>" value="<%= session.getAttribute(ControllerServlet.DATA_KEY1 + pid) %>" size="25">

</td>

</tr>

<tr>

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

</tr>

<tr>

<td class="celljustifyright">

<input class="button" type="submit" value="Ok" name="submit" >

</form>

</td>

<td> </td>

<td class="celljustifyleft">

<form method="post" action="<%= request.getAttribute(ControllerServlet.EDIT_CANCEL) %>" accept-charset="UTF-8">

<input class="button" type="submit" value="Cancel" name="submit" >

</form>

</td>

</tr>

</table>

</td>

</tr>

</table>

Store this JSP code in a file named Editor.jsp in the portlet-source-directory/

Static/wars/sample.remote/jsp

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:

<%@ page language="java" contentType= "text/html; charset=UTF-8" %>

<%@ page import="sample.remote.ControllerServlet" %>

<h1>Error</h1>

<p><%= request.getAttribute(ControllerServlet.ERROR_MESSAGE) %></p>

Store this JSP code in a file named Error.jsp in the portlet-source-directory/

Static/wars/sample.remote/jsp

directory.

Create the Help.jsp Page

The following example shows the code for the Help JSP page, which displays text to help the user understand how to use the portlet:

<%@ page language="java" contentType= "text/html; charset=UTF-8" %>

<%@ page import="com.sas.portal.portlet.RemotePortletContext" %>

<%@ page import="com.sas.portal.portlet.remote.RemotePortletToolkitUtil" %>

<%@ page import="sample.remote.ControllerServlet" %>

68 Step 6: Create the Controller Servlet Class

4 Chapter 4

<% try {

RemotePortletContext pcontext =

RemotePortletToolkitUtil.getRemotePortletContext(request);

String pid = pcontext.getId();

%>

<h1>Portlet Help</h1>

<p>Portlet ID: <%= pid %></p>

<p>This is where portlet help would be displayed</p>

<%

} catch (Throwable thr1) { thr1.printStackTrace();

}

%>

Store this JSP code in a file named Help.jsp in the portlet-source-directory/Static/

wars/sample.remote/jsp

directory.

Step 6: Create the Controller Servlet Class

The SampleRemote portlet has its own class, ControllerServlet, to support the actions of the JSP pages for the application. The following example shows the source code for the ControllerServlet class.

Note:

This example uses the remote user context to obtain application metadata.

This is the simplest way for a remote portlet to obtain metadata, but it has a negative effect on performance because Java objects execute in the remote services JVM rather than locally. For more information about remote contexts, see “Obtaining a User and

Session Context” on page 16

4 package sample.remote; import com.sas.portal.portlet.NavigationUtil; import com.sas.portal.portlet.PortletContext; import com.sas.portal.portlet.RemotePortletContext; import com.sas.portal.portlet.remote.RemotePortletToolkitUtil; import com.sas.services.session.SessionContextInterface; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class ControllerServlet extends HttpServlet {

/* Request attribute key for the error screen error message */ public static final String ERROR_MESSAGE = "sample.remote.errormessage";

/* Request attribute key for the edit screen Ok button URL */ public static final String EDIT_OK = "sample.remote.editok.url";

4 Step 6: Create the Controller Servlet Class

69

/* Request attribute key for the edit screen Cancel button URL */ public static final String EDIT_CANCEL = "sample.remote.editcancel.url";

/* Name of field1 input parameter */ public static final String EDIT_FIELD1 = "sample.remote.editfield1.name";

/* Attribute name for persistent storage of string entered during edit mode */ public static final String DATA_KEY1 = "sample.remote.key1."; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException

{ processRequest(request, response);

} public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException

{ processRequest(request, response);

} public boolean processRequest(HttpServletRequest request,

HttpServletResponse response) throws ServletException

{

String data; try {

// If there are multiple instances of the same remote portlet in a

// users portal session, they will use the same HttpSession. This

// requires session attributes to be namespaced.

HttpSession session = request.getSession();

ServletContext servletContext = getServletConfig().getServletContext();

// Check for logoff notification before doing anything else. Multiple

// portlet instance can have information stored in the HttpSession,

// but the logoff request will only be processed once. Use of an

// HttpSessionBindingListener is recommended if resources need to be

// cleaned up when the session is invalidated.

if (RemotePortletToolkitUtil.isLogoffRequest(request)) { session.invalidate(); return false;

}

// Retrieve the remote portlet context that is needed to process

// the request.

RemotePortletContext pcontext =

RemotePortletToolkitUtil.getRemotePortletContext(request); if (pcontext == null) {

// If there is no remote portlet context, goto error page.

request.setAttribute(ERROR_MESSAGE, "No remote portlet context");

RequestDispatcher rd = servletContext.getRequestDispatcher("/jsp/Error.jsp");

70 Step 6: Create the Controller Servlet Class

4 Chapter 4 rd.forward(request, response); return false;

}

// The portlet id is uniquely identifies a portlet instance.

String pid = pcontext.getId();

// A remote portlet does not have access to the portlet Configuration

// object, so it is responsible for persisting data. This codes uses

// the HttpSession to cache data, but does not implement a persistent

// store.

if (session.getAttribute(DATA_KEY1 + pid) == null) session.setAttribute(DATA_KEY1 + pid, "initial state");

String jspurl = null;

String action = RemotePortletToolkitUtil.getAction(request, pcontext); if (action.equalsIgnoreCase(RemotePortletToolkitUtil.PAGE_REFRESH_ACTION)

|| action.equalsIgnoreCase("default")) {

// This portlet was called with either the default action or

// no action. Both indicate a page refresh.

jspurl = "/jsp/Viewer.jsp";

} else if (action.equalsIgnoreCase("urlsubmit")) {

// This is where the portlet would process submit parameters.

// When finished processing, redisplay.

jspurl = "/jsp/Viewer.jsp";

} else if (action.equalsIgnoreCase("formsubmit")) {

// This is where the portlet would process submit parameters.

// When finished processing, redisplay.

jspurl = "/jsp/Viewer.jsp";

} else if (action.equalsIgnoreCase("startedit")) {

// Start edit mode.

// The following call resets the portlet mode back to

// display mode when the submit URL is issued and thus

// needs to be called before NavigationUtil.buildBaseURL

pcontext.resetMode();

//Create the URLs for the OK and Cancel buttons.

String submiturl =

NavigationUtil.buildBaseURL(pcontext, request, "endedit"); request.setAttribute(EDIT_OK, submiturl); request.setAttribute(EDIT_CANCEL, submiturl); jspurl = "/jsp/Editor.jsp";

} else if (action.equalsIgnoreCase("endedit")) {

// Exit edit mode

String submitAction = request.getParameter("submit"); if ((submitAction != null)

&& submitAction.equalsIgnoreCase("Ok")) {

// This is where you would add code to persist changes and

4 Step 7: Create the Portlet Deployment Descriptor

71

// update your model.

data = request.getParameter(EDIT_FIELD1); session.setAttribute(DATA_KEY1 + pid, data);

}

// When finished processing, redisplay.

jspurl = "/jsp/Viewer.jsp";

} else if (action.equalsIgnoreCase("help")) {

// Help mode.

jspurl = "/jsp/Help.jsp";

} else {

// An error occurred.

request.setAttribute(ERROR_MESSAGE,

"Unknown portlet action: " + action); jspurl = "/jsp/Error.jsp";

}

RequestDispatcher rd = servletContext.getRequestDispatcher(jspurl); rd.forward(request, response);

} catch (Exception ex) { ex.printStackTrace(); throw new ServletException(ex);

} return true;

}

}

Create a directory named sample under the portlet-source-directory/Static/wars/

sample.remote/source

directory, and then create a directory named remote under the

portlet-source-directory/Static/wars/sample.remote/source/sample directory. Store the class source code in a file named ControllerServlet.java in the

portlet-source-directory/Static/wars/sample.remote/source/sample/remote directory.

Step 7: 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 contents of the portlet deployment descriptor file for the

SampleRemote. For more information about portlet deployment descriptor files, see

“Creating a Portlet Deployment Descriptor” on page 4.

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

The DOCTYPE statement must be present in the descriptor file in order for the portlet to run.

However, the DTD does not need to be accessible at the URL that the statement specifies.

<!DOCTYPE portlets SYSTEM "http://www.sas.com/idp/portlet.dtd">

<portlets>

72 Step 7: Create the Portlet Deployment Descriptor

4 Chapter 4

The

<remote-portlet>

element assigns the name SampleRemote to the portlet. The name cannot contain spaces. The portlet identifier, which consists of the portlet path (defined in the

<portlet-path>

element) together with the portlet name, must be unique within the SAS

Information Delivery Portal.

The true setting for the

passContextId=

attribute makes the SAS Information Delivery Portal session information, including user identity, available to the remote portlet.

<remote-portlet name="@webapp.testportlet.contextroot@" title="@webapp.testportlet.display.name@" passContextId="true" editorType="portlet" showEditProperties="true">

<localized-resources locales="en" />

<deployment scope="user" autoDeploy="false" userCanCreateMore="true" />

<portlet-path>/sample/portlets/remote</portlet-path>

The URL for the remote portlet’s Web application, named HelloUserWebApp, is specified in the

<url>

subelement of the

<portlet-action>

element. This subelement must contain a fully qualified URL, including a fully qualified host domain name.

<portlet-actions>

<portlet-action name="default" default="true">

<url>@javaportal.url@@webapp.testportlet.contextroot@/Controller</url>

</portlet-action>

<portlet-action name="startedit" editor="true">

<url>@javaportal.url@@webapp.testportlet.contextroot@/Controller</url>

</portlet-action>

<portlet-action name="endedit">

<url>@javaportal.url@@webapp.testportlet.contextroot@/Controller</url>

</portlet-action>

<portlet-action name="help" help="true">

<url>@javaportal.url@@webapp.testportlet.contextroot@/Controller</url>

</portlet-action>

<portlet-action name="logoff" remote-logoff="true">

<url>@javaportal.url@@webapp.testportlet.contextroot@/Controller</url>

</portlet-action>

</portlet-actions>

</remote-portlet>

</portlets>

Store this portlet deployment descriptor source text in a file named

portlet.xml.orig

in the portlet-source-directory/Configurable/pars/

sample.remote

directory. The testportlet scripting facility performs name/value pair substitution on this file to produce the portlet.xml file.

4 Step 9: Compile the Remote Portlet

73

Step 8: Create a Title and Description for the Portlet

The SampleRemote portlet uses a display resources file to provide a description that is placed in the portlet’s metadata for display to users. If this file is not provided, the portal creates a default description based on the portlet’s name. For more information about display resources files, see “Creating Display Resources Files” on page 6.

For the SampleRemote portlet, create a display resources file with the following content: portlet.title=Remote Portlet Sample portlet.description=Remote Portlet Sample

Store this text in a file named portletDisplayResources.properties in the

portlet-source-directory/Static/pars/sample.remote/SampleRemote/classes directory.

Step 9: Compile the Remote Portlet

The action class that was defined in Step 6 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 SampleRemote 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/wars/sample.remote 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.

4

2

3

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.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleRemote directory, run the configuration script with the following arguments to compile the

Java class: cfg compileRemotePortlet -Dmetadata.connection.passwd="password"

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

SAS installation.

4

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.

4

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleRemote

directory to determine whether any errors occurred.

74 Step 10: Create the EAR and PAR Files and Deploy and Test the Portlet

4 Chapter 4

Step 10: Create the EAR and PAR Files and Deploy and Test the Portlet

The last step in developing the SampleRemote portlet is to archive its files into EAR and PAR files and deploy the Web application and the new portlet. For a remote portlet, the EAR file includes all of the Web application’s supporting files, including the files created in Steps 2 through 6. The PAR file contains the portlet definition created in

Steps 7 and 8. To create the EAR and PAR files and deploy the Web application and the portlet, follow these steps:

1

2

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.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleRemote directory, run the configuration script with the following arguments: cfg buildWebapps -Dmetadata.connection.passwd="password"

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

SAS installation.

3

4

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.

4

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleRemote

directory to determine whether any errors occurred.

From the SAS-configuration-directory/Lev1/CustomAppData/SampleRemote directory, run the configuration script with the following arguments: cfg deployWebapps -Dmetadata.connection.passwd="password"

7

8

5

6

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

SAS installation.

The sample.remote.ear file containing the Web application will be copied to the staging area under the SAS configuration directory. You must manually deploy the file to your Web application server.

Review the customconfig.log file in the SAS-configuration-directory/Lev1/

CustomAppData/SampleRemote

directory to determine whether any errors occurred.

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.

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

Start the Web application server on which the SAS Information Delivery Portal is deployed. The SampleRemote 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.

A P P E N D I X

1

Moving Existing Custom Portlets to SAS Information Delivery

Portal 4.2

75

Overview

75

Java Package Changes

75

JAR File Changes

75

Smart Object Changes

76

Remote Portlet API Changes

76

Logoff Portlet Action

76

RemotePortletToolkitUtil Classes

76

Overview

Custom portlets developed for the previous version of the SAS Information Delivery

Portal must be recompiled before they can be used in SAS Information Delivery Portal

4.2. In some cases, additional modification might be necessary. This appendix describes some of the portal framework changes that affect custom portlets.

Java Package Changes

Portlets that use the following Java classes must be updated and recompiled:

3

3

3 com.sas.portal.mgmt.api.MetadataCredentialsHolder must be changed to com.sas.portal.common.MetadataCredentialsHolder

com.sas.portal.mgmt.api.MetadataCredentialsProvider must be changed to com.sas.portal.common.MetadataCredentialsProvider

com.sas.portal.portlet.PortletConstants must be changed to com.sas.portal.common.PortletConstants

These package changes resolve circular dependencies.

JAR File Changes

Portlets that include the sas.portal.metadata.jar file must remove it from build-time and run-time dependency lists. The sas.portal.jar and sas.portal.metadata.jar files were collapsed into a single sas.portal.jar file to resolve circular dependencies.

76 Smart Object Changes

4 Appendix 1

Smart Object Changes

Portlets that reference the SAS 9.1.3 SP4 smart object com.sas.portal.metadata.omr.OMRPortalSubscriber must be changed to reference the

SAS 9.2 smart object com.sas.services.information.metadata.OMRContentSubscriber.

Remote Portlet API Changes

Logoff Portlet Action

The logoff portlet action allows the Web application associated with the remote portlet to receive notification when a user logs off the portal. This allows resources to be cleaned up immediately, as opposed to waiting for an HttpSession time-out. To implement, the portlet.xml file must contain a logoff action like the following:

</portlet-action>

<portlet-action name="logoff" remote-logoff="true">

<url>http://host-name:8080/SASRemotePortlet/Controller</url>

</portlet-action>

The following code in the remote portlet Web application processes the logoff action:

// Check for logoff notification before doing anything else.

if (RemotePortletToolkitUtil.isLogoffRequest(request)) { session.invalidate(); return false;

}

RemotePortletToolkitUtil Classes

The com.sas.portal.portlet.remote.RemotePortletToolkitUtil class contains the following new utility methods that make it easier to write remote portlets:

3

A convenience routine that returns the portlet action targeted to the current portlet instance: static String getAction(HttpServletRequest request,

RemotePortletContext context)

3

The portlet action is defined in the portlet.xml file. If the request is targeted to another portlet instance or the page is refreshing, it returns

RemotePortletToolkitUtil.PAGE_REFRESH_ACTION.

A convenience routine that returns the portlet ID for the current portlet: static String getPortletId(HttpServletRequest request)

Because the portlet ID is unique per portlet instance, this provides a mechanism for allowing multiple portlet instances on a page,

3

A convenience routine to retrieve the RemotePortletContext for the portlet: static RemotePortletContext getRemotePortletContext(HttpServletRequest request)

Moving Existing Custom Portlets

4 RemotePortletToolkitUtil Classes

77

3

A convenience routine that checks for a logoff notification: static boolean isLogoffRequest(HttpServletRequest request)

3

This call should be made before processing the request. Multiple portlet instances can have information stored in the HttpSession, but the logoff request is processed only once. Use an HttpSessionBindingListener if resources need to be cleaned up when the session is invalidated.

A convenience routine that returns true if the request was targeted to the current portlet instance: static boolean isPortletRequest(HttpServletRequest request)

78

Index

A

action classes

8

error handling

10

initializer

8

portlet

9

postprocessing

10

application programming interface

See Portlet API

D

display resources file

6

document type definition

4

DTD

See document type definition

E

EAR files

See enterprise archive files enterprise archive files

60

error handling action class

10

H

help

11

I

initializer action class

8

J

Java Standard Tag Libraries

7

JavaServer Pages files

7

JSP files

See JavaServer Pages files

JSTL

See Java Standard Tag Libraries

L

local context

16

local portlet

4

N

namespace

15

P

PAR file

See portlet archive file picklist

23

portlet

1

API

19

deploying in portal

13

deployment descriptor

3

display page

3

display resources file

3

implementing help

11

local

4

localizing descriptions

6

localizing titles

6

moving existing portlets

75

namespaces

15

obtaining user locale

17

obtaining user name

17

remote

5

samples

22

scripting facility

22

portlet action class

9

Portlet API

19

portlet archive file

2, 13

directory structure

13

portlet configuration directory

See testportlet scripting facility portlet deployment descriptor

4

portlet source directory

See testportlet scripting facility portlet.xml file

See portlet deployment descriptor postprocessing action class

10

R

remote context

16

remote portlet

5

resource bundle

30

S

sample portlets

SampleDisplayURL

40

79

80

Index

SampleForm

32

SampleRemote

58

SampleWelcome

24

SampleDisplayURL portlet

40

SampleForm portlet

32

SampleRemote portlet

58

SampleWelcome portlet

24

SAS AppDev Studio

3

SAS custom tags

7

SAS Foundation Services

16

SAS Information Delivery Portal

1

session context

16

Spring framework

64

T

taglib directive

7

testportlet scripting facility

22

configuration script

23

portlet configuration directory

23

portlet source directory

23

U

user context

16

UTF-8 directive

7

V

Versioned JAR Repository

22

W

Web application deployment descriptor

61

Your Turn

We welcome your feedback.

3

3

If you have comments about this book, please send them to [email protected].

Include the full title and page numbers (if applicable).

If you have comments about the software, please send them to [email protected].

SAS

®

Publishing Delivers!

Whether you are new to the work force or an experienced professional, you need to distinguish yourself in this rapidly changing and competitive job market. SAS

®

Publishing provides you with a wide range of resources to help you set yourself apart. Visit us online at support.sas.com/bookstore.

SAS

®

Press

Need to learn the basics? Struggling with a programming problem? You’ll find the expert answers that you need in example-rich books from SAS Press. Written by experienced SAS professionals from around the world, SAS Press books deliver real-world insights on a broad range of topics for all skill levels.

s u p p o r t . s a s . c o m / s a s p r e s s

SAS

®

Documentation

To successfully implement applications using SAS software, companies in every industry and on every continent all turn to the one source for accurate, timely, and reliable information: SAS documentation.

We currently produce the following types of reference documentation to improve your work experience:

• Online help that is built into the software.

• Tutorials that are integrated into the product.

• Reference documentation delivered in HTML and PDF –

free on the Web.

• Hard-copy books.

s u p p o r t . s a s . c o m / p u b l i s h i n g

SAS

®

Publishing News

Subscribe to SAS Publishing News to receive up-to-date information about all new SAS titles, author podcasts, and new Web site features via e-mail. Complete instructions on how to subscribe, as well as access to past issues, are available at our Web site.

s u p p o r t . s a s . c o m / s p n

SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration.

Other brand and product names are trademarks of their respective companies. © 2009 SAS Institute Inc. All rights reserved. 518177_1US.0109

advertisement

Key Features

  • Provides a framework for developing custom portlets
  • Uses the open-source Struts architecture and conforms to industry-standard Model-View-Controller (Model 2) design patterns
  • Supports portlets running remotely in other Web technology frameworks
  • Simplifies portlet deployment using a portlet deployment descriptor and a portlet archive (PAR) file
  • Provides a set of action and initializer classes to reduce the need for developing custom programs
  • Provides access to SAS custom tags and to tags in the Struts development framework to simplify development of JSP pages for your portlets

Frequently Answers and Questions

How can I create a custom portlet for the SAS Information Delivery Portal?
This document outlines the steps for developing and deploying custom portlets in the SAS Information Delivery Portal. It covers topics such as creating portlet deployment descriptors, developing JSP pages, and implementing portlet help.
What are the different types of portlets that can be developed?
You can develop local portlets, which run within the SAS Information Delivery Portal, and remote portlets, which execute outside of the portal container. Local portlets have access to the SAS Information Delivery Portal’s local user and session context, while remote portlets have access to a remote user and session context.
How can I test a custom portlet I have developed?
To test a local portlet, deploy it into a staging area, which is a test installation of the SAS Information Delivery Portal. To test a remote portlet, test and debug the Web application that is called by the portlet by using the application's direct URL.

Related manuals

Download PDF

advertisement

Table of contents