Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Exploiting the WebSphere Portal 5.1.0.1 programming model: Part 4: Making your portal dynamic and context sensitive

Jan Engehausen (jan.engehausen@de.ibm.com), Technical Lead, WebSphere Portal Engine Component, IBM
Jan Engehausen photo
Jan Engehausen is the technical team lead of the WebSphere Portal Engine component, located in the IBM Development Laboratory in Boeblingen, Germany. He holds a Master of Science degree from the Technical University of Clausthal, Germany. He joined IBM in 2000, working on an object-oriented scripting language before joining the Portal Development Team in late 2002. Before becoming the team leader, his major focus was the Engine's model implementation and its interfaces.
Stefan Hepper, WebSphere Portal Programming Model Architect, IBM
Stefan Hepper is the responsible architect for the WebSphere Portal and Workplace programming model and public APIs. He co-led the Java Portlet Specification V1.0 (JSR 168) and is now leading the V2.0 (JSR 286) effort. Stefan received a Diploma of Computer Science from the University of Karlsruhe, Germany, and in 1998 he joined the IBM Böblingen Development Laboratory.
Andreas Nauerz (andreas.nauerz@de.ibm.com), Software Engineer, IBM
Author photo: Andreas Nauerz
Andreas Nauerz Andreas Nauerz works as Software Engineer in the IBM Laboratories at Boeblingen, Germany. His current work areas include Business Process Integration and Dynamic UI Management. He studied Computer Science at the University of Cooperative Education of Mannheim, the University of Staffordshire, the University of Saarbruecken, and the University of Hagen, respectively.
Juergen Schaeck (jschaeck@de.ibm.com), Software Engineer, IBM
author
Juergen Schaeck is a Software Engineer at IBM Boeblingen Lab. Juergen holds a Master's degree from the University of Karlsruhe and currently works in WebSphere Portal Development. He is responsible for Business Process Integration and Dynamic UI Management in WebSphere Portal.

Summary:  This final part describes how to exploit the IBM® WebSphere® Portal V5.1.0.1 programming model to make your portals more dynamic and context sensitive. By using the Model SPI, you can access the different sub-models within the overall portal model, and then base your markup rendering on these models. You see an example that accesses page meta data, so that the administrator can set a context for this page that is then leveraged by the portlets on that page. Next, you see how to use the Dynamic UI Manager API to launch temporary, dynamic pages, and to set a specific context for a page. A flight booking application demonstrates the Dynamic UI Manager API, by creating dynamic pages for the different steps in the booking process.

View more content in this series

Date:  27 Sep 2006 (Published 02 Aug 2006)
Level:  Intermediate
Also available in:   Chinese  Russian

Activity:  11198 views
Comments:  

Introduction

Portal models represent the data that the portal uses to produce a portal page. Included in this collection of models are the Content model, which defines the page content, and the Navigation model, which defines the topology for navigating through the content.

The first part of this article examines all the available models, and shows a sample portlet using the page meta data to access page context information.

Next, you see how to add dynamic capability to the portal models with the dynamic UI manager, which lets you create dynamic pages.

Finally, a detailed example shows how to use the Dynamic UI manager API to create a flight booking application.


Leveraging the Model SPI

The public Model SPI introduced with WebSphere Portal V5.1.0.1 provides read-access to portal models that are used to aggregate and render portal content.

Your portlets can access the models shown in Table 1.


Table 1. Models available in WebSphere Portal V5.1.0.1
ModelDescription

Content model

Describes the topology in which the content is structured for a specific user. The content model is a tree structure composed of content nodes of various types including pages, labels, internal URLs, and external URLs. For details on the content tree see the Sub packages of the Model SPI topic in the InfoCenter (listed in Resources).

Navigation model

Describes the topology of the navigation visible to a specific user. This model is composed of navigation nodes. In WebSphere Portal V5, the navigation nodes are implied by the structure of the content model. A navigation node references content represented by content nodes.

