Skip Headers
Oracle® Application Server Wireless Developer's Guide
10g Release 2 (10.1.2)
B13819-02
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

9 Using Multi-Channel Server

Each section of this document presents a different topic. These sections include:

Section 9.1, "Overview of Multi-Channel Server"

Section 9.2, "Multimedia Adaptation"

Section 9.3, "Device Adaptation"

Section 9.4, "Modifying Multi-Channel Server Runtime"

Section 9.5, "Modifying the Data Models"

9.1 Overview of Multi-Channel Server

The Internet has reinvented itself in the last few years. Previously, users typically accessed the Internet only from their desktop personal computers using one of the two popular browsers. That has drastically changed. Today, the Internet is accessible from smart phones, personal data assistants (PDAs), pagers, regular phones, cars, even refrigerators and other home appliances. This presents great opportunities for enterprises to provide new services. But, it is also a huge challenge for developers. Previously, they used only one markup language, HTML, to develop their applications; they only needed to provide for two browsers accessing their applications. Now, almost every channel has its own markup language; browsers have different capabilities and support different varieties of the same markup language. For example, most of the smart phones support WML. But there are different versions of WML supported by different phones. Even those claiming to support the same version of WML may still have some (minor) deviations from the standard. Phones typically use VoiceXML. Again, there are different varieties of VoiceXML that the different Voice Gateways support. How can developers create web applications for these varieties of channels? One option is to create separate applications for every channel that use the channel specific markup language. That option is prohibitively time-consuming and expensive.

9.1.1 Benefits of Multi-Channel

Oracle took the Multi-Channel challenge very seriously and decided to do something to help developers and enterprises to easily develop their applications only once for all channels. OracleAS Wireless Multi-Channel Server (MCS) hides the complexity that all channels present to developers. It acts as a single browser that accesses web applications.

The Multi-Channel Server supports three device-independent markup languages for developing applications:

Some developers may not be concerned with multi-channel, and may only want to expose their applications to, say, the voice channel. Why use MCS in such a case? There are at least two reasons why even in that case you should consider the MCS:

  • You can develop your application using XHTML instead of VoiceXML. Most web developers already know XHTML and they will not need to learn VoiceXML. This obviously will save you time and money.

  • There are a variety of Voice Gateways that support different varieties of VoiceXML. So, if you develop your application in native VoiceXML, then you must certify your application against all the different voice gateways. MCS guarantees that your application will work with many voice gateways without any changes.

Even if you are planning to expose your application through only one channel now, you may reconsider this in the future and decide that it will be beneficial to provide additional access to that application. In that case, you will not need to make changes in the application because MCS will already support the new channel.

9.1.2 Features of Multi-Channel Server

