ovidiu 02/01/09 14:20:42
Modified: src/documentation/xdocs/developing book.xml
src/java/org/apache/cocoon cocoon.roles
src/java/org/apache/cocoon/transformation
TraxTransformer.java
src/webapp cocoon.xconf sitemap.xmap
src/webapp/docs/samples samples.xml
Added: src/documentation/xdocs/developing deli.xml deliquick.xml
src/java/org/apache/cocoon/components/deli Deli.java
DeliImpl.java
src/webapp deliCocoonConfig.xml legacyDevice.xml
src/webapp/stylesheets deli_test.xsl
Log:
Added support for Deli, a CC/PP and UAProf support library by Mark Butler
<[EMAIL PROTECTED]>.
Revision Changes Path
1.2 +2 -0 xml-cocoon2/src/documentation/xdocs/developing/book.xml
Index: book.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/documentation/xdocs/developing/book.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- book.xml 3 Jan 2002 12:31:02 -0000 1.1
+++ book.xml 9 Jan 2002 22:20:42 -0000 1.2
@@ -15,6 +15,8 @@
<menu-item label="Avalon" href="avalon.html"/>
<menu-item label="Using Databases" href="datasources.html"/>
<menu-item label="Parent CM" href="parent-component-manager.html"/>
+ <menu-item label="Deli quick start" href="deliquick.html"/>
+ <menu-item label="CC/PP and UAProf" href="deli.html"/>
</menu>
<menu label="Java">
1.1 xml-cocoon2/src/documentation/xdocs/developing/deli.xml
Index: deli.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XML Spy v3.0.7 NT (http://www.xmlspy.com) by Mark Butler
(Hewlett-Packard Laboratories UK) -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"dtd/document-v10.dtd">
<document>
<header>
<title>DELI: A Delivery Context Library for CC/PP and UAProf</title>
<authors>
<person name="Mark H. Butler" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Introduction">
<p>In order for a web server
to provide optimized content to different clients it requires a description of the
capabilities of the client. Two new compatible standards have been created for
describing delivery context based on the
<link href="http://www.w3.org/RDF/">Resource Description Framework (RDF)</link>:
<link href="http://www.w3.org/Mobile/CCPP/">Composite Capabilities / Preferences
Profile (CC/PP)</link>
created by the <link href="http://www.w3.org">W3C</link> and
<link
href="http://www1.wapforum.org/tech/terms.asp?doc=WAP-248-UAProf-20010530-p.pdf">User
Agent Profile (UAProf)</link>
created by the
<link href="http://www.wapforum.org">WAP Forum</link>.
These standards allow the efficient transmission of
delivery context information to the server even via low bandwidth wireless networks.
Instead of sending an entire profile with every request,
a client only sends a reference to a profile, stored on a third device known
as a profile repository, along with a list of differences specific to this
particular
client. The process of reassembling the final profile from
the profile references and differences is known as profile resolution.</p>
<p><link href="http://www-uk.hpl.hp.com/">HP Labs</link>
has produced an open-source library called DELI that allows Java servlets to resolve
HTTP requests
containing CC/PP or UAProf information and query the resolved
profile. This document describes how DELI may be used
within Apache Cocoon. For more information on the DELI library please refer to the
<link href="http://www-uk.hpl.hp.com/people/marbut/">DELI web-site</link>.
DELI currently uses
<link href="http://www.hpl.hp.com/semweb/jena-top.html">Jena</link>, an RDF
Framework developed at HP Labs. For more details of Jena see Brian McBride's
<link href="http://www-uk.hpl.hp.com/people/bwm/papers/20001221-paper/">paper</link>
and the HP Labs
<link href="http://www.hpl.hp.com/semweb/">Semantic Web activity</link> homepage.</p>
</s1>
<s1 title="CC/PP">
<p>CC/PP is described in
<link href="http://www.w3.org/TR/CCPP-struct-vocab/">CC/PP Structure and
Vocabularies</link>,
<link href="http://www.w3.org/TR/2000/WD-CCPP-ra-20000721/">CC/PP Requirements and
Architecture</link> and
<link href="http://www.w3.org/TR/2000/WD-CCPP-ta-20000721/">CC/PP Terminology and
Abbreviations</link>.
A CC/PP profile is broadly constructed as a two level hierarchy:
a profile has a number of components and each component has a number
of attributes. A proposed
(and largely deprecated) protocol for CC/PP is described in
<link href="http://www.w3.org/TR/NOTE-CCPPexchange">CC/PP exchange protocol using
HTTP extension framework</link> and
<link
href="http://search.ietf.org/internet-drafts/drafts-hjelm-http-cnhttp-scenarios-00.txt">Content
Negotiation Header in HTTP Scenarios</link>.
The protocol work has been
deprecated because the CC/PP Working Group was not chartered by
the W3C to do protocol work. In addition this protocol uses
<link href="http://www.w3.org/Protocols/HTTP/ietf-http-ext/">HTTP-ex</link> which
means it
is incompatible with existing HTTP web servers. Therefore it is suggested that
people requiring CC/PP functionality should use the W-HTTP protocol
used by UAProf. This has identical functionality to the deprecated CC/PP protocol
based on HTTP-ex, but
will work with existing HTTP servers. Hopefully when the CC/PP Working Group is
recharted to work
on protocols, it will propose a protocol compatible with HTTP/1.1 similar to
W-HTTP.</p>
</s1>
<s1 title="UAProf">
<p>The UAProf specification is based on the CC/PP
specification. Like CC/PP,
a UAProf profile is a two level hierarchy composed of components and
attributes. Unlike CC/PP, the UAProf specification also proposes a vocabulary
- a specific set of components and attributes - to describe the next
generation of WAP phones.
The specification also describes two protocols for transmitting the profile
from the client to the server. Currently DELI only supports one of the UAProf
protocols, as the other is based on HTTP-ex so is incompatible with existing
web servers. </p>
<p>Profiles using the UAProf vocabulary consist of six
components:
HardwarePlatform, SoftwarePlatform, NetworkCharacteristics, BrowserUA,
WapCharacteristics and PushCharacteristics. These components contain attributes.
In DELI each attribute has a distinct name and has an associated collection type,
attribute type and resolution rule. In UAProf there are three collection types:</p>
<ul>
<li><code>Simple</code> contains a single
value e.g. ColorCapable in HardwarePlatform. </li>
<li><code>Bag</code> contains multiple
unordered values e.g. BluetoothProfile in the
HardwarePlatform component.</li>
<li><code>Seq</code> contains multiple ordered
values e.g. Ccpp-AcceptLanguage
in the SoftwarePlatform component.</li>
</ul>
<p>In addition attributes can have one of four
attribute types:</p>
<ul>
<li><code>String</code> e.g. BrowserName in
BrowserUA.</li>
<li><code>Boolean</code> e.g. ColorCapable in
HardwarePlatform.</li>
<li><code>Number</code> is a positive integer
e.g. BitsPerPixel in HardwarePlatform.</li>
<li><code>Dimension</code> is a pair of
positive integers e.g. ScreenSize in HardwarePlatform.</li>
</ul>
<p>Finally attributes are associated with a resolution
rule:</p>
<ul>
<li><code>Locked</code> indicates the final
value of an attribute is the first
occurrence of the attribute outside the default description block.</li>
<li><code>Override</code> indicates the final
value of an attribute is the last occurrence
of the attribute outside the default description block.</li>
<li><code>Append</code> indicates the final
value of the attribute is the
list of all occurrences of the attribute outside the default
description block.</li>
</ul>
<p>The UAProf vocabulary is described using the file
<code>uaprofspec.xml</code>.
This describes the attribute name, component,
collectionType, attributeType and resolution rule of each component.
The vocabulary description file has the following format:</p>
<source><![CDATA[
<?xml version="1.0"?>
<vocabspec>
<attribute>
<name>CcppAccept</name>
<component>SoftwarePlatform</component>
<collectionType>Bag</collectionType>
<attributeType>Literal</attributeType>
<resolution>Append</resolution>
</attribute>
</vocabspec>
]]></source>
</s1>
<s1 title="W-HTTP Protocol">
<p>An
example W-HTTP request using this protocol is shown below:</p>
<source><![CDATA[
GET /ccpp/html/ HTTP/1.1
Host: localhost
x-wap-profile:"http://127.0.0.1:8080/ccpp/profiles/test09defaults.rdf",
"1-Rb0sq/nuUFQU75vAjKyiHw=="
x-wap-profile-diff:1;<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:prf="http://www.wapforum.org/profiles/UAPROF/ccppschema-20010430#">
<rdf:Description rdf:ID="MyDeviceProfile">
<prf:component>
<rdf:Description rdf:ID="HardwarePlatform">
<rdf:type
rdf:resource="http://www.wapforum.org/profiles/UAPROF/ccppschema-
20010426#HardwarePlatform"/>
<prf:BitsPerPixel>16</prf:BitsPerPixel>
</rdf:Description>
</prf:component>
</rdf:Description>
</rdf:RDF>
]]></source>
<p>The first two lines
describe the resource that is being requested by the client,
http://localhost/ccpp/html, and the method being used to make
the request, GET, and the protocol being used HTTP/1.1. The
remaining lines of the request describe the device delivery context.
This is specified using a profile reference and a profile-diff.
The profile is referenced via the x-wap-profile line and has the URI</p>
<source><![CDATA[
http://127.0.0.1:8080/ccpp/profiles/test09defaults.rdf.
]]></source>
<p>After the profile reference, there is a value</p>
<source><![CDATA[
1-Rb0sq/nuUFQU75vAjKyiHw==
]]></source>
<p>known as a profile-diff digest.
The first part of the profile-diff-digest, 1-, is the profile-diff
sequence number. This is used to indicate the order of the
profile-diffs and to indicate which profile-diff the profile-diff
digest refers to. The remainder of the profile-diff digest is
generated by applying the
<link href="http://www.faqs.org/rfcs/rfc1321.html">MD5 message digest
algorithm</link> and Base64
algorithm to the corresponding profile-diff. The MD5 algorithm
takes as input a message of arbitary length and produces as output
a 128-bit "fingerprint" or "message-digest" of the input.
The
<link href="http://www.faqs.org/rfcs/rfc2045.html">Base64 algorithm</link> takes as
input arbitary binary data and
produces as output printable encoding data.</p>
<p>After the profile-diff digest, the next line
contains the
x-wap-profile-diff. This request header field also has a
profile-diff sequence number which indicates that this
profile-diff corresponds to the previous
profile-diff-digest. The profile-diff itself consists of the XML
fragment which spans the remainder of the request. Multi-line
request header fields are permitted by the HTTP/1.1 specification
as long as each subsequent line starts with either a tab character
or a whitespace. </p>
<p>When the server receives a HTTP request with UAProf
request headers, it has to perform profile resolution
i.e. retrieve the referenced profile(s) and any further
profiles referenced via default blocks. It then has to
merge these profiles and the profile-diffs while
applying the UAProf resolution rules.</p>
</s1>
<s1 title="Configuring DELI">
<p>In order to use DELI, you need to enable the DELI component in the
<code>cocoon.xconf</code> file
and configure TraxTransformer in the <code>sitemap.xmap</code> file to supply the
CC/PP profile to a stylesheet via parameters.
In addition, you may want to configure DELI using <code>deliCocoonConfig.xml</code>,
the DELI
configuration file or <code>legacyDevices.xml</code>, the
DELI legacy device support file.</p>
<s2 title="Cocoon.xconf">
<p>In order to use DELI you need to specify
the configuration file and set the use-deli parameter to true in
<code>cocoon.xconf</code>:</p>
<source><![CDATA[
<deli>
<parameter name="deli-config-file" value="deliCocoonConfig.xml"/>
<parameter name="use-deli" value="true"/>
</deli>
]]></source>
</s2>
<s2 title="Sitemap.xmap">
Then to provide the resolved DELI profile as a parameter in stylesheets, you need
to configure TraxTransformer to use DELI in <code>sitemap.xmap</code>:
<source><![CDATA[
<map:transformers default="xslt">
<map:transformer name="xslt"
src="org.apache.cocoon.transformation.TraxTransformer"
pool-max="32" pool-min="16" pool-grow="4">
<use-request-parameters>false</use-request-parameters>
<use-browser-capabilities-db>false</use-browser-capabilities-db>
<use-deli>true</use-deli>
</map:transformer>
]]></source>
</s2>
<s2 title="Main Configuration File">
<p>DELI also has its own
configuration file has the following format:</p>
<source><![CDATA[
<?xml version="1.0"?>
<deli>
<debug>false</debug>
<printDefaults>false</printDefaults>
<printProfileBeforeMerge>false</printProfileBeforeMerge>
<legacyDeviceFile>legacyDevice.xml</legacyDeviceFile>
<vocabularyFile>uaprofspec.xml</vocabularyFile>
</deli>
]]></source>
<p>This file can contain a number of configuration
directives described in
in the following sections:</p>
<s3 title="Caching options">
<p>The caching options control how the server
caches referenced profiles. DELI can either cache
profiles indefinitely or update stale profiles after a set
interval. It is also possible to configure the maximum size
of the profile cache.</p>
<table>
<tr>
<th>Element Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>
<tr>
<td>maxCachedProfileLifetime</td>
<td>24 hours</td>
<td>The maximum lifetime of a
cached profile in hours.</td>
</tr>
<tr>
<td>maxCacheSize</td>
<td>100</td>
<td>The maximum number of
profiles in the profile cache.</td>
</tr>
<tr>
<td>refreshStaleProfiles</td>
<td>false</td>
<td>Do we refresh cached
profiles after the maximum lifetime has expired?</td>
</tr>
</table>
</s3>
<s3 title="Debugging options">
<p>The debugging options are used to control
the
information that DELI prints to the Servlet engine console.</p>
<table>
<tr>
<th>Element Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>
<tr>
<td>debug</td>
<td>true</td>
<td>Is the automatic debug log
information turned on?</td>
</tr>
<tr>
<td>printDefaults</td>
<td>true</td>
<td>Print both default and
override values of attributes for debugging purposes?</td>
</tr>
<tr>
<td>printProfileBeforeMerge</td>
<td>false</td>
<td>Print the profile before
merging for debugging purposes?</td>
</tr>
</table>
</s3>
<s3 title="Legacy device options">
<p>As already mentioned DELI can support
legacy devices
by recognising the user-agent string supplied by a client
and mapping it on to a profile. In order to use this facility
it is necessary to supply an XML file that contains information
about legacy device user-agent strings and the corresponding
profile URLs. The format for the legacy device file is
described in a subsequent section. </p>
<table>
<tr>
<th>Element Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>
<tr>
<td>supportLegacyDevices</td>
<td>true</td>
<td>Is the legacy device
database turned on?</td>
</tr>
<tr>
<td>legacyDeviceFile</td>
<td>legacyDevice.xml</td>
<td>The file containing the
legacy device database.</td>
</tr>
</table>
</s3>
<s3 title="Protocol options">
<p>It is
possible to switch on whitespace normalisation in profile-diffs
prior to calculating the profile-diff-digest so that additional
whitespaces added by the proxy are ignored. To use this option clients must also
support whitespace normalisation.</p>
<table>
<tr>
<th>Element Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>
<tr>
<td>normaliseWhitespaceInProfileDiff</td>
<td>true</td>
<td>Is whitespace
normalisation of the profile-diff prior to calculating the profile-diff-digest turned
on?</td>
</tr>
</table>
</s3>
<s3 title="Vocabulary options">
<p>DELI has a number of vocabulary options.
Firstly
it is possible to configure the vocabulary using an
XML file. Secondly it is possible to
specify the URI to be used for the RDF namespace and the
CC/PP or UAProf namespace. This is important because as
the specifications are revised they adopt new namespaces.
Thirdly it is possible to set the string used to represent
components and defaults in the vocabulary. This is important
because the two standards currently use different cases for
the first letter of default elements (CC/PP uses "default"
whereas UAProf uses "Default"). </p>
<table>
<tr>
<th>Element Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>
<tr>
<td>vocabularyFile</td>
<td>uaprofspec.xml</td>
<td>The file containing the
vocabulary specification.</td>
</tr>
<tr>
<td>ccppUri</td>
<td>http://www.wapforum.org/profiles/UAPROF/ccppschema-20010430#</td>
<td>The namespace used for
CC/PP constructs such as component.</td>
</tr>
<tr>
<td>rdfUri</td>
<td>http://www.w3.org/1999/02/22-rdf-syntax-ns#</td>
<td>The namespace used for RDF
constructs.</td>
</tr>
<tr>
<td>componentProperty</td>
<td>component</td>
<td>The name for
components.</td>
</tr>
<tr>
<td>defaultProperty</td>
<td>Default</td>
<td>The name for defaults</td>
</tr>
</table>
</s3>
</s2>
<s2 title="Configuring Legacy Devices">
<p>It is easy to configure DELI to recognise legacy
devices via user-agent strings. The legacy device configuration file maps user-agent
strings on to profile references on a profile repository.
By default this is done in the <code>legacyDevice.xml</code> file, although it is
possible to select a different file.
The legacy device configuration file has the following format:</p>
<source><![CDATA[
<?xml version="1.0"?>
<devices>
<legacyDevice>
<useragentstring>MSIE</useragentstring>
<profileref>http://localhost:8080/cocoon/resources/legacyProfiles/msie.rdf</profileref>
</legacyDevice>
</devices>
]]></source>
<p>Where <code>useragentstring</code> is a device
unique string found in
the user-agent string of the device and <code>profileref</code> is a URL
for the appropriate profile on a profile repository. </p>
</s2>
</s1>
<s1 title="Writing CC/PP and UAProf aware stylesheets">
<p>Once you have got DELI running on Cocoon, the next
step in creating a CC/PP aware site is to create some stylesheets that
use profile information. DELI makes CC/PP or UAProf attributes available
to XSLT stylesheets as parameters. As CC/PP attributes are unique
within a profile, the component information is omitted. Hence to retrieve the
<code>CcppAccept</code> attribute you use the XPath
<code>deli-capabilities/browser/CcppAccept</code>
whereas to retrieve the <code>ScreenSize</code> attribute you use the
XPath <code>deli-capabilities/browser/ScreenSize</code>.
In addition where attributes contain multiple values e.g. Bags or Sequences
those values are separated using <code><![CDATA[<li>]]></code> elements.
Hence to retrieve the individual elements you use the XPath
<code>deli-capabilities/browser/CcppAccept/li</code>.
The following code demonstrates how to retrieve both a simple and a complex
attribute:</p>
<source><![CDATA[
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="deli-capabilities"/>
<xsl:template match="/">
<xsl:if test="contains($deli-capabilities/browser/CcppAccept/li,'wml')">
<xsl:call-template name="wmldevice"/>
</xsl:if>
<xsl:if test="not(contains($deli-capabilities/browser/CcppAccept/li,'wml'))">
<xsl:call-template name="htmldevice"/>
</xsl:if>
</xsl:template>
<xsl:template name="wmldevice">
<wml>
<card id="init" newcontext="true">
<p>
<xsl:call-template name="capabilities"/>
</p>
</card>
</wml>
</xsl:template>
<xsl:template name="htmldevice">
<html>
<head>
<title>Test Page for DELI in Cocoon</title>
</head>
<body>
<xsl:call-template name="capabilities"/>
</body>
</html>
</xsl:template>
<xsl:template name="capabilities">
<xsl:if test="$deli-capabilities/browser/ImageCapable">
ImageCapable: <xsl:value-of select="$deli-capabilities/browser/ImageCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CcppAccept">
CcppAccept:
<xsl:for-each select="$deli-capabilities/browser/CcppAccept/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
]]></source>
</s1>
</body>
</document>
1.1 xml-cocoon2/src/documentation/xdocs/developing/deliquick.xml
Index: deliquick.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XML Spy v3.0.7 NT (http://www.xmlspy.com) by Mark Butler
(Hewlett-Packard Laboratories UK) -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"dtd/document-v10.dtd">
<document>
<header>
<title>DELI Quick Start Guide</title>
<authors>
<person name="Mark H. Butler" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="DELI Quick Start Guide">
<p>For more information on DELI, see the <link
href="deli.html">DELI documentation</link>.</p>
<p>In order to enable DELI and try the test pages, you need to enable
the DELI component in the <code>cocoon.xconf</code> file. Make sure that
the configuration file is correctly specified and
set the use-deli parameter to true in <code>cocoon.xconf</code>:</p>
<source><![CDATA[
<deli>
<parameter name="deli-config-file" value="deliCocoonConfig.xml"/>
<parameter name="use-deli" value="true"/>
</deli>
]]></source>
<p>Then configure TraxTransformer in the <code>sitemap.xmap</code> file to supply
the
CC/PP profile to a stylesheet via parameters e.g.:</p>
<source><![CDATA[
<map:transformer
name="xslt"
src="org.apache.cocoon.transformation.TraxTransformer"
pool-max="32" pool-min="16" pool-grow="4">
<use-request-parameters>false</use-request-parameters>
<use-browser-capabilities-db>false</use-browser-capabilities-db>
<use-deli>true</use-deli>
</map:transformer>
]]></source>
<p>By default DELI recognises Internet Explorer and the Nokia WAP development kit as
legacy browsers. If you are using a different browser, you may need to edit the
<code>legacyDevices.xml</code>, the DELI legacy device support file. For more
details see the <link href="deli.html">DELI documentation</link>.</p>
</s1>
</body>
</document>
1.2 +4 -0 xml-cocoon2/src/java/org/apache/cocoon/cocoon.roles
Index: cocoon.roles
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/cocoon.roles,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cocoon.roles 3 Jan 2002 12:31:06 -0000 1.1
+++ cocoon.roles 9 Jan 2002 22:20:42 -0000 1.2
@@ -33,6 +33,10 @@
<role name="org.apache.cocoon.Processor"
shorthand="processor"/>
-->
+ <role name="org.apache.cocoon.components.deli.Deli"
+ shorthand="deli"
+ default-class="org.apache.cocoon.components.deli.DeliImpl"/>
+
<role name="org.apache.cocoon.Processor"
shorthand="sitemap"
default-class="org.apache.cocoon.sitemap.SitemapManager"/>
1.1 xml-cocoon2/src/java/org/apache/cocoon/components/deli/Deli.java
Index: Deli.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.cocoon.components.deli;
import org.apache.avalon.framework.component.Component;
import org.apache.cocoon.environment.Request;
import org.w3c.dom.Document;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import com.hp.hpl.deli.*;
/**
* A component for providing CC/PP and UAProf support using the DELI
* library.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Mark H. Butler</a>
* @version CVS $ $ $Date: 2002/01/09 22:20:42 $
*/
public interface Deli extends Component {
String ROLE = "org.apache.cocoon.components.deli.Deli";
/** Process a HttpServletRequest and either extract
* CC/PP or UAProf information from it and use this information
* to resolve a profile or examine the user agent string, match
* this using the DELI legacy device database, and use this
* information to retrieve the appropriate CC/PP profile.
*
*@param theRequest The Request.
*@return The profile as a vector of profile attributes.
*@exception IOException.
*@exception ServletException.
*@exception Exception.
*/
public Profile getProfile(Request theRequest) throws IOException,
ServletException, Exception;
/** Convert a profile stored as a vector of profile attributes
* to a DOM tree.
*
*@param theProfile The profile as a vector of profile attributes.
*@return The DOM tree.
*/
public Document getUACapabilities(Profile theProfile);
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/deli/DeliImpl.java
Index: DeliImpl.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.cocoon.components.deli;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.cocoon.environment.http.HttpContext;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.Constants;
import org.apache.cocoon.xml.dom.DOMFactory;
import org.apache.cocoon.components.parser.Parser;
import java.util.Vector;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.io.IOException;
import java.io.BufferedReader;
import java.net.MalformedURLException;
import java.security.Principal;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletRequest;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import com.hp.hpl.deli.Profile;
import com.hp.hpl.deli.ProfileAttribute;
import com.hp.hpl.deli.Workspace;
/**
* Allows the use of <a href="http://www-uk.hpl.hp.com/people/marbut/">DELI</a>
* to provide <a href="http://www.w3.org/Mobile/CCPP/">CC/PP</a> or
* <a
href="http://www1.wapforum.org/tech/terms.asp?doc=WAP-248-UAProf-20010530-p.pdf">UAProf</a>
* support. For more details of DELI see the Technical Report
* <a href="http://www-uk.hpl.hp.com/people/marbut/DeliUserGuideWEB.htm">DELI:
* A Delivery Context Library for CC/PP and UAProf</a>.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Mark H. Butler</a>
* @version CVS $ $ $Date: 2002/01/09 22:20:42 $
*/
public class DeliImpl extends AbstractLoggable implements Configurable, Component,
Deli,
Composable, Disposable, ThreadSafe, Contextualizable
{
/** The path to the Cocoon configuration files */
private String defaultPath = null;
/** The name of the main DELI configuration file */
private String deliConfig = "deliCocoonConfig.xml";
/** The DELI workspace */
private Workspace workspace;
/** The component manager */
protected ComponentManager manager = null;
/** Parser used to construct the DOM tree to import the profile to a stylesheet */
Parser parser;
/** A context, used to retrieve the path to the configuration file */
protected Context context;
/** This flag indicates whether DELI has been enabled in sitemap.xmap */
boolean useDeli = false;
/** Contextualize this class */
public void contextualize(Context context) throws ContextException
{
this.context = context;
org.apache.cocoon.environment.Context envContext =
(org.apache.cocoon.environment.Context)
context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
try
{
this.defaultPath = envContext.getRealPath("/");
}
catch (Exception e)
{
getLogger().error("DELI: Could not retrieve directory for configuration
files", e);
}
}
/** Compose this class */
public void compose(ComponentManager manager) throws ComponentException
{
this.manager = manager;
parser = (Parser)this.manager.lookup(Parser.ROLE);
}
/** Configure this class */
public final void configure(Configuration conf) throws ConfigurationException
{
Parameters params = Parameters.fromConfiguration(conf);
this.deliConfig = params.getParameter("deli-config-file", this.deliConfig);
this.useDeli = params.getParameterAsBoolean("use-deli", this.useDeli);
if (this.useDeli)
{
workspace = new Workspace(this.defaultPath, this.deliConfig);
}
}
/** Dispose of this class */
public void dispose()
{
if(parser != null) this.manager.release((Component)parser);
}
/** Process a HttpServletRequest and either extract
* CC/PP or UAProf information from it and use this information
* to resolve a profile or examine the user agent string, match
* this using the DELI legacy device database, and use this
* information to retrieve the appropriate CC/PP profile.
*
*@param theRequest The Request.
*@return The profile as a vector of profile attributes.
*@exception IOException.
*@exception ServletException.
*@exception Exception.
*/
public Profile getProfile(Request theRequest) throws IOException,
ServletException, Exception
{
CocoonServletRequest servletRequest = new CocoonServletRequest(theRequest);
Profile theProfile = new Profile(workspace, (HttpServletRequest) servletRequest);
return theProfile;
}
/** Convert a profile stored as a vector of profile attributes
* to a DOM tree.
*
*@param theProfile The profile as a vector of profile attributes.
*@return The DOM tree.
*/
public Document getUACapabilities(Profile theProfile)
{
Document document;
Element rootElement;
Element attributeNode;
Element complexAttributeNode;
Text text;
document = ((DOMFactory)parser).newDocument();
rootElement = document.createElementNS(null, "browser");
document.appendChild(rootElement);
Iterator profileIter = theProfile.iterator();
while (profileIter.hasNext())
{
ProfileAttribute p = (ProfileAttribute) profileIter.next();
attributeNode = document.createElementNS(null, p.getAttribute());
rootElement.appendChild(attributeNode);
Vector attributeValue = p.get();
Iterator complexValueIter = attributeValue.iterator();
if (p.getCollectionType().equals("Simple"))
{
// Simple attribute
String value = (String) complexValueIter.next();
text = document.createTextNode(value);
attributeNode.appendChild(text);
}
else
{
// Complex attribute e.g. Seq or Bag
while (complexValueIter.hasNext())
{
String value = (String) complexValueIter.next();
complexAttributeNode = document.createElementNS(null, "li");
attributeNode.appendChild(complexAttributeNode);
text = document.createTextNode(value);
complexAttributeNode.appendChild(text);
}
}
}
return document;
}
/**
* Stub implementation of HttpServletRequest
*/
public class CocoonServletRequest implements HttpServletRequest
{
Request request;
public CocoonServletRequest(Request request)
{
this.request = request;
}
public String getAuthType(){ return request.getAuthType(); }
public long getDateHeader(String s){ return request.getDateHeader(s); }
public String getHeader(String s){ return request.getHeader(s); }
public Enumeration getHeaders(String s){ return request.getHeaders(s); }
public Enumeration getHeaderNames(){ return request.getHeaderNames(); }
public String getMethod(){ return request.getMethod(); }
public String getPathInfo(){ return request.getPathInfo(); }
public String getPathTranslated(){ return request.getPathTranslated(); }
public String getContextPath(){ return request.getContextPath(); }
public String getQueryString(){ return request.getQueryString(); }
public String getRemoteUser(){ return request.getRemoteUser(); }
public boolean isUserInRole(String s){ return request.isUserInRole(s); }
public String getRequestedSessionId(){ return
request.getRequestedSessionId(); }
public String getRequestURI(){ return request.getRequestURI(); }
public String getServletPath(){ return request.getServletPath(); }
public boolean isRequestedSessionIdValid(){ return
request.isRequestedSessionIdValid(); }
public boolean isRequestedSessionIdFromCookie(){ return
request.isRequestedSessionIdFromCookie(); }
public Object getAttribute(String s){ return request.getAttribute(s); }
public Enumeration getAttributeNames(){ return request.getAttributeNames(); }
public String getCharacterEncoding(){ return request.getCharacterEncoding();
}
public int getContentLength(){ return request.getContentLength(); }
public String getContentType(){ return request.getContentType(); }
public String getParameter(String s){ return request.getParameter(s); }
public Enumeration getParameterNames(){ return request.getParameterNames(); }
public String[] getParameterValues(String s){ return
request.getParameterValues(s); }
public String getProtocol(){ return request.getProtocol(); }
public String getScheme(){ return request.getScheme(); }
public String getServerName(){ return request.getServerName(); }
public int getServerPort(){ return request.getServerPort(); }
public String getRemoteAddr(){ return request.getRemoteAddr(); }
public String getRemoteHost(){ return request.getRemoteHost(); }
public void setAttribute(String s, Object obj){ request.setAttribute(s,obj);
}
public void removeAttribute(String s){ request.removeAttribute(s); }
public boolean isSecure(){ return request.isSecure(); }
public StringBuffer getRequestURL() { return null; }
public Map getParameterMap() { return null; }
public void setCharacterEncoding(String s) { }
public Principal getUserPrincipal(){ return request.getUserPrincipal(); }
public Locale getLocale(){ return request.getLocale(); }
public Enumeration getLocales(){ return request.getLocales(); }
public String getRealPath(String s){ return null; }
public Cookie[] getCookies(){ return null; }
public RequestDispatcher getRequestDispatcher(String s){ return null; }
public BufferedReader getReader() throws IOException{ return null; }
public ServletInputStream getInputStream() throws IOException{ return null; }
public HttpSession getSession(boolean flag){ return null; }
public HttpSession getSession(){ return null; }
public boolean isRequestedSessionIdFromURL(){ return false; }
public boolean isRequestedSessionIdFromUrl(){ return false; }
public int getIntHeader(String s){ return 0; }
}
}
1.2 +59 -4
xml-cocoon2/src/java/org/apache/cocoon/transformation/TraxTransformer.java
Index: TraxTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/TraxTransformer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TraxTransformer.java 3 Jan 2002 12:31:20 -0000 1.1
+++ TraxTransformer.java 9 Jan 2002 22:20:42 -0000 1.2
@@ -25,6 +25,7 @@
import org.apache.cocoon.caching.TimeStampCacheValidity;
import org.apache.cocoon.components.browser.Browser;
import org.apache.cocoon.components.xslt.XSLTProcessor;
+import org.apache.cocoon.components.deli.Deli;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.Cookie;
import org.apache.cocoon.environment.Request;
@@ -40,6 +41,9 @@
import java.text.StringCharacterIterator;
import java.util.*;
+import com.hp.hpl.deli.Profile;
+import com.hp.hpl.deli.ProfileAttribute;
+
/**
* This Transformer is used to transform this incomming SAX stream using
* a XSLT stylesheet. Use the following sitemap declarations to define, configure
@@ -76,10 +80,18 @@
* of the session information available in the XSLT stylesheetas.<br>
* These infos are (boolean values are "true" or "false" strings: session-is-new,
* session-id-from-cookie, session-id-from-url, session-valid, session-id.<br>
- * Note that this might have issues concerning cachability of the generated output
of this
- * transformer.<br>
* This property is false by default.
*
+ * <p> The <use-deli> configuration forces the transformer to
+ * make all the properties from the CC/PP profile resolved from the
+ * request available in the XSLT stylesheets. CC/PP support is
+ * provided via the DELI library. If the request does not provide
+ * CC/PP information, then CC/PP information can added via the DELI
+ * legacy device database. This property is false by default.
+ *
+ * <p>Note that these properties might introduces issues concerning
+ * cacheability of the generated output of this transformer.<br>
+ *
*
* The <xslt-processor> configuration allows to specify the XSLT processor
that will be
* used by its role name. This allows to have several XSLT processors in the
configuration
@@ -103,7 +115,8 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a>
- * @version CVS $Id: TraxTransformer.java,v 1.1 2002/01/03 12:31:20 giacomo Exp $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Mark H. Butler</a>
+ * @version CVS $Id: TraxTransformer.java,v 1.2 2002/01/09 22:20:42 ovidiu Exp $
*/
public class TraxTransformer extends AbstractTransformer
implements Transformer, Composable, Recyclable, Configurable, Cacheable, Disposable
{
@@ -113,6 +126,9 @@
/** The Browser service instance */
private Browser browser = null;
+ /** The DELI service instance */
+ private Deli deli = null;
+
/** Should we make the request parameters available in the stylesheet? (default
is off) */
private boolean useParameters = false;
private boolean _useParameters = false;
@@ -121,6 +137,10 @@
private boolean useBrowserCap = false;
private boolean _useBrowserCap = false;
+ /* Should we make the DELI CC/PP profile available to the stylesheet (default
is off) */
+ private boolean useDeli = false;
+ private boolean _useDeli = false;
+
/** Should we make the cookies availalbe in the stylesheet? (default is off) */
private boolean useCookies = false;
private boolean _useCookies = false;
@@ -170,11 +190,16 @@
child = conf.getChild("xslt-processor-role");
String xsltRole = child.getValue(XSLTProcessor.ROLE);
- if (this.getLogger().isDebugEnabled() == true) {
+ child = conf.getChild("use-deli");
+ this.useDeli = child.getValueAsBoolean(false);
+ this._useDeli = this.useDeli;
+
+ if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("Use parameters is " + this.useParameters +
" for " + this);
this.getLogger().debug("Use cookies is " + this.useCookies + " for
" + this);
this.getLogger().debug("Use browser capabilities is " +
this.useBrowserCap + " for " + this);
this.getLogger().debug("Use session info is " + this.useSessionInfo
+ " for " + this);
+ this.getLogger().debug("Use DELI is " + this.useDeli + " for " +
this);
this.getLogger().debug("Use XSLTProcessor of role " + xsltRole);
}
@@ -196,6 +221,8 @@
getLogger().debug("Looking up " + Browser.ROLE);
}
this.browser = (Browser) manager.lookup(Browser.ROLE);
+ getLogger().debug("Looking up " + Deli.ROLE);
+ this.deli = (Deli) manager.lookup(Deli.ROLE);
}
/**
@@ -216,6 +243,7 @@
xsltProcessor.setSourceResolver(resolver);
_useParameters = par.getParameterAsBoolean("use-request-parameters",
this.useParameters);
_useBrowserCap = par.getParameterAsBoolean("use-browser-capabilities-db",
this.useBrowserCap);
+ _useDeli = par.getParameterAsBoolean("use-deli", this.useDeli);
_useCookies = par.getParameterAsBoolean("use-cookies", this.useCookies);
_useSessionInfo = par.getParameterAsBoolean("use-session-info",
this.useSessionInfo);
if (this.getLogger().isDebugEnabled() == true) {
@@ -409,6 +437,32 @@
getLogger().error("Error setting Browser info", e);
}
+ if (this._useDeli) try {
+ Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT);
+ if (map == null)
+ {
+ map = new HashMap();
+ }
+
+ if (request != null)
+ {
+
+ Profile theProfile = deli.getProfile(request);
+ org.w3c.dom.Document deliCapabilities =
deli.getUACapabilities(theProfile);
+ map.put("deli-capabilities", deliCapabilities);
+
+ String accept = request.getParameter("accept");
+ if (accept == null)
+ accept = request.getHeader("accept");
+
+ /* add the accept param */
+ map.put("accept", accept);
+ }
+
+ } catch (Exception e) {
+ getLogger().error("Error setting DELI info", e);
+ }
+
return map;
}
@@ -475,6 +529,7 @@
this._useParameters = this.useParameters;
this._useCookies = this.useCookies;
this._useBrowserCap = this.useBrowserCap;
+ this._useDeli = this.useDeli;
this._useSessionInfo = this.useSessionInfo;
super.recycle();
}
1.5 +6 -0 xml-cocoon2/src/webapp/cocoon.xconf
Index: cocoon.xconf
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/cocoon.xconf,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- cocoon.xconf 9 Jan 2002 12:01:33 -0000 1.4
+++ cocoon.xconf 9 Jan 2002 22:20:42 -0000 1.5
@@ -194,6 +194,12 @@
<parameter name="servlet-name" value="*.jsp"/>
</jsp-engine>
+ <!-- Deli support -->
+ <deli>
+ <parameter name="deli-config-file" value="deliCocoonConfig.xml"/>
+ <parameter name="use-deli" value="true"/>
+ </deli>
+
<!-- Xscript:
-->
<xscript logger="core.xscript">
1.4 +27 -0 xml-cocoon2/src/webapp/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/sitemap.xmap,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sitemap.xmap 8 Jan 2002 10:08:03 -0000 1.3
+++ sitemap.xmap 9 Jan 2002 22:20:42 -0000 1.4
@@ -107,6 +107,15 @@
pool-max="32" pool-min="16" pool-grow="4">
<use-request-parameters>false</use-request-parameters>
<use-browser-capabilities-db>false</use-browser-capabilities-db>
+ <use-deli>false</use-deli>
+ </map:transformer>
+
+ <map:transformer name="xslt-deli" logger="sitemap.transformer.xslt"
+ src="org.apache.cocoon.transformation.TraxTransformer"
+ pool-max="32" pool-min="16" pool-grow="4">
+ <use-request-parameters>false</use-request-parameters>
+ <use-browser-capabilities-db>false</use-browser-capabilities-db>
+ <use-deli>true</use-deli>
</map:transformer>
<map:transformer name="log" logger="sitemap.transformer.log"
@@ -458,6 +467,12 @@
<map:pipelines>
+ <map:pipeline>
+ <map:match pattern="sites/images/*.gif">
+ <map:read src="resources/images/{1}.gif" mime-type="image/gif"/>
+ </map:match>
+ </map:pipeline>
+
<!-- Utility for viewing source xml or html -->
<map:pipeline>
<!-- sample use of regexp equivalent to "**.source" using wildcard
@@ -680,6 +695,18 @@
<!-- ================ Hello =========================== -->
+
+ <map:match pattern="deli.html">
+ <map:generate src="docs/samples/hello-page.xml"/>
+ <map:transform src="stylesheets/deli_test.xsl" type="xslt-deli"/>
+ <map:serialize type="html"/>
+ </map:match>
+
+ <map:match pattern="deli.wml">
+ <map:generate src="docs/samples/hello-page.xml"/>
+ <map:transform src="stylesheets/deli_test.xsl" type="xslt-deli"/>
+ <map:serialize type="wap"/>
+ </map:match>
<map:match pattern="hello.html">
<map:generate src="docs/samples/hello-page.xml"/>
1.1 xml-cocoon2/src/webapp/deliCocoonConfig.xml
Index: deliCocoonConfig.xml
===================================================================
<?xml version="1.0"?>
<deli>
<debug>false</debug>
<printDefaults>false</printDefaults>
<printProfileBeforeMerge>false</printProfileBeforeMerge>
<legacyDeviceFile>legacyDevice.xml</legacyDeviceFile>
<vocabularyFile>uaprofspec.xml</vocabularyFile>
</deli>
1.1 xml-cocoon2/src/webapp/legacyDevice.xml
Index: legacyDevice.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<devices>
<legacyDevice>
<useragentstring>MSIE</useragentstring>
<profileref>http://localhost:8080/cocoon/legacyProfiles/msie.rdf</profileref>
</legacyDevice>
<legacyDevice>
<useragentstring>Nokia-WAP-Toolkit</useragentstring>
<profileref>http://localhost:8080/cocoon/legacyProfiles/nokia.rdf</profileref>
</legacyDevice>
<legacyDevice>
<useragentstring>Rainbow</useragentstring>
<profileref>http://localhost:8080/cocoon/legacyProfiles/nokia.rdf</profileref>
</legacyDevice>
</devices>
1.2 +12 -0 xml-cocoon2/src/webapp/docs/samples/samples.xml
Index: samples.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/docs/samples/samples.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- samples.xml 3 Jan 2002 12:31:39 -0000 1.1
+++ samples.xml 9 Jan 2002 22:20:42 -0000 1.2
@@ -105,6 +105,18 @@
</sample>
</group>
+ <group name="CC/PP and UAProf">
+ <sample name="Quick Start" href="documents/deliquick.html">
+ Read this to find out how to enable DELI before trying the test pages.
+ </sample>
+ <sample name="DELI" href="deli.html">
+ Test page for HTML clients.
+ </sample>
+ <sample name="DELI" href="deli.wml">
+ Test page for WAP clients.
+ </sample>
+ </group>
+
<group name="Dynamic Content">
<sample name="Simple XSP" href="xsp/simple">
Simple XSP example.
1.1 xml-cocoon2/src/webapp/stylesheets/deli_test.xsl
Index: deli_test.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="deli-capabilities"/>
<xsl:param name="accept"/>
<xsl:template match="/">
<xsl:if test="contains($accept,'wml')">
<xsl:call-template name="wmldevice"/>
</xsl:if>
<xsl:if test="not(contains($accept,'wml'))">
<xsl:call-template name="htmldevice"/>
</xsl:if>
</xsl:template>
<xsl:template name="wmldevice">
<wml>
<card id="init" newcontext="true">
<p>
<xsl:call-template name="capabilities"/>
</p>
</card>
</wml>
</xsl:template>
<xsl:template name="htmldevice">
<html>
<head>
<title>Test Page for DELI in Cocoon</title>
</head>
<body>
<xsl:call-template name="capabilities"/>
</body>
</html>
</xsl:template>
<xsl:template name="capabilities">
<xsl:if test="$deli-capabilities/browser/ColorCapable">
ColorCapable: <xsl:value-of select="$deli-capabilities/browser/ColorCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/AudioInputEncoder">
AudioInputEncoder: <xsl:for-each
select="$deli-capabilities/browser/AudioInputEncoder/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/DownloadableBrowserApps">
DownloadableBrowserApps: <xsl:for-each
select="$deli-capabilities/browser/DownloadableBrowserApps/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/TextInputCapable">
TextInputCapable: <xsl:value-of
select="$deli-capabilities/browser/TextInputCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/ImageCapable">
ImageCapable: <xsl:value-of select="$deli-capabilities/browser/ImageCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CcppAccept">
CcppAccept:
<xsl:for-each select="$deli-capabilities/browser/CcppAccept/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CcppAccept-Charset">
CcppAccept-Charset: <xsl:for-each
select="$deli-capabilities/browser/CcppAccept-Charset/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CcppAccept-Encoding">
CcppAccept-Encoding: <xsl:for-each
select="$deli-capabilities/browser/CcppAccept-Encoding/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CcppAccept-Language">
CcppAccept-Language: <xsl:for-each
select="$deli-capabilities/browser/CcppAccept-Language/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JavaPlatform">
JavaPlatform: <xsl:for-each select="$deli-capabilities/browser/JavaPlatform/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JVMVersion">
JVMVersion: <xsl:for-each select="$deli-capabilities/browser/JVMVersion/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/XhtmlModules">
XhtmlModules: <xsl:for-each select="$deli-capabilities/browser/XhtmlVersion/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SupportedPictogramSet">
SupportedPictogramSet: <xsl:for-each
select="$deli-capabilities/browser/SupportedPictogramSet/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/OutputCharSet">
OutputCharSet: <xsl:for-each select="$deli-capabilities/browser/OutputCharSet/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/InputCharSet">
InputCharSet: <xsl:for-each select="$deli-capabilities/browser/InputCharSet/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WmlScriptVersion">
WmlScriptVersion: <xsl:for-each
select="$deli-capabilities/browser/WmlScriptVersion/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WmlVersion">
WmlVersion: <xsl:for-each select="$deli-capabilities/browser/WmlVersion/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/VideoInputEncoder">
VideoInputEncoder: <xsl:for-each
select="$deli-capabilities/browser/VideoInputEncoder/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SupportedBeareres">
SupportedBearers: <xsl:for-each
select="$deli-capabilities/browser/SupportedBearers/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SecuritySupport">
SecuritySupport: <xsl:value-of select="$deli-capabilities/browser/SecuritySupport"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CurrentBearerService">
CurrentBearerService: <xsl:value-of
select="$deli-capabilities/browser/CurrentBearerService"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/BrowserName">
BrowserName: <xsl:value-of select="$deli-capabilities/browser/BrowserName"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/BrowserVersion">
BrowserVersion: <xsl:value-of select="$deli-capabilities/browser/BrowserVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SupportedBlueToothVersion">
SupportedBluetoothVersion: <xsl:value-of
select="$deli-capabilities/browser/SupportedBlueToothVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SoftwareNumber">
SoftwareNumber: <xsl:value-of select="$deli-capabilities/browser/SoftwareNumber"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/HtmlVersion">
HtmlVersion: <xsl:value-of select="$deli-capabilities/browser/HtmlVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JavaAppletEnabled">
JavaAppletEnabled: <xsl:value-of
select="$deli-capabilities/browser/JavaAppletEnabled"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JavaScriptEnabled">
JavaScriptEnabled: <xsl:value-of
select="$deli-capabilities/browser/JavaScriptEnabled"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JavaScriptVersion">
JavaScriptVersion: <xsl:value-of
select="$deli-capabilities/browser/JavaScriptVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/PreferenceForFrames">
PreferenceForFrames: <xsl:value-of
select="$deli-capabilities/browser/PreferenceForFrames"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/TablesCapable">
TablesCapable: <xsl:value-of select="$deli-capabilities/browser/TablesCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/XhtmlVersion">
XhtmlVersion: <xsl:value-of select="$deli-capabilities/browser/XhtmlVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WapDeviceClass">
WapDeviceClass: <xsl:value-of select="$deli-capabilities/browser/WapDeviceClass"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WapVersion">
WapVersion: <xsl:value-of select="$deli-capabilities/browser/WapVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WmlDeckSize">
WmlDeckSize: <xsl:value-of select="$deli-capabilities/browser/WmlDeckSize"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WmlScriptLibraries">
WmlScriptLibraries: <xsl:for-each
select="$deli-capabilities/browser/WmlScriptLibraries/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WtaiLibraries">
WtaiLibraries: <xsl:for-each
select="$deli-capabilities/browser/WtaiLibraries/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/WtaiVersion">
WtaiVersion: <xsl:value-of select="$deli-capabilities/browser/WtaiVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/BluetoothProfile">
BluetoothProfile: <xsl:for-each
select="$deli-capabilities/browser/BluetoothProfile/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/ImageCapable">
ImageCapable: <xsl:value-of select="$deli-capabilities/browser/ImageCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Keyboard">
Keyboard: <xsl:value-of select="$deli-capabilities/browser/Keyboard"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/CPU">
CPU: <xsl:value-of select="$deli-capabilities/browser/CPU"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Model">
Model: <xsl:value-of select="$deli-capabilities/browser/Model"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/NumberOfSoftKeys">
NumberOfSoftKeys: <xsl:value-of
select="$deli-capabilities/browser/NumberOfSoftKeys"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/PixelAspectRatio">
PixelAspectRatio: <xsl:value-of
select="$deli-capabilities/browser/PixelAspectRatio"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/PointingResolution">
PointingResolution: <xsl:value-of
select="$deli-capabilities/browser/PointingResolution"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/ScreenSize">
ScreenSize: <xsl:value-of select="$deli-capabilities/browser/ScreenSize"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/ScreenSizeChar">
ScreenSizeChar: <xsl:value-of select="$deli-capabilities/browser/ScreenSizeChar"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/StandardFontProportional">
StandardFontProportional: <xsl:value-of
select="$deli-capabilities/browser/StandardFontProportional"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/SoundOutputCapable">
SoundOutputCapable: <xsl:value-of
select="$deli-capabilities/browser/SoundOutputCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/TextInputCapable">
TextInputCapable: <xsl:value-of
select="$deli-capabilities/browser/TextInputCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/RecipientAppAgent">
RecipientAppAgent: <xsl:value-of
select="$deli-capabilities/browser/RecipientAppAgent"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/OSVersion">
OSVersion: <xsl:value-of select="$deli-capabilities/browser/OSVersion"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/MexeSpec">
MexeSpec: <xsl:value-of select="$deli-capabilities/browser/MexeSpec"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/MexeClassmarks">
MexeClassmarks: <xsl:for-each
select="$deli-capabilities/browser/MexeClassmarks/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/JavaEnabled">
JavaEnabled: <xsl:value-of select="$deli-capabilities/browser/JavaEnabled"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/DownloadableSoftwareSupport">
DownloadableSoftwareSupport: <xsl:for-each
select="$deli-capabilities/browser/DownloadableSoftwareSupport/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/AcceptDownloadableSoftware">
AcceptDownloadableSoftware: <xsl:value-of
select="$deli-capabilities/browser/AcceptDownloadableSoftware"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/VoiceInputCapable">
VoiceInputCapable: <xsl:value-of
select="$deli-capabilities/browser/VoiceInputCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Vendor">
Vendor: <xsl:value-of select="$deli-capabilities/browser/Vendor"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/FramesCapable">
FramesCapable: <xsl:value-of select="$deli-capabilities/browser/FramesCapable"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/BitsPerPixel">
BitsPerPixel: <xsl:value-of select="$deli-capabilities/browser/BitsPerPixel"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-Accept">
Push-Accept: <xsl:for-each select="$deli-capabilities/browser/Push-Accept/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-Accept-Charset">
Push-Accept-Charset: <xsl:for-each
select="$deli-capabilities/browser/Push-Accept-Charset/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-Accept-Encoding">
Push-Accept-Encoding: <xsl:for-each
select="$deli-capabilities/browser/Push-Accept-Encoding/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-Accept-Language">
Push-Accept-Language: <xsl:for-each
select="$deli-capabilities/browser/Push-Accept-Language/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-Accept-AppID">
Push-Accept-AppID: <xsl:for-each
select="$deli-capabilities/browser/PushAccept-AppID/li">
<xsl:value-of select="."/>,
</xsl:for-each>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-MsgSize">
Push-MsgSize: <xsl:value-of select="$deli-capabilities/browser/Push-MsgSize"/>
<br/>
</xsl:if>
<xsl:if test="$deli-capabilities/browser/Push-MaxPushReq">
Push-MaxPushReq: <xsl:value-of select="$deli-capabilities/browser/Push-MaxPushReq"/>
<br/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]