Navigation Selection model

Describes the selected node in the portal navigation model.

Language model

Lists languages supported by the portal.

Layout model

Describes the layout of a page. It is composed of layout nodes, which can be containers, that affect the layout of the page (rows and columns), or controls that affect the content (portlets) of a page.

Markup List

Lists the markup languages supported by the portal.

Skin List

Lists skin objects used by the portal.

Theme List

Lists theme objects used by the portal.

JSR 168 portlets can access these models through specific portlet services, which are located in the com.ibm.portal.portlet.service.model package. For more details, see the Sub packages of the Model SPI section of the WebSphere Portal InfoCenter, and see the SPI Model Javadoc (listed in Resources).

Listing 1 shows how a JSR 168 compliant portlet obtains the navigation selection model.


Listing 1. Obtaining a navigation selection model
                
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
. . .
import com.ibm.portal.ModelException;
import com.ibm.portal.navigation.NavigationSelectionModel;
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.portlet.service.PortletServiceUnavailableException;
import com.ibm.portal.portlet.service.model.NavigationSelectionModelProvider;
. . .

final PortletServiceHome psh;
final Context ctx = new InitialContext();
try {
	psh = (PortletServiceHome) ctx.lookup("portletservice/" 
	  + NavigationSelectionModelProvider.class.getName());
} catch (NameNotFoundException ex) {
    psh = null;
    // error handling
}
if (psh != null) {
    try {
        final NavigationSelectionModelProvider provider = 
          (NavigationSelectionModelProvider) psh.
          getPortletService(NavigationSelectionModelProvider.class);
        final NavigationSelectionModel model = 
          provider.getNavigationSelectionModel(aRequest, aResponse);
        // . . .
    } catch (PortletServiceUnavailableException e) {
        // error handling
    } catch (ModelException e) {
        // error handling
    }
}

In Listing 1, the JNDI lookup for the portlet service NavigationSelectionModelProvider returns the model based on the portlet request and response. Because the JNDI lookup can be expensive, it is good practice to store the provider object as a member variable of the portlet, and to initialize it in the init() method.


Sample portlet: Accessing page meta data

Let's see how a portlet can use the Model SPI to read page meta data so that the portlet can "adapt" according to the page on which it is placed.

A node in the content model can carry meta data, represented with the com.ibm.portal.MetaData interface. A portlet can obtain MetaData by using the (optionally implemented) com.ibm.portal.MetaDataProvider interface. Listing 2 shows how to obtain the meta data of a content node.


Listing 2. Obtaining the content meta data
                
import com.ibm.portal.MetaData;
import com.ibm.portal.MetaDataProvider;
import com.ibm.portal.content.ContentNode;
import com.ibm.portal.navigation.NavigationNode;
…

final NavigationSelectionModel model = 
  provider.getNavigationSelectionModel(aRequest, aResponse);
final NavigationNode selectedNode = (NavigationNode) model.getSelectedNode();
if (selectedNode != null) {
    // a selected node is present, obtain the content node
	final ContentNode contentNode = selectedNode.getContentNode();
    if (contentNode instanceof MetaDataProvider) {
        final MetaData data = (MetaData) ((MetaDataProvider) 
				contentNode).getMetaData();
        // . . .
    }
}

You would set the meta data on content nodes using XML Access (prior to WebSphere Portal V6.0, this is the only way to set the content meta data). You use the parameter tag on content-node elements to set the meta data, as shown in Listing 3.


Listing 3. Setting content meta data using XML Access
                
<content-node action="update" …>
    . . .
	<parameter name="page.contact.name" type="string" update="set">
		<![CDATA[Jane Doe]]>
	</parameter>
	<parameter name="page.contact.email" type="string" update="set">
		<![CDATA[jane.doe@domain.prefix]]>
    </parameter>
    . . .
</content-node>

In this example, we set contact information for a portal page as meta data on the content node (see above XML Access excerpt). The portlet then can use this information to display contact information, as shown in Listing 4.