Here are some of the key features of Multi-Channel Server:

  • Multi-Channel Content Adaptation—the same device-independent content is delivered to different channels on different devices. Multi-Channel Server adapts application content based on current user device capabilities. It considers the device-specific markup language, screen size, network speed, etc.

  • Support for Standard Markup Languages—applications are developed using standard markup languages. That saves development time and money since developers are not required to learn new markup languages. Even if the application is to be delivered to a single channel (for example, voice), developers do not need to learn a new channel-specific markup language. They can use the very popular XHTML and still deliver their content to VoiceXML or WML or other devices.

  • Devices and Gateways Certification—with so many emerging devices and gateways on the market, it is difficult for application developers to certify that their application will run on all of them. There are only two major browsers for the PC, but still most web applications must be tailored to work best on either one of them. When you consider the new mobile devices, it becomes impossible for the developers to guarantee that their applications will work on all of them. Multi-Channel Server ensures compatibility with all those devices.

  • Device Detection—Multi-Channel Server uses a sophisticated algorithm to detect devices making requests. It takes into account User-Agent, Accept, and other HTTP headers. Some device capabilities (for newer devices) are also submitted with the request by the device and used for best content adaptation.

  • Multimedia Adaptation—along with text adaptation, Multi-Channel Server does device-specific adaptation of images, ringtones, voice grammars and audio/video streams.

  • Single Browser—Multi-Channel Server is the only browser that the applications interact with. It shields application developers from any deficiencies that the end user device may have. For example, most mobile devices do not support HTTP cookies. But cookies are the easiest way to keep user sessions. Multi-Channel Server handles session and other cookies on behalf of the end user device.

  • XForms Engine—Multi-Channel Server adds the power of XForms (http://www.w3.org/TR/xforms/) support to any user device.

  • Work with Existing Portals—access any device through your existing Portal by deploying Multi-Channel Server in front of your Portal server.

  • URL Caching—some devices have very limited memory, thus they limit the content that they can receive. Multi-Channel Server caches long URLs that are sent to a device, reducing the content size.

In addition to Multi-Channel Server, Oracle Application Server also includes Wireless and Voice Portal built on top of MCS. Here are some of the additional features that are provided by the Wireless and Voice Portal:

  • Portal—the Wireless and Voice Portal provides full portal capabilities, including users and services managements, ACL, etc. The portal provides users with their own customizable home page which is a launch pad for individual services. The available services have a wide variety of forms, including database information, personalization, alerts, and location services. The large number of content sources adds to the complexity of having a manageable way to deliver each application to every type of device in the most optimized fashion.

  • Network Adaptation—in addition to the HTTP(S) protocol, the Wireless and Voice Portal also supports various other protocols to allow access from non-HTTP devices. Network adaptation is based on an extensible framework that allows customers to plug in their own drivers for adapting to any network protocol.

  • J2ME WebServices—the Wireless and Voice Portal provides a WebServices proxy to let J2ME-enabled devices access WebServices. This enables MIDlets developers to enhance their applications by accessing any external applications exposed as WebServices.

The following figure shows the main components of the Multi-Channel Server.

Multi-Channel Server is an extensible applications platform. It is built from pluggable modules. Modules implementation can be replaced to alter the default behavior. All modules and their default implementation are described below.

9.2 Multimedia Adaptation

This section contains information on how you can adapt various multimedia content for devices.

9.2.1 Overview of Multimedia Adaptation Services

OracleAS Wireless Multimedia Adaptation Services provide device-specific adaptation of images, ringtones, voice grammars and audio/video streams. These services are an integral part of the core Multi-Channel Server.

Devices and the browsers on them support different image formats, and have different screen sizes and color depths. As part of the content adaptation performed by OracleAS Wireless in responding to a request, images are dynamically adapted to suit client devices. Additionally, the new Intelligent Messaging component uses Image Adaptation Services to convert images for EMS and MMS.

Ringtone adaptation is provided as a Java API and allows for conversion of ringtone data to formats supported by the most popular phones. The supported formats include RTTL, iMelody and MIDI. The framework for ringtone adaptation allows developers to easily add support for new ringtone formats. The Intelligent Messaging component uses Ringtone Adaptation Services to convert ringtones for delivery through SMS, EMS and MMS.

Multimedia Adaptation Services further enhance the voice support of OracleAS Wireless by allowing voice gateway vendors to extend the OracleAS Wireless platform to support new or vendor-specific grammar formats. These formats are transformed (through the SimpleGrammar tag) into the format supported by the voice browser. Grammars that are defined in OracleAS Wireless XML are considered inline, whereas those provided by a URL reference are considered external. Voice gateway vendors wanting to support a new grammar format can easily provide XSL stylesheets to transform OracleAS Wireless XML grammars to their grammar format. Support for inline grammar transformation is provided directly in the voice transformer, and Oracle Corporation also provides a framework for external voice grammar transformations using the relevant XSL stylesheet.

9.2.2 Image Adaptation Features

The most important features of image adaptation are:

  • Support for multiple input image formats.

    • File Formats: BMP, GIF, JFIF, PNG, TIFF, WBMP

    • Content Formats: MONOCHROME, 1BIT, 2BIT, 4BIT, 8BIT, 12BIT, 16BIT, 24BIT, 32BIT, 48BIT, LUT, DRCT, RGB, GRAY

    • Compression Formats: JPEG, BMPRLE, LZW, LZWHDIFF, FAX3, FAX4, HUFFMAN3, PACKBITS, GIFLZW, DEFLATE

  • Support for multiple output image content formats including support for different color depths, compression formats, color schemes and file formats.

    • File Formats: JFIF (JPEG), GIF, BMP, WBMP, PNG

    • Compression: JPEG, GIFLZW, BMPRLE, DEFLATE

    • Content Formats: MONOCHROME, 2BITLUTGRAY, 4BITLUTGRAY, 8BITLUTGRAY, 8BITLUTRGB, 24BITRGB, 8BITGRAY

  • Support for scaling and resizing images.

    • Scale to fixed dimensions.

    • Maintaining aspect ratio, scale to fit in a bounding box. (If original image dimensions are smaller than desired image dimensions, the original image dimension is used to define a bounding box.)

    • Reduce size of image data in bytes to honor limits on size placed by device/network.

    • Provides the above image processing functionality as a J2EE-compliant component of OracleAS Wireless.

  • Supports limitation on URL length.

  • Supports inbound and outbound image caching. Inbound caching means that the original images are cached in the middle tier (using webcache) so that the requests from different device types for the same image would result in one fetch of the original image. Outbound caching means that the adapted images are cached (using webcache) so that different users on similar devices can share the same adapted image.


    Note:

    Image caching policy is determined by the owner of the original image. MCS passes on cache headers to the web cache so that if certain images are not cacheable, web cache will not cache them.

9.2.2.1 Authoring Multichannel Applications with Images

See Chapter 8, "OracleAS Wireless Developer Kit" for details on application development in XHTML and Wireless XML respectively with regards to using image adaptation.

9.2.3 Command-Line Tool

A command line tool is provided to convert images in batch mode before deployment to the web/wireless application.

  • Name: ImageGenerate.{bat|sh}

  • Description: A shell or unix shell script that invokes a Java application to generate images in all the formats supported by the different devices from a specified input image. The batch or script file can be found in ORACLE_HOME\wireless\bin\ImageGenerate.bat for Windows and in ORACLE_HOME/wireless/bin/ImageGenerate.sh for Unix.

  • Usage:

    ImageGenerate.{bat|sh} -inFile filename -outFile filename [-outW width] [-outH height] -outFormat format [-outContent contentType] [-dataSizeLimit limit] [-maintainRatio {true|false}]
    
    
  • Parameters

    • inFile filename - The filename of the input file to process. Required argument.

    • outFile filename - The resulting file after processing. Required argument.

    • outW width - The width in pixels of the resulting image. Optional argument.

    • outFormat format - The output file format of the resulting image.

      For examples, see interMedia User's Guide (available on Oracle Technology Network) for full specification.

      Examples include: GIFF - Gif format, JFIF - jpg format, WBMP - wbmp format. PNGF - png format. Required argument.

    • outContent contentType - The content format of the resulting image.

      For example, MONOCHROME to change the image to a black and white representation, or for GIF images 4BITLUT to change to 4 bit (16 color) representation. See interMedia User's Guide for full specification. Optional argument.

    • dataLimitSize datalimitsize - For GIF images only. Make the image fit in the specified size by reducing the pixel depth, eventually to monochrome, and then reducing the image size if necessary. Optional argument.

    • maintainRatio {true | false} - Maintain the aspect ratio of the image. Make it fit within box bounded by outW and outH. Default true. Optional argument.

      Usage:

      ImageGenerate -inFile stock_600_450.jpg -outFile stock_240_180.gif -outW 240 -outH 180 -outContent monochrome -outFormat giff
      
      

      Note:

      Ensure that either Java_HOME or ORACLE_HOME is defined as an environmental variable.

9.2.4 Extensibility Using ImageProcessor API

This section details the ImageProcessor API.

9.2.4.1 Description

The ImageProcessor Interface consists of a method named process that rewrites a given image URL into another URL that links to an image better suited for display on the calling device. The device information is provided by passing in a handle to the oracle.panama.model.Device instance corresponding to the calling device. Typically, the rewritten URL points to a server that can dynamically generate an adapted image based on the input image URL and device characteristics. ImageProcessor Interface is shown in Example 9-1.

Example 9-1 Interface oracle.panama.multimedia.ImageProcessor

package oracle.panama.multimedia;
 
import oracle.panama.model.Device;
 
/** Use this interface to replace the existing Image processing
 *  implementation for all formats with your own implementation
 */
public interface ImageProcessor {
ImageResponse process(ImageRequest request, Device) throws MultimediaException;
}

The classes oracle.panama.multimedia.ImageRequest and ImageResponse capture the input image and desired output image information. For more details, see the Javadoc for oracle.panama.multimedia.

9.2.4.2 Implementation

The default implementation of this interface oracle.panama.multimedia.impl.ImageProcessorImpl rewrites URLs to point at the Multimedia Adaptation Services image adaptation servlet. The servlet fetches the original image and dynamically processes it to return an adapted image to the requesting device.

9.2.4.3 Configuration

If you intend to replace the default implementation of the ImageProcessor interface, you must use the OracleAS Wireless Tools to give the name of the implementation class.

  1. Log in to the OracleAS Wireless Tools as an administrator.

  2. Under the System folder, click Site Administration.

  3. Under Component Configuration click Multimedia Adaptation Services.

  4. Replace the Image Provider Class Name field value with your class name and click OK.

  5. Additionally, ensure that the class is part of the OracleAS Wireless classpath.

9.2.5 Ringtone Adaptation

This section describes ringtone adaptation.

9.2.5.1 Features

Ringtone Adaptation is used to convert ringtones specified in certain input formats to the device supported formats. This happens automatically for XMS messaging applications. However for developers who want greater control over the ringtone adaptation, a Java API is provided.

Here are the supported conversions:

  • From RTTTL to Nokia binary, IMelody, MIDI

  • From IMelody to Nokia binary, RTTTL, MIDI

9.2.5.2 RingtoneProcessor Java API

The RingtoneProcessor Interface (Example 9-2)consists of a method-named process that rewrites a given ringtone into the format required by the output device. The process method accepts a RingtoneRequest instance, and returns the converted ringtone as output as a RingtoneResponse instance. This interface is invoked by the messaging framework and can be used directly as well.

Example 9-2 Interface oracle.panama.multimedia.Ringtone.Processor

package oracle.panama.multimedia;
 
/** Use this interface to replace the existing Ringtone processing
 *  implementation for all formats with your own implementation
 */
public interface RingtoneProcessor {
RingtoneResponse process(RingtoneRequest request) throws MultimediaException;
}

Example 9-3 Class oracle.panama.multimedia.RingtoneRequest

package oracle.panama.multimedia;
import Java.io.InputStream;
public class RingtoneRequest {
    /** Ringtone input data types */
    public static int RINGTONE_DATA_STRING = 0;
    public static int RINGTONE_DATA_STREAM = 1;
    public static int RINGTONE_DATA_BYTES = 2;
    public static int RINGTONE_DATA_NULL = -1;
    public String inputFormat = null;
    public String outputFormat = null;
    public String inputMimeType = null;
    public String outputMimeType = null;
    private String dataString = null;
    private InputStream dataStream = null;
    private byte[] dataBytes = null;
    private int dataType = RINGTONE_DATA_NULL;
    public RingtoneRequest()  {
    }
 
    public void setData (String ringtone) {
    	this.dataString = ringtone;
    	this.dataType = RINGTONE_DATA_STRING;
    }
 
    public void setData (InputStream ringtone) {
    	this.dataStream = ringtone;
    	this.dataType = RINGTONE_DATA_STREAM;
    }
 
    public void setData (byte[] ringtone) {
    	this.dataBytes = ringtone;
    	this.dataType = RINGTONE_DATA_BYTES;
    }
 
    public String getDataAsString () {
    	return this.dataString;
    }
 
    public InputStream getDataAsStream() {
    	return this.dataStream;
    }
 
    public byte[] getDataAsBytes() {
	    return this.dataBytes;
    }
 
    /** note, no setDataType method is provided to prevent
     *  inconsistency. The dataType attribute is set when 
     *  setting data.
     */
    public int getDataType() {
    	return this.dataType;
    }
}

Example 9-4 Class oracle.panama.multimedia.RingtoneResponse

package oracle.panama.multimedia;
 
import Java.io.OutputStream;
 
public class RingtoneResponse {
    public String inputFormat = null;
    public String outputFormat = null;
    public String inputMimeType = null;
    public String outputMimeType = null;
    private String dataString = null;
    private OutputStream dataStream = null;
    private byte[] dataBytes = null;
    private int dataType = RingtoneRequest.RINGTONE_DATA_NULL;
    public RingtoneResponse()  {
    }
 
    public void setData (String ringtone) {
    	this.dataString = ringtone;
    	this.dataType = RingtoneRequest.RINGTONE_DATA_STRING;
    }
 
    public void setData (OutputStream ringtone) {
    	this.dataStream = ringtone;
    	this.dataType = RingtoneRequest.RINGTONE_DATA_STREAM;
    }
 
    public void setData (byte[] ringtone) {
    	this.dataBytes = ringtone;
    	this.dataType = RingtoneRequest.RINGTONE_DATA_BYTES;
    }
 
    public String getDataAsString () {
      return this.dataString;
    }
 
    public OutputStream getDataAsStream() {
    	return this.dataStream;
    }
 
    public byte[] getDataAsBytes() {
    	return this.dataBytes;
    }
 
    /** note, no setDataType method is provided to prevent
     *  inconsistency. The dataType attribute is set when 
     *  setting data.
     */
    public int getDataType() {
    	return this.dataType;
    }
}

9.2.5.3 Implementation

The class oracle.panama.multimedia.RingtoneProcessorImpl implements the above interface. This implementation looks up configuration parameters to load the matrix of ringtone conversion implementations. A ringtone converter converts from one format to another and implements the interface defined in the Ringtone Converter Java API section. To add support for a new ringtone format (such as RTTTL2, which is similar to an existing format [RTTTL]), you only need to provide Java code for converting from RTTTL to RTTTL2 and vice versa. You need not convert from the new format to all the other supported formats. If there are multiple ways to convert from one format to another, the shortest sequence of converters will be selected (for example, converting from IMelody to RTTTL2: If you provide only a new RTTTL to RTTTL2 converter, MCS will convert from IMelody to RTTTL to RTTTL2. If you provide your own IMelody to RTTTL2 converter, it is chosen since the sequence of converters is shorter.).

9.2.5.4 Configuration

If you intend to replace the default implementation of the RingtoneProcessor interface, you must use the OracleAS Wireless Tools to give the name of the implementation class.

  1. Log in to OracleAS Wireless Tools as an administrator.

  2. Under the System folder, click Site Administration.

  3. Under Component Configuration click Multimedia Adaptation Services.

  4. Replace the Ringtone Provider Class Name field value with your class name and click OK.

  5. Additionally, ensure that the class is part of the OracleAS Wireless CLASSPATH.

9.2.5.5 Sample Usage

Example 9-5 shows a sample program that illustrates the use of RingtoneProcessor.

Example 9-5 RingtoneProcessor sample program

import Java.io.FileOutputStream;
import Java.io.ByteArrayOutputStream;
import oracle.panama.multimedia.RingtoneProcessor;
import oracle.panama.multimedia.RingtoneRequest;
import oracle.panama.multimedia.RingtoneResponse;
import oracle.panama.multimedia.MultimediaException;
 
public class RingtoneUserTest {
 
public static void main(String[] args) {
try {
RingtoneProcessor processor = 
RingtoneProcessorProvider.getProvider();
if (processor != null) {
   RingtoneRequest request = new RingtoneRequest();
   request.inputFormat = "IMELODY";
request.setData("BEGIN:IMELODY\nVERSION:1.2\nFORMAT:CLASS1.0\nMELODY:r1a1a2a3e3lmnop2a2a2a2g2a2r3a3a3e3g2a3a3a2a2g2\nEND:IMELODY\r\n");
request.outputFormat = "RTTTL";
   RingtoneResponse response = processor.process(request);
   int dType = response.getDataType();
   if (dType == RingtoneRequest.RINGTONE_DATA_STRING) {
   System.out.println(response.getDataAsString());
   } else if (dType == RingtoneRequest.RINGTONE_DATA_STREAM) {
   FileOutputStream outFile = 
   new FileOutputStream("ringtone.txt");
   ((ByteArrayOutputStream) 
   response.getDataAsStream()).writeTo(outFile);
   } else if (dType == RingtoneRequest.RINGTONE_DATA_BYTES) {
     // process the byte array response
   } else {
   // process failed to set the response data
   }
} else {
// Processor is null!! No ringtone converter available
System.out.println("No ringtone converter available");
}
} catch (Exception ex) {
ex.printStackTrace();
} catch (Error e) {
e.printStackTrace();
System.out.println("Error parsing ringtone");
}
    }
}

9.2.6 Ringtone Converter Java API

This section describes the ringtone converter API.

9.2.6.1 Description

The Ringtone Conversion Interface consists of an overloaded method (convert) that rewrites a given ringtone from one format to another. The convert method accepts an instance of RingtoneRequest and returns the converted ringtone in a RingtoneResponse instance. This interface is used by the RingtoneProcessorImpl to call the different converters for the supported formats. By implementing this interface (along with adding some configuration information), support for new ringtone formats can be added incrementally.

9.2.6.2 Interface oracle.panama.multimedia.RingtoneConverter

public RingtoneResponse convert (RingtoneRequest request);

9.2.6.3 Implementation

The class oracle.panama.multimedia.RingtoneConverterImpl implements the above interface. This implementation supports all the specified ringtone conversions.

9.2.6.4 Configuration

If you want to extend the default RingtoneProcessor implementation by providing additional RingtoneConverter implementations for new formats you must specify the RingtoneConverter implementation classes using the configuration file config.properties in: ORACLE_HOME/wireless/server/classes/oracle/panama/multimedia. You must add the new format name to the property ringtone.formats and the implementation class to the property ringtone.converters, as shown in Example 9-6.

Example 9-6 Extending the default RingtoneProcessor implementation

------------------
#Formats
 
ringtone.formats=RTTTL NOKIA IMELODY MIDI
 
#Converters in one string:triplets of "from format","to format","impln class"
 
ringtone.converters=RTTTL NOKIA oracle.panama.multimedia.RingtoneConverterImpl\
                 RTTTL IMELODY oracle.panama.multimedia.RingtoneConverterImpl \
                 IMELODY RTTTL oracle.panama.multimedia.RingtoneConverterImpl \
                 IMELODY MIDI oracle.panama.multimedia.RingtoneConverterImpl
 
-------------------
 

For example, to add RTTTL2, the property file would look like:

-------------------------
#Formats
 
ringtone.formats=RTTTL NOKIA IMELODY MIDI RTTTL2
 
#Converters in one string:triplets of "from format","to format","impln class"
 
ringtone.converters=RTTTL NOKIA oracle.panama.multimedia.RingtoneConverterImpl\
                 RTTTL IMELODY oracle.panama.multimedia.RingtoneConverterImpl \
                 IMELODY RTTTL oracle.panama.multimedia.RingtoneConverterImpl \
                 IMELODY MIDI oracle.panama.multimedia.RingtoneConverterImpl \
                 RTTTL RTTTL2 my.package.RTTTLToRTTTL2Converter \
-----------------------

If you added a RTTTL2 to RTTTL converter as well, you will need to add another triplet to ringtone.converters like "RTTTL2 RTTTL another.package.RTTTL2Converter"

9.3 Device Adaptation

Device adaptation is the process of transforming the source content to a target device taking into account and optimizing for various factors such as:

OracleAS Wireless adapts input source document written in XHTML/XForms, XHTML MP, and OracleAS Wireless Markup Language to various mobile devices:

OracleAS Wireless Device Adaptation provides the following key benefits for developers:

9.3.1 Device Repository

OracleAS Wireless Device Repository contains a wealth of device knowledge that is at the heart of the system. Administrators and developers can add new device information using the OracleAS Wireless Tools.

All information in the Device Repository is used for source content adaptation to the target device. It is important the information in the repository be kept up-to-date.

9.3.2 Device Repository Access

Developers can access information in the Device Repository in these ways:

  • Oracle Application Server Device Repository API

  • W3C CSS Media Queries Standard

Oracle Application Server Device Repository API is a set of Java APIs available to Java and JSP developers for programmable API access to the Device Repository. CSS Media Queries can be used by OracleAS Wireless Markup authors to access Device Repository information directly from the source document. CSS Media Queries is W3C Standard with Candidate Recommendation status. For further information on CSS Media Queries, see OracleAS Wireless CSS Support on Oracle Technology Network.

9.3.3 Device Detection

OracleAS Wireless automatically detects the type of device making a service request. The device detection component uses the User Agent, if available, to determine which device from the Device Repository to associate with the service request.

Here is how the device detection rule works:

  1. If the UserAgent is not available in the HTTP Header, then proceed to Step 4.

  2. Select a device from the Device Repository, where the useragent match string matches the UserAgent from the HTTP Header.

  3. If more than one device is returned, then choose the one with the longest useragent match string. If this result in exactly one device matched, then return the device. Done.

  4. Use the Accept HTTP Header to determine the preferred content types as per the IETF RFC-2616 specification.

  5. Return the first device that matches the preferred mime-type.

  6. If the request contains x-up-devcap-screenpixels and x-up-devcap-screenchars HTTP headers, then find the closest matching logical device using ScreenWidth, ScreenHeight, ScreenRows, ScreenColumns attributes of the device.

  7. If there are no devices selected, then log an error in the log file.

Device Detection in OracleAS Wireless can be customized by specifying a hook class that implements the interface:

oracle.panama.rt.hook.DeviceIdentificationHook

The default implementation of the hook is provided in:

oracle.panma.rt.hook.DeviceIdentificationPolicy class

9.3.4 Dynamic HTTP Header Composition and UAProf

The Device Repository APIs perform Dynamic HTTP Header form factor composition when such information is in the HTTP Request. Dynamic HTTP Header composition is accomplished as follows:

  1. Retrieve the device information from the repository and create an instance of oracle.panama.model.DeviceV2 object.

  2. Search for known device form factor information in the HTTP Header and update the appropriate attributes in oracle.panama.model.DeviceV2.

9.3.5 Device Transformers

The final phase in Oracle Application Server Device Adaptation is the selection and invocation of the device transformers to generate the markup language suitable for rendering on the target device from a supported source input document. Every device in the Device Repository has a list of appropriate transformers for that device.


Note:

You cannot add two transformers with the same MIME_TYPE to a single device.

The device transformers are grouped by the OracleAS Wireless Markup Language it accepts as an input source document as shown in Table 9-1.

Table 9-1 Device Transformer Input Markup

Transformer prefix OracleAS Wireless Markup OracleAS Wireless Markup Mime Type

mxml-

mobile-xml

text/vnd.oracle.OracleAS Wireless XML

xforms-

xhtml+xforms

application/vnd.oracle.xhtml+xforms

xhtml-

xhtml+mp

application/vnd.wap.xhtml+xml


Table 9-2 lists transformers, accepted by OracleAS Wireless Markup Language and the generated markup by the transformer:.

Table 9-2 Device Transformers for mobile-xml

Transformer Target Markup Description

mxml-ASYNC_Java

text/plain

SMS devices, Text

mxml-Adomo

text/vxml

Adomo Voice Gateway

mxml-Verascape

text/vxml

Verascape Voice Gateway

mxml-VoiceGenie

text/vxml

VoiceGenie Voice Gateway

mxml-avantgo

text/html

AvantGo Browser

mxml-blazer

text/html

Handspring Blazer Browser

mxml-chtml

text/html

cHTML browsers

mxml-ciscoip

text/xml

Cisco IP Phone

mxml-goweb

text/html

GoWeb browser

mxml-hdml

text/x-hdml

HDML browser

mxml-hdml-kddi

text/x-hdml

EZweb HDML browser

mxml-html32

text/html

W3C HTML 3.2 compliant browsers

mxml-html40

text/html

W3C HTML 4.0 compliant browsers

mxml-mml

text/html

J-PHONE Type C3 or later

mxml-mml-t04

text/html

J-PHONE Type C2

mxml-palm-family

text/html

Palm browsers

mxml-pocketpc

text/html

PocketPC PDA browsers

mxml-smil

application/smil

MMS SMIL

mxml-wml11

text/vnd.wap.wml

WML11 compliant browsers

mxml-wml11-ericsson

text/vnd.wap.wml

Ericsson WML11 browsers

mxml-wml11-openwave

text/vnd.wap.wml

Openwave WML11 browsers

mxml-wml11-wig

text/vnd.wap.wml

WIG browsers

mxml-xmp

text/html

XHTML MP Browsers


Table 9-3 lists the device transformers for XHTML+XForms.

Table 9-3 Device Transformers for XHTML+XForms

Transformer Target Markup Description

xforms-Verascape

text/vxml

Verascape Voice Gateway

xforms-VoiceGenie

text/vxml

VoiceGenie Voice Gateway

xforms-async_xhtml

text/plain

SMS, Text

xforms-chtml

text/html

cHTML Browsers

xforms-hdml

text/x-hdml

HDML browser

xforms-html32

text/html

W3C HTML 3.2 compliant browsers

xforms-html32-handheld

text/html

HTML 3.2 HandHeld Friendly browsers

xforms-html40

text/html

W3C HTML 4.0 compliant browsers

xforms-mml

text/html

J-PHONEType C3 or later

xforms-mms-smil

application/smil

MMS SMIL

xforms-palm-family

text/html

Palm browsers

xforms-wml11

text/vnd.wap.wml

WML11 compliant browsers

xforms-wml11-ericsson

text/vnd.wap.wml

Ericsson WML11 browsers

xforms-wml11-openwave

text/vnd.wap.wml

Openwave WML11 browsers

xforms-xmp

text/html

XHTML MP Browsers


Table 9-4 lists the device transformers for XHTML + MP.

Table 9-4 Device Transformers for XHTML+MP

Transformer Target Markup Description

xhtml-chtml

text/html

cHTML browser

xhtml-hdml

text/x-hdml

HDML browser

xhtml-html32

text/html

W3C HTML 3.2 compliant browsers

xhtml-html32-handheld

text/html

HTML 3.2 HandHeld Friendly browsers

xhtml-html40

text/html

W3C HTML 4.0 compliant browsers

xhtml-mml

text/html

Type 3 J-Phone

xhtml-mms-smil

application/smil

MMS SMIL

xhtml-palm-family

text/html

Palm browsers

xhtml-wml11

text/vnd.wap.wml

WML11 compliant browsers

xhtml-wml11-ericsson

text/vnd.wap.wml

Ericsson WML11 browsers

xhtml-wml11-openwave

text/vnd.wap.wml

Openwave WML11 browsers

xhtml-xmp

text/html

XHTML MP Browsers


9.3.6 Device Repository API

oracle.panama.model.Device API is deprecated. There is a new API available, oracle.panama.model.DeviceV2. DeviceV2 interface should be used to access the Device Repository from Java and JSP applications.

DeviceV2 interface can be accessed from the old Device API as follows:

Device device = RequestFactory.lookupRequest();
DeviceV2 devicev2 = device.getDeviceV2();

The above code segment retrieves the target device from the Device Repository for the current HTTP Request context. That is, devicev2 is a handle to the actual device information.

Once a handle is obtained for a DeviceV2 interface, retrieving device attributes or capability is straight-forward. There are three methods provided to retrieve the capability value as a Java boolean, String, or int as in Example 9-7

Example 9-7 Retrieving capability value

boolean bool = devicev2.getDeliveryContextAttributeBoolean(DeviceAttr.COLORCAPABLE);
String model = devicev2.getDeliveryContextAttributeString(DeviceAttr.MODEL); 
int width = devicev2.getDeliveryContextAttributeString(DeviceAttr.DEVICEWIDTH);

All device attributes or capabilities are listed in the oracle.panama.model.DeviceAttr interface. Table 9-5 lists all device attributes or capabilities.

Table 9-5 General Device Features

Device Attribute Description

VENDOR

Device Manufacturer

MODEL

model number

DEVICECLASS

deviceclass (deprecated)

MEDIA

CSS Media Type used for CSS Media Queries

DEVICETAG

Tag to identify and group related devices in the repository

DEVICEWIDTH

width of viewable area in pixels

DEVICEHEIGHT

height of viewable area in pixels

PIXELPITCH

size of pixel in mm (only for bitmap devices)

DEFAULTFONTSIZE

default font size on the device

GRID

Grid device (not a bitmap device)

COLORCAPABLE

If true, then device can render color

PAGEDMEDIA

If true, then it's a paged device like WAP/WML

BITSPERPIXEL

Bits per pixel for a monochrome device, or bits per color component for a color device.

MAXDOCSIZE

Maximum document size

TEXTINPUTCAPABLE

If true, device supports text input

NUMBEROFSOFTKEYS

Number of softkeys on the device

KEYBOARD

Keyboard type. One of (qwerty, phone keypad, disambiguating)


Table 9-6 lists browser capabilities.

Table 9-6 Browser Capabilities

MARKUP LANGUAGE List of markup supported on the device

PROLOG

XML prolog for the document

SUPPORTSAMPERSANDENTITY

If true, device supports XML ampersand entity. (deprecated)

SUPPORTSRELATIVEURL

If true, relative URL is supported

SUPPORTSCOOKIE

If true, supports cookies

MESSAGINGBASED

If true, supports asynchronous messaging

TABLESCAPABLE

If true, supports tables

AUDIOCONTENT

List of supported audio mime types

E-MAILCAPABLE

If true, capable of sending/receiving e-mail

TEXTTOSPEECH

If true, supports TTS engine

SPEECHGRAMMAR

If true, supports grammar

RECORDSPEECH

If true, can record speech

VOICECALLCAPABLE

If true, can make voice calls

CALLCONTROLCAPABLE

If true, can control calls

DEFAULTMARKUPLANGUAGE

Default mime type sent to device

ACCEPT

List of accepted mime types

ACCEPT_CHARSET

List of accepted character encodings

IMAGECAPABLE

If true, can display images (deprecated)

IMAGECONTENTTYPES

List of supported image mime types

VICEOCAPABLE

If true, supports video (deprecated)

VIDEOCONTENTTYPES

List of supported video mime types (deprecated)

VIDEOMODE

Supported video mode (deprecated)

AUDIOCONTENTTYPES

List of supported audio mime types

REVERSEENTITYMAP

List of XML Entity conversion rules


Table 9-7 lists messaging capabilities.

Table 9-7 Messaging Capabilities

DELIVERYTYPES List of supported messaging delivery types or channels

BANDWIDTH

Network speed

URLCAPABLE

Can follow URL hyperlinks directly

NOKIASMARTMESSAGING CAPABLE

If true, supports Nokia Smart Messaging

RINGTONECAPABLE

If true, supports downloadable ringtones

OPERATORLOGOCAPABLE

If true, can download operator logo

VCARDCAPABLE

If true, can support vcard

VCALENDARCAPABLE

If true, supports vcalendar

SYNCMLCAPABLE

If true, supports SYNCML

MESSAGESIZELIMIT

Maximum number of characters per message

MULTIMEDIAAUDIOFORMATS

Multi-media audio types

MULTIMEDIAIMAGEFORMATS

Multi-media image types

MULTIMEDIAVIDEOFORMATS

Multi-media video formats

SMILLAYOUTCAPABLE

If true, MMS browser supports SMIL layout tag


Table 9-8 lists VoiceXML gateway capabilities.

Table 9-8 VoiceXML Gateway Capabilities

GRAMMARCONTENTTYPES List of supported speech grammar mime types

MIMETYPE_TEXTTOVOICEGRAMMAR

Gateway specific mimetype of Voice Grammars generated from text

MIMETYPE_OGSTOVOICEGRAMMAR

Gateway specific mimetype of Voice Grammars generated from OGS Grammars

MIMETYPE_TEXTTODTMFGRAMMAR

Gateway specific mimetype of DTMF Grammar's generated from text

MIMETYPE_OGSTODTMFGRAMMAR

Gateway specific mimetype of DTMF Grammars generated from OGS Grammars

MIMEMAP_APPLICATION_SRGS_XML

Enter gateway specific mimetype for application/srgs+xml

MIMEMAP_APPLICATION_X_ABNF

Enter gateway specific mimetype for application/x-abnf

MIMEMAP_APPLICATION_X_GSL

Enter gateway specific mimetype for application/x-gsl

MIMEMAP_APPLICATION_X_JSGF

Enter gateway specific mimetype for application/x-jsgf

MIMEMAP_APPLICATION_X_DTMF

Enter gateway specific mimetype for application/x-dtmf

MIMEMAP_APPLICATION_X_WATSON

Enter gateway specific mimetype for application/x-watson

MIMEMAP_APPLICATION_X_SWI

Enter gateway specific mimetype for application/x-swi


Table 9-9 lists the Java (J2ME) capabilities.

Table 9-9 Java (J2ME) Capabilities

JavaCAPABLE If true, supports J2ME

JavaPLATFORM

Java configuration installed on the device such as CDC

JVMVERSION

JavaVM Version

JavaPROFILE

Java profile installed on the device such as MIDP

JavaPROVISIONPROTOCOL

Provisioning protocol, such as SUN-OTA

JavaMAXDOWNLOADSIZE

The maximum download size allowed for the JVM installed

JVMHEAPSIZE

JVM heap size


9.3.7 Device Information and Classification

OracleAS Wireless Server sends information about the user device to the back end applications using HTTP headers. This information may be used by the application to optimize the content that it generates. Table 9-10 lists of headers that an application will receive.

Table 9-10 Device Information and Classification

HTTP Header Name Description

X-Oracle-Device.Class

Indicates the Channel mode and the form factor of a device. Each value of the Device.class indicates a unique communication channel mode and the unique form factor. (For possible values, explanation and representative devices see below)

X-Oracle-Device.Orientation

Along with the form factor, the orientation of a device will help applications to change the rendering style for certain devices. Possible values are landscape/portrait, with default being portrait. (if nothing is specified by the System or if Width=height).

X-Oracle-Device.MaxDocSize

The Maximum size (in bytes) of XML document (service response) that handled by the device making the current request. This is an approximation, as the Byte size of the document and target device digest byte size cannot be mapped. Also embedded content like Audio and Image need to be considered towards this size. If the service returns XML document greater than the MaxDocSize, the response for such a request is undefined.

X-Oracle.Device.Secure

Possible values "true" or "false". Indicates if the connection between OracleAS Wireless server and the device was secure when the current request for the resource was made.

X-Oracle-Orig-User-Agent

If the request to the OracleAS Wireless server was made through HTTP protocol and the device sent User-Agent HTTP header then that header will be resend to the application using the header name.

X-Oracle-Orig-Accept

If the request to the OracleAS Wireless server was made through HTTP protocol and the device sent Accept HTTP header then that header will be resend to the application using the header name.


9.4 Modifying Multi-Channel Server Runtime

OracleAS Wireless Multi-Channel Server (MCS) Runtime is invoked directly through OC4J Servlets, Async Servers, Voice Servers, or indirectly through the OC4J Servlet Filters. The MCS runtime processes requests from any devices, user agents, and autonomous mobile agents that use diverse communication channels, such as Voice, Hypertext Transaction Protocol (HTTP), Instance Messaging, SMS, e-Mail, or two-way paging. The MCS runtime adapts the service requests from any of these channels and transcodes the service responses to take advantage of the unique device capabilities, freeing developers from the encumbrance of device idiosyncrasies. By adapting the requests from different communication channels to the standard J2EE Servlet 2.3 service requests, OracleAS Wireless MCS lets developers develop generic applications using industry-standard Servlet API, JSP, XHTML, XForms, and CSS in addition to Oracle's own OracleAS Wireless XML. The MCS can effectively utilize an extensible repertoire of device models in a centrally managed device knowledge repository to take advantage of specific device capabilities.

This section describes the functions of MCS runtime. It describes the MCS runtime session management, session persistency, runtime API and extensibility, content adaptation, and URL rewrite mechanisms. The MCS runtime performs automatic session tracking and terminates the sessions when they expire after the maximum interval of inactivity or when the devices disconnect.

9.4.1 MCS Runtime Session Management

OracleAS Wireless MCS runtime tracks runtime sessions independently of the OC4J Servlet sessions by rewriting every URL with an added parameter, PAsid, which specifies the MCS session ids. The session tracking identifies that a sequence of requests are submitted by the same user. The MCS runtime session contains the device credentials, user preferences, runtime contexts, cookies, URL caches, and other states essential for context-sensitive services. Furthermore, these MCS session states can be persistent. The MCS session id is used to restore the persistent MCS session states any time the MCS session id is referenced in the request, for example by putting the PAsid parameter in the URL. The MCS runtime maintains the runtime session so that users connecting through transient sessions under the alternative channels can share long-lived MCS runtime sessions. The persistent MCS sessions increase the life time of sessions and make the multi-modal interaction more enduring.

MCS runtime sessions can be bound to OC4J Servlet sessions. WAP 2.0 devices that implement the WAP HTTP State Management Specification (http://www.wapforum.org/) can support cookies for session management. Most of the commercial WAP gateways manage cookies on behalf of WAP devices. If the device or gateway does not support cookies, the OC4J Servlet container can revert to URL rewriting to track sessions. Since the MCS runtime also tracks the session, it is possible for more than one MCS runtime session to be bound to the same OC4J Servlet session. For example, two browser windows on the same device can open two independent MCS runtime sessions although the browsers may share the same servlet session because of the shared cookie repository.

The MCS runtime session states can be replicated to other OC4J instances in the island (An island replicates session state between two or more OC4J instances.) so that device requests can be redirected to another OC4J instance in the island when the first instance fails. By default, the binding to the OC4J Servlet session is enabled and is necessary to configure the OC4J session replication and failover. When the servlet sessions expire, the MCS runtime sessions that are bound to the servlet sessions are invalidated, provided the MCS runtime session is not bound to active sessions for other channels such as voice, instance messaging, or SMS. The invalidation of the MCS runtime session only releases the in-memory resources, but does not destroy the persistent MCS session states that can be restored when the runtime session is reactivated.

MCS runtime sessions are expired when the sessions remain idle for more than what is specified by a site-wide configuration parameter value for the Runtime Session Life Time (seconds) under System > Wireless Server: Administration > Runtime Configuration Console. The default session life time is 10 minutes. This parameter is overridden by the OC4J Servlet session expiration time, which is 30 minutes by default, when the MCS runtime session is bound to the OC4J Servlet session. The session binding from the runtime sessions to Servlet sessions can be disabled by the parameter setting enable.http.session.binding=false in the System.properties file. The MCS session persistency is enabled through the Enable Runtime Session Persistency" option under System > Wireless Server: Administration > Runtime Configuration Console. The runtime session persistency is disabled by default. The Persistent Session Life Time (days) under the same console specifies when the persistent MCS sessions are purged from persistent storage after they remain idle for the specified number of days. The MCS persistent session life time can be many orders longer than the OC4J Servlet session life time or the MCS runtime session life time; the default setting is two days.

9.4.2 Multi-Channel Gateway Usage

To use Multi-Channel Gateway, you must create and deploy your web application. You can use any web technology to develop your application. You can use either static or dynamic pages. Also, you can use either Mobile XML or XHTML markup language. The only requirement is that the application is accessible through HTTP(S) protocol. You application may or may not run on the same machine as the Multi-Channel Gateway.

For simplicity, we assume that the application is a simple JSP (Hello.jsp). The URL to access this JSP directly is: http://myhost:8080/jsp/Hello.jsp.

The Multi-Channel Gateway is another web application that can be accessed using the following URL: http://hostname:7777/mcs/remote/ (7777 is the default port for Oracle Application Server Wireless). But by accessing the Multi-Channel Gateway URL, you will not get any content because the Multi-Channel Gateway does not produce content. In order to access your own application (the content source) from your device through the Multi-Channel Gateway you must specify a special URL. To illustrate how that URL is created, consider the sample URL:

http://myhost:8080/jsp/Hello.jsp

The URL that you must enter in your device is:

http://hostname:7777/mcs/remote/http/myhost/8080/jsp/Hello.jsp

Here is how the above URL was created:

  1. Get the basic Multi-Channel Gateway URL. That is, http://hostname:7777/mcs/remote/

  2. Create the absolute URL (including the port number even if you use the default port number: 80 for HTTP and 443 for HTTPS) to your application.

  3. Replace the:// and: in your application original URL with / (That is, change from http://myhost:8080/jsp/Hello.jsp to http/myhost/8080/jsp/Hello.jsp

  4. Append the modified URL to the Multi-Channel Gateway URL.

Passing parameters to your web application is very simple. Just use the standard URL syntax and append the query string at the end of the URL.

For example: If you want to pass fname and lname parameters to your Hello.jsp then use the following syntax:

http://hostname:7777/mcs/remote/http/myhost/8080/jsp/Hello.jsp?fname=John&lname=Doe

When a request is received from the user device to the Multi-Channel Gateway, it recreates the original application URL, that is:

http://myhost:8080/jsp/Hello.jsp

and sends a request to that URL. The Multi-Channel Gateway uses the same HTTP method that the user device used to send the request (If the user device used GET, then the Multi-Channel Gateway will use GET to access the back end application. Currently only GET and POST are supported.)

9.4.3 Performance Optimization and JSP Files Modification

In general, Oracle Application Server Containers for J2EE (OC4J) examines JavaServer Pages (JSP) files to detect changes, then recompiles. However, this OC4J behavior was changed in regards to the JSP files that are deployed inside the ptg web application.

If you make changes to these included, precompiled JSP files, OC4J will not detect and compile the changes in those JSP files.


Note:

For more information on OC4J Configuration, see "JSP Configuration Parameters" in Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide.

For example, all JSP files that are deployed inside the ptg web application are precompiled. If for some reason you want to modify those JSP files, then you can no longer use the precompiled class files; you must change the OC4J settings to enable JSP compilation. To do that, modify the web.xml file for the ptg application, located in:

ORACLE_HOME/OC4J_Wireless/applications/ptg/ptg-web/WEB-INF/web.xml.

In order to avoid this problem (in which modifications to JSP files do not take effect), and to optimize the performance of some of the JSP files included in Oracle Application Server Wireless, you must modify the web.xml file, as detailed below:

  1. Delete the following from the file:

    <!-- WARNING!!! Overridden JSP engine settings With this configuration the JSP files in this application will NOT be recompiled. Any changes to the JSP source files will NOT take effect. If you want to switch back to the default JSP engine settings simply comment out the servlet declaration and mapping for the jsp servlet below. --><servlet><servlet-name>jsp</servlet-name><servlet-class>oracle.jsp.runtimev2.JspServlet</servlet-class><!-- you can disable page scope listener if you don't need this function. --><init-param><param-name>check_page_scope</param-name><param-value>true</param-value></init-param><!-- you can set main_mode to "justrun" to speed up JSP dispatching, if you don't need to recompile your JSP anymore. You can always switch your main_mode. Please see our doc for details --><init-param><param-name>main_mode</param-name><param-value>justrun</param-value></init-param><load-on-startup>0</load-on-startup></servlet><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>/*.jsp</url-pattern></servlet-mapping><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>/*.JSP</url-pattern></servlet-mapping><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>/*.jspx</url-pattern></servlet-mapping><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>/*.sqljsp</url-pattern></servlet-mapping><servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>/*.SQLJSP</url-pattern></servlet-mapping>
    
    
  2. You must also delete the ORACLE_HOME/j2ee/OC4J_Wireless/applications/ptg/ptg-web/WEB-INF/classes/_modules directory, and all class files in the ORACLE_HOME/j2ee/OC4J_Wireless/applications/ptg/ptg-web/WEB-INF/classes directory whose names start with an underscore ( _ ).

  3. Restart the OC4J_Wireless application.

9.4.4 MCS Runtime API

OracleAS Wireless MCS Runtime API provides the Java interfaces to examine the runtime execution states, trace the runtime execution flow, and augment the default execution semantics. The Runtime API consists of the following Java packages:

  • oracle.panama.rt provides the interfaces to the essential runtime objects for state management.

  • oracle.panama.rt.event provides the interfaces to monitor the runtime execution sequence based on the Java event model.

  • oracle.panama.rt.hook provides the interfaces for the essential runtime customizable components and the default implementation policies for these interfaces.

These packages are included in the wireless.jar file. Make sure you have included wireless.jar in your Java classpath when you compile your Java application or plug-in components that depend on the MCS Runtime API.

9.4.4.1 Runtime Objects

The oracle.panama.rt package defines the core of the Runtime API. The runtime custom plug in components, such as Event Listeners, can use the Request, Response, and Session interfaces in the oracle.panama.rt package.

The following subsections describe the interfaces in this package. The interfaces are:

9.4.4.1.1 Request

A request object is used to define the URL parameters and HTTP header attributes for a service request. It also defines the user agent type, device model, and other runtime contexts. A listener can subscribe to events from a request.

The following methods in the Request interface allow you to access, replace, add, or remove the parameters that are associated with the request object:

  • Object getAttribute(AttributeCategory category, String name)

  • Object setAttribute(AttributeCategory category, String name, Object attribute)

The methods access the name and value of the attributes, which can be user parameters, system parameters, or application contexts. There are three categories of attributes:

  • PARAMETERS

  • RUNTIME

  • CONTEXTS

The most important attribute category for Request is PARAMETERS, which contains the query and form parameters submitted by a user. The MCS runtime parses the URL query strings to retrieve the parameters. Other runtime components can set these parameters programmatically. Since MCS runtime rewrites and caches the URLs, some of the parameters are retrieved from the URL cache in the runtime session. MCS runtime may need to parse both the query strings from the HTTP request and the URL cache in the session to build a complete list of query parameters.

9.4.4.1.2 Response

This interface represents the Response objects in MCS runtime. A listener can subscribe to events from a Response. The Response object is the execution result of the Request object.

9.4.4.1.3 Session

This interface represents the session objects in MCS runtime. Any request can only be executed in a valid session context. A session can expire after the session exceeds the maximum interval of inactivity. Developers can store the session-long information in the corresponding session object. A listener can subscribe to events from a session. See Section 9.4.1, "MCS Runtime Session Management" for how MCS runtime sessions are established.

The session caches the device credentials, personalization preferences, uncompressed URLs, Cookies, and XForms Documents among other runtime contexts. The SMS and Instant Messaging servers use the runtime sessions extensively to manage dynamically generated short names, for example, single digit menu numbers to identify the URLs. Sessions states include Cookies that represent various states of authentication against content providers' applications. The MCS runtime caches the XForms documents in the runtime session. The session owner can interact with XForms documents over several request/response messages before submitting the instance data to applications.

The following methods in the Session interface allow you to access, replace, add, or remove the parameters that are associated with the session object:

  • Object getAttribute(AttributeCategory category, String name)

  • Object setAttribute(AttributeCategory category, String name, Object attribute)

The methods access the name and value of the attributes. There are three categories of attributes:

  • PARAMETERS

  • RUNTIME

  • CONTEXTS

9.4.4.2 Event Listeners

The MCS runtime is invoked from the OC4J Servlets, Servlet Filters, Voice Servers, or Async Servers. Similar to the Servlet 3.2 Filters, the MCS runtime controllers are extensible through pluggable MCS runtime Request, Response, and Session Listeners.

During the establishing of an MCS session, the expiration of an MCS session, or the processing of a request and response, MCS runtime can generate a sequence of events to signal the execution progress if any interested listener is registered with these objects. The listeners can monitor the runtime progress and modify the request and response data without changing the execution flow of the controllers in the MCS runtime. The possible applications for the event listeners include data logging, performance monitoring, and more advanced context-aware customizations. The oracle.panama.rt.event package defines the API based on the JDK Event models.

Listener and Event form an important Observer design pattern in which the Listener represents an observer. Three types of listeners are defined:

The ListenerRegistrationHook subscribes listeners to receive events from the subject, such as Request, Response, or Session.

9.4.4.2.1 RequestListener Interface

The implementor of oracle.panama.rt.event.RequestListener can receive any of the following events:

  • before request

  • request begin

  • service begin

  • service end

  • transform begin

  • transform end

  • request end

  • after request

  • request error

Which specific Request-related event will be generated is controlled by the event mask in System Manager > Site > Wireless Web Server > Event and Listeners in OracleAS Wireless Tools. For example, if you want to have your RequestListener receive the request begin event, you should set the Enable request begin Event to true in System Manager > Site > Wireless Web Server > Event and Listeners control panel in OracleAS Wireless Tools. The site configuration property names are:

  • wireless.http.event.beforeRequest

  • wireless.http.event.requestBegin

  • wireless.http.event.requestEnd

  • wireless.http.event.serviceBegin

  • wireless.http.event.serviceEnd

  • wireless.http.event.transformBegin

  • wireless.http.event.transformEnd

  • wireless.http.event.requestError

  • wireless.http.event.afterRequest

The RequestListener can intercept the input parameters during the requestBegin(RequestEvent) and apply additional business rules on the request parameters before service invocation.

9.4.4.2.2 ResponseListener Interface

The implementor of oracle.panama.rt.event.ResponseListener can receive the Response-related event. The only possible Response-related event is response error. If you want MCS runtime to have your ResponseListener receive the response error event, you should set the Enable response error Event option to true in System Manager > Site > Wireless Web Server > Event and Listeners control panel in OracleAS Wireless Tools. The site configuration property name is: wireless.http.event.responseError

9.4.4.2.3 SessionListener Interface

The implementor of oracle.panama.rt.event.SessionListener can receive Session life cycle events. The possible Session events include:

  • before session

  • session begin

  • session authenticated

  • session end

  • after session

Which specific Session event will be generated is controlled by the event masks in the System Manager > Site > Wireless Web Server > Event and Listeners control panel in OracleAS Wireless Tools. For example, if you want to have your SessionListener receive the session begin event, set the Enable session begin Event option to true in the System Manager > Site > Wireless Web Server > Event and Listeners control panel in OracleAS Wireless Tools. The site configuration property names are:

  • wireless.http.event.beforeSession

  • wireless.http.event.sessionBegin

  • wireless.http.event.sessionAuthenticated

  • wireless.http.event.sessionEnd

  • wireless.http.event.afterSession

9.4.4.2.4 MCS Runtime Listeners Implementation Guidelines

The following steps describe how to set up the customized Event Listener.


Note:

Ensure that you set your CLASSPATH properly; include all relevant files. View your log.xml file to see the files that must be included.

  1. Implement the RequestListener, ResponseListener, or SessionListener interfaces.


    Note:

    Each Listener must provide this method:

    public static <ClassName> getInstance();


  2. Compile the new Java source files from Step 1 with the wireless.jar file in the classpath.

  3. Modify the event mask entries in the System Manager > Site > Wireless Web Server > Event and Listeners control panel to enable the generation of specific events.

  4. Specify the class names for the RequestListener, ResponseListener, and SessionListener in the System Manager > Site > Wireless Web Server > Event and Listeners control panel of OracleAS Wireless Tools. The site configuration property names are:

    • wireless.http.locator.combined.listener.classes

    • wireless.http.locator.session.listener.classes

    • wireless.http.locator.response.listener.classes

    • wireless.http.locator.request.listener.classes

  5. Restart the OracleAS Wireless instance.

Any of the event listeners may throw the AbortServiceException to signal the MCS runtime controller to reject the request, but this veto signal is effective only if it is raised during one of the following events when the service is yet to be invoked:

  • beforeRequest(RequestEvent)

  • beforeSession(SessionEvent)

  • sessionAuthenticated(SessionEvent)

  • requestBegin(RequestEvent)

  • sessionBegin(SessionEvent)

  • serviceBegin(RequestEvent)

The listeners may throw the AbortServiceException during the serviceEnd(), transformBegin(), and transformEnd() events to refuse the service's content to the user, although any durable effect of the service invocation cannot be rolled back. The sessionEnd(), afterSession(), requestEnd(), and afterRequest() methods should not throw the AbortServiceException.

A listener that implements the Request, Response, and Session listener interfaces is described in Example 9-8. The listener in this example listens to all Request, Response, and Session events. The sample listener logs the response time of the requests.

Example 9-8 An implementation of the Event Listeners

package oracle.panama.rt.event; 
 
import oracle.panama.rt.Request; 
import oracle.panama.rt.Response; 
import oracle.panama.rt.Session; 
import oracle.panama.rt.AttributeCategory; 
import oracle.panama.rt.event.RequestEvent; 
import oracle.panama.rt.event.ResponseEvent; 
import oracle.panama.rt.event.SessionEvent; 
import oracle.panama.rt.event.RequestListener; 
import oracle.panama.rt.event.ResponseListener; 
import oracle.panama.rt.event.SessionListener; 
import oracle.panama.rt.event.AbortServiceException; 
 
public class Listener implements RequestListener, ResponseListener, SessionListener { 
 
      private final static String BEFORE_REQUEST    = "L__L1"; 
      private final static String REQUEST_BEGIN     = "L__L2"; 
      private final static String SERVICE_BEGIN     = "L__L3"; 
      private final static String SERVICE_END       = "L__L4"; 
      private final static String TRANSFORM_BEGIN   = "L__L5"; 
      private final static String TRANSFORM_END     = "L__L6"; 
      private final static String REQUEST_END       = "L__L7"; 
      private final static String AFTER_REQUEST     = "L__L8"; 
      private final static String BEFORE_SESSION    = "L__L9"; 
      private final static String SESSION_BEGIN     = "L__LA"; 
      private final static String SESSION_END       = "L__LB"; 
      private final static String AFTER_SESSION     = "L__LC"; 
 
      public void beforeSession(SessionEvent event) throws AbortServiceException { 
            System.out.println(event.toString()); 
      } 
 
      public void sessionBegin(SessionEvent event) throws AbortServiceException {      //[29]
         StringBuffer buf = new StringBuffer(1000000); 
         event.getSession().setAttribute(AttributeCategory.RUNTIME, this.SESSION_BEGIN, buf);
      } 
 
      public void beforeRequest(RequestEvent event) throws AbortServiceException { 
            event.put(BEFORE_REQUEST, new Long(event.getTimeStamp())); 
      } 
 
      public void requestBegin(RequestEvent event) throws AbortServiceException { 
            event.put(REQUEST_BEGIN, new Long(event.getTimeStamp())); 
      } 
 
      public void serviceBegin(RequestEvent event) throws AbortServiceException { 
            event.put(SERVICE_BEGIN, new Long(event.getTimeStamp())); 
      } 
 
      public void serviceEnd(RequestEvent event) throws AbortServiceException { 
            event.put(SERVICE_END, new Long(event.getTimeStamp())); 
      } 
 
      public void transformBegin(RequestEvent event) throws AbortServiceException { 
            event.put(TRANSFORM_BEGIN, new Long(event.getTimeStamp())); 
      } 
 
      public void transformEnd(RequestEvent event) throws AbortServiceException { 
            event.put(TRANSFORM_END, new Long(event.getTimeStamp())); 
      } 
 
      public void requestEnd(RequestEvent event) throws AbortServiceException { 
            event.put(REQUEST_END, new Long(event.getTimeStamp())); 
      } 
 
       public void afterRequest(RequestEvent event) throws AbortServiceException {     //[54]
             Long val; 
             long t1, t2, t3, t4, t5, t6; 
 
           StringBuffer buf = (StringBuffer) event.getRequest().getSession().getAttribute(
            AttributeCategory.RUNTIME, this.SESSION_BEGIN); 
 
              /* compute total response time */ 
              t6 = event.getTimeStamp(); 
              val = (Long) event.get(this.BEFORE_REQUEST); 
              t1 = val.longValue(); 
              buf.append("Request time = "); 
              buf.append(t6 - t1); 
              buf.append("\r\n"); 
  
              /* compute service time */ 
              val = (Long) event.get(this.SERVICE_END); 
              t3 = val.longValue(); 
              val = (Long) event.get(this.SERVICE_BEGIN); 
              t2 = val.longValue(); 
              buf.append("Service time = "); 
              buf.append(t3 - t2); 
              buf.append("\r\n"); 
  
              /* compute transform time */ 
              val = (Long) event.get(this.TRANSFORM_END); 
              t5 = val.longValue(); 
              val = (Long) event.get(this.TRANSFORM_BEGIN); 
              t4 = val.longValue(); 
              buf.append("Transform time = "); 
              buf.append(t5 - t4); 
              buf.append("\r\n"); 
      } 
 
       public void sessionEnd(SessionEvent event) throws AbortServiceException {     // [84]
             StringBuffer buf = (StringBuffer) event.getSession().getAttribute( AttributeCategory.RUNTIME, this.SESSION_BEGIN); 
             System.out.println(buf.toString()); 
             System.out.println(event.toString()); 
      } 
 
      public void afterSession(SessionEvent event) throws AbortServiceException { 
             System.out.println (event.toString()); 
      } 
 
      public void requestError(RequestEvent event) throws AbortServiceException { 
             System.out.println(event.toString()); 
      } 
 
      public void responseError(ResponseEvent event) throws AbortServiceException { 
            System.out.println(event.toString()); 
      } 
 
} 

