Sun Java System Portal Server 7.2 Developer's Guide

Chapter 5 Overview of the Container Providers

Containers are channels that include in their output the content of one or more other channels. The container providers present containment metaphors for channel aggregation including single, table, tab, and framed.

This chapter discusses the out-of-the-box extensible set of container providers that implement various metaphors for aggregating content and contains the following sections:

The ContainerProvider Architecture

This section shows the relationship between the various interfaces and classes discussed in this chapter. The JSPProvider (see Chapter 4, Overview of the Leaf Providers for more information) and ContainerProviderAdapter classes extend ProfileProviderAdapter (see Chapter 2, Overview of the Provider API (PAPI) for more information).

The ContainerProvider interface defines the interface for implementing a container provider. A container provider generates its views by being a client of other provider objects.

The ContainerProviderAdapter provides default implementations of the following methods in the ContainerProvider:

For more information on all the methods in this class, see the Javadocs.

The ContainerProviderContext extends ProviderContext and adds container functionality to the ProviderContext interface. The ContainerProviderAdapter uses the ContainerProviderContext object as the persistent store.

The JSPContainerProviderAdapter extends the JSPProvider (see Chapter 4, Overview of the Leaf Providers for more information) and provides implementations of methods in the ContainerProvider interface to facilitate the execution of JSPs.

The JSPTabContainerProvider extends the JSPContainerProviderAdapter and provides default implementation for methods in the TabContainer interface. The JSPSingleContainerProvider and the JSPTableContainerProvider also extend the JSPContainerProviderAdapter.

Figure 5–1 The ContainerProvider Architecture

Container Provider Architecture.

Overview of the ContainerProviders

To support the container providers, the PAPI includes three APIs, the ContainerProvider interface, the ContainerProviderAdapter class, and the ContainerProviderContext interface. This section provides an overview of these three APIs.

ContainerProvider Interface

The ContainerProvider interface defines the interface for implementing a container provider and is the programmatic entity for generating container channels.

A container provider has a selected and available channels list, and allows getting and setting of these lists. Selected channels are those that are considered active on the Desktop. Available channels are those that are available to be activated on the Desktop. That is, selected channels are those that are available and selected for display on the Desktop by the user; available channels are those that are available for display on the Desktop, but not selected for display on the Desktop by the user.

The Desktop container providers (such as JSPSingleContainerProvider, JSPTableContainerProvider, and JSPTabContainerProvider) discussed in this chapter extend the JSPContainerProviderAdapter that implements the ContainerProvider interface.

The ContainerProvider includes interfaces to get/setAvailableChannels and get/setSelectedChannels. See the Javadocs for more information.

ContainerProviderContext Interface

The ContainerProviderContext interface provides an environment for container provider execution. More formally, this class adds container channel functionality to the ProviderContext interface (see Chapter 2, Overview of the Provider API (PAPI) for more information). That is, where provider object can obtain access to a ProviderContext object, container providers obtain access to a ContainerProviderContext object.

A ContainerProviderContext object has a superset of the functionality exposed in ProviderContext. The additions are related to managing contained providers. For example, container channel functionality includes getting provider objects, fetching content, content caching, adding clients, creating channels and containers, and getting and setting selected and available channels list.

The ContainerProviderContext is the object to get the container channel properties from the store at run time. The ContainerProviderContext can also be used to getProvider() on another channel or container and getContent() on another channel or container.

ContainerProviderAdapter Class

The ContainerProviderAdapter class extends ProfileProviderAdapter. ContainerProviderAdapter can be used as the base class for any container provider (except for the JSP-based container providers, which can extend the JSPContainerProviderAdapter). For example, the sample template-based Desktop container providers are developed based on this class.

The ContainerProviderAdapter class provides default implementations of methods in the ContainerProvider interface implemented using a ContainerProviderContext object as the persistent store. This class also has the getContainerProviderContext() method, which gets the container provider context, in addition to the get/setAvailableChannels and get/setSelectedChannels methods.

JSPContainerProviderAdapter Class

To extend container functionality for JSP-based container providers, a JSPContainerProviderAdapter class is included with the software. This class extends the JSPProvider. The JSPContainerProviderAdapter can be used as the base class for any JSP-based ContainerProvider and is similar in functionality to the ContainerProviderAdapter. For example, the JSPSingleContainerProvider extends from this class.

The JSPContainerProviderAdapter class provides default implementations of methods in the ContainerProvider interface implemented using a ContainerProviderContext object as the persistent store and extends JSPProvider to facilitate the execution of JSPs. It includes interfaces to get/setAvailableChannels(), get/setSelectedChannels(), and getContainerProviderContext().