Listing 4. Displaying contact information
                
final MetaData data = (MetaData) ((MetaDataProvider) contentNode).getMetaData();
final Object name = data.getValue("page.contact.name");
final Object mail = data.getValue("page.contact.email");
if ((name != null) && (mail != null)) {
    // we have the information
    out.write("Contact information: <a href=\"mailto:");
    out.write(mail.toString());
    out.write("\">");
    out.write(name.toString());
    out.write("</a>");
}


Creating dynamic user interfaces

Now that you have some background in WebSphere Portal's content model and have seen how to use the SPI to work with it, let's look at how to create dynamic user interfaces. You use WebSphere Portal's Dynamic UI Management feature to create portlets and portal pages at run time. You see how to do this in a sample application.

Understanding Dynamic UI Management

You can use Dynamic UI Management to modify a user's content model (and, implicitly, the navigation model) at run time, triggered by a user interaction.

Being able to dynamically modify the content model creates many new options; for example, you can:

  • Increase usability by keeping to a minimum the number of pages in a portal and number of portlets on a page.

    Based on user interaction, you can display pages and portlets at the time they are needed, and you can remove them when they become obsolete.

  • Re-use components.

    You can parameterize individual pages and portlets with the current application context so that they seamlessly integrate with the calling application.

  • Enable multi-page applications.

    Your application can use multiple pages, such as to implement a wizard dialog.

Without Dynamic UI Management, creating a user-specific content model is basically a filtering step during which Portal Access Control (PAC) rules are applied to the "Static Content Model" that is defined by the administrator.

Figure 1 shows an example of a content model in which the current user possesses only VIEW rights to some of the nodes of the sub-tree, starting at node 1.2. Therefore, the user-specific model is a subset of the portal pages.


Figure 1. Creation of a user's content model
Creation of a user's content model

Conceptually, when you use Dynamic UI Management, you add another step to the process of generating a user-specific content model. The PAC-filtered model is processed in this new step, during which additional pages can be added and removed before rendering.

Important: Because modifications of the content model are based on user interactions and only apply to a given user, those modifications are stored in the user's session. Therefore, you cannot use Dynamic UI Management for the anonymous user or on public portal pages where no user session is created.


Figure 2. Creation of a user's content model using Dynamic UI Management
Creation of a user's content model using Dynamic UI Management

WebSphere Portal provides theDynamicUICtrl service as the API for custom applications to modify a user's content model at run time. To enable portlet developers to easily exploit the dynamic portal capabilities, the Dynamic UI Controller encapsulates some aspects of the Model SPI. The Dynamic UI Manager operates on the following artifacts.


Table 2. Artifacts used by Dynamic UI Manager
ArtifactDescription

Page definition

A page definition is a standard portal page that acts as a blueprint or template for the creation of a dynamic page. Developers can use standard portal tools (Manage Pages, XML Access) to create the page; you do not have to create a Model SPI-compliant object tree within your own code.

Portlet definition

The portlet definition is the portlet equivalent of a page definition. It consists of the portlet and a set of default preference settings.

Context

This is a set of values (properties) that is passed to all portlets on a dynamic page or to a specific portlet.

Extension node

An extension node is a content node in portal that is marked as the place where dynamic pages show up when they are created.

Example: Flow of dynamic UI creation

Figure 3 shows an example flow of this general scenario: A portlet displays a list of products. When a user selects a product, a new page opens to display another portlet that shows the selected product's detailed information.


Figure 3. Adding a dynamic page using Dynamic UI Manager
Adding a dynamic page using Dynamic UI Manager

