Sun logo      Previous      Contents      Index      Next     

Sun ONE Portal Server 6.2 Developer's Guide

Chapter 2
Using Provider API (PAPI)

This chapter provides an overview of the Sun™ ONE Portal Server software Provider Application Programming Interface (PAPI) and includes instructions for developing a custom provider.

This chapter contains the following sections:


Overview of the Provider API and Desktop Servlet

Figure 2-1 shows the relationship between the various interfaces, classes, and exceptions discussed in this chapter. For detailed information on these interfaces, classes, and exceptions, see the Javadocs at http://hostname:port/portal/javadocs.

Figure 2-1  The Provider Application Programming Interface (PAPI)

This figure shows the Provider API (PAPI) base classes.

The Provider API

This section provides an overview of the interfaces (see Provider, ProviderWidths, and ProviderEditTypes), base classes (see ProviderAdapter, ProfileProviderAdapter), context (see ProviderContext), exceptions (see Exceptions), and the lifecycle of the provider.

Provider

The Provider interface clearly defines the communication channel between a container and a provider. The container may be the DesktopServlet, or another provider object. The methods defined in the Provider interface supply the basic handshaking required for a container to display the content from a provider object.

A provider can implement this interface. Clients of the Provider interface call the methods in this interface to query information or to perform an action in the provider. Such clients include, but are not limited to, the DesktopServlet and other channels (container channels).

There are essentially two types of methods in this interface:

Methods that handle actions    

This includes getContent(), getEdit(), and processEdit() methods.

Methods that describe how the provider should be treated by the containing entity    

This includes all methods that begin with is and get (minus the get* methods used for handling actions).

See the Javadocs for more information on the methods in this interface.

ProviderAdapter

The ProviderAdapter class implements aspects of the Provider using the ProviderContext. The ProviderAdapter class implements the ProviderWidths interface, which defines the provider widths, and ProviderEditTypes interface, which defines the edit types, making the constants defined in these interfaces available to classes that extend ProviderAdapter.

Developers who wish to implement a provider can extend this class or the ProfileProviderAdapter class for forward compatibility and convenient access to the ProviderContext interface.

See the Javadocs for more information on the methods in this class.

ProfileProviderAdapter

The ProfileProviderAdapter is a subclass of the ProviderAdapter that includes convenience wrappers around some commonly used methods in the ProviderContext interface, like get/set*Property(), exists*Property(), get/setStringAttribute(), and getTemplate().

The advantages of using the wrapper methods in the ProfileProviderAdapter class as opposed to using the methods in the ProviderContext interface are the following:

See the Javadocs for more information on the methods in this class.

ProviderContext

The ProviderContext object provides information pertaining to the environment that a provider object is executing within. Such information may be specific to the user, to the web container, or be global (shared between multiple users). This interface does not define what information falls into each of these categories; this is left up to the implementation. Provider developers can obtain a handle to a ProviderContext object by extending ProviderAdapter, and then calling ProviderAdapter.getProviderContext().

The ProviderContext forms the layer between the services used by the provider and the provider implementation thus isolating the provider code from specific service interfaces and implementations. It defines the service interface for the Desktop, and allows different implementation to access the actual data.

The following are some of the methods in the ProviderContext:

See the Javadocs for more information on the methods in this interface.

ProviderWidths

The ProviderWidths interface defines the widths that can be returned from the Provider.getWidth() method. The width is a suggestion to a client of a provider object as to how much screen real estate should be given to display the provider’s default view.

See the Javadocs for more information on the methods in this interface.

ProviderEditTypes

The ProviderEditTypes interface defines the edit types that can be returned from the Provider.getEditType() method. The edit type informs a client of a provider object what it can expect to be returned from the provider’s getEdit() method. The edit type can be EDIT_COMPLETE or EDIT_SUBSET.

See the Javadocs for more information on the methods in this interface.

PropertiesFilter

The PropertiesFilter abstract class, when extended, can describe a specific filter criteria. To implement a specific filter, one must minimally implement the getCondition() and match() methods in the PropertiesFilter abstract class.

Out of the box, the Portal Server software includes filters based on locale and client. The locale and client filter extend the PropertiesFilter abstract class and includes an implementation of the getCondition() and match() methods in the PropertiesFilter class. See the Javadoc for more details.

Exceptions