Three sample extensions (namely JSPSingleContainerProvider Class, JSPTableContainerProvider Class, and JSPTabContainerProvider Class) to the JSPContainerProviderAdapter API are included.

JSPSingleContainerProvider Class

This section contains discusses about the JSPSingleContainerProvider in detail:

Introduction to JSPSingleContainerProvider

A single container wraps the content of a single channel. The single container enables a channel to take over an entire browser page. For example, this can be used to provide the front page or can be used to display a single channel whose name is passed in the request parameter. Typically, the front page consists of some banners and the output of another channel. The purpose of the single channel is to allow these banners, menu bars, and the like to be wrapped around the content of the included channel.

Another purpose of the single container is that the decorative elements (such as banners and menu bars) which wrap around the channel can be easily changed without changing the channel itself.

Using the JSPSingleContainerProvider

The JSPSingleContainerProvider class extends JSPContainerProviderAdapter. A single container simply displays a single leaf channel or a container. It must be a JSP that wraps a container or leaf channel.

ProcedureThe JSPSingleContainerProvider Class

  1. Gets the selected channel name.

  2. Returns the selected channel name as a String.

    If more than one channel is defined, it displays the first channel in the list.

    Some examples of single container include JSPContentContainer, JSPLayoutContainer, JSPEditContainer.

JSPTableContainerProvider Class

This section discusses about the JSPTableContainerProvider in detail:

Introduction to JSPTableContainerProvider

A table container aggregates the content of other channels into rows and columns. It can be thought of as a bucket for the content of other channels. The JSPTableContainerProvider class extends JSPContainerProviderAdapter.

The table container facilitates the aggregation of multiple channels into a single display. That is, the JSPTableContainerProvider aggregates channels into HTML rows and columns.

Using the JSPTableContainerProvider

A JSPTableContainerProvider provides methods that allow the associated JSP files to use these methods, and generate a view that arranges the contained channels to be displayed in a HTML table. By the nature of the container provider, the JSPTableContainer has a list of available channels and a list of selected channels.

Available channels are the channels that are available to be activated in the Desktop, and selected channels are the channels that are displayed in the Desktop. Selected and available channels list is defined in the table container channel definition in the display profile.

The TabContainer

A tab container aggregates the output of channels, providing a tabbed user interface to switch between them. A tab container’s configuration can be modified at runtime to vary which leaf channel is displayed.

A tab container provider generates its views primarily by being a client of table container objects. The TabContainer displays one of its contained channels at a time. It allows containers to be arranged onto virtual pages. The container can then switch between these pages allowing them to be physically viewed one at a time.

It allows the user to switch logically separate row-column displays. From the container perspective, each page is a table container. The tab container then contains multiple table containers, one for each page. By default, each tab in a tab container corresponds to a table container. The tab container can contain any number of table, single, or tab containers theoretically. Having a tab container inside a tab container is not advisable.

A tab container provider is a container provider that has a selected and available channels list, and allows getting and setting of these lists. Selected channels are the table containers that are considered active on the Desktop. Available channels are those that are available to be activated on the Desktop.

The TabContainer interface defines the interface for implementing a TabContainerProvider. A TabContainerProvider must implement this interface. This interface contains methods to query information about a TabContainer and to set the properties of a TabContainer. See the Javadocs for more information on the methods in this interface.

UnmodifiableTab Interface

The UnmodifiableTab interface represents a tab that cannot be modified. This interface includes methods to:

ModifiableTab Interface

The ModifiableTab interface represents an instance of the tab that can be modified. It extends UnmodifiableTab and all modifiable tabs inherit the characteristics of the UnmodifiableTab. This interface provides methods to allow the user to reset the display name (setDisplayname()) and description (setDesc()) of the predefined tab.

JSPTabContainerProvider Class

The JSPTabContainerProvider includes the functionality to enable display of JSPs in the TabContainer environment. It provides methods that allow the associated JSP files to use these methods, and generate a view that aggregates the output of channels, providing a tabbed user interface to switch between them.

The JSPTabContainerProvider class extends JSPContainerProviderAdapter and implements the TabContainer interface.

AJAXTableContainerProvider Architecture

The AJAXTableContainerProvider integrates Asynchronous JavaScript and XML (AJAX) capabilities at the portal framework level. The container provides asynchronous loading of individual channels and portlets.

This section contains the following sections:

The AJAXTableContainerProvider is based on a hybrid architecture. Unlike other portal containers where all the processing takes place on the server and only the HTML content is returned to a browser, in the AJAXTableContainerProvider, several tasks such as page construction, style, and container controls are handled at the client side using DHTML and Javascript. The server-side component of the container provider sends a JavaScript Object Notation (JSON) message in response to requests, and the client-side JavaScript processes the JSON message to make the appropriate changes to the portal interface. Similarly, if the user modifies the portal interface, the changes are persisted to the server using AJAX.