Using the Dynamic UI Manager API, the following control flow would be implemented.

  1. The user clicks a product in the list, initiating a call to the performAction method of the portlet.

    Important: Modifications of the content tree are only allowed in the action phase.

  2. In the performAction method, the portlet code obtains a reference to the Dynamic UI Controller, and calls the addPage method, which takes the extension node and the object id of the page definition as parameters. Because the Product Details portlet should directly display the details of the selected product, a page context object is created that contains the product ID. The ID is passed as an additional parameter to the addPage method, and then delivered to the portlets on the newly generated page instance.
  3. The Dynamic UI Controller performs a lookup of the page definition, uses its layout model as the blueprint, and creates a new dynamic page out of it. The page context is transmitted to the portlets on the newly generated page instance.
  4. The portlet redirects the user to the newly created page.

For more information see the WebSphere Portal Info Center and the DynamicUIManagement and PropertyBroker packages in the Portlet API Javadoc (listed in Resources).

Dynamic UIs (Dynamic Pages/Portlets) created by the Dynamic UI Manager APIs possess the following attributes:

  • A dynamic UI can only be launched by a portlet using the Dynamic UI Manager API.
  • Because of its dynamic nature, the interface is not persisted in the portal database and has a maximum lifetime of the user's session with the portal.
  • The interface can also be closed prior to the end of the session, either programmatically or by the user.
  • A dynamic UI is independent of its point of origin. For example, if a portlet launches a dynamic page, the launched page is maintained even if the originating portlet or page is deleted.
  • A dynamic UI is a copy of a page or portlet definition at the time the instance is created, and it is not affected by subsequent changes to the definition. By default, the dynamic UI acquires the title and description of its page or portlet definition. However, you can programmatically overwrite the title and description when the dynamic UI is launched.

Also, consider these limitations before using a dnamic UI with your portal:

  • DynamicPages cannot be bookmarked.
  • Pages are user specific, and have limited caching options.
  • There is no support for the creation of hierarchies of dynamic pages.
  • Portlets can only be added to the page on which the calling portlet is placed.
  • Portlets cannot store anything persistent in their portlet preferences.

Travel agency scenario

A mythical company, which we call Dynamic Travel Agency Corp. is a travel agency that books flights, cars, and hotels for customers. Customers can request orders by phone, mail, fax, or by physically visiting one of the agency offices.

The administrative agent usually works on bookings that arrive by phone, mail, or fax; however, bookings by phone call or made in person take priroty. So, he often needs to stop working on one booking form, and launch a new form so he can start a new booking process for the customer on the phone or sitting in the office.

In this case, he usually has not completed the original booking form he had started and cannot yet submit it. Because he cannot continue filling out that booking form, and needs to start the booking process for the higher priority customer, he wants to be able to continue with the previous one later. Therefore, he needs to have several instances of the booking forms launched at the same time, so that he does not lose the data that he has already entered on a the first form (which has not yet been completed). And, he wants to be able to start a new booking process, simultaneously.

DynamicUI management lets you launch and remove several instances of pages containing the booking forms simultaneously.

In addition, when working on the pages containing the booking forms, the agent can use "supporting elements" (portlets). These portlets can transmit information to the main portlet through WebSphere Portal's cooperative portlet capability. He can let them display and disappear on-demand, which avoids overloading the page with too many portlets.

Flow

The agent starts at what he calls the "launchpad" to launch instances of flight, car, or hotel booking form pages (Figure 4). Each time the agent clicks a link, a new, independent instance of either a flight, car, or hotel booking form page launches.


Figure 4. Agent uses the launchpad to start new bookings
Agent uses the launchpad to start new bookings

The agent starts to book a flight for an order that arrived by mail. He clicks the Book a flight link, and a new form page launches to which he is redirected. He starts filling out that form (Figure 5).


Figure 5. Agent fills out the new flight booking form
Agent fills out the new flight booking form

Before he can complete the form, a customer enters his office who wants to book a flight, too. The agent needs a new flight booking form page. He navigates back to the launchpad, and clicks the Book a flight link once more. A new instance of the corresponding page opens (Figure 6).


Figure 6. Agent opens another new, independe flight booking form
Agent opens another new, independe flight booking form