The Desktop expects a provider to only throw ProviderException or a subclass of the ProviderException. For correct operation, a provider must only throw expected exception type. That is:

Exceptions from providers are logged in /var/opt/SUNWam/debug/desktop.debug file. Note that this file is created only if there is an error.

ProviderException

The ProviderException is a generic superclass for all provider related exceptions.

AsciiFormInputExpectedException

The AsciiFormInputExpectedException will be thrown from Provider.processEdit() method when something other than ASCII only encoded form input is sent to it.

InvalidEditFormDataException

The InvalidEditFormDataException is thrown from the Provider.processEdit() method when there is an error in the data input by the user. If thrown, the Desktop will send back the same Edit page, and will attach the exception’s message as a parameter to the URL. For example, if the exception is:

throw new InvalidEditFormDataException("Error Error");

the Desktop will redirect back to the same Edit page, adding the error message to the URL error parameter:

error=Error Error

The edit page wrapper then looks for the error parameter in the URL and if present, displays the message (or the value of the error parameter) at the top of the page in red.

UnknownEditTypeException

The UnknownEditTypeException may be thrown from Provider.getEditType() method if an unknown or undefined edit type is encountered.

The Provider Life Cycle

This section describes the lifecycle of the provider per user session. Figure 2-2, Figure 2-3, and Figure 2-4 shows how the Desktop handles each user session.

A session is created at the time the user logs in to the portal Desktop and ends when they logout. The session also ends when the user session is idle, or when the session times out. For authless logins, a single session is shared amongst all clients accessing the Desktop in authless mode, and the authless session never dies.

For each request, the DesktopServlet will validate the user session; if it is a valid session, the DesktopServlet will start to process the request. If a session does not exist, the DesktopServlet will create a session.

The creation of the provider context is equivalent to the creation of a session. The container provider context object (see "ContainerProviderContext") is generated and maintained, one per session. So each time a request comes in, the cached container provider context object is used. For example, in Figure 2-2, when the first initial request comes in, the container provider context is created and initialized, and when the subsequent requests come in, as in the reload and logout requests shown in Figure 2-3 and Figure 2-4 respectively, the cached container provider context is returned.

The container provider context maintains a list of its contained provider objects and their cached content locally. Contained providers are created and initialized once per session, and their content is cached in the provider context object. Subsequent requests access the cached provider objects that live inside the provider context object.

The contentChanged() and allContentChanged() methods signify that either the content for one channel or all channels has changed, respectively. This is used to remove all the cached content for the channels, as well as to clear the cached provider objects. When the requested action is logout, as shown in Figure 2-4, the DesktopServlet will redirect the request to the logout URL, and the session will be destroyed. At this point, the provider context object is removed from the cached list, and ready for garbage collection. Also, if the session expires or timesout, the provider context object is removed from the cached list.

Figure 2-2 and Figure 2-4 shows a sample of how the content and logout actions are processed. For detailed information on how the DesktopServlet and the back end providers handle each action (including content and logout), see "The DesktopServlet."

Figure 2-2  The Provider Life Cycle - Initial Request for Authenticated User

This figure shows how the DesktopServlet handles an initial request for authenticated users

Figure 2-3  The Provider Lifecycle - Desktop Reload Request for Authenticated User

This figure shows how the DesktopServlet handles a reload request from authenticated users.

Figure 2-4  The Provider Lifecycle - Logout Request

This figure shows how the DesktopServlet handles logout request.

The DesktopServlet

This section provides an overview of the DesktopServlet and discusses the relationship between the DesktopServlet and the PAPI. It provides information on how the DesktopServlet uses the various methods in the PAPI to perform the various actions (such as content, edit, process, and logout).

Introduction

The DesktopServlet coordinates the drawing of the Desktop, dispatches the process to the target channel based on the information stored in the underlining services, and validates the user with the Sun™ ONE Identity Server software.

In this sense, the DesktopServlet is a router of requests. It catches requests for content and processing, and passes them on to the specific provider object. Whenever a provider throws an exception that cannot be handled by the container provider, the exception will propagate all the way up to the DesktopServlet, and the DesktopServlet will display an error page.

For detailed information on how the DesktopServlet creates and validates a user session and creates and gets the provider context object, see the "The Provider Life Cycle." The following sections only describe how the DesktopServlet handles the various actions.

DesktopServlet Actions

