Oracle Portal-to-Go Implementation Guide Release 1.0.2.2 A86635-02 |
Library | Service | Contents | Index

# 13
Portal-to-Go Extensibility

This document discusses the components you can use to extend Portal-to-Go functionality. Topics include:

- Overview

- Daemons

- Hooks

- Extending the Core Components

## Overview

Portal-to-Go supports system-wide extensibility. Not only can you create adapters and transformers that extend its core functionality, you can modify the internal processing of its core objects and create specialized components for system monitoring and integration.

Portal-to-Go uses the System.properties file to determine at runtime which components to use for system processes. When you create a class to implement specialized functionality, you plug the class into the Portal-to-Go architecture by identifying the class as a key value in the System.properties file.

Portal-to-Go supports the following types of plug-in classes:

- Daemons: Daemons are processing objects that execute in their own thread. Typically, they listen for and respond to events.

- Hooks: Hooks process objects that execute in the same thread as Portal-to-Go.

To customize or implement a new component in the Portal-to-Go architecture:

1. Create the class that implements the component customization or extension.

2. Reference the class in the System.properties file.

3. Configure any parameters that are specific to the component in the appropriate properties files.

You must implement the pluggable class as a singleton (only a single instance of the class can exist in the system at a time), with static class methods. You should include the class in the system CLASSPATH, so that it can be loaded by the standard Java Virtual Machine class loader. When changing a component, you must shut down and restart the Portal-to-Go server processes.

## Daemons

You create your own Portal-to-Go system daemons by implementing the following interfaces:

- `oracle.panama.util.NotificationListener`

- `oracle.panama.core.admin.LogListener`

### Notification Listeners

You use the notification listener interface to implement your own Portal-to-Go notification engine. The notification engine responds to incoming messages. Currently, the default implementation of the notification engine handles email (SMTP) and Short Message Service (SMS) messages.

You can use only one notification engine in a Portal-to-Go system.

You specify domain-specific runtime parameters for the notification engine in the Notification.properties file. This file contains settings for the SMS listener port and the server name.

### Log Listeners

You implement the log listeners interface to create classes that respond to log events.

You can create any number of log listeners in Portal-to-Go.

## Hooks

Portal-to-Go provides the following types of hooks:

Name | Method | Purpose
--- | --- | ---
Service hook |
    MasterServiceHook.isVisible(
                   service,
                   request)
| Determines whether a service is visible (such as location-dependent services).
Request hook |
    ParmHook.requestBegin(
                   request)
| Executes when a request arrives.
User authentication hooks |
    UserAuthenticationHook.checkUser(
                   name)
    UserAuthenticationHook.authenticate(
                   info, request)
| Gets the user from an external source. Authenticates the user.
Provisioning hook |
    ProvisioningHook.getRootFolder(user)
| Creates a root folder for a new user.
Device identification hook |
    UserAgent.findDeviceType(
                request)
| Identifies the user's device.
Notification listener |
    NotificationListener.onMessage(
          NotificationEvent ev)
| Implements a new notification engine.

## Extending the Core Components

In some cases, you may want to alter the internal processing for the Portal-to-Go objects. You can accomplish this using programmatic hooks provided by Portal-to-Go.

While you can extend internal object processing, you cannot alter the fundamental object model. The following sections provide a sample implementation that extends the master service. For more information regarding the hooks in object functionality, see the Portal-to-Go API specification.

#### Step 1: Override the Existing Implementation

You must be able to construct each persistent object with either a known object identifier or an empty constructor, as follows:

    public class MyMasterService extends MasterService {
      public MyMasterService() {
        super();
      }
      public MyMasterService(Long id) {
        super(id);
      }

    // override some logic.
    public void invoke(ServiceRequest request) throws Exception {
      super.invoke(request);
      sendMessageToOnlinePaymentSystem(request);
      }
    }

#### Step 2: Plug in the Implementation with a Locator

Each persistent object has two methods that the persistent locator must implement. The persistent locator must also implement the singleton pattern, as follows:

    MasterService lookupMasterService(Long id);
    MasterService newMasterService();

    public class MyPersistentLocator extends PersistentLocatorImpl {
    private static PersistentLocator instance = null;

      // Always calls to the empty constructor of the superclass
      protected MyPersistentLocator() {
        super();
      }

      // The thread-safe singleton getter
      public static PersistentLocator getInstance() {
        if (instance == null) {
          MyPersistentLocator impl = null;
          synchronized (MyPersistentLocator.class) {
            if (instance == null) {
              impl = new MyPersistentLocator();
              instance = impl;
            }
          }
        // do the initialization here needed for some components,
        // to avoid recursive loops
        // watch out for initialize() methods
        if (impl != null) {
          impl.initialize();
        }
      }
      return instance;
    }

    // Override newMasterService
    public MasterService newMsterService() {
      return new MyMasterServiceImpl();
    }

    // Override lookupMasterService
    public MasterService lookupMasterService(Long id) {
      MasterService m = (MasterService)getMasterSet().get(id); // always
                                              // check the cache first

      if (m == null) { // no hit
        m = new MyMasterServiceImpl(id); // activate an existing
                                       //      object from storage
      }
      return m;
      }
    }

#### Step 3: Reference the Class in the System Properties File

Reference the new locator in the System.properties file:

    locator.persistent.class=MyPersistentLocator

| Copyright © 2000 Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index