Working with the customer in his office, the agent starts to fill out the form. Because the customer is not sure which datest to select for his travel, the agent dynamically launches a supporting element, that is, an additional portlet which is a calendar portlet, to help the customer make his choices. The agent clicks the Display calendar portlet link to open the portlet (Figure 7).


Figure 7. Agent opens the calendar portlet for the customer
Agent opens the calendar portlet for the customer

After the customer picks the dates, the agent clicks the Hide calendar portlet link to remove the portlet.

As soon as the entire form has been filled out, the agent submits the form and the corresponding page instance closes. Then, he can then continue with the previous flight booking process he had started before the customer came into the office.

As long as other dynamic page instances are available, the agent is re-directed to one of those after closing an instance.

The little "X" displayed beside a dynamic pages lets the agent close instances he no longer needs, without submitting a form.


Implementing a dynamic UI application

Now, let's walk through the highlights of implementing the flight booking application.

The launchpad

First, develop the portlet that lets the agent launch dynamic booking pages.

Within the init method of the portlet, retrieve the set of necessary services.

  1. Use DynamicUIManagerService to launch dynamic page instances.
    // DynamicUIManagerService
    final PortletServiceHome dynamicUIManagerFactoryServiceHome = 
      (PortletServiceHome) ctx.lookup("portletservice/com.ibm.portal.portlet.service.
      dynamicui.DynamicUIManagementFactoryService");
    dynamicUIManagerFactoryService = (DynamicUIManagementFactoryService) dynamicUIManagerFactoryServiceHome.getPortletService(DynamicUIManagementFactoryService.class);

  2. Use RedirectURLGeneratorFactoryService to obtain an instance of the RedirectURLGenerator which generates URLs to perform redirects (for example, to launch dynamic pages).
    // RedirectURLGeneratorFactoryService
    final PortletServiceHome redirectServiceHome = (PortletServiceHome) ctx.lookup
    ("portletservice/com.ibm.portal.portlet.service.state.RedirectURLGeneratorFactoryService"
    );
    redirectService = (RedirectURLGeneratorFactoryService) 
    redirectServiceHome.getPortletService(RedirectURLGeneratorFactoryService.class);

  3. Use PropertyFactory to create property values that can be transmitted to launched dynamic pages.
    // PropertyFactoryService
    final PortletServiceHome propertyFactoryServiceHome = (PortletServiceHome) ctx.lookup
      ("portletservice/com.ibm.portal.propertybroker.service.PropertyFactory"); 
    propertyFactory = (PropertyFactory)propertyFactoryServiceHome.getPortletService
    (com.ibm.portal.propertybroker.service.PropertyFactory.class);

  4. Use PropertyBrokerContextPassingService to transmit these properties to launched dynamic pages.
    // PropertyBrokerContextPassingService
    final PortletServiceHome contextPassingServiceHome = (PortletServiceHome) ctx.lookup("
    portletservice/com.ibm.portal.propertybroker.service.PropertyBrokerContextPassingService
    ");
    contextPassingService = (PropertyBrokerContextPassingService)
    contextPassingServiceHome.getPortletService
    (com.ibm.portal.propertybroker.service.PropertyBrokerContextPassingService.class);

  5. Attach actionURLs to the three links: Book a flight, Book a car, and Book a hotel.
    <tr>
    <td>
    <img src="<%=renderResponse.encodeURL(renderRequest.getContextPath() 
    + "/images/airplane.jpg")%>" border="0"/>
    </td>
    <td>
    <a href="<portlet:actionURL> 
    <portlet:param name='action' value='bookFlight'/> 
    </portlet:actionURL>">Book a flight</a>
    </td>
    </tr>
    
    <tr>
    <td>
    <img src="<%=renderResponse.encodeURL(renderRequest.getContextPath() 
    + "/images/acar.jpg")%>" border="0"/>
    </td>
    <td>
    <a href="<portlet:actionURL> 
    <portlet:param name='action' value='bookCar'/> 
    </portlet:actionURL>">Book a car</a> <br>
    </td>
    </tr>
    
    <tr>
    <td>
    <img src="<%=renderResponse.encodeURL(renderRequest.getContextPath() 
    + "/images/ahotel.jpg")%>" border="0"/>
    </td>
    <td>
    <a href="<portlet:actionURL> 
    <portlet:param name='action' value='bookHotel'/> 
    </portlet:actionURL>">Book a hotel</a> <br>
    </td>
    </tr>

  6. To implement the launching task, within the processAction method of the portlet, first, determine the ID of the page definition describing the dynamic page to be launched.
    // Lookup ID of the page to be launched
    final Context ctx = new InitialContext();
    final Name uniqueName = new CompositeName("portal:uniquename");
    uniqueName.add(BOOK_FLIGHT_PAGE_UNIQUE_NAME);
    ObjectID oidForUniqueName = (ObjectID) ctx.lookup(uniqueName);

  7. Then, use DynamicUIManagerService to launch the dynamic page.
    // Launch dynamic page
    DynamicUICtrl DynamicUICtrl = dynamicUIManagerFactoryService.getDynamicUICtrl
    	(request, response, EXTENSION_NODE_UNIQUE_NAME);
    ObjectID launchedPageID = DynamicUICtrl.addPage(oidForUniqueName, 
    	new LocalizedImpl("Book flight", "Dynamic page to book a flight"), null);

    The variable EXTENSION_NODE_UNIQUE_NAME contains the unique name of the extension node with which the dynamic page instance should be launched.

    The LocalizedImpl object contains the title and description for the dynamic page instance.

    Important: When you exploit the Dynamic UI Manager API, you need to create your own LocalizedImpl implementation implementing the Localized interface.

    After the page or portlet is launched, the variable launchedPageID contains the ID of the dynamic page instance.

    The argument that is set to null could have been used to transmit additional properties to the dynamic page instance. However, you could not transmit the ID of the dynamic page instance using that argument because you do not know the ID before the page has been launched.

  8. On the dynamic page, you need to know the ID of the page (that is, the value of the variable launchedPageID) in order to close it again. So, create a property containing the ID of the dynamic page instance.
    // Create property (we need to know the launched page ID in order to close the page later)
    PropertyController property1 = propertyFactory.createProperty(config);
    property1.setName(PROPERTY_NAME);
    property1.setClassname("java.lang.String");
    property1.setDirection(Direction.OUT);
    
    PropertyValue value = 
      propertyFactory.createPropertyValue(request, property1, launchedPageID);
    PropertyValue[] propertyValues = new PropertyValue[1];
    propertyValues[0] = value;
     

  9. Then, transmit the property using PropertyBrokerContextPassingService to the dynamic page instance.
    // Transmit property
    contextPassingService.changedProperties
    (request, response, launchedPageID, propertyValues);

  10. Finally, redirect the agent to the launched dynamic page.
    // Redirect to launched page
    RedirectURLGenerator redirector = redirectService.getURLGenerator(request, response);
    EngineURL redirectURL = redirector.createPageURL(launchedPageID);
    
    response.sendRedirect(redirectURL.toString());

