Oracle9i Application Server Wireless Edition Developer's Guide Release 1.1 Part Number A86700-01 |
|
This document describes how to create and manage Wireless Edition transformers. Each section of this document presents a different topic. These sections include:
Wireless Edition transformers are Java programs or XSLT stylesheets that convert a document into either the target format or another Wireless Edition format.
The Wireless Edition supports two types of transformers:
Result transformers typically convert content from Adapter Result format to Simple Result format. The Adapter Result format is an intermediary format layer that enables efficient exchange of user interface-independent data. You may use it, for example, to link chained services. A chained service is a Wireless Edition service that invokes another service. An adapter can pass the service link using the Adapter Result format. A result transformer must render the Adapter Result document in Simple Result format before the Wireless Edition can deliver it to the user.
Device transformers convert Simple Result documents into the format of the target device. You can use two types of device transformers in the Wireless Edition:
The Wireless Edition requires you to associate a transformer to each logical device.
A logical device is a repository object that represents either a physical device, such as an Ericsson mobile phone, or an abstract device, such as an email server. Logical devices represent the interface between transformers and the target devices or applications. For more information on logical devices, see Oracle9i Application Server Wireless Edition Implementation Guide.
The transformer associated with a logical device is the device's default transformer. Default transformers are typically generalized for a markup format, but they can also be specific to a target device.
The Wireless Edition uses the device's default transformer to convert any service targeted for that type of device, unless a custom device transformer overrides the default transformer. A custom device transformer enables you to control how a specific service appears on a specific device. While several logical devices can use a single default transformer, a custom transformer can be associated with only one master service and one logical device. The custom transformer optimizes the presentation of that service for a particular device and can only be used for that device.
The Wireless Edition publishes device transformation rule files so that anyone can create support for any type of device and markup language.
The Wireless Edition initial repository includes transformers for several target formats, such as CHTML, HDML, HTML, MML, VoiceXML, VoxML, and WAP (WML).
By modifying the transformers provided with the Wireless Edition, or by creating new ones, you can target new device platforms and optimize content presentation for specific devices.
Transformers not only map source tags to target format tags, they can manipulate content. They can rearrange, filter, and add text (such as boilerplate text). This enables you to present content in the format, as well as the form factor that is best suited for the target device.
When you create a transformer, you map the elements in the source content to the result format. For example, the Tiny HTML transformer, which is included in the initial Wireless Edition repository, maps several Simple Result elements as follows:
Table 3-1 Tiny HTML Transformer Mapping
Similarly, when you create a new transformer, you create a logical mapping between the abstract user interface elements represented by the Simple Result elements and the target format.
You can implement the Wireless Edition transformers as either Java transformers or XSLT stylesheets.
XSLT stylesheets are XML documents that specify the processing rules for other XML documents. The XSLT processor included with the Oracle XML processor conforms to the final W3C XSLT specification, Working Draft of August 13, 1999.
An XSLT stylesheet, like a Java transformer, is specific to a particular DTD. It should handle all elements declared in a DTD. When it finds the element in a source document, it follows the rules defined for the element to format its content.
XSLT stylesheets can include complex pattern matching and result handling logic. They typically include literal result elements, such as the target format markup tags.
Java transformers implement the RtTransformer
interface. The transformers convert the XML structure in the SimpleResult document into a device-specific markup language. The classes that implement the RuntimeAdapter
interface can use the ServiceContext
interface in the oracle.panama.rt
package. The ServiceContext
interface contains the input and output parameters for the service. It also contains the AdapterResult and SimpleResult, which are externalized as an XML document.
The ServiceContext
XML document is the input document for the transformer. The XSL stylesheets for the transformers must be written against the DTD for the ServiceContext
XML document. The implementation of the RtTransformer
interface must provide a default constructor (that is, a constructor without arguments). Also, the implementation should return a String
object, which is the result document that contains a device-specific markup language, such as WML.
You can create a Java transformer or an XSL transformer. When you create a transformer, make sure that you have accomplished the following first:
A result transformer must render the AdapterResult document in SimpleResult XML format, which is based on the SimpleResult DTD. The SimpleResult XML provides the input to the device transformer, which then converts the service in terms of the particular type of device for which the service is targeted.
If the format of the target device requires a device transformer that is different than the available default transformers, then you should create a custom device transformer.
Use the Create New Transformer form in the Service Designer to create a transformer in the repository. For information on how to use the form, see Section 3.6.1, "Creating a Transformer in the Repository".
To create an XSL transformer, start your code with the following line after the header:
<xsl:template match="/">
In the processing sequence of the XSLT stylesheet, the stylesheet first matches, or selects, a SimpleResult element using pattern-matching semantics. The <xsl:template match="/"> element, for example, matches the document's root element.
It then uses the apply-template
element <xsl:apply-templates/> to process the contents of a found element, including all sub-elements. A select
attribute limits the processing scope to a specified sub-element.
The following transformer converts SimpleResult documents to plain text. It is the XSLT version of the Java transformer described in Section 3.5.3, "Creating a Java Transformer". This XSLT device transformer is included in the Wireless Edition initial repository.
<?xml version = '1.0' encoding = 'UTF-8'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="SimpleTextItem | SimpleFormItem | SimpleMenuItem"> <xsl:text/> <xsl:value-of select="."/> </xsl:template> <xsl:template match="SimpleRow"> <xsl:text/> <xsl:for-each select="./SimpleCol"> <xsl:text/> <xsl:value-of select="."/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
The sample code illustrates the processing sequence for XSLT stylesheets. After matching, or selecting, a SimpleResult element and processing the contents of that found element, the stylesheet then descends the source element tree, selecting and processing each sub-element.
Character instructions, such as value-of
and for-each
, manipulate the content of matching elements. The value-of
element extracts the actual content of the element. The for-each
element applies iterative processing.
This example does not include literal text elements. The following illustrates the use of literal text elements:
<xsl:template match="SimpleTextItem"> <P> <xsl:value-of select="."/> </P> </xsl:template>
This XSLT element maps the content of SimpleTextItem
to HTML paragraph tags. For example, if passed the following Wireless Edition element:
<SimpleTextItem>Scott</SimpleTextItem>
The XSLT segment would produce the following:
<P> Scott </P>
The following ResultTransformer segment shows how a ResultTransformer can enable chained services. It uses the AdapterResult of a user's selection to link to a target, which is the subsequent service in the chain.
<xsl:template match="AdapterResult"> <SimpleResult> <SimpleContainer> <SimpleMenu name="Query Results"> <xsl:for-each select="Table/Row"> <xsl:if test="position() < 8"> <SimpleMenuItem> <xsl:attribute name="target"> ___REQUEST_NAME__?PAoid=__PAoid__ &PAsection=Result&href=<xsl:value-of select="./href"></xsl:value-of></xsl:attribute> <xsl:value-of select="./Title"></xsl:value-of> </SimpleMenuItem> </xsl:if> </xsl:for-each> </SimpleMenu> <SimpleContainer> </SimpleResult> </xsl:template>
The XML parser processes the AdapterResult XML document using the ResultTransformer.
In the above example, the ResultTransformer includes the variables _REQUEST_NAME__ and _PAoid__. For more information about these and other Runtime variables, see Chapter 6, "Using the Runtime API".
For example, given the following string:
http://www.host.com/ptg/rm?PAoid=250
_REQUEST_NAME
represents ptg/rm
_SERVICE_NAME
represents 250 (which could be a folder, an alias, a master service, or a link)
You can select the values of these variables in a transformer directly with a construct such as the following:
<xsl:value-of select="//_REQUEST_NAME"/>
A Java transformer specifies a Java class transformer implementation. To create a Java transformer for the Wireless Edition, you implement the RtTransformer
interface.
/*$Copyright:
* Copyright (c) 2000 Oracle Corporation all rights reserved
* $
*/
package oracle.panama.rt.xform;import java.io.Writer;
import org.w3c.dom.Element;
import oracle.panama.PanamaException;/**
* Transform from a XML structure to a device specific content.
*/
public interface RtTransformer {
/**
* Transform the simple result XML document into a device specific markup language.
* @param element the <code>SimpleResult</code> XML Element to process.
* @param out the output writer for the result
*/
public void transform(Element element, Writer out) throws PanamaException;
}
The implementation must be thread-safe and it must provide a default constructor (that is, a constructor without arguments). The transformer should return a String
object, which is the result document that contains a device-specific markup language.
The following section describes the components of an RtTransformer
interface implementation.
This section presents the components of a Java transformer. The transformer that is used in this section as an example converts SimpleResult XML to plain text. While the transformer does not create markup tags in the resulting document, it does apply simple text formatting elements, such as line breaks and tabs. Though simple, these elements illustrate how you can convert SimpleResult XML elements into another format, such as the particular format of the target device.
/* * * $Copyright: * Copyright (c) 1999 Oracle Corporation all rights reserved * $ */ package oracle.panama.core.xform; import org.w3c.dom.NodeList; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.io.Writer; import java.io.IOException; import oracle.panama.PAPrimitive; import oracle.panama.PanamaException; import oracle.panama.model.Service; import oracle.panama.rt.RequestFactory; import oracle.panama.rt.Request; import oracle.panama.rt.xform.RtTransformer; /** * Transform from panama simple result to plain text. This transformation is * very simple and is intended to be used when sending SMS messages to cell * phones. * * @author pelarsso * @version $Revision: 1.9 $ * @since PANAMA_10 */ public class SimpleResultToText implements RtTransformer { /** * Empty constructor. */ public SimpleResultToText() {} /** * @return null if the name is of zero length or null otherwise return the name. */ private String getName(String name) { return name == null || name.length() == 0 ? null : name; } /** * @return the name of this element, thename is wither the attribute value of title or name in this order. */ private String getName(Element el) { String attr; attr = getName(el.getAttribute("title")); if (attr == null) { attr = getName(el.getAttribute("name")); } return attr; } /** * @return the text node value of this element or an empty string if none exists. */ private String getTextValue(Element el) { Node n = el.getFirstChild(); return (n != null && n.getNodeType() == Node.TEXT_NODE) ? n.getNodeValue() : ""; } /** * Format the element to a string. * @param el the XML element. * @return the string representation. */ private String format(Element el) { if (el == null) { return ""; } StringBuffer buf = new StringBuffer(); String attr = getName(el); if (attr != null) { buf.append(attr); buf.append(": "); } buf.append(getTextValue(el)); return buf.toString(); } /** * Get the child where matching the name. * * @param element the parent element. * @param name the name of the sub-element to search for. * @return the first matching child or null if no match. */ private Element getChildByName(Element element, String name) { Element rEl = null; for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling()) { if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(name)) { rEl = (Element)node; break; } } return rEl; } /** * Transform the simple result XML document into a device specific markup language. * @param element the <code>SimpleResult</code> XML Element to process. * @param out the output writer for the result */ public void transform(Element element, Writer out) throws PanamaException { // Put in the request name as header Request req = RequestFactory.lookupRequest(); Service service = req == null ? null : (Service) req.getServiceContext().getService(); StringBuffer buf = new StringBuffer((service == null) ? "" : service.getName()); // Get all elements in the first container. Element el = getChildByName(element, "Result"); if (el != null) { el = getChildByName(el, PAPrimitive.TAG_SIMPLERESULT); if (el != null) { el = getChildByName(el, PAPrimitive.TAG_SIMPLECONTAINER); if (el != null) { element = el; } } } NodeList list = element.getElementsByTagName("*"); String tag; boolean newRow = false; for (int i = 0; i < list.getLength(); i ++) { el = (Element)list.item(i); tag = el.getTagName(); if (tag.equals("SimpleRow")) { newRow = true; buf.append("\n"); } else if (tag.equals("SimpleCol")) { if (!newRow) { buf.append("\t"); } else { newRow = false; } buf.append(format(el)); } else if (tag.equals("SimpleText") || tag.equals("SimpleForm") || tag.equals("SimpleMenu")) { newRow = true; buf.append("\n"); } else if (tag.equals("SimpleTextItem") || tag.equals("SimpleFormItem") || tag.equals("SimpleMenuItem")) { if (!newRow) { buf.append("\n"); } else { newRow = false; } buf.append(format(el)); } } String result = buf.toString(); try { out.write(result); out.flush(); } catch (IOException ex) { throw new PanamaException(ex); } } }
The following sections describe each method in the transformer.
The SimpleResultToText() method is the default constructor for instantiating the transformer. Any transformer you create must also provide an empty default constructor.
This transformer uses the format()
method to format text, form, and menu items. The format()
method uses the tag name as the item label, followed by the text of the item. Element.getTagName()
returns the name of the element.
For example, given the following XML element:
<User>Scott</User>
The format()
method returns:
User: Scott
The transform()
method is the only required method in a transformer class. In the sample, the transform()
method places each element from the source document in a node list. A node list is an indexed collection of elements.
NodeList list = element.getElementsByTagName("*");
The transform()
method then steps through every element in the node list, testing each against the elements in the Simple Result DTD. If the source element matches the test Simple Result element, the method formats the element. It then appends the results to a buffer which, when finished, is returned to the caller.
The Service Designer enables you to manage transformers in the Wireless Edition repository. Using the Service Designer, you can create and update transformers, and remove them from the repository.
You use the Create New Transformer form in the Service Designer to create a transformer in the repository. To display the form:
The form includes the following parameters:
Table 3-2 Transformer Parameters
The Open dialog box appears, as shown in the following figure.
Navigate to find the XSL file that you want to use, then click Open. The contents of the imported XSL stylesheet appear within the Style-sheet field in the Create New Transformer dialog box. Click Finish. You have created a new transformer.
To modify a transformer in the Wireless Edition repository, follow these steps:
Modify the parameters as required and click Apply. For information on the parameters in the transformer properties panel, see Section 3.2, "Wireless Edition Transformers".
To remove a transformer from the repository:
Wireless Edition provides a command-line utility you can use to test the transformers you create. The Xslt
utility takes a source document and an XSLT stylesheet, and writes the result document to standard output.
You invoke Xslt
from the command prompt as follows:
java oracle.panama.util.Xslt mystylesheet.xsl < myxml.xml
In addition to the command-line utility, Wireless Edition enables you to test transformers using the Transformer Testing Tool. The Transformer Testing Tool allows users to test a transformer with a single tool.
The screen for this tool is divided into the following three panes:
The pane on the upper-left of the screen contains the Service, Logical Device, and User Agent fields, which you use to select the service, the logical device, and the user agent for the transformer that you want to test. To find a service, click the Browse button to invoke a tree view of the services in the Wireless Edition repository. Click the service you want and then click OK.
To select a logical device for this service, click the down arrow in the Logical Device Field to display a list of logical devices. Select a logical device from this drop-down list. You can begin testing the transformer for this master service and logical device by clicking Run. The transformer test result appears in the TargetResult panel in the Output Formats pane of the screen. You may also include input parameters as part of your testing using the Input Parameters pane.
The pane on the upper right of the Transformer Testing Tool lists the input parameters for the adapter used by the master service selected in the upper-right pane.
The parameters listed in this pane have the following attributes:
Table 3-3 Attributes of the Input Parameters
You can use this panel to edit the input parameters. You can also use the Add or Delete buttons to add or remove an input parameter from the master service. Clicking Reset sets the input parameters back to their original state. After you have edited the input parameters, click Run in the upper-left pane. The test results appear in the Target Result panel in the bottom pane of the Transformer Testing Tool.
The bottom portion of the Transformer Testing Tool is divided into the following tabs, which show the output formats of the source content:
These tabs enable you to test and view the results (i.e., the AdapterResult, SimpleResult, and TargetResult) as well as edit and create the Result Transformer and Device Transformer of the service.
The AdapterResult panel enables you to see the Wireless Edition source content in the AdapterResult format, the intermediary format between the source and the target output device. Source content in the AdapterResult format must be converted into SimpleResult format before it can be delivered to a target device. The AdapterResult panel is blank if no AdapterResult is produced.
The ResultTransformer panel enables you to specify a transformer that Wireless Edition uses to convert AdapterResult content to SimpleResult format.
Note: You can enable this panel and make it editable by adding and specifying a value for either the PAsection or the PAX argument in the Input Parameters panel. |
The SimpleResult panel shows the source content in the SimpleResult DTD format, which is the format that is needed to convert content sources from the AdapterResult into the target device format.
SimpleResult is the Wireless Edition's internal representation of the output that is returned by an adapter. If an adapter does not return its output as a SimpleResult, the master service must use the ResultTransformer to convert the AdapterResult into the SimpleResult format.
The DeviceTransformer panel lists the logical devices in the repository. You can specify a custom transformer to be used with the master service for a logical device. A custom transformer enables you to optimize the presentation of service content for a particular device. Since the transformer is specialized for a particular device and master service, you can associate a custom transformer with only one master service and one logical device.
The TargetResult panel displays the source content in the format of the logical device selected in the upper-left panel.
Note: For more information on the Simple Result DTD, refer to Appendix A, "Simple Result DTD Reference". |
|
Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|