The DesktopServlet understands several actions. Every action has an associated channel or container name and actions are performed on the associated channel or container. Actions are passed to the servlet via request parameters. The associated channel name is also passed as a parameter.

For example, to perform an action on a channel, pass in the following parameters to the servlet:

DesktopServletURL?action=actionType&provider=ChannelName

Here:

The action and provider parameters are not required; if they are absent, the default action is content, and provider is the value set in the Desktop service for the default channel.

The content, edit, and process actions map directly to method calls into the PAPI. For Desktop actions that map to PAPI method calls, the servlet passes an HTTP request and response object to the respective provider method. These objects are not the same objects passed into the servlet. The request and response objects passed to provider objects from the servlet are wrappers around the original request and response passed into the servlet. This is because there is certain functionality that is available from request and response objects that is not applicable to a provider. See the Javadocs for the Provider interface for more information.

The HTTP parameters in the original request object are processed before they are copied to the wrapper servlet request and response objects. As part of this processing, the parameters are decoded from the character set encoding used to represent the page into Unicode that is used in Java String objects. Therefore, the parameters that are passed to the providers are all stored as Unicode, and the provider does not have to do any decoding of its own related to the character encoding for the page.

Action content

When the action is content, the DesktopServlet gets the named channel’s main content. When the DesktopServlet receives a request where the action is content, to perform the content action on the channel, it takes the following parameters:

DesktopServletURL?action=content&provider=ChannelName[&last=false]

The content action maps directly to the following method calls in the PAPI: ProviderContext.getDefaultChannelName(), Provider.isPresentable(), and Provider.getContent().

The flowchart in Figure 2-5 shows the various methods executed in the back end to process the content action. When the client makes a request for content (say after login), the DesktopServlet:

  1. Determines the provider responsible for generating the requested content.
  2. If provider is null, it uses the default channel name (stored in the DefaultChannelName attribute) to get the provider. The default channel name is an Sun ONE Identity Server software attribute (DefaultChannelName) in the Desktop service, which is set to the top most container that represents the whole Desktop view. The default channel name is set to the current target provider value when the request parameter last equals to true. If the provider is not null, the DesktopServlet gets the provider responsible from the HTTP parameter in the URL for generating the requested content.

  3. Once the provider is determined, the provider’s isPresentable() method is invoked to determine if the provider can be presented to the requesting client.
  4. If the provider is determined to be not presentable, an error is thrown on the Desktop. If the provider can be presented, the provider’s getContent() method fetches the content for display on the client’s Desktop.

  5. When last is set to false, the DesktopServlet will not set the last channel to the value of the provider parameter. If not specified, the default setting is last=true, and the last accessed channel is set to the value of the provider parameter.
  6. The next time when the action is content, the DesktopServlet provider parameter will be used to fetch the content. If the provider parameter is absent in the request URL, the DesktopServlet assumes it is equal to the value of the last request.

    Figure 2-5  DesktopServlet content Action


    This figure shows the DesktopServlet content action.

Action edit

When the action is edit, the DesktopServlet gets the named channel’s or edit container’s request parameters and starts to process the edit action. When the DesktopServlet receives a request where the action is edit, to perform the edit action, it takes the following parameters:

DesktopServletURL?action=edit&provider=ChannelName for backward compatibility

Or,

DesktopServletURL?action=edit&provider=editContainer&targetprovider=ChannelName

The DesktopServlet checks the edit types based on the values defined in the ProviderEditTypes interface.

DesktopServletURL?action=edit&provider=ChannelName