Tip: We transmit the ID of the launched page using the PropertyBrokerContextPassingService to demonstrate how to use this feature. Of course, you could also use the Model API to look up the ID of the launched page.

The dynamic page and the flight booking portlet

Next, develop the flight booking portlet.

  1. To receive a property transmitted by the PropertyBrokerContextPassingService, you need to enable the portlet to receive properties. Therefore, set a preference within its portlet.xml.
    <portlet-preferences>
    <preference>
    <name>com.ibm.portal.pagecontext.enable</name>
    <value>true</value>
    </preference>
    </portlet-preferences>

    JSR 168 compliant portlets receive page properties on the processAction method using the com.ibm.portal.context request attribute. The value of this attribute is a Map storing the context entries. Each property value is obtained by name.

  2. To get a value for the property with name PROPERTY_NAME use the following code.
    // Perform page context processingString specialAction = 
      request.getParameter("com.ibm.portal.action");
    
    if (specialAction != null && specialAction.equals("com.ibm.portal.pagecontext.receive")){
    // This indicates context was passed to the launched page
                java.util.Map contextMap = 
                  (java.util.Map) request.getAttribute("com.ibm.portal.pagecontext.context");
                
                // Read the information we need
                ObjectID launchedPageID = (ObjectID) contextMap.get(PROPERTY_NAME);
                
               // Store the informationr read in the session
                portletSession.setAttribute(LAUNCHED_PAGE_ID, launchedPageID);
    }
        

  3. To make use the transmitted property, store it in a portlet session variable.
  4. Then, as before, retrieve the required service. This time, you only need the DynamicUIManagerService to launch the additional (calendar) portlet.

