Oracle Portal-to-Go Implementation Guide Release 1.0.2.2 A86635-02 |
|
This document describes how to create and manage Java classes and stylesheets that implement Portal-to-Go adapters. Topics include:
A Portal-to-Go adapter is a Java application that retrieves data from an external source and renders it in Portal-to-Go XML. When invoked by a master service, an adapter returns an XML document that contains the service content.
In the Portal-to-Go architecture, adapters constitute the interface between the Portal-to-Go server and the content source.
Portal-to-Go adapters primarily return content. But they can also perform other functions. For example, the Provisioning adapter, which is included in the Portal-to-Go initial repository, manages Portal-to-Go users. You can use it to create, remove, and modify users.
To use a Portal-to-Go adapter, you create a master service that invokes the adapter. Master services encapsulate the primary Portal-to-Go functionality; they make information and applications available to the end users.
Portal-to-Go provides adapters that retrieve Web and database content. Chapter 5, "Portal-to-Go Services" describes the adapters provided by Portal-to-Go, and how to create services that use them.
You create your own Java adapters for Portal-to-Go by implementing the Adapter
interface. The adapter you create can be simple or very complex. It can be a self-contained application or, as in the case of the Web Integration adapter, it can invoke external applications. How the adapter retrieves information is transparent to Portal-to-Go. It must simply expose the entry points and return the value types that Portal-to-Go expects.
Adapters return content that conforms to a Portal-to-Go content DTD. In most cases, adapters return content that conforms to the Simple Result DTD. The Simple Result DTD contains elements that represent the components of an abstract UI, such as tables, forms, and menus.
Adapters can also return content in Adapter Result format. Adapter Result format is a intermediary, user interface-independent content format. You can use it to pass raw data between Portal-to-Go components, such as chained services. Since device transformers operate only on Simple Result format, a result transformer associated with a master service must convert an Adapter Result document to Simple Result format before the content can be delivered.
For more information on Portal-to-Go XML, see Chapter 8, "Working with Portal-to-Go XML."
Generally, an adapter performs the following functions:
The adapter should know the content source format and how to map it to a Portal-to-Go results format.
Follow these rules to create an adapter:
Adapter
interface.
Adapter
class:
The master service calls the init()
function once, the first time the adapter is invoked. The init()
function should perform initialization functions for the adapter. The master service calls the invoke()
function every time the adapter is invoked. The getInitDefinition()
and getAdapterDefinition()
methods enable Portal-to-Go to create an adapter definition for an adapter.
Portal-to-Go calls the methods in the following order:
The invoke()
method is then called again every time the adapter is invoked.
An adapter definition defines the parameters used by an adapter. To create an adapter definition, you instantiate the AdapterDefinition
interface. Each adapter has two adapter definitions: one for the input parameters required to initialize the adapter, and one for all adapter parameters--initializing, runtime, and output.
To make its parameters available to master services, each adapter must implement the following methods.
The following sample Java class is a complete, but minimal, adapter implementation. It greets a user by name. It takes a single initialization parameter, the string used for the greeting, and a single input parameter, the name of the user.
// Copyright (c) 1999, 2000 by Oracle Corporation, all rights reserved. // // Title: HelloAdapter // Usage: Demonstrate Panama Adapter with init/input parameters import org.w3c.dom.Element; import org.w3c.dom.Document; import org.w3c.dom.Text; import oracle.panama.Argument; import oracle.panama.Arguments; import oracle.panama.ArgumentType; import oracle.panama.ServiceRequest; import oracle.panama.adapter.Adapter; import oracle.panama.adapter.AdapterDefinition; import oracle.panama.adapter.AdapterException; import oracle.panama.adapter.AdapterHelper; import oracle.panama.core.util.XMLUtil; import oracle.panama.core.xml.XML; public class HelloAdapter implements Adapter { private boolean initialized = false; /** Greeting phrase, default is Hello */ private String greeting = "Hello"; /** Init parameter name for the greeting phrase */ public static final String GREETING = "greeting"; /** Input parameter name for the name to greet */ public static final String NAME = "name"; /** This is the initialization method, called once when the adapter * is instantiated for the very first time. Whatever you do here * should be synchronized to ensure that things are not initialized * twice. * @param args The parameters needed for initialization */ public void init (Arguments args) throws AdapterException { synchronized (this) { initialized = true; greeting = args.getInputValue( GREETING ); } } /** * This is the main request handler, invoked each time a client makes * a request. This is a simple example that is capable of returning * output according to Portal-to-Go simpleresult.dtd. * @param sr The ServiceRequest object * @return Element The XML element holding the result * @exception Exception Not used here. */ public Element invoke (ServiceRequest sr) throws AdapterException { // This adapter returns this XML element: // <SimpleResult> // <SimpleText title="Oracle Portal-to-Go Server Hello Sample"> // <SimpleTextItem name="message" title="Portal-to-Go says:"> // <greeting> <name>! // </SimpleTextItem> // </SimpleText> // </SimpleResult> // Create result element Document doc = sr.getOwnerDocument(); Element result = XML.makeElement(doc, "SimpleResult"); // Create SimpleText element Element st = XML.makeElement(result, "SimpleText"); st.setAttribute ("title", "Oracle Portal-to-Go Server HelloAdapter Sample"); result.appendChild (st); // Create SimpleTextItem element Element sti = XML.makeElement(st, "SimpleTextItem"); sti.setAttribute ("name", "message"); sti.setAttribute ("title", "Portal-to-Go says:"); st.appendChild (sti); // Create actual text String name = sr.getArguments().getInputValue( NAME ); Text txt = XML.makeText(sti, greeting + " " + name + "!"); sti.appendChild (txt); return result; } // The following method is required. If there are any initialization // parameters for this adapter they would be set here. private AdapterDefinition initDef = null; public AdapterDefinition getInitDefinition() { if (initDef == null) { synchronized (this) { if (initDef == null) { initDef = AdapterHelper.createAdapterDefinition(); // Any init parameters would be set here.. initDef.createInit( ArgumentType.SINGLE_LINE, GREETING, "Greeting phrase", null ); } } } return initDef; } private AdapterDefinition adpDef = null; public AdapterDefinition getAdapterDefinition() throws AdapterException { if (adpDef == null ) { synchronized (this) { if (adpDef == null) { if (initDef == null) throw new AdapterException ("Adapter is not properly initialized"); adpDef = initDef; adpDef.createInput( ArgumentType.SINGLE_LINE, NAME, "Name to greet", null ); } } } return adpDef; } public static void main(String[] arg) { oracle.panama.core.util.Locator.getInstance(); System.out.println("Start HelloAdapter"); HelloAdapter ha = new HelloAdapter(); Arguments args = oracle.panama.core.csc.CSCFactory.makeArguments(); try { args.setInputValue( GREETING, "Hey" ); AdapterDefinition ad = ha.getInitDefinition(); System.out.println("InitDefinition:\n" + ad); ha.init(args); ad = ha.getAdapterDefinition(); System.out.println("AdapterDefinition:\n" + ad); args.setInputValue( NAME, "Joe" ); ServiceRequest sr = oracle.panama.core.csc.CSCFactory.makeServiceRequest(null, args); Element result = ha.invoke(sr); System.out.println("Result:\n" + XMLUtil.valueOf(result)); } catch (Exception ex) { System.out.println("Exception " + ex.getMessage()); ex.printStackTrace(); ((oracle.panama.PanamaException)ex).getDetail().printStackTrace(); System.exit(-1); } System.out.println("Exit HelloAdapter"); System.exit(-1); } }
When invoked, the adapter returns this result:
<SimpleResult> <SimpleText title="Oracle Portal-to-Go Server Hello Sample"> <SimpleTextItem name="message" title="Portal-to-Go says:"> <greeting> <name>! </SimpleTextItem> </SimpleText> </SimpleResult>
The following sections describe each method in the sample adapter.
The init()
method initializes the adapter. Every adapter in Portal-to-Go must implement an init()
method. Portal-to-Go calls the initialization method once, when the adapter is first instantiated.
The init()
method takes an argument of type Arguments
. Arguments
is a convenience class for passing arguments. It includes various methods for setting and retrieving argument values. If invoked without an Argument
object, init()
throws an AdapterException
. The sample init()
method retrieves the initialization parameter value, the form of greeting, by calling args.getInputValue()
. It passes the form of the greeting to the method, as the parameter GREETING
. The default greeting set by the adapter is "Hello".
The contents of the initialization method must be synchronized to ensure that the class is not initialized again in another thread.
The sample sets the state variable, initialized
, to true. Any adapter you create should similarly keep track of its own state. In a typical adapter implementation, the init()
method would also contain logic for connecting to the content source.
The invoke()
method is the primary request handler. The master service calls this method every time a client makes a request. The adapter must be initialized before invoke()
can be called.
The invoke()
method takes an argument of type ServiceRequest
. It returns an XML element that holds the result.
Upon receiving an end user request, the Portal-to-Go request manager creates a ServiceRequest
object. The ServiceRequest
contains any parameter values specified by the user, service alias, or master service. The ServiceRequest
object also contains user information.
The sample invoke()
builds a Simple Result document, using methods in the packages org.w3c.dom.Element
and org.w3c.dom.Text
. First, it creates the root result element:
Element result = XML.makeElement("SimpleResult");
Next, it creates a SimpleText
element, sets its title attribute, and appends the element to the root element:
Element st = XML.makeElement("SimpleText"); st.setAttribute ("title", "Oracle Panama Server HelloAdapter Sample"); result.appendChild (st);
As defined in the Simple Result DTD, a SimpleTextItem
is a required child element of SimpleText
. The sample invoke()
method creates a SimpleText
element, sets its title attribute, and appends the element to the root element:
Element sti = XML.makeElement("SimpleTextItem"); sti.setAttribute ("name", "message"); sti.setAttribute ("title", "Portal-to-Go says:"); st.appendChild (sti);
It then retrieves the input parameter value, appends it to the result document, and returns the result to the caller, the master service:
String name = sr.getArguments().getInputValue( NAME ); Text txt = XML.makeText( greeting + " " + name + "!"); sti.appendChild (txt); return result;
Every adapter must implement getInitDefinition()
. This method enables master services to determine the initialization parameters used by the adapter.
The AdapterDefinition
class encapsulates adapter parameters. Your adapter should instantiate an AdapterDefinition
object to hold the parameter definitions. In the getInitDefinition()
method, you define the initialization parameters in the AdapterDefinition
object and return the AdapterDefinition
.
The method creates the initalization parameter with the following call:
initDef.createInit( Argument.SINGLE_LINE, GREETING, "Greeting phrase", null );
The createInit()
method has the following signature:
public InitArgument createInit(int type, String parameterName, String comment, String[] options);
The following table describes the method's arguments:
getAdapterDefinition()
defines the adapter's runtime input parameters. You should create an AdapterDefinition
object to hold the input parameters. You use the AdapterDefinition.createInput()
method to create input parameter definitions. This method is similar to createInit()
. It has the following signature:
public InputArgument createInput( int type, String parameterName, String comment, String[] options);
See "getInitDefinition()" for descriptions of each argument.
The getInitDefinition()
method cannot be invoked on an uninitialized adapter. Therefore, the method first tests the adapter's state.
Portal-to-Go provides the following interfaces for managing adapter arguments:
The interfaces implement the Arguments
interface. They include methods for creating, setting, and retrieving arguments. You can use the OutputArgument
interface to filter content returned by an adapter and to link adapter output to service input.
By filtering adapter output, you can apply a test to the content returned by an adapter. This enables you to deliver a service to an end user only if the results of the service (particularly a service invoked as a scheduled job) meet a specified condition.
For example, an end user may want to check the price of a certain stock and receive a notification if the stock reaches a certain price. You can use output filtering to create a test on the results of the scheduled adapter invocation, and deliver the service only if the result meets a condition the user sets.
The following code shows how to use output filters. The sample assumes that an output filter has been defined for a column in the database content source.
// Call provided API // Get the arguments from the ServiceRequest Arguments args = serviceRequest.getArguments(); // Assume that we have created our own SimpleResult wrapper MySimpleResult simpleResult = new MySimpleResult(); MySimpleResult notFoundResult = MySimpleResult.NOT_FOUND_MESSAGE; MyRow row; boolean match = true; int nRows = 0; MyResult result = <get the content ....>; while ((row = result.nextRow()) != null) { // Call provided API // only do this expensive op. if there is any filters defined. if (args.hasOutputFilters()) { match = true; for (int i = 0; i < row.getColumnCount(); i ++) { // Call provided API OutputArgument farg = args.getOutputArgument(row.getColumnName(i)); if (farg != null && !farg.compare(row.getColumnValue(i))) { // if any filtering // compare value. match = false; break; } } } if (match) { // only append row if it match the filtering. simpleResult.append(row); nRows ++; } } // Call provided API serviceRequest.setAnyResult(nRows != 0); // Let the ServiceRequest // know if any result was fetched or not. This is used // by the notification component to determine if the // result should be sent or not. return nRows != 0 ? simpleResult.getElement() : notFoundResult.getElement(); ...
After you create and compile the class that implements the adapter, you import the adapter into the Portal-to-Go repository.
By importing the adapter into the repository, you make it available to master services. You use the Service Designer to import the adapter into the Portal-to-Go repository. Before importing the adapter, place the Java class in an archive, either a JAR or ZIP file, which you include in the system CLASSPATH.
You use the Create New Adapter form to install an adapter in the repository. To invoke the form:
The form includes the following parameters:
You can delete an adapter as follows. If you delete an adapter used by active services, the Service Designer flags the services.
To delete an adapter:
To modify an adapter:
The stripper adapter dynamically retrieves content from a given URL and processes the markup tags in the content. Unlike the WIDL adapter, the stripper adapter does not require you to map the source page to output and input bindings in a WIDL file. Instead, the stripper adapter retrieves and processes arbitrary content.
After retrieving content, the stripper adapter calls a Java class to process the markup tags in the content. The stripper adapter locates the processing classes, or strip levels, that are available to it in the Strip.properties file. This file also contains proxy settings, which you must set to use the strip adapter.
Portal-to-Go provides two strip levels:
Level | Description | Implementing Class |
---|---|---|
0 |
Retains all tags in the content. |
Strip0 |
1 |
Strips all tags from the content. |
Strip1 |
To customize markup processing, you can create you own strip levels. To create a strip level, you extend the StripAbs
class. You then plug the strip level class into Portal-to-Go by referencing it in the Strip.properties file.
You must name your strip level class as follows:
Stripn.java
Where n is an integer representing the next available strip level. For example, given that Portal-to-Go provides strip levels 0 and 1, the first strip level you create should be level 2: Strip2.java.
The strip level you create must implement the following methods:
The exec()
method should process the content or invoke the logic that processes the content retrieved by the adapter. The getLevel()
should simply return the strip level.
Once you create and compile the strip level class, include it in the package oracle.panama.adapter.stripper
.
Finally, include a reference to the strip level in the Strip.properties file. For example:
//New strip level 3 stripper.strip3 = oracle.panama.adapter.stripper.Strip3
|
Copyright © 2000 Oracle Corporation. All Rights Reserved. |
|