The flowchart in Figure 2-6 shows the various methods executed in the back end to process the edit action. When the client makes a request to edit the channel’s editable parameters, the DesktopServlet:

  1. Determines the provider responsible for generating the requested content.
  2. If provider is null, it uses the default channel name to get the provider. Default or last accessed channel is not assumed when action equals edit. Otherwise, the DesktopServlet gets the provider responsible specified in the URL.

  3. Once the provider is determined, the channel’s isEditable() method is invoked to determine if the channel is editable.
  4. The DesktopServlet gets the named channel’s isEditable property. If the channel is determined to be not editable, an exception is thrown on the Desktop. If the channel can be edited, the DesktopServlet also checks the editType for that channel.

  1. If the channel’s edit type is:
    • EDIT_COMPLETE, the provider’s getEdit method is invoked and the Edit page for the channel is returned on the Desktop.
    • EDIT_SUBSET, the edit container’s provider name will be detected (via the default Desktop Edit Container attribute), and then the edit container’s getEdit() method will be invoked. Also:
      1. The edit container’s provides a common look and feel of the edit page for all the channels that it contains. After it generates the markup for the common look and feel, it detects the channel name from the request parameter and determines whether the target channel is editable.
      2. If the target channel is not editable, it throws a provider exception. If the target channel is editable, it gets the channel’s edit type and delegates the process to the target channel’s getEdit() method.

      3. If the channel’s edit type is:
      4. EDIT_COMPLETE, the Edit page is displayed.
      5. EDIT_SUBSET, the edit container’s content is displayed and it wraps around the channel’s edit content.
      6. Figure 2-6  DesktopServlet Legacy edit Action


        This figure shows the DesktopServlet legacy edit action.


        This flowchart is a continuation of the DesktopServlet legacy edit action.

DesktopServletURL?action=edit&provider=editContainer&targetprovider=ChannelName

The flowchart in Figure 2-7 shows the various methods executed in the back end to process the edit action. This flowchart shows how the DesktopServlet processes the edit action for a container. In this URL, the provider parameter specifies the edit container for the container, and the targetprovider parameter is the leaf channel inside the container. When the client makes a request to process this edit action, the DesktopServlet:

  1. Determines the provider responsible for generating the requested content.
  2. If provider is null, it uses the default channel name to get the provider. Default or last accessed channel is not assumed when action equals edit. Otherwise, the DesktopServlet gets the provider responsible specified in the URL.

  3. Once the provider is determined, the edit container’s isEditable() method is invoked to determine if the edit container is editable.
  4. The DesktopServlet gets the named edit container’s isEditable property. If the edit container is determined to be not editable, an exception is thrown on the Desktop. If the edit container can be edited, the DesktopServlet also checks the editType for that edit container.

  1. If the edit container’s edit type is:
    • EDIT_COMPLETE:
      1. The edit container’s getEdit method is invoked and the leaf channel’s name is determined from the request parameter.
      2. Once the leaf channel’s name is determined, the channel’s isEditable() method is invoked to determine if the channel is editable.
      3. If the channel is determined to be not editable, an exception is thrown on the Desktop. If the channel can be edited, the DesktopServlet also checks the editType for the leaf channel.

      4. If the leaf channel’s edit type is:
      5. EDIT_COMPLETE, the container calls the leaf channel’s getEdit() method and displays the edit page on the Desktop.
      6. EDIT_SUBSET, the container calls the leaf channel’s getEdit() method and the container’s Edit Container wraps the leaf channel’s content before displaying the Edit page ont the Desktop.
      7. A container can define different edit container and the edit container name must be specified as well as the target channel name. The default Desktop edit container name is stored in the Identity Server as a Desktop service attribute.

    • EDIT_SUBSET, the Desktop servlet fetches the name of the edit container to use to wrap the channel’s edit page. The servlet fetches a handle to the edit container, and then calls the edit container’s getEdit() method. The edit container detects the original channel’s name from request parameters and calls getEdit() on that channel, and wraps the channel’s content before returning it to the servlet. See the legacy edit action for EDIT_SUBSET in for more information.
    • Figure 2-7  DesktopServlet edit Action


      This flowchart shows the DesktopServlet Edit action.


      This flowchart is a continuation of the DesktopServlet edit action.

Action process

The process action allows the named channel to process URL parameters and form data, typically that of the channel’s edit form. When the DesktopServlet receives a request where the action is process, to perform the process action, it takes the following URL parameters:

DesktopServletURL?action=process&provider=channelName

Or,

DesktopServletURL?action=process&provider=editContainer&targetprovider=channelNa me

DesktopServletURL?action=process&provider=channelName

When the DesktopServlet receives a request where the action is process (see Figure 2-8), the DesktopServlet:

  1. Looks at the parameters to identify which provider will handle the action, through the provider’s processEdit() method.
  2. The processEdit() method is called to process the edit page generated from the getEdit() method. The request passed in contains the parameters.

  3. Re-directs to the URL returned from the provider’s processEdit() method.
  4. If there is an InvalidEditFormDataException, the DesktopServlet will redirect the browser back to the channel’s edit page and include a URL parameter error so that the channel may display the cause of the exception to the user. That is, the DesktopServlet will get the error message and generate a new request as follows:

    DesktopServletURL?action=edit&provider=channelName&error=errormessage

    Figure 2-8  DesktopServlet Legacy process Action


    This flowchart shows the DesktopServlet legacy process action.

