### Oracle9iAS Portal Developer Kit
Understanding the Provider Adapter

To Oracle9iAS Portal, a Web Provider is a server-side Web program capable of responding to specifically formatted HTTP requests at a registered URL. Java server-side Web programs are called "servlets". Thus, to the Portal, a Java Web Provider is a servlet registered to receive requests at a specific URL.

The PDK-Java architecture eliminates the need for the Provider to manage the communication between Oracle9iAS Portal using the Portal's language. It allows the Provider to concentrate on simply managing a set of portlets in its own language. PDK-Java (JPDK) offers developers a servlet called oracle.portal.provider.v1.http.HttpProvider whose main function is to handle communication between the Portal and the Web Provider.

This servlet, oracle.portal.provider.v1.http.HttpProvider, is known as the Provider Adapter. The Provider Adapter is responsible for receiving the Portal requests, unmarshalling the details, locating the target Provider, calling the Provider API to perform the function, and marshalling the results into the HTTP response. Both Oracle9iAS Portal and the Web Provider communicate directly with the Provider Adapter. PDK-Java includes the Provider Adapter you will use to front your portlets and provider. This articles describes the Provider Adapter.

ARCHITECTURE

The Provider Adapter serves two purposes. To Oracle9iAS, the Provider Adapter is the server-side Web program it communicates with. To the Provider and Portlet developer it is the entity that hides the details of the HTTP request and translating it into the appropriate method calls defined by the Web Provider Interfaces.

The Provider Adapter is needed to implement your Provider and Portlets. The Provider Adapter is not implemented by a developer. The Provider Adapter is implemented by the servlet "oracle.portal.provider.v1.http.HttpProvider".

Associating your Provider with the Provider Adapter

There is a one-to-one correspondence between a Provider Adapter and a Provider. That is each Provider Adapter represents one and only one Provider. This one-to-one relationship is established by the developer. The relationship is established in one of two ways: programmatically or via configuration.

Establishing the relationship programmatically

To programmatically relate your Provider with the Provider Adapter, you subclass "oracle.portal.provider.v1.http.HttpProvider" and override the getProviderClass method. The signature of this method is:

        public Class getClass() throws ServletException;

The method takes no parameters and returns the Java class that implements the Provider (oracle.portal.provider.v1.Provider) interface. In the example below, the Provider Adapter is called HelloWorldWebProvider. The adapter subclasses HttpProvider (oracle.portal.provider.v1.http.HttpProvider) and points to the Provider called HelloWorldProvider (mysample.provider.HelloWorldProvider).

    public class HelloWorldWebProvider extends oracle.portal.provider.v1.http.HttpProvider {
        // Name of the Provider class this Adapter represents

        static final String providerClassName = "mysample.provider.HelloWorldProvider";
        public Class getClass() throws ServletException {

            try {

                return Class.forName(providerClassName);

            } catch (ClassNotFoundException e) {

                throw new ServletException("Unable to find Provider class "

                      + providerClassName);

            }

        }
    }

Establishing the relationship declaratively

The second way to establish the relationship between the Provider and the Provider Adapter is via configuration. The PDK-Java runtime uses a declarative configuration file to define the various components that comprise your Provider. This file is named "provider.xml". It uses an XML syntax to define the characteristics of your Provider and the set of Portlets its manages. One characteristic is the name of the class that implements your Provider. This is represented in the class attribute of the `<provider>` tag. The example below points to the same provider class as the Adapter in the example above.

    <provider class="mysample.provider.HelloWorldProvider" >

         <portlet class="mysample.portlet.HelloWorldPortlet" />

    </provider>

When establishing the relationship declaratively, the getProviderClass() method locates this provider.xml file and extracts the provider's classname from the provider class attribute. The Adapter locates the provider.xml file via an initialization parameter. This is represented in the example below.

> >     public Class getClass() throws ServletException {
> >     String providerClassName = getInitParameter(PROVIDER);
> >         if (providerClassName == null) {
> >            providerClassName = DefaultProvider.getProviderClassFromXml(this);
> >         }
> >         if (providerClassName == null) throw new
> >            ServletException("No Provider class defined via this servlet's initArgs or provider.xml");
> >     try {
> >     return Class.forName(providerClassName);
> >     } catch (ClassNotFoundException e) {
> >     throw new ServletException("Unable to find Provider class " + providerClassName);
> >     }
> >     }

The default behavior of the Provider Adapter is to establish the relationship declaratively. To change the method in which the relationship is established, simply subclass oracle.portal.provider.v1.http.HttpProvider and override getClass().

The Provider Adapter is a servlet. Though the specifics vary, servlet runtimes let you set parameters that initialize the servlet when it is instantiated. For 9i Application Server (and Apache JServ), these parameters are set in your servlets initArgs setting contained in the servlet zone configuration file. The initialization parameter that describes the location of the provider.xml file is called "provider_root". In the example below, the provider_root argument allows the Provider Adapter to retrieve the provider classname from the provider.xml by pointing it to the \providers\hello directory.

    servlet.helloprovider.initArgs=provider_root=\providers\hello,debuglevel=1

CONFIGURATION

There are three aspects to configuring the Provider Adapter.

> - Configuring your Web server to map a distinct URL that represents the adapter servlet.
> - Configuring the adapter servlet via its initArgs.
> - Registering the Provider with the desired Portal by supplying this distinct URL

Configuring your Web server

