Flylib.com

Books Software

 
 
 

2.16 Attribute storage summary

 <  Day Day Up  >  

2.16 Attribute storage summary

There are many objects in the portal environment for storing attributes. In order to help you choose the right object for the right situation, refer to the following chart.

Object

Scope

Attribute Type

Programmatic Access

Best Practice

PortletRequest

Limited to request between the portal server and the portlet

object

getAttribute() setAttribute() removeAttribute()

Use a short term bucket for communication between portlet and JSP (ex: Portlet URI)

PortletSession

Limited to subsequent requests by the same user on the same concrete portlet instance

object

getAttribute() setAttribute() removeAttribute()

Use as an open line of communication between requests. (for example Shopping cart)

PortletSettings

Shared by all instances of the concrete portlet. Editable only in configure mode.

String

getAttribute() setAttribute() removeAttribute()

Use only for configuration information that is applicable to all instances (for example user ID)

PortletApplicationSettings

Shared by all concrete portlet instances deployed in the same concrete applicationd.itable only in configure mode.

String

getAttribute() setAttribute() removeAttribute()

Use only for configuration information that is applicable to all concrete portlet instances in the same application (for example server name )

PortletData

Persistently available to a single concrete portlet instance.

object(serializable)

getAttribute() setAttribute() removeAttribute()

Use for information that needs life beyond a session (for example portlet preferences)

PortletURI

One request through to the actionPerformed method

String

addParameter()

Use to provide default parameter values in case the user does not enter a value in a form

PortletMessage

Only available to registered message listeners in the event processing phase

Object

Since each custom portlet message can be implemented uniquely, access is not pre-defined

Use to adequately capture all the information necessary to complete the message. There is no predictably regarding order of execution for listeners so do depend on this.

PortletConfig

Same config object is available to every concrete portlet instance derived from the same abstract portlet.

String

getInitParameter()

This vale can only be set during development or deployment. Since its scope is very broad, use carefully .

DefaultPortlet Action

Available as long as the PortletURI it is attached to is available.

object

setParameter()

getParameters()

It is not recommended to store objects such as PortletResponse etc. Use sparingly.

PortletAdapter

Available to all instances of the concrete portlet. Value is not unique between users.

object

getVariable()

setVariable()

Use this object to store attributes that are not unique to any one user, and can be lost if the server shuts down

 <  Day Day Up  >  
 < Day Day Up > 

2.17 Portlet services

A PortalService is a discoverable extension to the Portal functionality. A portlet can query the container for a specific service and use that service without ever knowing the implementation or concerning itself with its life cycle management. Their life cycle is managed by the portal and as such does not have container restrictions placed on portlets. Example 2-26 illusstrates accesing a service in a portlet.

Example 2-32. Accessing a service
ContentAccessService service = (ContentAccessService)

       getPortletConfig().getContext().getService(ContentAccessService.class);

The default installation of WebSphere Portal Server ships with the ContentAccessService. Other services could be implemented by various vendors or by yourself as seen in 2.17.2, "Custom services" on page 109. WebSphere Portal Server also supplies the CredentialsVaultService, which is discussed in detail in 2.18, "Credential Vault" on page 113.

2.17.1 ContentAccessService

The ContentAccessService provides a convenient mechanism for accessing content outside the Portal Server. Whereas the PortletContext include method is limited to content relative to the Portlet Application, the ContentAccessService has no such limitations. Example 2-33 illustrates simple usage of the ContentAccessService. There are two important methods defined in this service:

  • include(String url, PorltetRequest request, PortletResponse response)

    This method will write the results of the URL to the response unfiltered . There is no opportunity to remove undesirable or malformed HTML. There is no URL rewriting whatsoever so relative links, such as images, will not be displayed properly. Use this method only when the URL can be trusted to return reliable content.

  • getURL(String url, PorltetRequest request, PortletResponse response)

    This method returns a java.net.URL object. This object can then be used to open a URLConnection, access an inputStream or access the host, port and other important information. This method provides the opportunity to filter the content prior to including it in the response.

Example 2-33. Using the ContentAccessService
public void

doView