DesktopServletURL?action=process&provider=editContainer&targetprovider=channelName

In this URL, the provider parameter specifies the edit container for the container, and the targetprovider parameter is the leaf channel inside the container. When the DesktopServlet receives a request where the action is process (see Figure 2-9), the DesktopServlet:

  1. Determines whether the edit container is editable.
  2. If the edit container is not editable, an exception is thrown on the Desktop and control is returned to the web container. If the edit container is editable, it calls the edit container processEdit() method and determines the channel’s name from the request parameter.

  3. Once the channel name is determined, it determines whether the channel is editable.
  4. If the channel is not editable, it throws a provider exception. If the channel is determined to be editable, it calls the channel’s processEdit() method.

  5. Re-directs to the URL returned from the provider’s processEdit() method.
  6. If there is an InvalidEditFormDataException, the DesktopServlet will redirect the browser back to the channel’s edit page and include a URL parameter error so that the channel may display the cause of the exception to the user. That is, the DesktopServlet will get the error message and generate a new request as follows:

    DesktopServletURL?action=edit&provider=channelName&error=errormessage

Action logout

The logout action ends the user session. When the DesktopServlet receives a request where the action is logout, to perform the logout action, it takes the following parameters:

DesktopServletURL/dt?action=logout

When the DesktopServlet receives a request for the logout action, it redirects the browser to a URL defined by the Sun ONE Identity Server software iplanet-am-platform-logout-url attribute in the Platform service. By default, this attribute has the value /amserver/logout. But, If this is set to something that does not terminate the user’s session, such as a static HTML page, then /portal/dt?action=logout will not terminate the user session.


Overview of Implementing a Custom Provider

This section describes the development process for a Sun ONE Portal Server provider. It touches on the public APIs available for integrating an application with the Sun ONE Portal Server software Desktop via the provider.

Before developing a custom provider, determine whether there is an existing Provider that can access the type of content you are targeting. For example, if you are trying to fetch content from a JSP page, you can create a channel based on the the pre-built JSP provider and configure it to access your JSP page. If none of the APIs can be used as is, determine whether or not the content can be presented by authoring a new provider by extending a provider base class (such as the ProviderAdapter or ProfileProviderAdapter).

See chapters 3, 4, and 5 for information on extending a provider base class and building block providers.

To develop a provider, you must start by:

Defining Specific Requirements and Functionality

Before beginning to develop a provider, determine the application specific requirements, content source, and properties of the provider.

Application Specific Requirements

Determine the nature of the provider. Will this provider be a building block provider or will this be a content provider? The content providers are special purpose providers and the building block providers are general purpose providers. For example, the bookmark channel is special purpose, where XMLProvider is general purpose. That is, the XMLProvider can be used, in general, to connect to an XML source and translate it via XSLT to some markup language.

Determine if the content made available via this provider will be:

Presentation Method

Determine whether the provider will fetch content from template files or JSPs. This will determine the logistics of the getTemplate() method.

Channel template files are stored in a directory based on the name of the channel, or the name of the provider that is used by the channel. The channel directory for the provider is created under the template root directory. By default, this will be:

/etc/opt/SUNWps/desktop/desktoptype/channeldirectory/templatefiles

The JSPs and templates are stored under /etc/opt/SUNWps/desktop/default and /etc/opt/SUNWps/desktop/sampleportal directories. Storing the files in the /etc/opt/SUNWps/desktop/default directory allows the files to be shared. That is, when the Desktop service uses the comma-separated string (as an ordered Desktop type list) in the Desktop type attribute to lookup, it starts at the first element in the list and each element represents a sub directory under the Desktop template base directory. If a template is not found in the first directory (or the first string in the desktop type attribute), then it proceeds to the next one in the list. This continues until the item is found (or not), for all Desktop type elements in the list. If the default directory is not included in the list, it will be added at the end of the list implicitly.

The directory search order for the template and JSP files is as follows:

desktoptype_locale/channelname/clientPath

desktoptype_locale/provider/clientPath