You need to implement two more things:

  • Capabilities to launch and remove the additional calendar portlet
  • Capability to close the dynamic page instance as soon as the form is submitted
  1. Again, attach actionURLs to the Display calendar portlet and Hide calendar portlet links. The actual launch and remove of the portlet is performed within the processAction method again.
  2. For launching the dynamic portlet, first lookup the ID of the portlet definition describing the dynamic portlet, and then launch the portlet using the DynamicUIManagerService. Save the ID of the launched portlet to be able to remove it again. Finally, redirect to the portlet:
    // Lookup ID of the portlet to be launched
    final Context ctx = new InitialContext();
    final Name uniqueName = new CompositeName("portal:uniquename");
    uniqueName.add(CALENDAR_PORTLET_UNIQUE_NAME);
    ObjectID oidForUniqueName = (ObjectID) ctx.lookup(uniqueName);
    
    // Launch portlet
    DynamicUICtrl DynamicUICtrl = dynamicUIManagerFactoryService.getDynamicUICtrl
    	(request, response, EXTENSION_NODE_UNIQUE_NAME);
    ObjectID launchedPortletID = DynamicUICtrl.addPortlet(oidForUniqueName, 
    	new LocalizedImpl("Calendar portlet", "Portlet to select dates"), null);
    // Remember ID
    portletSession.setAttribute(LAUNCHED_PORTLET_ID, launchedPortletID);
    
    // Redirect to launched portlet
    RedirectURLGenerator redirector = redirectService.getURLGenerator(request, response);
    EngineURL redirectURL = redirector.createPortletURL
    	(launchedPortletID);response.sendRedirect(redirectURL.toString());

  3. Remove the dynamic portlet in a similar fashion.
    // Remove portlet
    DynamicUICtrl DynamicUICtrl = dynamicUIManagerFactoryService.getDynamicUICtrl
    	(request, response, EXTENSION_NODE_UNIQUE_NAME);
    DynamicUICtrl.removePortlet((ObjectID) portletSession.getAttribute
    	(LAUNCHED_PORTLET_ID));// Tear down
    portletSession.removeAttribute(LAUNCHED_PORTLET_ID);

  4. Finally, we close the dynamic page as soon as the agent submits the form:
    // Remove page
    DynamicUICtrl DynamicUICtrl = dynamicUIManagerFactoryService.getDynamicUICtrl
    	(request, response, EXTENSION_NODE_UNIQUE_NAME);
    ObjectID newSelectionID = DynamicUICtrl.removePage((ObjectID)portletSession.getAttribute
    	(LAUNCHED_PAGE_ID));// Redirect to new selection
    RedirectURLGenerator redirector = redirectService.getURLGenerator(request, response);
    EngineURL redirectURL = redirector.createPageURL(newSelectionID);
    
    response.sendRedirect(redirectURL.toString());
      

The ID returned by the removePage method contains the ID of the page to redirect to next. As long as other dynamic page instances are available, this is one of those.

