Sun logo      Previous      Contents      Index      Next     

Sun ONE Portal Server 6.2 Developer's Guide

Chapter 6
Developing and Deploying Portlets

The Sun™ ONE Portal Server software includes an implementation of the Portlet Specification as defined by the JSR168 Expert Group. This chapter includes the following sections:


What is a Portlet?

Portlet refers to pluggable web components that process requests and generate content within the context of a portal. In the Sun ONE Portal Server software, portlets are managed by the Portlet Container. Conceptually, portlets they are equivalent to the Providers.


Overview of Developing and Deploying Portlets

To develop and deploy portlets:

  1. Develop the portlet class file.
  2. Create the portlet specific XML fragments and package it into a WAR file.
  3. Deploy the Portlet web application.
  4. Create and view the Portlets.


Extending the GenericPortlet Abstract Class

This section includes instructions for extending the GenericPortlet abstract class. It includes instructions to create a sample portlet named PrefPortlet. In the view mode, this portlet displays a salutation. In the edit mode of PrefPortlet, the user can change that salutation. The modified salutation is saved into the preference to be used for subsequent requests to the portlet.

Develop the Class File

Code Example 6-1 contains the class file for the sample PrefPortlet.

Code Example 6-1  PrefPortlet.java File  

package examples;

import javax.portlet.GenericPortlet;

import javax.portlet.ActionRequest;

import javax.portlet.RenderRequest;

import javax.portlet.ActionResponse;

import javax.portlet.RenderResponse;

import javax.portlet.PortletException;

import javax.portlet.PortletURL;

import javax.portlet.PortletMode;

import javax.portlet.PortletPreferences;

import javax.portlet.WindowState;

import java.io.IOException;

import java.io.PrintWriter;

public class PrefPortlet extends GenericPortlet {

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException {

        // process the salutation set by the user in the edit mode.

        String salutation = request.getParameter("SALUTATION");

        try {

            PortletPreferences pref = request.getPreferences();

            pref.setValue("salutation", salutation);

            pref.store();

        } catch (Exception e) {

            throw new PortletException(e.getMessage());

        }

        // return the user back to the view mode and normal state

        response.setPortletMode(PortletMode.VIEW);

        response.setWindowState(WindowState.NORMAL);

    }

    public void doView(RenderRequest request,RenderResponse response) throws PortletException,IOException {

        // displays the salutation stored in the preference.

        PortletPreferences pref = request.getPreferences();

        String salutation = pref.getValue("salutation","");

        response.setContentType(request.getResponseContentType());

        PrintWriter writer = response.getWriter();

        writer.write("Hello " + salutation);

    }

    public void doEdit(RenderRequest request,RenderResponse response) throws PortletException,IOException {

        // prompt the user for the salutation.

        PortletURL actionURL = response.createActionURL();

        response.setContentType(request.getResponseContentType());

        PrintWriter writer = response.getWriter();

        writer.write("<form method=’post’ action=’" + actionURL.toString());

        writer.write("’><TABLE WIDTH=’100%’><TR><TD ALIGN=’RIGHT’ VALIGN=’TOP’>salutation:</TD><TD ALIGN=’LEFT’><INPUT TYPE=’TEXT’ NAME=’SALUTATION’></TD></TR><TR><TD ALIGN=’RIGHT’>&nbsp;</TD><TD ALIGN=’LEFT’><INPUT TYPE=’SUBMIT’ NAME=’SUB1’ VALUE=’Submit’></TD></TR></TABLE></form>");

    }

    public void doHelp(RenderRequest request, RenderResponse response) throws PortletException {

        response.setContentType(request.getResponseContentType());

        try {

            response.setContentType(request.getResponseContentType());

            PrintWriter writer = response.getWriter();

            writer.write("Pref Portlet Help<p><p>");

        } catch (IOException e) {

            throw new PortletException("PrefPortlet.doHelp exception", e);

        }

    }

}

Compile the Portlet

