Oracle9i Application Server Wireless Edition Developer's Guide Release 1.1 Part Number A86700-01 |
|
This document describes how to create and manage Java classes that implement Wireless Edition adapters. Each section of this document presents a different topic. These sections include:
A Wireless Edition adapter is a Java application that retrieves data from an external source and renders it in Wireless Edition XML. When invoked by a master service, an adapter returns an XML document that contains the service content.
To use a Wireless Edition adapter, you create a master service that invokes the adapter. Master services encapsulate the primary Wireless Edition functionality; they make information and applications available to the end users.
The Wireless Edition provides adapters that retrieve any content, including Web, database, and spatial content. The Oracle9i Application Sever Wireless Edition Implementation Guide describes the adapters provided by the Wireless Edition, and explains how to create services that use them.
You create your own Java adapters for the Wireless Edition by implementing the RuntimeAdapter
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 the Wireless Edition. The adapter that you create must simply expose the entry points and return the value types that the Wireless Edition expects.
Adapters return content that conforms to a Wireless Edition content DTD. The returned content can be in one of the following formats:
In most cases, adapters return content that conforms to the SimpleResult DTD. The SimpleResult DTD contains elements that represent the components of an abstract user interface, such as tables, text, forms, and menus.
Adapters can also return content in the AdapterResult format. The AdapterResult format is an intermediary, user interface-independent content format. You can use it to pass raw data between Wireless Edition components, such as chained services.
Since device transformers operate only on the SimpleResult format, a ResultTransformer associated with a master service must convert an AdapterResult document to the SimpleResult format before the content can be delivered.
Generally, an adapter performs the following functions:
The adapter should know the content source format and how to map it to a Wireless Edition results format.
Follow these rules to create an adapter:
oracle.panama.rt.RuntimeAdapter
interface.
RuntimeAdapter
interface:
The master service calls the init()
function once, the first time the adapter is invoked. The init()
function performs initialization functions for the adapter. The master service calls the invoke()
function every time the adapter is invoked.
The getInitArguments()
, getInputArguments()
, and getOutputArguments()
methods enable the Wireless Edition to create an adapter definition for an adapter. The getInitArguments()
method gets the initialization arguments for the MasterService and returns the arguments or null if no arguments exist. The getInputArguments()
method gets the input arguments for the MaterService. The getOutputArguments()
method gets the output arguments for the MasterService. The destroy()
method destroys the provider, thereby releasing the resources that were implemented by the adapter.
The Wireless Edition calls the methods in the following order:
getInitArguments()
init()
getInputArguments()
getOutputArguments()
invoke()
destroy()
The invoke()
method is then called again every time the adapter is invoked.
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.
The complete source code for the sample appears in Section 2.4, "HelloAdapter Source Code".
The reference numbers in brackets that appear in the discussion refer to the corresponding section in the complete listing of the source code.
Sample: HelloAdapter
// Copyright (c) 1999 by Oracle Corporation, all rights reserved. // // Title: HelloAdapter // Usage: Demonstrate Panama Adapter with init/input parameters
When invoked, the adapter returns these XML elements which conform to the SimpleResult DTD:
<SimpleResult> [4] <SimpleContainer> <SimpleText title="Oracle Portal-to-Go Server Hello Sample"> <SimpleTextItem name="message" title="Portal-to-Go says:"> <greeting> <name>! </SimpleTextItem> </SimpleText> </SimpleContainer> </SimpleResult>
The following sections describe each method in the sample adapter.
The init()
method initializes the adapter. Every adapter in the Wireless Edition must implement an init()
method. The Wireless Edition 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 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 RuntimeAdapterHelper class contains methods for creating input arguments and output arguments. Following initialization, the createArguments()
and the createOutputArguments()
methods are called out. They return the input arguments and the output arguments as follows:
Public void init (Arguments args) throws AdapterException { [3] synchronized (this) { initialized = true; greeting = args.getInputValue ( GREETING ); } }
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 ServiceContext
. It returns an XML element that holds the result. See the source code section with the reference number [4] in the complete source code listing for HelloAdapter in Section 2.4, "HelloAdapter Source Code".
Upon receiving an end user request, the Wireless Edition Request Manager creates a ServiceContext
object. The ServiceContext
contains any parameter values specified by the user, service alias, or master service. The ServiceContext
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(doc, "SimpleResult");
Then, it creates the container element:
Element container = XML.makeElement(result, "SimpleContainer"); result.appendChild (container);
Next, it creates a SimpleText
element, sets its title attribute, and appends the element to the root element:
Element st = XML.makeElement(container, "SimpleText"); st.setAttribute ("title", "Oracle Portal-to-Go Server HelloAdapter Sample"); container.appendChild (st);
As defined in the SimpleResult 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(st, "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.getInputArguments().getInputValue( NAME ); Text txt = XML.makeText(sti, greeting + " " + name + "!"); sti.appendChild (txt); return result;
Every adapter must implement getInitArguments()
. This method enables a master service to determine the initialization parameters that are used by the adapter.
The RuntimeAdapter
class encapsulates the adapter parameters. In the getInitArguments()
method, you get the initialization parameters in the Adapter
object and return the initialization arguments.
The numbers in bold that appear on the right side of the source code excerpts below refer to where the excerpt is located within the complete source code listing in Section 2.4, "HelloAdapter Source Code".
private Arguments initArgs = null; [5] public Arguments getInitArgument() throws AdapterException { if (initArgs == null) { synchronized (this) { if (initArgs == null) { initArgs = RuntimeAdapterHelper.createArguments(); // Any init parameters would be set here.. Argument initArg = initArgs.createInput(GREETING, "Greeting phrase", null, true ); initArg.setType(ArgumentType.SINGLE_LINE); } } } return initArgs; }
private Arguments inputArgs = null; [6] public Arguments getInputArguments() throws AdapterException{ if (inputArgs == null ) { synchronized (this) { if (inputArgs == null) { inputArgs = RuntimeAdapterHelper.createArguments(); Argument inputArg = inputArgs.createInput(NAME, "Name to greet", null ,true); inputArg.setType(ArgumentType.SINGLE_LINE); } } } return inputArgs; }
private OutputArguments outputArgs = null; [7] public OutputArguments getOutputArguments() throws AdapterException{ if (outputArgs == null) { synchronized (this) { outputArgs = RuntimeAdapterHelper.createOutputArguments(); } } return outputArgs; } public void destroy() { } }
The Wireless Edition 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 Wireless Edition 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 Oracle9i Application Server Wireless Edition 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:
Table 2-1 Adapter 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 complete source code for HelloAdapter is listed below. Each section of the code is numbered on the right side of the text (for example, [1]
) to assist in mapping the description in Section 2.2.1, "Sample Adapter Class" to the source code in its entirety.
// Copyright (c) 1999 by Oracle Corporation, all rights reserved. // // Title: HelloAdapter // Usage: Demonstrate Panama Adapter with init/input parameters // Author: M.Lonnroth package sampleadapter; import org.w3c.dom.Element; [1] import org.w3c.dom.Document; import org.w3c.dom.Text; import oracle.panama.Argument; import oracle.panama.Arguments; import oracle.panama.OutputArguments; import oracle.panama.ArgumentType; import oracle.panama.rt.ServiceContext; import oracle.panama.adapter.RuntimeAdapter; import oracle.panama.adapter.AdapterException; import oracle.panama.adapter.RuntimeAdapterHelper; import oracle.panama.core.util.XMLUtil; import oracle.panama.core.xml.XML; public class HelloAdapter implements RuntimeAdapter { [2] 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 { [3] synchronized (this) { initialized = true; greeting = args.getInputValue( GREETING ); } } /** [4] * 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 (ServiceContext sr) throws AdapterException { // This adapter returns this XML element: // <SimpleResult> // <SimpleContainer> // <SimpleText title="Oracle Portal-to-Go Server Hello Sample"> // <SimpleTextItem name="message" title="Portal-to-Go says:"> // <greeting> <name>! // </SimpleTextItem> // </SimpleText> // </SimpleContainer> // </SimpleResult> // Create result element Document doc = sr.getXMLDocument(); Element result = XML.makeElement(doc, "SimpleResult"); // Create SimpleContainer element Element container = XML.makeElement(result, "SimpleContainer"); result.appendChild(container); // Create SimpleText element Element st = XML.makeElement(container, "SimpleText"); st.setAttribute ("title", "Oracle Portal-to-Go Server HelloAdapter
Sample"); container.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.getInputArguments().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 Arguments initArgs = null; [5] public Arguments getInitArguments() throws AdapterException { if (initArgs == null) { synchronized (this) { if (initArgs == null) { initArgs = RuntimeAdapterHelper.createArguments(); // Any init parameters would be set here.. Argument initArg = initArgs.createInput(GREETING, "Greeting phrase",
null, true ); initArg.setType(ArgumentType.SINGLE_LINE); } } } return initArgs; } private Arguments inputArgs = null; [6] public Arguments getInputArguments() throws AdapterException{ if (inputArgs == null ) { synchronized (this) { if (inputArgs == null) { inputArgs = RuntimeAdapterHelper.createArguments(); Argument inputArg = inputArgs.createInput(NAME, "Name to greet",
null ,true); inputArg.setType(ArgumentType.SINGLE_LINE); } } } return inputArgs; } private OutputArguments outputArgs = null; [7] public OutputArguments getOutputArguments() throws AdapterException{ if (outputArgs == null) { synchronized (this) { outputArgs = RuntimeAdapterHelper.createOutputArguments(); } } return outputArgs; } public void destroy() { } }
|
![]() Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|