Example 9-8 describes a sample listener that listens to all session, request, and response events. The example illustrates the use of the session for grouping all requests under the same session. The method sessionBegin() in line 29 creates a large string buffer for logging all events under the session. At the end of the session, in the sessionEnd() method in line 84, the string buffer containing the logs for the session is then printed. The values placed in the event object persist through the life cycle of the event source and can be retrieved during subsequent events. Alternatively, the listener may place the values in the RUNTIME attribute category of the Request or Session objects. Both techniques allow the listeners to correlate and trace the events from individual event sources. In the above example, the listener puts the timestamp of each event in the event object. These timestamps are retrieved at the end of the request as shown in the afterRequest() method in line 54, where the timestamps are used to compute the total response time, service time, and transform time for the request.

9.4.4.2.5 Deploy the Listener

In order to deploy your Listener, copy all of the .class files into the classes directory. By default: ORACLE_HOME/wireless/server/classes.

9.4.5 MCS Reverse Proxy, URL Rewrite, Caching, and Compression

The MCS runtime parses the documents and rewrites the URLs in the response documents before transforming and delivering the documents to the devices. The MCS replaces all URLs in the response document, including the channel protocol, target host names, and port numbers, so that the MCS can intercept all subsequent requests that follow from the links in the document. In this way, the MCS acts as a reverse proxy server to the devices.