This diagram shows the high-level architecture of the
AJAXTableContainerProvider.

The diagram shows the high-level architecture of the AJAXTableContainerProvider. The container is divided into two pieces:

Server-side Container Architecture

The AJAXTableContainerProvider is implemented as a JSPTableContainerProvider instance on the server. All the provider logic is implemented in JavaServer Page (JSP) template files of the AJAXTableContainerProvider. The container provider class remains JSPTableContainerProvider. For a content request, the AJAX Container returns a JavaScript object as a JSON representation of the display profile for the current user.


Example 5–1 JSON Representation of the Display Profile

An example JSON Representation of the Display Profile is shown here.

    "title": "News",
    "name": "NewsContainer",
    "layout": 3,
    "isAuthless": false,
    "maximizedChannel": "",
    "channelsIsMinimizable": {"SiteSearch": false},
    "channelsIsMinimized": {
        "NewsContainer/NextTourPoll": false,
        "SiteSearch": false
    },
    "channelsHasFrame": {
        "SiteSearch": false,
        "NewsContainer/google": true
    },
    "selectedChannels": [
        {
            "width": 1,
            "isEditable": false,
            "title": "Vote for our Next Tour",
            "description": "A poll to vote for what tour should be offered next.",
            "refreshTime": 0,
            "name": "NewsContainer/NextTourPoll",
            "id": "NextTourPoll"
        },
        {
            "width": 1,
            "isEditable": false,
            "title": "Search",
            "description": "Enter search term to search site content.",
            "refreshTime": 0,
            "name": "SiteSearch",
            "id": "SiteSearch"
        }
    ],
    "channelsIsDetachable": {"SiteSearch": false},
    "channelsRow": {
        "SiteSearch": "1",
        "NewsContainer/NextTourPoll": "1"
    },
    "refreshTime": "0",
    "isEditable": true,
    "channelsColumn": {
        "SiteSearch": "3",
        "NewsContainer/NextTourPoll": "1"
    },
    "description": Search",
    "channelsIsMaximizable": {"SiteSearch": false},
    "availableChannels": [
        {
            "width": 1,
            "isEditable": false,
            "title": "Customer Favorites",
            "description": "The top tours as rated by customers.",
            "refreshTime": 0,
            "name": "NewsContainer/CustomerFavorites",
            "id": "CustomerFavorites"
        },
        {
            "width": 2,
            "isEditable": false,
            "title": "UrlScraper Channel",
            "description": "This is a test for urlscraper",
            "refreshTime": 0,
            "name": "NewsContainer/google",
            "id": "google"
        }
    ]
}

The AJAXTableContainerProvider uses JSON Java API to construct a JSON representation of the display profile. The following JSON Java API classes are currently used in AJAXTableContainerProvider to construct the JSON message:


org.json.JSONObject
org.json.JSONArray
org.json.JSONException

Client-side Architecture

There are three high-level client side components:

AJAXTableContainerProvider JavaScript library

The AJAXTableContainerProvider JavaScript library handles the core logic of the container layout, style and container functionality. This library defines the following JavaScript classes:

sunportal.AJAXTableContainer

Defines methods that constructs the container and handles container functionality.

sunportal.AJAXChannel

Defines methods for individual channel control and display. A separate instance of this class is created for each channel on the page.

sunportal.AJAXRequest

Defines methods that handle the AJAX network Input and Output.

sunportal.AJAXPageOptions

Defines methods that handle the page preferences module.

sunportal.AJAXAddContent

Defines methods to preview and add new container content.

sunportal.AJAXPageStyles

Defines methods to modify the container style.

sunportal.AJAXChangeLayout

Defines methods to modify the container layout.

sunportal.AJAXUtils

Utility methods for other package classes.

portal.dnd.ChannelDropTarget

Defines methods for drag and drop functionality.

portal.dnd.ChannelDragSource

Defines methods for drag and drop functionality.

AJAXTableContainerProvider CSS

The AJAXTableContainerProvider ships with three out-of-the-box CSS themes: blue, orange and gray. Each CSS theme has the following directory structure:

styles
|---- <css theme name>
| |---- PrintableFloatingPane.css
| |---- images
| | |---- ajaxChannelEdit.png
| | |---- ajaxChannelHelp.png
| | |---- ajaxChannelMaximize.png
| | |---- ajaxChannelMinimize.png
| | |---- ajaxChannelRefresh.png
| | |---- ajaxChannelRemove.png
| | |---- ajaxChannelTitlebarBackground.gif
| | |---- ajaxChannelUnmaximize.png
| | |---- ajaxChannelUnminimize.png
| | |---- preview.png
| |---- screen.css