desktoptype_locale/channelname

desktoptype_locale/provider

desktoptype_locale/clientPath

desktoptype_locale

desktoptype/channelname/clientPath

desktoptype/provider/clientPath

desktoptype/channelname

desktoptype/provider

desktoptype

default_locale/channelname/clientPath

default_locale/provider/clientPath

default_locale/channelname

default_locale/provider

default_locale

default/channelname/clientPath

default/provider/clientPath

default/channelname

default/provider

default/clientPath

default

templateroot

Where

If there is no clientPath specified, then the directory search order is as follows:

desktoptype_locale/channelname

desktoptype_locale/provider

desktoptype_locale

desktoptype/channelname

desktoptype/provider

desktoptype/clientPath

desktoptype

default_locale/channelname

default_locale/provider

default_locale/clientPath

default_locale

default/channelname

default/provider

default/clientPath

default

templateroot

The root of the search directory (default value of /etc/opt/SUNWps/desktop/) can be changed by modifying the templateBaseDir property in the desktopconfig.properties file.


Note

If the channel display profile is defined inside a container display profile definition, the lookup for the channel will be desktoptype/containername/channelname/clientPath.


Provider-specific Properties

In the display profile, properties contain configuration information for the provider and the provider’s channels. A provider can define any number of specific properties. See "Properties in Display Profile" and Sun ONE Portal Server 6.2 Desktop Customization Guide for more information.

Also, a provider can have more than one properties file, which is actually a Java™ resource bundle file that enables localization of on-screen images or text. See "Properties in Resource bundle" for more information.

Properties in Display Profile

Provider specific properties are defined in the display profile. Provider specific properties are defined in the display profile within the <Properties></Properties> tag for the provider. The following is the structure of the properties in the display profile:

<Properties>

    <Collection>

        ...subset of property definitions

    </Collection>

    <Integer>...</Integer>

    <String>...</String>

    <Boolean>...</Boolean>

</Properties>

Typically, the custom provider will not modify the required properties. When properties are updated, they are set in the user’s display profile by the administrator via the administration console. However, values can only be set on existing properties.

If the provider class does not extend the ProfileProviderAdapter and implements the Provider interface, then the get*Property() methods cannot be used directly, and the display profile properties are not accessible. If the provider class implements the Provider interface directly, then no properties are required. Properties must be hardcoded return values or can come from another source such as a database. However, some provider properties are required if the provider implementation extends ProviderAdapter or ProfileProviderAdapter.

The following is a list of the mandatory properties for a provider. The mandatory properties described below are for a provider extending the ProviderAdapter or the ProfileProviderAdapter classes. If you are implementing the Provider interface directly, you can avoid the use of the display profile and the required properties outlined below.

title

Title of the Provider

description

Description of the Provider

refreshTime

Time interval for cached content

isEditable

Can the Provider be edited

editType

Type of edit form to use

width

Width of the Provider

helpURL

URL of a help page for this Provider

See Sun ONE Portal Server 6.2 Desktop Customization Guide for detailed information on the Display Profile properties.

Channel definitions that use a provider can overwrite the properties of that provider. At runtime, channel property values can be affected by the display profile merge process. See Sun ONE Portal Server 6.2 Administrator’s Guide for detailed information on the display profile merge process.

Properties in Resource bundle

Strings defined in the provider’s resource bundle properties file are displayed on the user’s Desktop and they are not the channel’s properties (such as the channel title). Strings are defined in the resource bundle to enable localization.

Typically, resource bundle includes properties that do not need to be customized by the administrator or the end-user. For example, properties that need to be localized, are read-only at runtime, and properties that do not change per channel should be included in a resource bundle. Properties that need to be localized, are settable, and properties that change per channel should be in the display profile.

By default, a provider’s resource bundle properties file is stored in portal-server-install-root/SUNWps/web-src/WEB-INF/classes directory. Note that you can change the file here, but you must re-deploy the portal web application for the changes to take effect.

Resource bundles that are needed by the custom providers should be copied into the provider class base directory (see "Provider Class File" for more information.) Resource bundles should be placed as individual files and cannot exist inside the JAR file under the provider class base directory.

Resource bundles are given a base name that equals to the name of the display profile provider definition that they are associated with. Typically, this is the relative (non-fully qualified) class name of the Java class file that implements the provider.