The MCS runtime caches each of the original URLs in the MCS session and replaces the URL with a much shorter URL consisting only the PAsid and PAckey parameters. The PAsid parameter specifies the MCS runtime session id. The PAckey parameter specifies the key to look up the URL in the MCS session. The MCS session id, the URL caches, cache keys, and cookies are part of the persistent states of the MCS session. The MCS runtime amends the requests that it intercepts with the parameters from the original URLs in the MCS session caches.

Acting as a virtual browser in the reverse proxy, the MCS generates the HTTP requests to the target host and port number that are accompanied by the cookies from the MCS session caches. The MCS URL cache-and-rewrite scheme affords a high compression ratio if the URLs contain many hidden fields.

9.4.6 MCS Virtual Browser Model

The MCS, acting as a reverse proxy server, rewrites all URLs including the channel protocol, target host, port number, and the form or query parameters so that it can proxy all requests from the devices. The MCS can thus translate the multi-channel proxy requests to the HTTP content provider requests. When generating the HTTP requests to the content providers, the MCS acts as a virtual browser to the content provider, thereby presenting a generic user agent type. The content providers need to write the application only for the generic user agent type of the MCS virtual browser. This simplifies the multi-channel application delivery model and at the same time provides a powerful development model based on industry-standard markup languages such as XHTML, XForms, and CSS.