When compiling a portlet, include the classpath. Ensure that portlet.jar is in your classpath when compiling the portlet. For example, to compile, type:

javac -classpath portal-server-install-root/SUNWps/lib/portlet.jar PrefPortlet.java


Note

This compiled class file must be included in the WAR file that will be deployed on the Portal Server using the pdeploy command.


Create a Portlet Web Application

Assemble the portlet class file and the XML fragments into a portlet web application. A portlet web application must be packaged as a WAR file. The portlet.xml file must be placed into the same location as the web.xml file.

To create a portlet web application:

  1. Create a complete portlet.xml file that includes the declaration for all the portlets.
  2. Code Example 6-2 contains the portlet.xml file that includes the declaration for the sample portlet. In Code Example 6-2, the XML file includes name, class, and cache information. Since the sample portlet also uses preferences, the preference setting is also included in the portlet.xml file. Also PrefPortlet supports the EDIT as well as HELP mode; so the supported modes are specified in the portlet.xml file.

    Code Example 6-2  portlet.xml File for the PrefPortlet  

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

    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:portlet="http://java.sun.com/xml/ns/portlet"

    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/portlet" version="1.0">

        <portlet>

            <portlet-name>PrefPortlet</portlet-name>

            <portlet-class>examples.PrefPortlet</portlet-class>

            <expiration-cache>0</expiration-cache>

            <supports>

                <mime-type>text/html</mime-type>

                <portlet-mode>EDIT</portlet-mode>

                <portlet-mode>HELP</portlet-mode>

            </supports>

            <portlet-info>

                <title>PrefPortlet</title>

                <keywords>Hello, world, test</keywords>

            </portlet-info>

            <portlet-preferences>

                <preference>

                    <name>name</name>

                    <value>World</value>

                </preference>

            </portlet-preferences>

        </portlet>

    </portlet-app>

  3. Create the web.xml file. A web application also requires a web.xml file.
  4. If you have servlets for your portlet web application, then the servlet definition can be incorporated in the web.xml file. Code Example 6-3 contains the web.xml file for the sample portlet.

    Code Example 6-3  web.xml File for PrefPortlet  

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

        <display-name>Portlet Examples</display-name>

    </web-app>

  5. Package everything into a WAR file.
  6. For the sample portlets, create an examples directory where all the files of the WAR will be placed. Then within the examples directory, create the WEB-INF directory. All the portlet files will be placed into the WEB-INF directory. For example, your directory hierarchy may look like this:

    examples/WEB-INF/

                    /web.xml

                    /portlet.xml

                    /classes/examples/PrefPortlet.class

  7. Create the WAR file. That is, change directories to examples and type the following command:
  8. jar -cvf examples.war *

Deploy the Application

The Sun ONE Portal Server software includes a deployment tool which will take your WAR and deploy it into the portal server. Before deploying the WAR file, determine where to place the portlets inside the organization.

With the following command, the sample portlets can be deployed into the organization.

pdeploy deploy -u uid -w amAdminPassword -g|-d distinguishedName -p ContainerAdminPassword examples.war

For more information on the pdeploy command, see Sun ONE Portal Server 6.2 Administrator’s Guide.

Create Channels from the Deployed Portlets

Once the portlet is deployed, the portal server is aware of the portlet defined in the application. You can start to create channels based on the portlet. To create channels, see Sun ONE Portal Server 6.2 Administrator’s Guide for more information.


Converting Providers to Portlets

This section includes instructions for converting the providers to JSR168 compatible portlets using a sample set of instructions for converting the HelloWorldProviderPA in Chapter 3, "Extending the Base Providers" into a portlet called HelloWorldPortlet.

Develop the Class File

Code Example 6-4 contains the HelloWorldPortlet class file. The HelloWorldPortlet, similar to the HelloWorldProviderPA, prints “Hello World!” on the channel.

Code Example 6-4  HelloWorldPortlet.java File  

package custom;

import java.io.IOException;

import java.io.PrintWriter;