To get the name of the resource bundle in your custom provider, call ProviderContext.getProviderName(). This value can then be used as the baseName argument to ResourceBundle.getBundle(). If you are extending ProviderAdapter, simply call getResourceBundle().

Developing the Provider Class File

This section includes information on the requirements for developing a provider’s class file.

Provider Class File Location

The provider classes must be deployed in the provider class base directory specified in the file /etc/opt/SUNWps/desktop/desktopconfig.properties. By default, the provider class base directory is /etc/opt/SUNWps/desktop/classes.

For hot deployment, the JAR file has to be dropped in the directory mentioned in providerClassBaseDir variable in the desktopconfig.properties file.

Provider Class File

The custom provider classes and all other custom classes that the provider classes reference can be bundled into a JAR file and placed in the provider class base directory. They can also exist as .class files in the provider class base directory.

If a class exists in a file and is also present in a JAR file under the provider class base directory, the class existing as a file under the provider class base directory is given the first preference. Once the class is found as a file, no attempt is made to check for its existence in a JAR file.

If a class file exists in two JAR files under the provider class base directory, the class is picked up from one of them at runtime. Do not duplicate classes in multiple JAR files.

When compiling the class file, the Servlet API (identity-server-install-root/SUNWam/lib/servlet.jar) and PAPI (portal-server-install-root/SUNWps/sdk/desktop/desktopsdk.jar) are required in the CLASSPATH. That is, when compiling a *Provider.java file, you must type:

javac -d /etc/opt/SUNWps/desktop/classes -classpath portal-server-install-root/SUNWps/sdk/desktop/desktopsdk.jar:identity-server-install-root/SUNWa m/lib/servlet.jar *Provider.java

Provider Class Loader

The provider class loader in the Sun ONE Portal Server software is used to load the classes. Each channel and each container is loaded with a separate provider class loader object. This enables on-the-fly reloading of classes when they change.

In order to upload a new version of a custom provider class without restarting the server:

In order to reload a property file, that is being used by a custom provider, with a modified property inside a resource bundle in the provider class base directory without restarting the server, change the last modified time on the custom provider class. If the custom provider class exists:

The presence of the provider class loader has an impact on the design of a multi-channel application in the Desktop. When an object reference is cast from one type to another, not only does the class of the variable need to match the class of the object, the two associated class loaders have to be the same too. This constraint can show up when objects are being passed between different channels in the Desktop.

For example, consider a portal application that uses two providers, one for a container and the other for several leaf channels. Call these providers HeadlineContainerProvider and HeadlineProvider. The container provider performs some common processing for the leaf channels, and then the leaf channels access the container object to get the results of that processing. One way to implement this would be to have the HeadlineContainerProvider put a reference to itself into the request object. For example, in the HeadlineContainerProvider.getContent(), do:

request.setAttribute("HeadlineContainer", this);

Then, in the HeadlineProvider.getContent() method, do:

HeadlineContainerProvider hcp = (HeadlineContainerProvider)request.getAttribute("HeadlineContainer");

This example will compile, but when the desktop loads and runs this code, the HeadlineProvider will cause a ClassCastException on this second statement. The reason is that the HeadlinerContainerProvider object is loaded by one provider class loader object and the HeadlineProvider object is loaded by a different class loader object. The class loader for HeadlineProvider also loads HeadlineContainerProvider because HeadlineProvider references HeadlineContainerProvider. So we have:

The HeadlineContainerProvider class is also loaded by loader2 because of the reference to it in the HeadlineProvider code. The cast is from the object container1 (loaded by loader1) to the variable hcp (of type HeadlineContainerProvider loaded by loader2). Thus the cast fails because the class loaders are not the same.

To understand a case where the classes could actually be different, consider the case where container1 is loaded at time 0, and channel1 is loaded at time 10, but the HeadlineContainerProvider class files was updated on disk at time 5. This means that channel1 will be running with a different version of the HeadlineContainerProvider class than that being used for container1. The case must fail because the class versions are different.

To implement this type of application, an alternate solution is to pass an object as a request or session property that has a class that is not in the /etc/opt/SUNWps/desktop/classes directory, such as String, Set, or Hashmap. These classes are never reloaded except when the server restarts. The data that you store in that object becomes a contract between different versions of the classes that use that object.

Creating XML Fragments for Display Profile