Acting as a virtual browser, the MCS can follow the URL redirects from the content provider applications. MCS also supports HTTP Header Referrer for external applications to trace the context of the requests. MCS can use both HTTP and HTTPS protocols and support session cookies as well as other persistent cookies, which can be part of the persistent MCS sessions. The MCS chooses to use the GET or POST methods depending on the methods the devices use to access MCS runtime. Only when the device does not use HTTP channel does the MCS runtime default to the GET method.

The MCS runtime can detect the redirect response codes, such as the HTTP response code 301 to 305, and follow the redirected URLs specified by HTTP Location header. The MCS can also support post-based redirects. To send a post-based redirect, the content provider should send HTTP header x-oracle-mobile-redirect with value true, and the OracleAS Wireless XML form as shown in Example 9-9 as the response content. The line [3] sends a Post redirect to the URL http://OracleAS Wireless.oracle.com. The param1=value1 is passed as post data to the URL.

Example 9-9 OracleAS Wireless XML form

<%
response.setHeader("x-oracle-mobile-redirect", "true");
response.setHeader("Content-Type", "tex/vnd.oracle.OracleAS Wireless XML");  // [3]
%>
<?xml version = "1.0" encoding = "UTF-8" standalone="yes" ?>
<!DOCTYPE SimpleResult PUBLIC "-//ORACLE//DTD SimpleResult 1.1.0//EN" 
"http://xmlns.oracle.com/ias/dtds/SimpleResult_1_1_0.dtd">
<SimpleResult>
   <SimpleContainer>
      <SimpleForm name="ProcessSignOnForm" mimetype="text/vnd.oracle.OracleAS Wireless XML" 