import javax.portlet.GenericPortlet;

import javax.portlet.PortletException;

import javax.portlet.RenderRequest;

import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet {

    public void doView(RenderRequest request,RenderResponse response)

        throws PortletException, IOException {

        response.setContentType(request.getResponseContentType());

        PrintWriter writer = response.getWriter();

        writer.write("Hello World");

    }

}

Mapping ProviderAdapter to GenericPortlet

When developing the class file, use the following table comparing GenericPortlet to ProviderAdapter:

Table 6-1  Mapping ProviderAdapter to GenericPortlet  

ProviderAdapter

GenericPortlet

public void init(String n, HttpServletRequest req)

public void init (PortletConfig config)

public URL processEdit (HttpServletRequest request,HttpServletResponse response)

public void processAction (ActionRequest request,ActionResponse response)

 

public void render (RenderRequest request, RenderResponse resposne)

public StringBuffer getContent (HttpServletRequest request, HttpServletResponse response)

protected void doView (RenderRequest request,RenderResponse response)

public StringBuffer getEdit (HttpServletRequest request, HttpServletResponse response)

protected void doEdit (RenderRequest request,RenderResponse response)

public URL getHelp(HttpServletRequest req, String key)

protected void doHelp (RenderRequest request, RenderResponse response)

public String getName()

public String getPortletName ()

public String getTitle()

protected String getTitle(RenderRequest request)

public ResourceBundle getResourceBundle(String base)

public ResourceBundle getResourceBundle()

public java.util.ResourceBundle getResourceBundle (java.util.Locale locale)

 

public PortletConfig getPortletConfig ()

 

public PortletContext getPortletContext ()

 

public String getInitParameter(java.lang.String name)

 

public java.util.Enumeration getInitParameterNames()

 

public void destroy ()

public int getEditType()

 

public int getWidth()

 

public boolean isEditable()

 

public boolean isPresentable()

 

public ProviderContext getProviderContext()

 

Sample Code Fragments for Provider to Portlet Conversion

This section includes some sample code fragments for Provider to Portlet conversion.

Example 1

The

ProviderContext.getStringAttribute("firstname");

maps to:

Map ui = (Map)renderRequest.getAttribute("javax.portlet.userinfo");

String firstname = (String)ui.get("firstname");

Example 2

The

ProviderContext.getSessionProperty()/setSessionProperty()

maps to (or can use)

PortletSession.getAttribute(), PortletSession.setAttribute()

Example 3

The

ProviderContext.getDesktopURL()

maps to (or can use)

PortletURL.RenderResponse.createRenderURL(), RenderResponse.createActionURL()

Dispatching to a JSP

PortletRequestDispatcher dispatcher = pContext.getRequestDispatcher("test.jsp");

dispatcher.include(request, response);

Help

getHelp()

In Provider returns, this method returns a helpURL which can be pointing to a static help file.

doHelp()

For portlets, this method has to be implemented for writing out the help content dynamically.

Title

getTitle()

For ProviderAdapter, this method returns the title from the Display Profile title property.

For portlets, the title is returned by the portlet implementation.

editType

For a provider, the editType display profile property can be specified to determine whether the provider implementation will draw the complete edit page or a subset of it.

For portlets, the editType is always EDIT_COMPLETE and the complete page including the form, the Finish, and the Cancel buttons have to be generated by the portlet. Only the banner and footer are drawn by the PortletEdit.jsp in /etc/opt/SUNWps/desktop/default directory.

PortletPreferences

The

ProfileProviderAdapter.getStringProperty(key)

maps to

PortletPreferences.getValue(key, default)

The

ProfileProviderAdapter.getListProperty(key)

maps to

PortletPreferences.getValues(key, default[])

Compile the Portlet

When compiling a portlet, include the classpath. Ensure that portlet.jar file is in your classpath when compiling the portlet. For example, to compile, type:

javac -classpath portal-server-install-root/SUNWps/lib/portlet.jar HelloWorldPortlet.java