A provider must be defined in the display profile before it can be used. This definition associates the provider with its class file implementation and includes the provider’s properties. That is, the provider’s display profile fragment should include default values for all the properties that are used in the provider.java file. For example, if the provider.java file contains getStringProperty(“color”), the provider’s display profile fragment should include a default value for color.

The provider’s XML fragment in the display profile must adhere to the following structure:

<DisplayProfile>

    <Providers>

        <Provider name=”providername

            class=”provider class name”>

            <Properties>...</Properties>

        </Provider>

    </Providers>

</DisplayProfile>

See Sun ONE Portal Server 6.2 Desktop Customization Guide for more information on the display profile provider definitions.

The provider definition is the template that decides the properties for the provider’s channels. However, the display profile definition for the channel ultimately decides the values for the channel’s properties. When a channel sets a property, the property is set in the channel and not in the provider’s properties. When defining channel properties in the display profile, include only those properties where the provider defaults are not applicable.

The provider’s channel XML fragment in the display profile must adhere to the following structure:

<DisplayProfile>

    <Channels>

        <Channel name=”channelname” provider=”providername”>

            <Properties>...</Properties>

        </Channel>

    </Channels>

</DisplayProfile>

See Sun ONE Portal Server 6.2 Desktop Customization Guide for more information on the display profile channel definitions.

The channel definition in the display profile need not have the <Container> tag unless the channel is defined within a container. Channel definitions in the display profile can be encapsulated inside a container. The advantage of this is that it provides name scoping so that channels with the same name do not collide.

Unless a channel is referenced directly from the DesktopServlet URL, in which case it need not be encapsulated inside a container, you must reference a channel from some container in order to see it.

The container within which the channel will operate must adhere to the following structure:

<DisplayProfile>

    <Channels>

        <Container>

            <Properties>...</Properties>

            <Available>...</Available>

            <Selected>...</Selected>

            <Channel>...</Channel>

        </Container>

    </Channels>

</DisplayProfile>

To upload display profile changes, type:

where provider.xml contains the display profile XML fragment for the provider. See Sun ONE Portal Server 6.2 Administrator’s Guide for more information on the dpadmin command and on administering Sun ONE Portal Server software display profile.

Installing the Provider

This section provides information on:

Installing a provider

This section includes instructions for installing the provider using the par utility and manually.

Installing Manually

To install the provider manually:

  1. Compile the provider class file and copy the file to the provider class base directory which, by default, is /etc/opt/SUNWps/desktop/classes. Or copy the file to the location specified in the /etc/opt/SUNWps/desktop/desktopconfig.properties file.
  2. Copy the resource bundle files, if any, to /etc/opt/SUNWps/desktop/classes directory.
  3. Develop the JSPs and templates for the provider and copy the files to the template root directory for the provider which, by default, is /etc/opt/SUNWps/desktop/desktoptype/providerName.
  4. Develop and upload the display profile XML fragments for the provider, the provider’s channels, and the container within which the channels will operate, if any.
Transporting Using the par Utility

Utilize the par utility for deploying channels and providers. The par command enables you to transfer or move providers or channels from one Sun ONE Portal Server software host to another. The par utility creates a specialized packaging mechanism called a .par file for transport of channels and providers into and out of the server. A .par file is an extended form of the .jar file format, with added manifest information to carry the deployment information and an XML document intended for integration into the Sun ONE Portal Server software display profile on the target server.

The use of .par files is optional. You can just as well copy all files into their correct locations. The par utility makes deployment easier if you have to install the files on multiple servers.

To create a .par file from scratch, use the jar or export subcommand of the par utility.

To export an existing provider, use the export subcommand of the par utility.

For example, if you have the provider associated files in the development environment ready for deployment into the production environment, use the following command to build the channel and provider into a par file which can then be deployed on the system.

par export -r dn_amadmin -p password -v provider.par dn exportfile

To deploy the par file into the system, use the following command:

par import -r dn_amadmin -p password -v provider.par dn provider=providername,channel=channelname


Note

All providers that ship with Sun ONE Portal Server software are in the service-level Desktop display profile. There is no command to extract them all.


See Sun ONE Portal Server 6.2 Administrator’s Guide for more information on the par utility.



Previous      Contents      Index      Next     


Copyright 2003 Sun Microsystems, Inc. All rights reserved.