target="http://OracleAS Wireless.oracle.com/MyApp" method="post">
         <SimpleFormItem name="param1" value="value1" type="hidden"/>
      </SimpleForm>
   </SimpleContainer>
</SimpleResult>

The MCS sends the referring URLs in the HTTP Header Referrer. This mechanism is used by content providers to trace the context of the current request. The Referrer header is not sent by default but the OracleAS Wireless XML attribute sendreferer described in Example 9-10 is used to indicate that the Referrer header should be sent.

Example 9-10 OracleAS Wireless XML attribute sendreferer

<?xml version="1.0" encoding="UTF-8"?>
<SimpleResult>
    <SimpleContainer>
        <SimpleHref target="HelloWorld.xml" sendreferer="true">Send Referer</SimpleHref>
         <SimpleHref target="HelloWorld.xml" sendreferer="false">Don't Send Referer </SimpleHref>
    </SimpleContainer>
</SimpleResult>

The MCS can access HTTPS protocol based URLs. Before using HTTPS, the client certificates should be configured using the Site Configuration Tool. The MCS can access external URLs through a HTTP proxy server. The proxy settings can be specified using the Site Configuration Tool.

The MCS runtime implements the version 0 of the Cookie Specification by Netscape (http://www.netscape.com/newsref/std/cookie_spec.html). It stores the Cookies sent by the external URLs in the MCS runtime session and sends the relevant cookies from the session with the HTTP URL request to content providers. The cookies are valid as long as the MCS sessions are valid. The persistent MCS sessions must be enabled to support persistent cookies.

The MCS performs the content adaptation, and adapts web content written in standard XHTML, XForms, and CSS markups languages to the device-specific markup languages. The MCS uses a sophisticated algorithm to determine the device and network capability by looking at the User-Agent, Accept, HTTP headers attributes, and the optional device identifications and physical device models specified by the user when they register their devices. The MCS also examines the device capabilities that some of the newer devices submit with the request. It uses a repertoire of device models in the device knowledge base to render the optimal content adaptation.

9.4.7 Wireless and Voice Portal

OracleAS Wireless also includes the facilities (such as User and Device Provisioning, User Management, Content and Service Management, Single-Sign-On Authentication, Authorization, Device Registration, User Preferences Management, End-User Personalized Portals, Billing Systems Integration, etc.), that are necessary components to build a self-contained Portal. The Wireless and Voice Portal shares the User Repositories, Oracle Internet Directory, and Single-Sign-On credentials with the Oracle Application Server Portal Product and can interoperate with the main Portal. In the Wireless and Voice Portal Runtime, every request from the device is serviced within the context of a valid runtime session. The requests from anonymous devices are also tracked and assigned to individual runtime sessions although the owners of the sessions may be the Guest user, which is an anonymous user.

9.4.7.1 Device Identification

The OracleAS Wireless and Voice Portal runtime automatically provisions a virtual user in the Oracle Application Server OID User Repository for each device that can be consistently identified, using the identifiers available in the devices. Runtime sessions for virtual users are opened whenever the device identifiers are present in the requests. The device identifiers may be based on native device identifiers such as the Mobile Identification Number (MIN), Mobile Subscriber ISDN (MSISDN), Ipv6 Address, Electronic Serial Number (ESN), etc. The device identifiers may also be provisioned into the device by the WAP gateway. The WAP Client ID Specification (http://www.wapforum.org/) defines a standard scheme for supporting the device identifiers. If no device identifiers are supplied in the request, the OracleAS Wireless runtime provisions the device identifiers into the devices using the persistent cookies whenever possible.

The Wireless and Voice Portal runtime uses the device identifiers only to facilitate personalization under the virtual user. The runtime sessions opened under the virtual users have access to the information such as personalized presets and preference profiles in the repository. The device identifier also enables the device to reconnect to the same runtime session for the user, as long as the session has not expired. The device identifiers add robustness to the session management for Wireless and Voice devices, enabling continuity of the service in the face of intermittent connection losses. The users may also make telephone calls in between connections to the portal without losing their contexts.

Device identifiers are not a means of authentication. Although the runtime sessions for the virtual users are not authenticated, it does not prevent the users from accessing their personalized portals. The users may establish authenticated sessions only if they register with the Wireless and Voice Portal. The user can supply the user name and password during the registration. The user's personalization profiles and presets are still available to the user after the user becomes registered. The advantages of the registration include the authentication process that gives access to the secured services, such as e-Wallets and financial transaction services.

9.4.7.2 Virtual User Concept

The Wireless and Voice Portal runtime automatically provisions virtual users in the Wireless repository for devices that can be consistently identified, using the identifiers available in the devices. The virtual user option gives the device owners immediate access to the personalization features of the portal, which enhance the user experience. It automates the provisioning process for the carrier and enterprise portal administrators using the emerging WAP Client ID standards.

Device owners can register with Wireless and Voice Portal to gain access to secured services through authentication. The registration can be done from the setup menus by the device owner. This self-provisioning registration feature further simplifies the administration tasks. The devices with virtual user support let the registered users connect to Wireless and Voice Portal and access the personalized services without signing on to the system until they are requested by the secured services to authenticate. The virtual user feature not only improves the accessibility of the portal but also enhances the data mining capability of portal operators since the activities of the devices can be identified with virtual identities.

The virtual user feature can be disabled by the site wide configuration parameter setting wireless.virtualuser.enabled=false. This property can be modified by the Enable Virtual User option in the System Manager>Site>User Provisioning control panel. If the virtual user feature is disabled or if the device does not support device identifier, then the session is opened under the Guest user, which must be provisioned in the repository. The Wireless and Voice Portal bootstrap repository includes the anonymous user Guest.

Applications that have direct access to the Wireless and Voice Portal runtime objects can check the value of oracle.panama.model.UserType returned by the getUserType() method in oracle.panama.model.User. The User of the runtime session can be retrieved from the getUser() method in oracle.panama.rt.Session. The external content providers can get the user type information from the HTTP header attribute x-oracle-user.userkind. The possible values of this attribute are anonymous, virtual, or registered.

9.4.7.3 Authentication and Authorization

The application programs for services that require authenticated sessions must add the PAlogin=true parameter in the URLs. When the Wireless and Voice Portal runtime detects the PAlogin=true parameter among the URL parameters in the request for a service, the runtime tries to authenticate the user if the runtime session is not already authenticated. The authentication process, which typically involves the user supplying the user name and password to the Oracle Application Server Single Sign On (SSO) Server, is performed before the runtime invokes the service being requested. After the PAlogin parameter invokes the authentication process, the application programs for secured services still must verify that the session is authenticated. The applications that have direct access to the Wireless and Voice Portal runtime objects can use isUserAuthenticated() method in oracle.panama.rt.Session interface. The external content providers can get the information from the HTTP header attribute x-oracle-user.authkind which has the values authenticated or unauthenticated.

In addition, the applications can also check if the session is secured by the SSL, TLS, or WTLS channels. The application that has direct access to the Wireless and Voice Portal runtime objects can use the isSecure() method in the oracle.panama.rt.Request interface. External content providers can get the isSecure() condition through the HTTP header attribute x-oracle-device.secure, which has the values true or false.

The authorization for access to a service is performed for each request for all authenticated or unauthenticated sessions. The authorization makes sure that the session user has the privilege to access the service. The default authorization policy does not differentiate whether the session is authenticated or unauthenticated. The unauthenticated sessions of a virtual or registered user has as much visibility as the authenticated sessions. It is therefore critical for the applications to apply the PAlogin parameter to enforce the authentication.

9.4.8 Globalization (NLS) Support

The Multi-Channel Server is a middle-tier server that is deployed between the device browser and the back-end web application. It communicates to the device and to the application through the HTTP(S) protocol.

In order to correctly do the character encoding/decoding for the requests/responses. the Multi-Channel Server must know the character encoding that both sides—device and application—use. These are the assumptions that the Multi-Channel Server makes when handling character encoding for each HTTP hop:

  1. First Request from the Device—MCS uses the Accepted Character Encodings attribute of the device browser to decode the request parameters sent by the browser.

  2. First Request from MCS to the Application—MCS does not know the character encoding that the Application expects. In this case, MCS UTF-8 character encoding for the very first request to the Application.

  3. First Response from the Application—MCS follows the Hypertext Transfer Protocol—HTTP/1.1 specification to detect the media type of the entity-body sent to the recipient. According to that specification, the sender should include Content-Type HTTP header and add a charset value indicating the content character set. For example:

    Content-Type: application/vnd.oracle.xhtml+xforms; charset=ISO-8859-4
    

    If the Content-Type header or the charset value are missing, then the MCS assumes ISO-8859-1 character encoding.


    Note:

    MCS remembers this character encoding value and will use it in subsequent requests to the Application.

  4. First Response from MCS—The MCS uses the Accepted Character Encodings attribute of the device browser to decode the request parameters sent by the browser.

  5. Subsequent Request from the Device—The MCS uses the Accepted Character Encodings attribute of the device browser to decode the request parameters sent by the browser.

  6. Subsequent Request from MCS to the Application—The MCS uses the same character encoding sent by the Application in the previous response.

  7. Subsequent Response from the Application—The MCS uses the same logic as explained in step 3. The Application must specify the character encoding again. The Application can use a different encoding (though this is not common).

  8. Subsequent Response from MCS—The MCS uses the Accepted Character Encodings attribute of the device browser to decode the request parameters sent by the browser.

Steps 5-8 repeat for all requests/responses after the first request/response.

In short, MCS always uses the Accepted Character Encodings device attribute to do the character encoding/decoding when communicating with a device. It always uses the charset value in the Content-Type HTTP header when communicating with the application. An exception from this rule is only the very first request from the MCS to the application when the MCS uses UTF-8 character encoding.

9.5 Modifying the Data Models

This section includes information on Wireless Services, and how to use them to provide the most efficient functionality to users.

9.5.1 Overview of OracleAS Wireless Services

Services enable end users to access the functionality of OracleAS Wireless. They represent a link between the content source and the delivery target. Services tie a specific data source (through an adapter) to the different devices.

There are different types of services:

  • MasterService—provides the actual implementation of the service. MasterServices specify the adapter used for the service and any service-specific parameters.

  • Link—a pointer to a service. In most cases Links are used to publish MasterServices to end users and to customize the MasterService parameters.

  • Module--a pointer to a MasterService with a known URL.

  • Folder--container for other services, including other Folders. Used to build service trees.

  • ExternalLink--a service that points to an external resource.

9.5.2 MasterService

MasterServices provide the basic wireless functionality. They are the actual implementation of the service. Each MasterService is based on one adapter. A MasterService sets values for the adapter init, input and output parameters. Each MasterService creates its own instance of the adapter it uses. Therefore, several services can use the same type of adapter, and each can pass its own service-specific argument values.

It is recommended that you build all MasterServices using the HTTPAdapter. That gives you the flexibility to implement the service business logic using JSPs or other web technologies.

9.5.2.1 Link

Links are used to further customize existing services by overriding the values of their parameters.

When a Link service is invoked the OracleAS Wireless server merges the parameters with the parameters of the service the Link points to, and invokes that service.

Links are also used to better organize services into user service trees. They give you the flexibility to publish the same service under different names and in different folders (different levels in the service tree). If you do not override any parameter values, then invoking the link is the same as invoking the service it points to.

9.5.2.2 Module

Modules are wireless services with well-known virtual URLs (OMP URL, that is, omp://my.module).

Modules can be called from any application or module and may be instructed to return control to another application or module. Calls may be nested to any level. This mechanism of bi-directional linking allows quick applications assembly.

An important difference between a module and a regular service is that the module receives information about the service it needs to return to after it is done. This is not always the caller of the module (the module caller may want the module to return to a different service).

9.5.2.3 Folder

Folders are containers for other services. They are used to better organize user-accessible services into a service tree. The content of a folder is displayed by invoking its rendering service; a special service associated with each folder.

The system rendering service displays the folder child services ordered by the specified sort rule.

Optionally, you can specify icons and audio files to be displayed or played when a service link is displayed in the folder content or when the service is invoked.

9.5.2.4 ExternalLink

An ExternalLink is a wireless service that points to an external resource. The external resource is typically a Web page that serves content in a format supported by the target device.

OracleAS Wireless does not process the content of the ExternalLink target. As a result, ExternalLink services are not available to all targeted devices, as are other wireless services. In most cases, ExternalLinks are set in the Customization portal by the end user, not in the Service Designer.

9.5.3 Access Control

There are two type of services in terms of access:

  • User Private Services—accessible by a single user.

  • Shared Services—accessible by multiple users.

There are different rules that apply to those two type of services.

  • The user private services are services that reside in the user home service tree. Users can access all of those services. No other user can access those services.

  • Shared services, in contrast, are accessed by multiple users. The access is controlled by the User - Group - Service relationship. When you assign a service to a group, all users from that group can access the service.

9.5.4 Folder Renderer

This section describes folder renderer.

9.5.4.1 Overview

Folder Renderer is a runtime component of OracleAS Wireless that is responsible for rendering the content of a folder. In order to provide customization possibilities to end users, the logic of the Folder Renderer component is externalized in the form of Folder Renderer Hook.

See the oracle.panama.rt.hook.FolderRendererHook Java interface for more details.

Out of the box, OracleAS Wireless provides a default implementation of the Folder Renderer Hook. The default implementation consists of multiple parts:

  • A system master service based on OC4J Adapter, which has a virtual URL of omp://oracle.iasw.folder.renderer.

  • A Java class that is responsible for looking up the master service and invoking it. The name of this Java class is oracle.panama.rt.hook.FolderRendererPolicy and it implements the interface FolderRendererHook.

  • A set of JSP pages. The master service points to a single JSP, with the relative URL of iaswfr/FolderRenderer.jsp, which acts as the point-of-entry to a set of JSP pages that is capable of rendering the content of a folder.

  • A utility Java class that contains a library of methods invoked by the JSP pages. The name of this Java class is oracle.panama.rt.hook.FolderRendererUtil.

The motivation of using a JSP-based folder renderer framework is to provide maximum customization possibilities to end users. With the logic of folder renderer written in JSP, end users can change the JSP pages easily without recompiling any Java code. The use of JSP-based Folder Renderer allows several possible levels of customization, which are listed below.

  • User can modify the JSP that is part of the default implementation.

  • User can create a new set of JSP pages and change the relative URL of the system master service to point to the new JSP pages.

  • User can create a new master service and a new set of JSP pages. In this approach, user replaces the default master service that is pointed by the virtual URL omp://oracle.iasw.folder.renderer with the new one.

  • Users can write their own implementation of the interface FolderRendererHook. The default implementation of this interface is oracle.panama.rt.hook.FolderRendererPolicy.

To be able to customize the Folder Renderer, users must understand the structure of the JSP pages and the execution flow.

9.5.4.2 Structure of JSP pages

The logical structure of the JSP pages is as follows:

  • The top level JSP page that acts as the entry point is FolderRenderer.jsp. From FolderRenderer.jsp, we check the device category of the connecting device and include the second level of appropriate JSP page.

  • This second level of JSP is named XXXRenderer.jsp, where XXX is the device category of the connecting device. XXXRenderer.jsp itself includes three JSP pages, which are XXXHeader.jsp, XXXBody.jsp, and XXXFooter.jsp.

For example, if the request is from WAP phone, FolderRenderer.jsp will include MicroBrowserRenderer.jsp, which then includes MicroBrowserHeader.jsp, MicroBrowserBody.jsp, and MicroBrowserFooter.jsp.

9.5.4.3 Execution Flow

The default implementation of Folder Renderer has the following execution flow:

  1. When the OracleAS Wireless runtime is ready to render a folder, it calls oracle.panama.rt.hook.FolderRendererPolicy invoke() method.

  2. The invoke() method uses the hard-coded value of virtual URL. omp://oracle.iasw.folder.renderer, looks up the master service, and invoke the master service. The master service is implemented as a JSP, which has a relative URL of iaswfr/FolderRenderer.jsp.

  3. The FolderRenderer.jsp is called and does the following:

    • Gets all the necessary information (such as ServiceContext, Session, User, Device) from the request and stores it. This information will be used by other JSP pages that are included from FolderRenderer.jsp.

    • Checks which device category the connecting device belong to and includes the appropriate JSP page (explained above).

  4. The included JSP pages will render the content of the current folder.

9.5.5 Bookmark

OracleAS Wireless Server can be used to manage user bookmarks on the server side. Each bookmark refers to a Data Source (URL) whose returned content can be in any device-specific markup language. In OracleAS Wireless Server, users and administrators can place bookmarks anywhere in the user service tree.

Each Bookmark is a logical entry and can contain multiple URLs corresponding to different markup languages. For example, a Yahoo bookmark can contain a URL http://www.yahoo.com for HTML markup language and URL http://wap.yahoo.com for WML markup language. If a user accesses the Yahoo bookmark from a device supporting WML markup language, then the content from the http://wap.yahoo.com URL is returned to the device. If the Yahoo bookmark is accessed from a device supporting HTML language then the content from the http://www.yahoo.com URL is returned.

Each markup language can be uniquely identified by its MIME-type. Internally OracleAS Wireless Server stores bookmarks <URL, markup language> combinations as <URL, MIME-type> combinations.

Bookmarks are integrated with the wireless transcoding API that allows WML content (text/vnd.wap.wml MIME-type) to be converted to OracleAS Wireless XML, and then converted to any device-specific markup language supported by the OracleAS Wireless Server.

Depending on the MIME-type associated with the URL, some URLs are accessed directly from the user's device and some URLs are accessed through OracleAS Wireless. Currently only URLs associated with the text/vnd.wap.wml MIME type are accessed through OracleAS Wireless Server. This list will be extended when the transcoding API supports more input markup languages.

Additionally, any URL of a bookmark can be marked as a default URL. If a device accesses a bookmark which does not have a URL corresponding to the markup language supported by the device, then OracleAS Wireless Server invokes the default URL, transcodes the content to OracleAS Wireless XML, which is again transformed to the markup language supported by the device.

The markup language of the content returned by the default URL must be supported by the wireless transcoding API (that is, only WML text/vnd.wap.wml MIME-type content can be used in the default URL).

There are several ways to access a URL stored in a bookmark, depending on the user device and the MIME-types that are supported by that Bookmark (that is, the MIME-types for which there are associated URLs):

  • The user's device supports WML content type and there is a URL associated with text/vnd.wap.wml MIME type. In this case the user's device accesses the URL through the OracleAS Wireless Server. The WML content is not modified, except that all relative URLs are rewritten to point back to the OracleAS Wireless Server. All subsequent requests go through OracleAS Wireless Server.

  • The user's device supports a markup language other than WML and there is a corresponding URL for that MIME type in the bookmark. In this case, the URL is accessed directly from the user's device without coming to OracleAS Wireless Server (that is, the user leaves the wireless portal).

  • The user's device supports a markup language other than WML, there is no URL in the Bookmark associated with that markup language, but there is a default URL (with text/vnd.wap.wml MIME type). In this case the user's device sends a request to OracleAS Wireless Server. The server fetches the WML content, transcodes the WML to OracleAS Wireless XML, and then converts the OracleAS Wireless XML to the device-specific markup language and sends the response back to the device. This is repeated for all subsequent requests.

  • The user's device supports a markup language for which there is no corresponding URL in the bookmark and there is no default URL. In this case the default FolderRenderer will not display a link for invoking that bookmark and the user will not see it.

9.5.5.1 Creating and Editing Bookmarks Using OracleAS Wireless Tools

Users can use OracleAS Wireless Tools (or Customization Portal) to create, edit and delete bookmarks.

9.5.6 Model API: General Usage

OracleAS Wireless Repository comprises the models for the Model-View-Control (MVC) architecture, while the OracleAS Wireless Runtime layer comprises the controllers for the MVC. The repository Model API in oracle.panama.model package lets you develop applications that create, delete, modify, and query the persistent objects in the OracleAS Wireless Repository.

OracleAS Wireless Repository imposes the organizational structure among the objects. For example, a user can belong to multiple Groups. Each user is assigned one or more Roles. A user can access the services that are accessible to the groups to which the user belongs. However, the implementations of the user interface can access external provisioning systems or repositories, such as the Oracle Internet Directory (OID) and the Oracle Applications User Repository (AOL), to manage the information for enterprise users and specify the user's roles, the user's group membership, and the particular services that are accessible to that user.

A Folder is a special kind of Service used as a container of the services to build the service trees. A Service or Folder can be assigned to one or more groups. A user can own a collection of DeviceAddresses, a collection of LocationMarks, a collection of Customization Profiles, and one or more collections of Presets which are used in advanced customization. A default LocationMark and a default Profile can be assigned for each user. The Device interface in the Model API defines the target device protocol (such as: WAP, SMS, or E-MAIL), as well as specifies the physical characteristics of target devices that can be used by the adapters and the transformers (for example, screen width and height, screen columns and rows, and number of softkeys).

The intended users of the Model API are developers of customization portals, portlets, custom hooks, listeners, and applications such as JSPs, servlets, modules, and other (URL addressable) resources that are invoked through the HTTP Adapter. Developers can also develop standalone applications which manipulate persistent objects using the Model API. Although these interfaces preserve the data integrity in the repository, they do not enforce access control security. The applications that access the repository through the Model API are not authenticated or authorized by the same Authentication and Authorization mechanisms in the OracleAS Wireless runtime layer. In fact, the Model APIs are used by trusted components to develop and customize authentication and authorization policies. OracleAS Wireless Tools provide authentication and authorized access control to the repository. Developers should apply extreme caution when developing services using the interfaces in the Model API, and should take appropriate measures to prevent any undesired side-effects when these services are invoked by the end users.


Note:

If you use the Wireless model API, and make changes to Wireless cache-persistent objects, you must ensure that stale copies of objects do not remain in one or more of your caches.

Caching is done in per each JVM; when you custom-deploy Wireless, multiple JVMs are created. These JVMs must be synchronized to eliminate the possibility of stale copies of objects existing in caches.

Include the following code (only needed once, not multiple times for multiple JVMs) in your web application file (web.xml) to ensure that the changes are propagated across all web applications:

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><filter-mapping>...</filter-mapping><listener><listener-class>oracle.panama.servlet.CacheManagerListener</listener-class></listener><servlet>...</servlet><!-- ... --></web-app>


9.5.6.1 Data Model Cache and Synchronization

Repository objects are cached in the Java instances main memory when they are accessed from the Data Model API. These objects are removed from the main memory cache only after they are not accessed through the API for a time-to-live interval. This interval can be configured from Cache Object Life Time property in System Manager > Site > Runtime Configuration control panel in the OracleAS Wireless Tools. If the repository object is modified and committed into the repository from one of the Java instances; all other Java instances will automatically reload the modified object from the repository. You can specify the number of cache synchronization threads from System Manager > Site > Object Cache Synchronization control panel in the OracleAS Wireless Tools.

9.5.6.2 Interfaces and Interface Hierarchy

The ModelObject is the root interface that represents the common behavior and properties of all repository objects. It is included in the oracle.panama.model package.

9.5.6.3 Model API Inheritance Hierarchy

The oracle.panama.model package also provides the following three locator and factory objects to access the model objects:

  • MetaLocator—the starting point for using the Model API. From this call you can get references to the ModelFactory and ModelServices interface implementations.

  • ModelFactory—a factory to create model objects.

  • ModelServices—the locator to access model objects.

Here is a brief description of the different model interfaces. For more details about the interfaces please refer to the model API Specification.

  • Adapter—the repository container for the RuntimeAdapter, which is the interface that is to be implemented by all custom adapters. The Adapter incorporates the RuntimeAdapter classes into the repository and supports the loading and initialization of the RuntimeAdapter.

  • DeviceV2—the definition of the target logical device protocol. It can, for example, be WML11 for WML specific devices, but also WML_Nokia7110 for Nokia specific WML. Other examples are SMS and E-MAIL. DeviceV2 contains the Transformer objects.

  • User—represents the identity of the user and facilitates personalization in the OracleAS Wireless portals.

  • Profile—users can have one or more Profiles that encompass customizations of the service trees. The Profile for a user can specify a preferred ordering of services in a folder.

  • Group—a collection of users. It is used to publish specific services to group members. A user can access services that are accessible to the group to which the user belongs.

  • Role—like a Group, a role is a collection of users. But while groups are used for the access control at run-time, Roles are used to control the access to different webtools.

  • Service—an abstract interface and handles all generic aspects of a service. It contains the following subinterfaces:

    • MasterService—the final Service. It is the template for all other Services. It always uses an adapter to communicate with an external source.

    • Folder—similar to a directory in a file system; it contains other services including other sub-folders.

    • ExternalLink—a logical reference to an external URL. One ExternalLink can refer to one URL per channel, or multiple channels can shared a single URL.

    • LocalModule—a pointer to a modulable MasterService.

    • Link—a pointer to any other service including another Link. The Link is used to customize MasterServices or to create private tree structures of accessible MasterServices. It can override any accessible parameter kept by the service chain down to the final master service.

  • LocationMark— a persistent object that represents the named a geocoded physical address.

  • Transformer—the base interface for all transformation sub-classes. It is the repository container for the real transformation implementation (Java or XSL). It performs loading and initialization of the custom transformer classes that implements the oracle.panama.rt.xform.RtTransformer interface. It also provides the XSLT transformers for the XSLT stylesheets.

    It has the following subinterfaces:

    • JavaTransformer—a class that implements the Transformer interface and is expected to handle the transformation from the device independent markup language to the device-specific markup language. It incorporates the oracle.panama.xform.RtTransformer classes into the repository. It performs loading and initialization of the custom transformer classes that implements the oracle.panama.rt.xform.RtTransformer interface.

    • XSLTransformer—uses XSLT stylesheet which is expected to handle the transformation from the device independent markup language to the device-specific markup language. It incorporates the custom XSLT stylesheets into the repository. It also provides the XSLT processors for the XSLT stylesheets.

9.5.6.4 Sample Code that Uses the Data Model API

The following sample code illustrates how you can provision new objects into the OracleAS Wireless repository using the interfaces in the Model API. The example includes the standalone class to introduce the sample codes, although other type of components, such as adapters, hooks, listeners, and servlets can be used to illustrate the Model API. The example only shows the search, create, delete, and commit operations in the Model API but does not include the necessary business logics.

The numbers that appear in brackets next to a line of code in Example 9-11 are referenced in the discussion to correlate the explanation with the corresponding lines in the code itself.

Example 9-11 MetaLocator interface

Use MetaLocator to get the ModelFactory and ModelServices (line [1]). 
Use ModelFactory to create a new object.
Use ModelServices to search for an object. 
MetaLocator metaLocator = MetaLocator.getInstance(); 
modelFactory = metaLocator.getModelFactory();
modelServices = metaLocator.getModelServices();

The MetaLocator interface is used to lookup the ModelFactory and ModelServices. The getInstance() method in this interface gets the singleton instance of this MetaLocator. The methods getModelFactory and getModelServices look up the ModelFactory and the ModelServices.

Typically, to create a new object, one should check first if the object already exists. To look up any object, use the ModelServices interface and the method lookupX(Java.lang.String name), where X is the interface name of the object. In this sample code, to create a new user (the code section for creating a new user starts in line [2]), you first look up the user by using the lookupUser(userName) method in the ModelServices interface (line [3]), as the following line of code shows:

modelServices.lookupUser(userName); 

Lookup operation should be the first step before creating any new persistent object in the Repository. The lookupUser(userName) method searches for the user by name and, if the User by that name is found, returns the User object. If the user with that name cannot be found, the method throws the PanamaRuntimeException.

Next, check if the group to which the user belongs (or should belong) already exists (line [4]). Following the convention for looking up any object, you use the ModelServices interface and the lookupGroup(groupName) method to look up a group by name. If the group is found, the method returns the Group object. If the group is not found, the method throws the PanamaRuntimeException.

After checking if the user and the group already exist, you create the new user object (Example 9-12) (line [5] to line [6]):

Example 9-12 Creating a new user object

{
     user = modelFactory.createUser(userName, groups); 
} else {
     user = modelFactory.createUser(userName);
}
user.setPassword(userPassword);
user.setEnabled(true); 

You must save the newly created user. Each newly created object must be saved after it is created (line [7]):

modelFactory.save();

Save applies to all created or modified objects in the current thread. The objects are saved to the persistent storage and the transaction is committed. The method throws PanamaException if it is unable to save the work.

The searchUser() method in the sample code (line [8]) illustrates how to search a User object. To enumerate over a set of users (for example, all the users whose names start with the letter B), you use the ResultSetEnumeration (line [9]) returned by the method findUsers (line [10]). The method findUsers uses the pattern matching on the names. See also lines [11] and [12] in the listing of the complete sample code.

Close the ResultSetEnumeration (line [13]) to release the database cursor, which otherwise will remain open.

To delete a user, use the deleteUser method following the sample code section in line [14]. The user name must be exact in line [15]. ModelServices.lookupUser() method rejects the pattern matching templates by throwing exceptions. The user object is deleted in line [16].

Example 9-13 Deleting users

import Java.util.Vector;
 
import oracle.panama.PanamaException;
import oracle.panama.PanamaRuntimeException;
 
import oracle.panama.model.MetaLocator;
import oracle.panama.model.ModelFactory;
import oracle.panama.model.ModelServices;
import oracle.panama.model.ResultSetEnumeration;
import oracle.panama.model.User;
import oracle.panama.model.Group;
 
 
/**
 * This is a sample program demonstrates the usage of the model API.
 */
public class SampleModelClient {
 
    private ModelFactory modelFactory;
    private ModelServices modelServices;
    
    public SampleModelClient() {
        MetaLocator metaLocator = MetaLocator.getInstance();       [1]
        modelFactory = metaLocator.getModelFactory();
        modelServices = metaLocator.getModelServices();
    }
	
    /**
     * Get all group names
     */
    private String[] getGroupNames() throws PanamaException, PanamaRuntimeException {
        String[] names;
        ResultSetEnumeration result = null;
        try {
            // Find all user groups - use a wildcard for the name expression
            result = modelServices.findGroups("*");
            Vector buffer = new Vector();
            while (result.hasMoreElements()) {
                Group group = (Group)result.next();
                String name = group.getName();
                buffer.addElement(name);
            }
            names = new String[buffer.size()];
            buffer.copyInto(names);
        } catch (PanamaRuntimeException ex) {
            throw ex;
        } finally {
            if (result != null) {
                result.close();
                result = null;
            }
        }
        return names;
    }
 
    /**
     * Create a new user.
     */
    private void createUser(String userName, String userPassword, String groupName)    [2]
                           throws PanamaException, PanamaRuntimeException {
        try {
            // First check if the user does not already exists
            modelServices.lookupUser(userName);                    [3]
            // If we are here the user must already exists
            return;
        } catch (PanamaRuntimeException ignore) {}
        Group group = null;
        try {
            // Get the group to add the user
            group = modelServices.lookupGroup(groupName);          [4]
        } catch (PanamaRuntimeException ex) {
            // A PanamaRuntimeException is thrown if the group is not found
            group = null;
        }
        User user;
        // modelFactory.createUser() will automatically create a
        // home folder for the new user.
        if (group != null) {
            Group[] groups = new Group[1];
            groups[0] = group;
            user = modelFactory.createUser(userName, groups);      [5]
        } else {
            user = modelFactory.createUser(userName);
        }
        user.setPassword(userPassword);
        user.setEnabled(true);                                     [6]
 
        // save the newly created object
        modelFactory.save();                                       [7]
    }
 
    /**
     * Search for users.
     */
    private User[] searchUser(String userNamePattern)              [8]
                              throws PanamaException, PanamaRuntimeException {
        User[] users;
        ResultSetEnumeration result = null;                        [9]
        try {
            result = modelServices.findUsers(userNamePattern);     [10]
            Vector buffer = new Vector();
            while (result.hasMoreElements()) {                     [11]
                User user = (User) result.next();                  [12]
                buffer.addElement(user);
            }
            users = new User[buffer.size()];
            buffer.copyInto(users);
        } catch (PanamaRuntimeException ex) {
            throw ex;
        } finally {
            if (result != null) {
                result.close();                                    [13]
                result = null;
            }
        }
        return users;
    }
 
    /**
     * Delete a user.
     */
    private void deleteUser(String userName)                       [14]
                            throws PanamaException, PanamaRuntimeException {
        try {
            if (userName != null && userName.length() > 0) {
                User user = modelServices.lookupUser(userName);    [15]
                user.delete();                                     [16]
                
                // Save the changes
                modelFactory.save();
            }
        } catch (PanamaRuntimeException ex) {
            throw ex;
        }
    }
 
}

9.5.7 Wireless Model API Deployment and CLASSPATH

When using Wireless model APIs in an application deployed in a container other than OC4J_Wireless, this error may appear: JAVA.LANG.CLASSNOTFOUNDEXCEPTION: ORACLE.PANAMA.CORE.MODELSERVICESIMPL.

This occurs when the CLASSPATH is set incorrectly. The CLASSPATH must contain paths that enable access to the Wireless libraries.


Note:

This can be done after application deployment, using the Enterprise Manager.

9.5.7.1 Adding Custom Paths

To add or edit custom paths (for OC4J instances that have access to Wireless public APIs) using Enterprise Manager, follow these steps:

  1. Log in to an EM standalone console and create a new OC4J instance (or modify an existing OC4J instance) to add the custom CLASSPATH.

  2. Click the OC4J instance container (in this case OC4J_Wireless). Or, click Create OC4J Instance, and give it a unique name to create a new instance of OC4J Wireless.

9.5.7.1.1 Adding CLASSPATH to an OC4J Instance

To add CLASSPATH information to the OC4J instance (globally for all .EAR files):

  1. Click Administration to administer this OC4J Instance.

  2. Click Global Web Module.

  3. Click General.

  4. Add the custom classes directory (or .JAR file) by clicking Add Another Row in the Class Paths section.

  5. Enter the path for each library (or classes directory). These Wireless paths must be added to enable access to the Wireless libraries:

    ORACLE_HOME/wireless/server/classes ORACLE_HOME/wireless/bin/internal ORACLE_HOME/wireless/lib/wireless.jar ORACLE_HOME/wireless/lib/wireless_drm.jar

9.5.7.1.2 Adding CLASSPATH to a Deployed EAR File

To deploy a new ear file:

  1. Click Applications.

  2. Use the Deploy EAR File button to follow the wizard.

To add to the classpath of a deployed EAR file:

  1. Click on the ear file (in this case wireless and click the General link in Administration at the bottom.

  2. Add the custom classes directory (or jar file) using by clicking Add Another Row in the Library Path section. Enter the path for each library or classes directory. These Wireless paths must be added to enable access to the Wireless libraries:

    ORACLE_HOME/wireless/server/classes ORACLE_HOME/wireless/bin/internal ORACLE_HOME/wireless/lib/wireless.jar ORACLE_HOME/wireless/lib/wireless_drm.jar