Create a Portlet Web Application

Assemble the portlet class file and the XML fragments into a portlet web application. A portlet web application must be packaged as a WAR file. The portlet.xml file must be placed into the same location as the web.xml file.

To create a portlet web application:

  1. Create a portlet.xml file that includes the declaration for all the portlets.
  2. Code Example 6-5 contains the portlet.xml file that includes the declaration for the sample HelloWorldPortlet.

    Code Example 6-5  portlet.xml File for the HelloWorldPortlet  

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

    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:portlet="http://java.sun.com/xml/ns/portlet"

    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/portlet" version="1.0">

        <portlet>

            <portlet-name>HelloWorldPortlet</portlet-name>

            <portlet-class>custom.HelloWorldPortlet</portlet-class>

            <expiration-cache>0</expiration-cache>

            <supports>

                <mime-type>text/html</mime-type>

                <portlet-mode>VIEW</portlet-mode>

            </supports>

            <portlet-info>

                <title>HelloWorldPortlet</title>

            </portlet-info>

        </portlet>

    </portlet-app>

  3. Create the web.xml file. A web application also requires a web.xml file.
  4. If you have servlets for your portlet web application, then servlet definition can be incorporated in the web.xml file. Code Example 6-6 contains the web.xml file for the sample HelloWorldPortlet.

    Code Example 6-6  web.xml File for HelloWorldPortlet  

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

        <display-name>Portlet Examples</display-name>

    </web-app>

  5. Package everything into a WAR file.
  6. For the sample portlets, create an examples directory where all the files of the WAR will be placed. Then within the examples directory, create the WEB-INF directory. All the portlet files will be placed into the WEB-INF directory. For example, your directory hierarchy may look like this:

    examples/WEB-INF/

                    /web.xml

                    /portlet.xml

                    /classes/examples/HelloWorldPortlet.class

  7. Create the WAR file. That is, change directories to examples and type the following command:
  8. jar -cvf examples.war *

Deploy the Application

The Sun ONE Portal Server software includes a deployment tool which will take your WAR file and deploy it into the portal server. Before deploying the WAR file, determine where to place the portlets inside the organization.

With the following command, the sample portlets can be deployed into the organization.

pdeploy deploy -u uid -w adminpassword -g|-d distinguishedname -p ContainerAdminPassword examples.war

For more information on the pdeploy command, see Sun ONE Portal Server 6.2 Administrator’s Guide.

Create Channels from the Deployed Portlets

Once the portlet is deployed, the portal server is aware of the portlet defined in the application. You can start to create channels based on the portlet. To create channels, see Sun ONE Portal Server 6.2 Administrator’s Guide for more information.


Files Used by Portlets

portlet.xml

All portlet and portlet related configurations must be specified in the portlet.xml file. Each portlet.xml file contains one or more portlet definitions. Each portlet definition defines information such as the portlet name, portlet class, portlet preferences, and init parameters. See Code Example 6-2 for a sample portlet.xml file.

sun-web.xml

Include a sun-web.xml file in the WEB-INF directory if you use Sun™ ONE Application Server software as your web container for the portlet application and if your portlet application:

The session cookie property, cookiePath (in Code Example 6-7), specifies the pathname that is set when the cookie is created. The browser sends the cookie if the pathname for the request contains this pathname. If set to / (forward slash), the browser sends cookies to all URLs served by the Sun ONE Application Server software. You can set the path to a narrower mapping to limit the request URLs to which the browser sends cookies. By default, the cookiePath property contains the context path at which the web module is installed. The cookiePath property must be changed only if necessary.

The application server reclaims old sessions based on it’s own schedule. If you include HttpSession.setMaxInactiveInterval or PortletSession.setMaxInactiveInterval in your code, then ensure that the following entries appear in the sun-web.xml file. The value associated with the reapIntervalSeconds should be smaller than the inactive time you have set in the code.