Configuring your adapter servlet in your Web server varies depending on the nature of the servlet engine your server runs. This article describes the configuration using 9i Application Server and Apache Jserv.

Apache JServ separates servlets into "zones". A zone is mapped to a Web server virtual path. For example the default servlet zone is called "root". The "root" zone is mapped to the /servlets virtual path. You configure zones in the jserv.conf file. Requests whose URI paths begin with /servlets will be processed by the JServ servlet engine to point to the directory specified in the jserv.conf file. Therefore, all requests beginning with /servlets are processed by a servlet registered in the root zone.

The servlet engine maps an HTTP request to a servlet using either a fully qualified name or a servlet alias. The fully qualified name of a servlet is its package.classname. For the example above where the HttpProvider has been subclassed, you can invoke the servlet using the following URL:

> http://mydomainname.com/servlets/mysample.provider.HelloWorldWebProvider

Note: The reference is to the class that subclassed HttpProvider, not the one that implements your Provider.

A servlet alias is a registered name that represents the servlet. For example if the HelloWorldWebProvider servlet is aliased to hello you can invoke the servlet using the following URL:

> http://mydomainname.com/servlets/hello

You configure a servlet alias in your zone's properties file. The following is the configuration statement that aliases "hello" to the standard HttpProvider.

>     servlet.hello.code=oracle.portal.provider.v1.http.HttpProvider

It is expected that most developers will use the declarative (configuration) technique described above to associate their Provider with the adapter servlet. In this situation you are required to use servlet aliasing to configure the adapter servlet. This ensures distinct URLs for each adapter hosted in the same zone.

Configuring the adapter servlet's initArgs

The HttpProvider servlet supports four initArgs:

- provider_root (required)
- sessiontimeout (required)
- debuglevel
- provider_definition
- auto_reload

PROVIDER_ROOT

The provider_root initialization argument is a required argument that specifies your provider's root directory. As already explained, this parameter specifies the location of the provider.xml file. In addition, it is used by the default PersonalizationManager service provided in PDK-Java as the root directory for its filesystem based repository. This parameter is optional and need not be set if your Provider neither relies on the provider.xml file nor uses the DefaultPortletPersonalizationManager (default implementation of the PortletPersonalizationManager).

SESSIONTIMEOUT

The sessiontimeout initialization argument is a required argument that specifies, in milliseconds, the duration of this servlet's HttpSession. This is a required argument if your Provider uses servlet sessions to maintain state. By default, the DefaultProvider (base implementation of the Provider interface) creates a servlet session which requires that this parameter is set. The value of this argument must be the same as the actual servlet session configuration. You can locate this value in your servlet's zone.properties file. Search for the configuration setting session.timeout. E.g. a 30 minute timeout is

>     session.timeout=1800000

You configure initArgs as follows:

>     servlet.hello.initArgs=provider_root=\providers\hello,sessiontimeout=1800000

You may wonder why we require this parameter in this first place and why we don't just use the existing setting in the zone.properties file. We need this parameter because the current portal architecture requires that any cookies a Provider establishes must be created when the Provider's initSession method is called. Most servlets use cookie-based HttpSessions. If the administrator who registers your Provider in the Portal sets the login (initSession) frequency to once per user session, the Portal must know when your servlets session will timeout to ensure the initSession method gets recalled to reestablish the session even though the Portal's user session is still valid.

We are unable to use the JServ configuration setting because JServ doesn't make it available to the Adapter servlet.

DEBUGLEVEL

The debuglevel initialization argument is an optional argument that allows you to view the PDK-Java Framework testpage. For security purposes, the testpage for the PDK-Java Framework does not display or displays a "Permission Denied" error. The debuglevel also adds additional levels of debugging to PDK-Java ranging from 1 to 5. To view the testpage and/or debug PDK-Java, you must add the debuglevel initialization parameter to the provider's servlet.

>     servlet.hello.initArgs=provider_root=\providers\hello,sessiontimeout=1800000,debuglevel=1

PROVIDER_DEFINITION

The provider_definition initialization argument is an optional argument that allows you to specify a name for the provider_definition file. If this argument is not specified in the zone.properties file, the framework will parse a file called "provider.xml" in the directory specified. You can use any name for your registry file by specifying the name as an argument to the provider's servlet.

>     servlet.hello.initArgs=provider_root=\providers\hello,sessiontimeout=1800000,provider_definition=myprovider.xml

AUTO_RELOAD

The auto_reload initialization argument allows you to configure your Provider to automatically reload it's provider registry (provider.xml) file. If configured for automatic reload, the provider checks to see if the registry file has been updated since it was last loaded. In order to minimize the performance impact of this feature and allow it to be used in a production environment, the reload is only triggered when your provider receives a get_portlet or get_portlets message from a portal. You can force this to occur from the portal by refreshing an individual provider or refreshing the entire portlet repository.

To enable auto-reload of your provider registry, add auto_reload=true to the initArgs of your provider servlet.

>     servlet.hello.initArgs=provider_root=\providers\hello,sessiontimeout=1800000,auto_reload=true

Note: Reloading the provider registry only reloads the provider and portlet definitions from the registry. It will not force Java classes or JSPs that have already been loaded into memory to be reloaded.

Registering the Provider (adapter) with the Portal

You register the Provider Adapter with the Oracle9iAS Portal using the "Add a Portlet Provider" Administrator screen. This is described in more detail in the Oracle9iAS Portal online documentation.

Revision history:

- July 2, 2001