To create a customized theme, developers can copy an existing theme directory and modify the screen.css file, PrintableFloatingPane.css file, and the images to desired design and color. The screen.css file defines all the CSS classes used by the container. The PrintableFloatingPane.css is used by the floating pane widget that is used by some channels in the container.

Dojo JavaScript library

The AJAXTableContainerProvider uses Dojo, an open source Javascript library, for all the DOM manipulation, network I/O and visual effects. More information about Dojo can be found at http://www.dojotoolkit.org. The Dojo packages & classes used in the container are listed below


dojo.io.*
dojo.event.*
dojo.html
dojo.widget.Toggler
dojo.widget.ContentPane
dojo.widget.Dialog
dojo.dnd.*
dojo.fx.html

AJAXEditContainer Overview

In addition to AJAXTableContainerProvider, an AJAXEditContainer is also implemented. AJAXEditContainer allows inline editing of channel preferences from the AJAXTableContainerProvider. AJAXEditContainer is an instance of JSPSingleContainerProvider. AJAXEditContainer sends back HTML content for edit pages, and a JSON response upon successful completion of edit process. Examples of JSON messages returned by the AJAXEditContainer are shown below.


Example 5–2 Success Message

{
   "response": {
        "status": "SUCCESS",
        "messages": [
            ""
        ]
    }
}


Example 5–3 Failure Message

{
   "response": {
        "status": "FAIL",
        "messages": [
           "A serious error has occured in the Desktop. 
						This may have been caused by a mis-configuration on the server.",
           "Please report this problem to your administrator.",
           "Possible causes : Your session has expired or has been otherwise 
						terminated. Please re-login.",
       ]
   }

}

Using the AJAXTableContainerProvider JavaScript API

Channels and Portlets can use the AJAXTableContainerProvider JavaScript API to quickly incorporate AJAX functionality in their content. Note that JSR-168 Portlets using this JavaScript API will not be portable across containers. AJAXTableContainerProvider methods can be accessed using an instance object by name container. The container is available on a portal page to all page elements, including channel and portlet elements.

Utility Methods

The following table shows the utility methods that can be called on the container object.

container.submitContentForm (channelName, formId)

This method can be called from any channel to submit a form asynchronously. The form is submitted with the POST method. The existing channel content is automatically replaced with the response content of the form submit. It takes the following arguments:

channelName

Name of channel or portlet as a String

formId

ID of the form element

The JavaScript source file is AJAXTableContainer.js.

container.getSelectedChannelByName(channelName)

Gets the HTML node element of a channel or portlet. It takes the channelName argument to specify the name of the channel or portlet. The JavaScript source file is AJAXTableContainer.js.

container.getChannelContentNode(channelNode)

Returns the HTML node element of the content DIV of a channel. It takes the channelNode argument to specify the HTML node element of the channel. The JavaScript source file is AJAXTableContainer.js.

container.getChannelEditNode(channelNode)

Returns the HTML node element of the inline edit DIV of a channel. It takes the channelNode argument to specify the HTML node element of the channel. The JavaScript source file is AJAXTableContainer.js.

Getting a channel Name or ID

To make changes to a channel, the HTML node element of the channel is required. The HTML node element can be obtained using the container.getSelectedChannelByName(channelName) method. This however requires the name of the channel or portlet.

The name can be obtained in the JavaScript logic of a channel using one of the following ways:

Using Dojo

AJAXTableContainerProvider ships with Dojo 0.3.1. The Dojo object is available for channels and portlets to use on the portal page. The Dojo object instance name is dojo. Channels can call utility methods of Dojo, such as dojo.byId() using the dojo object. Channels can also create Dojo widgets using the dojo object, and also use dojo.io.bind for content requests. For example, a channel can use dojo.io.bind to fetch content from some URL (that has to be on the same domain as the portal).

Namespacing Channel Elements

Namespacing your channel elements to avoid conflicts is very important. To ensure that two channel elements do not conflict, unique names for elements have to be used.

Channels names can be made unique by any of the following ways:

Cross-domain AJAX

At the core of every AJAX request lies the XMLHttpRequest object. One of the security restrictions of the XMLHttpRequest object is that cross domain requests cannot be made. You cannot use the XMLHttpRequest object on the portal page to fetch content from a server that resides on a different domain than the host portal. This restriction applies to sunportal.AJAXRequest and dojo.io.*. There are workarounds for this restriction, such as implementing a cross-domain proxy and on-demand JavaScript loading. You can find more information about these techniques on AJAX related websites.

AJAXTableContainerProvider Localization

All the English messages used by the AJAXTableContainerProvider are defined in ajaxcontainers.properties resource bundle deployed under /var/opt/SUNWportal/portals/portal-ID/desktop/classes (on Solaris).