(PortletRequest request, PortletResponse response) throws

                      PortletException, IOException {

   ContentAccessService cas = (ContentAccessService)

                             getPortletConfig().

                             getContext().

                             getService(ContentAccessService.class);

   cas.include("http"//www.ibm.com", request, response);

}

2.17.2 Custom services

The Portlet API allows you to create your own services that you can install into the portal server. The main benefits of services are twofold. First, they execute outside of the Portlet Containers. Secondly, the are not tied to any given portlet and therefore their life cycle is not dependent on individual portlets. This means that once the service has been initialized , it is available to all portlets with no further initialization cost. Likewise, the destruction cost is not absorbed by any single portlet.

To create your own service, there are four steps. Some of these steps are optional. This section will use a custom MailService as an example. This example allows a portlet to locate the MailService, send an e-mail and verify that it was in fact sent. The actual implementation of the JavaMail API is not included for clarity.

  1. Define the service

    First, you must define an interface that defines the functionality this service will provide. The custom service interface must extend PortletService. The PortletService interface is a flag interface and therefore does not define any methods.

    Example 2-34. Defining the Service Interface.
    package com.yourco.services.mailservice;
    
    
    
    import org.apache.jetspeed.portlet.service.*;
    
    
    
    public interface MailService extends PortletService {
    
    
    
       public boolean sendEMail(String address, String subject, String message);
    
    }
    
  2. Implement the service

    The Service interface then needs to be implemented. The implementation class must implement the custom service interface you defined as well as the PortletServiceProvide interface. The PortletServiceProvide defines the init and destroy methods that must be implemented. The init method may be called by the factory when the implementation class is first created. In practice, while your custom factories may choose not to utilize this method, the default factories do. The init method is an appropriate location to load initialization parameters, establish connection pools, etc. Initialization parameters are discussed in step 4. The destroy method is an appropriate location to release any resources or perform any other common clean-up code.

    Example 2-35. Implementing the custom service
    package com.yourco.services.mailservice.impl;
    
    
    
    import org.apache.jetspeed.portlet.service.*;
    
    import org.apache.jetspeed.portlet.service.spi.*;
    
    import com.yourco.services.mailservice.MailService;
    
    
    
    public class
    
    MailServiceImpl
    
    implements PortletServiceProvider, MailService {
    
    
    
       private String server_name;
    
    
    
       public void
    
    init
    
    (PortletServiceConfig config)
    
          throws PortletServiceUnavailableException {
    
          //Set Mail Server name based on inititialization parameters
    
          server_name = config.getInitParameter("SERVER_NAME");
    
       }
    
    
    
       public void
    
    destroy
    
    () {
    
          //No resources to destroy
    
       }
    
    
    
       public boolean sendEMail(String address, String subject, String message) {
    
          //Send mail using JavaMail API
    
          return true;
    
       }
    
    }
    
  3. Create the service factory

    This step is optional when creating custom services. The factory is used by the PortletContext object to retrieve an instance of the service. Two default factories are provided with Portlet API. PortletServiceDefaultFactory will always return a new instance of the service. PortletServiceCacheFactory will always return the same instance of the service. Both of these factories call the init method of the service they are instantiating. Generally, either of the two default factories will provide the functionality you need when creating custom services. However, to ensure this example is complete, Example 2-36 illustrates a custom factory for the MailService service.

    Example 2-36. Creating a custom factory
    package com.yourco.services.mailservice.factory;
    
    
    
    import java.util.*;
    
    import javax.servlet.ServletConfig;
    
    import org.apache.jetspeed.portlet.service.*;
    
    import org.apache.jetspeed.portlet.service. spi.*;
    
    import org.apache.jetspeed.portletcontainer.service.*;
    
    import com.yourco.services.mailservice.impl.MailServiceImpl;
    
    
    
    public class
    
    MailServiceFactory
    
    implements PortletServiceFactory{
    
    
    
       private PortletServiceProvider psp = null;
    
    
    
       public PortletService createPortletService(Class service, Properties props,
    
                 ServletConfig config) throws PortletServiceUnavailableException {
    
          if (psp != null) {
    
             return psp;
    
          } else {
    
             psp = new MailServiceImpl();
    
             psp.init(new PortletServiceConfigImpl(service, props, config));
    
             return psp;
    
          }
    
       }
    
    }
    
  4. Register the service

    Once the service interface has been defined, the implementation class created and the factory decided upon, the classes should be packaged into a jar file. This jar should be placed in the <WAS-ROOT>lib\app directory. If you have decided to use one of the default factories, they are already in this directory in the wps.jar file.

    Once the files have been deployed, the service must be registered. Open the PortletService.properties file in the <WP-ROOT>\app\wps.ear\ wps.war\WEB-INF\conf directory. It is recommended that you make a backup of this file prior to modifying it. The service and its factory must be registered as illustrated in Example 2-37. The first mapping indicates that when a service is requested, the specified implementation class should be returned. The second mapping indicates which factory should be used to create this service when requested . This mapping should specify your custom factory, org.apache.jetspeed.portletcontainer.service.PortletServiceCacheFactory or org.apache.jetspeed.portletcontainer.service.PortletServiceDefaultFactory.

    Example 2-37. Registering the service in PortletServices.properties
    com.yourco.services.mailservice.MailService =
    
          com.yourco.services.mailservice.impl.MailServiceImpl
    
    com.yourco.services.mailservice.impl.MailServiceImpl.factory =
    
          com.yourco.services.mailservice.factory.MailServiceFactory
    

    Initialization parameters are also supplied in the PortletService.properties file as illustrated in Example 2-38. Accessing these parameters is illustrated in Example 2-35 on page 111.

    Example 2-38. Setting Unit parameters in PortletService.properties
    com.yourco.services.mailservice.impl.MailServiceImpl.SERVER_NAME =
    
       "
    
    SERVER_NAME
    
    "
    
  5. Test the service

    In order for the service to become available in the Portal, the Portal Server must be restarted. Using the WebSphere Administrator's Console, restart the WebSphere Portal Application Server. Example 2-39 shows a simple portlet making use of the MailService service.

    Example 2-39. Using the MailService service
    public void
    
    actionPerformed
    
    (ActionEvent event) throws PortletException {
    
       PortletRequest request = event.getRequest();
    
       String address = request.getParameter("address");
    
       String subject = request.getParameter("subject");
    
       String msg = request.getParameter("msg");
    
       MailService mailService = (MailService)
    
          getPortletConfig().getContext().getService(MailService.class);
    
       String result = "" + mailService.sendEMail(address, subject, msg);
    
       request.getPortletSession().setAttribute("EmailResult", result);
    
    }
    
 < Day Day Up >