<sun-web-app>

    <session-config>

        <session-manager>

            <manager-properties>

                <property name="reapIntervalSeconds" value="5"/>

            </manager-properties>

        </session-manager>

    </session-config>

</sun-web-app>

For further information about how to configure the sun-web.xml file, please see Sun ONE Application Server 7 Developer’s Guide to Web Applications.

sun-portlet.xml

Besides the portlet.xml file, the Sun ONE Portal Server software includes a sun-portlet.xml file. The sun-portlet.xml file includes some configuration data which is needed by the portlet container implementation, but is not included in JSR 168 v1.0 release’s deployment descriptor. This file is packaged and deployed at the same location as the portlet.xml file in the WAR file.

This file must be included in the portlet application WAR file if you wish to make use of the extensions. This file includes two extensions to:

If this file in not included in the WAR file, then default values are used by the portlet container.

Code Example 6-8  sun-portlet.xml File Sample  

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

<portlet-app-extension xmlns="http://www.sun.com/software/xml/ns/portal_server"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:sunportal="http://www.sun.com/software/xml/ns/portal_server"

xsi:noNamespaceSchemaLocation="http://www.sun.com/software/xml/ns/portal_server" version="1.0">

    <save-preferences-in-render-permission>1</save-preferences-in-render-permission>

    <portlet>

        <portlet-name>JSPPortlet</portlet-name>

        <deployment-extension>

            <extension-element>

                <session-enabled>0</session-enabled>

            </extension-element>

        </deployment-extension>

    </portlet>

    <portlet>

        <portlet-name>BookmarkPortlet</portlet-name>

        <deployment-extension>

            <extension-element>

                <session-enabled>0</session-enabled>

            </extension-element>

        </deployment-extension>

    </portlet>

    <portlet>

        <portlet-name>NotepadPortlet</portlet-name>

        <deployment-extension>

            <extension-element>

                <session-enabled>0</session-enabled>

            </extension-element>

        </deployment-extension>

    </portlet>

</portlet-app-extension>

The sun-portlet.xml file includes the following configuration information:

Portlet Application Extension Definition    

This is defined using the portlet-app-extension element. The portlet-app-extension element is the root of the deployment extension descriptor for a portlet application. This is a required element if the sun-portlet.xml file is included in your WAR file.

Permission to Save Preferences In Render Method    

This is defined using the save-preferences-in-render-permission element. The value for this element indicates whether or not the portlet application allows preferences value to be saved in the render method. A value of 1 means it is allowed and a value of 0 means it is not allowed. By default, the value is 0.

Portlet Definition    

This is defined using the portlet element. The portlet element contains the declarative data of a portlet. Each portlet element must contain the portlet-name element and zero or more deployment-extension elements. The portlet-name element contains the portlet name, and the deployment-extension element contains zero or more extension-element elements. In this release, there is only one extension-element defined, which is the session-enabled element.

The session-enabled element indicates whether or not a portlet uses session. A value of 1 means the portlet uses session, a value of 0 means the portlet does not use a session. The default value of the session-enabled is 1. That is, if a portlet does not define the session-enabled element in the sun-portlet.xml file, it is session enabled. The session-enabled element allows the portlet container to optimize the loading of portlets for performance improvement.

PDConfig.properties

Some of the default setting used by the pdeploy command to deploy portlet application are available in PDConfig.properties file. The PDConfig.properties file is installed into /etc/opt/SUNWps/portlet directory.

When the pdeploy command deploys the portlet application, it prepares the portlet application by consulting the following parameters:

logger.log.level=SEVERE

By default the log level is set to SEVERE. Valid values for this parameter are: ALL, OFF, INFO, WARNING, SEVERE.

logger.file.dir=/var/op t/SUNWam/debug/

This parameter indicates the directory to which the log file for the deployed portlet application is stored.

validate_schema=true

This parameter indicates whether or not schema validation should be performed during deployment.



Previous      Contents      Index      Next     


Copyright 2003 Sun Microsystems, Inc. All rights reserved.