Deploying the application

  1. First, deploy the applications contained in the WAR named DynamicUISample.war using the Web Modules portlet.
  2. Create a page titled DynamicUI sample (for example, under the Home page), and place the portlet named Dynamic launching portlet onto it using the Manage Pages portlet.
  3. Assign the unique name extensionNode to that page using the Custom Unique Names portlet in the Portal Settings group.
  4. Assign the DynamicUI transformation, which enables dynamic pages (portlets) to be launched under the extension node, by issuing the following command in the PortalServer/config directory:
    wpsconfig.{bat|sh} enable-page-as-extension-node –DPageUniqueName=extensionNode

  5. Set properties (such as PortalAdminId and PortalAdminPwd) in the wpconfig.properties file.
  6. Create the page definition of the flight booking page. Use the Manage Pages portlet again to create a page titled Flight booking page, and add the Flight book portlet onto it. This page should not be visible to the users.
  7. Using the Custom Unique Names portlet, assign Flight booking page the unique name dynamicui.sample.flightbookingpage, and the portlet named Calendar selector portlet the unique name dynamicui.sample.calendar . The unique names are used to launch dynamic instances of these pages or portlets.

    Important: Page definitions are usually created directly under the node CONTENT_ROOT so that they do not display within the normal navigation. You need to assign appropriate access rights to that page (and the portlets on it) because these rights are preserved on its dynamic page instances.

The entire sample (binaries and sources) is provided together with this article (see download).


Conclusion

In this last part of the series on the WebSpherer Portal V5.1.0.1 programming model, we covered some of the more advanced portal API's that fall under the System Programming Interface (SPI) category. We described the different portlet models and how you can access them. Then, we showed how to make the models dynamic, to add dynamic pages and portlets. Finally, we created a sample application using the dynamic page launching capability for a flight booking application that launches currently-needed portlets for each step in a flight booking process.



Download

DescriptionNameSizeDownload method
Code samplesDynamicUISample.war49KBHTTP

Information about download methods


Resources

About the authors

Jan Engehausen photo

Jan Engehausen is the technical team lead of the WebSphere Portal Engine component, located in the IBM Development Laboratory in Boeblingen, Germany. He holds a Master of Science degree from the Technical University of Clausthal, Germany. He joined IBM in 2000, working on an object-oriented scripting language before joining the Portal Development Team in late 2002. Before becoming the team leader, his major focus was the Engine's model implementation and its interfaces.

Stefan Hepper

Stefan Hepper is the responsible architect for the WebSphere Portal and Workplace programming model and public APIs. He co-led the Java Portlet Specification V1.0 (JSR 168) and is now leading the V2.0 (JSR 286) effort. Stefan received a Diploma of Computer Science from the University of Karlsruhe, Germany, and in 1998 he joined the IBM Böblingen Development Laboratory.

Author photo: Andreas Nauerz

Andreas Nauerz Andreas Nauerz works as Software Engineer in the IBM Laboratories at Boeblingen, Germany. His current work areas include Business Process Integration and Dynamic UI Management. He studied Computer Science at the University of Cooperative Education of Mannheim, the University of Staffordshire, the University of Saarbruecken, and the University of Hagen, respectively.

author

Juergen Schaeck is a Software Engineer at IBM Boeblingen Lab. Juergen holds a Master's degree from the University of Karlsruhe and currently works in WebSphere Portal Development. He is responsible for Business Process Integration and Dynamic UI Management in WebSphere Portal.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=151760
ArticleTitle=Exploiting the WebSphere Portal 5.1.0.1 programming model: Part 4: Making your portal dynamic and context sensitive
publish-date=09272006
author1-email=jan.engehausen@de.ibm.com
author1-email-cc=
author2-email=sthepper@de.ibm.com
author2-email-cc=
author3-email=andreas.nauerz@de.ibm.com
author3-email-cc=
author4-email=jschaeck@de.ibm.com
author4-email-cc=