raphael 2002/11/19 07:55:17
Added: xdocs client-media.xml
Log:
Add the client media type detection and matching documentation
Revision Changes Path
1.1 jakarta-jetspeed/xdocs/client-media.xml
Index: client-media.xml
===================================================================
<?xml version="1.0" encoding="iso-8859-1"?>
<document>
<properties>
<title>Client media selection</title>
<authors>
<person name="Rapha�l Luta" email="[EMAIL PROTECTED]"/>
</authors>
</properties>
<body>
<section name="Client media selection">
<p><strong>
The features described in this section are mostly new to Jetspeed 1.4b2. This
documentation
is a living document that may reflect changes that will occur until the
release is out.
</strong></p>
<p>
The Jetspeed layout engine uses a configurable matching algorithm to determine
the type
of content format to return to the client. This matching is based on the
following parameters:
</p>
<ul>
<li>a definiton of the media types supported by the portal</li>
<li>a definition of the known user agents and their rendering capabilities</li>
<li>
an algorithm that calculates how the clients are matched up to specific
media types
</li>
</ul>
</section>
<section name="Media Types">
<p>
Media types represent the different document formats supported by the portal
and are defined
in the central <a href="registry.html">Registry</a>.
</p>
<p>
These media types definition typically associatee a well known MIME type with
one or more
required capabilities that will be used to differentiate between user-agents.
</p>
<p>
For example, in this registry definition, the "html" media type represents the
markup that
can be sent to full-blown HTML 3.2 client, supporting features like tables and
images while the
"htmlite" can be used to service user agrents without any table capabilities
and "htmltext"
will service user-agents without any image support.
</p>
<source><![CDATA[
<media-type-entry name="html">
<mime-type>text/html</mime-type>
<character-set>UTF-8</character-set>
<meta-info>
<title>HTML</title>
<description>HTML for HTML 4.0 browsers</description>
</meta-info>
<capability-map>
<capability>HTML_TABLE</capability>
<capability>HTML_IMAGE</capability>
</capability-map>
</media-type-entry>
<media-type-entry name="htmlite">
<mime-type>text/html</mime-type>
<character-set>UTF-8</character-set>
<meta-info>
<title>HTML Lite</title>
<description>HTML without table support</description>
</meta-info>
<capability-map>
<capability>HTML_IMAGE</capability>
</capability-map>
</media-type-entry>
<media-type-entry name="htmltext">
<mime-type>text/html</mime-type>
<character-set>UTF-8</character-set>
<meta-info>
<title>HTML Text</title>
<description>HTML without image support</description>
</meta-info>
<capability-map>
<capability>HTML_TABLE</capability>
</capability-map>
</media-type-entry>
]]></source>
</section>
<section name="Client descriptions">
<p>
The client descriptions, which are also stored in the <a
href="registry.html">Registry</a>,
provide the portal engine with a simple definition of the client specific
rendering capabilities.
</p>
<p>
A simple client entry will be typically composed of the following elements:
</p>
<dl>
<dt><strong>a user-agent pattern</strong></dt>
<dd><p>
This user-agent pattern, defined by a regular expression, will be tested
against incoming
User-agent identification header to identify it.
</p></dd>
<dt><strong>a list of supported MIME types</strong></dt>
<dd><p>
This list details all the MIME types supported by this client, <strong>in
descending order of
preference</strong>
</p></dd>
<dt><strong>a list of rendering capabilities</strong></dt>
<dd><p>
These optional capabilities help identify the actual client characteristics
for the different
supported MIME Types and select the corect media type. There's currently no
formal capability
defintions but they should match with those used in the Media types
definition to have any
effect.
</p></dd>
</dl>
<source><![CDATA[
<client-entry name="lynx">
<user-agent-pattern>Lynx.*</user-agent-pattern>
<manufacturer>GNU</manufacturer>
<model>None</model>
<version></version>
<mimetype-map>
<mimetype>text/html</mimetype>
</mimetype-map>
<capability-map>
<capability>HTML_TABLE</capability>
<capability>HTML_NESTED_TABLE</capability>
<capability>HTML_FORM</capability>
<capability>HTML_FRAME</capability>
<capability>HTTP_COOKIE</capability>
</capability-map>
</client-entry>
]]></source>
<p>
Since clients user agent identification strings are matched against the
different client
definitions pattern, the order of the definitions in the registry is important
as the
most specific patterns must be listed first else the generic ones will prevent
them from
being used.
</p>
</section>
<section name="Matching algorithm">
<p>
There are actually 2 matching algorithms used in cunjunction with the client
detection capabilities.
</p>
<p>
The first one is used to determine, for a client user-agent, on ordered list
of media types supported
by this client.
</p>
<ol>
<li>
find the first client definition whose pattern matches the client user agent
string. If none
are found or an invalid user agent string is used, the algorithm will use a
preconfigured default
user agent string.
</li>
<li>
create an empty list of supported media types for this client
</li>
<li>
for each mime type supported by the client
</li>
<ol>
<li>append to the list all the Media entries of the same MIME type and such
as all their capabilities
are supported by the client definition. These entries are added in the
order they are encountered in
the Media registry
</li>
<li>append to the list all the Media entries of the same MIME type but whose
capabilities are not
completely supported. These entries are added in the order they are
encountered in
the Media registry
</li>
</ol>
</ol>
<p>
For example, for a user agent string of "Lynx/3.2 (Windows; U; NT 5.0) [en]"
and the above Media
and Client definitions, the algorithm will output the following list of
ordered media types:
</p>
<ul>
<li>htmltext</li>
<li>html</li>
<li>htmlite</li>
</ul>
<p>
This algorithm is implemented in the <code>BaseCapabilityMap</code>
implementation of
the <code>CapabilityMap</code> interface.
</p>
<p>
The other algorithm is used to include this list of supported media types into
the
profile and template finding algorithms.
</p>
<p>
These algorithms will use this media list to iterate through all the media
types before
defaulting to a generic no media search. A typical search path would thus be:
</p>
<ol>
<li>/user/anon/htmltext/en/US/default.psml</li>
<li>/user/anon/htmltext/en/default.psml</li>
<li>/user/anon/htmltext/default.psml</li>
<li>/user/anon/html/en/US/default.psml</li>
<li>/user/anon/html/en/default.psml</li>
<li>/user/anon/html/default.psml</li>
<li>/user/anon/htmlite/en/US/default.psml</li>
<li>/user/anon/htmlite/en/default.psml</li>
<li>/user/anon/htmlite/default.psml</li>
<li>/user/anon/default.psml</li>
</ol>
<subsection name="Examples">
<p>
This section details how to modify an out of the box Jetspeed installation
to support
3 different sets of clients: Internet Explorer 4+ compatible, Netscape
Navigator 4 compatible
and W3C DOM compatible (Mozilla, Opera, etc...). This can be very useful if
you plan to
make heavy use of advanced CSS and DOM.
</p>
<dl>
<dt><strong>Step 1: Plan your media-types and update your Media
Registry</strong></dt>
<dd>
<p>
To achieve the above plan, we decide to use the default "html" media to
represent
be W3C compliant and we'll create 2 variants, one called "ie5" for
Internet Explorer like
browsers and the other "ns4" for Netscape 4. These different entries
will be differentiated
based on their DHTML and TABLE capabilities since Netscape 4 has a known
deficiency in
handling deeply nested table.
</p>
</dd>
</dl>
<source><![CDATA[
<media-type-entry name="html">
<mime-type>text/html</mime-type>
<meta-info>
<title>HTML</title>
<description>DHTML for W3C DOM browsers</description>
</meta-info>
<capability-map>
<capability>HTML_TABLE</capability>
<capability>HTML_IMAGE</capability>
<capability>HTML_NESTED_TABLE</capability>
<capability>HTML_DOM_1</capability>
<capability>HTML_CSS1</capability>
<capability>HTML_CSSP</capability>
<capability>HTML_JAVASCRIPT</capability>
</capability-map>
</media-type-entry>
<media-type-entry name="ie5">
<mime-type>text/html</mime-type>
<meta-info>
<title>HTML Internet Explorer</title>
<description>DHTML for Internet Explorer</description>
</meta-info>
<capability-map>
<capability>HTML_TABLE</capability>
<capability>HTML_IMAGE</capability>
<capability>HTML_NESTED_TABLE</capability>
<capability>HTML_DOM_IE</capability>
<capability>HTML_CSS1</capability>
<capability>HTML_CSSP</capability>
<capability>HTML_JAVASCRIPT</capability>
</capability-map>
</media-type-entry>
<media-type-entry name="ns4">
<mime-type>text/html</mime-type>
<meta-info>
<title>HTML Netscape</title>
<description>DHTML for Navigator 4</description>
</meta-info>
<capability-map>
<capability>HTML_TABLE</capability>
<capability>HTML_IMAGE</capability>
<capability>HTML_DOM_NS4</capability>
<capability>HTML_LAYER</capability>
<capability>HTML_JAVASCRIPT</capability>
</capability-map>
</media-type-entry>
]]></source>
<dl>
<dt><strong>Step 2: Test your media definitions against your target
clients</strong></dt>
<dd>
<p>
Before going further in customizing your site, make sure that the Client
definition
provided by Jetspeed will correctly match your target user agent with
the intended
media type. If run with DEBUG enabled, Jetspeed will write in your log
file the
user agent string recieved and how it has been matched.
</p>
<p>
Based on the above definitions and the defaule client.xreg registry, you
should have
the following results:
</p>
</dd>
</dl>
<table>
<tr>
<th>browser</th>
<th>list of selected medias</th>
</tr>
<tr>
<td>Internet Explorer 5+</td>
<td><code>ie5 html ns4 xml</code></td>
</tr>
<tr>
<td>Netscape Navigator 4.x</td>
<td><code>ns4 html ie5</code></td>
</tr>
<tr>
<td>Mozilla 1.x</td>
<td><code>html ie5 ns4 xml</code></td>
</tr>
<tr>
<td>Lynx</td>
<td><code>html ie5 ns4</code></td>
</tr>
<tr>
<td>Konqueror</td>
<td><code>ns4 html ie5</code></td>
</tr>
</table>
<p>
Note that Opera is not listed because it would change depending on the
user-agent
announced configured in Opera and Konqueror is mapped to ns4 because it has
no explicit
matching client definition in the registry. In order to properly map these
browsers to
"html" media as expected, we would need to update the default client.xreg to
add
<strong>at the beginning of the file</strong> :
</p>
<source><![CDATA[
<client-entry name="opera">
<user-agent-pattern>.*Opera.*</user-agent-pattern>
<manufacturer>Opera</manufacturer>
<model></model>
<version></version>
<mimetype-map>
<mimetype>text/html</mimetype>
</mimetype-map>
<capability-map>
<capability>HTML_3_2</capability>
<capability>HTML_JAVA</capability>
<capability>HTML_JAVASCRIPT</capability>
<capability>HTML_TABLE</capability>
<capability>HTML_NESTED_TABLE</capability>
<capability>HTML_FORM</capability>
<capability>HTML_FRAME</capability>
<capability>HTML_IMAGE</capability>
<capability>HTML_PLUGIN</capability>
<capability>HTML_CSS1</capability>
<capability>HTML_CSSP</capability>
<capability>HTML_IFRAME</capability>
<capability>HTML_DOM_1</capability>
<capability>HTTP_COOKIE</capability>
</capability-map>
</client-entry>
<client-entry name="konqueror">
<user-agent-pattern>.*Konqueror.*</user-agent-pattern>
<manufacturer>Opera</manufacturer>
<model></model>
<version></version>
<mimetype-map>
<mimetype>text/html</mimetype>
</mimetype-map>
<capability-map>
<capability>HTML_3_2</capability>
<capability>HTML_JAVA</capability>
<capability>HTML_JAVASCRIPT</capability>
<capability>HTML_TABLE</capability>
<capability>HTML_NESTED_TABLE</capability>
<capability>HTML_FORM</capability>
<capability>HTML_FRAME</capability>
<capability>HTML_IMAGE</capability>
<capability>HTML_PLUGIN</capability>
<capability>HTML_CSS1</capability>
<capability>HTML_CSSP</capability>
<capability>HTML_IFRAME</capability>
<capability>HTML_DOM_1</capability>
<capability>HTTP_COOKIE</capability>
</capability-map>
</client-entry>
]]></source>
<dl>
<dt><strong>Step 3: Customize your templates</strong></dt>
<dd>
<p>
You can now start creating browser specific templates by creating "ie5"
and "ns4"
directories where necessary and defining your templates there. The
search mechanism
settings will ensure that if no specific "ns4" or "ie5" resource is
found, the
default "html" one will be used so that you don't have to duplicate all
your
templates that don't use any browser specific features.
</p>
<p>
In this scenario, there's probably no need to consider setting up
specific PSML
resources for "ie5" or "ns4" but for some other usage scenarios it may
be useful.
</p>
</dd>
</dl>
</subsection>
</section>
<section name="Capability API">
<p>
The capability API defined in package
<code>org.apache.jetspeed.capability</code> is very
simple since it consists only of one <code>CapabiltyMap</code> interface and
one
<code>CapabilityMapFactory</code> factory.
</p>
<p>
The default <code>CapabilityMap</code> implementation is a wrapper around a
<a href="registry.html#Registry API">Registry</a> <code>ClientEntry</code>.
</p>
<p>
The <code>CapabilityMap</code> associated with a request can be retrieved from
the <code>JetspeedRunData</code> object with the <code>getCapability()</code>
method
and can thus be used by default in all the Velocity templates if you wish to
test for
a specific capability.
</p>
<subsection name="Examples">
<p>
The first example presents how a portlet can programatically adjust its
content based on the
CapabilityMap:
</p>
<source><![CDATA[
import org.apache.jetspeed.portal.portlets.AbstractPortlet;
import org.apache.jetspeed.portal.PortletException;
import org.apache.turbine.util.RunData;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.capability.CapabilityMap;
import org.apache.ecs.ConcreteElement;
import org.apache.ecs.html.*;
public class HelloClientPortlet extends AbstractPortlet
{
public ConcreteElement getContent(RunData data)
{
CapabilityMap cm =
((JetspeedRunData)data).getCapability();
String message = "Hello "+cm.getAgent();
if (cm.hasCapability("HTML_TABLE"))
{
return new Table().append(
new TR().append(
new TD().append(
mesage
)
)
)
}
else
{
return new P().append(message);
}
}
}
]]></source>
<p>
The same effect can be achieved within a VelocityPortlet template by using
the following sequence:
</p>
<source><![CDATA[
#if $data.Capability.hasCapability("HTML_TABLE")
<table><tr><td>
#else
<p>
#end
Hello $data.Capability.Agent
#if $data.Capability.hasCapability("HTML_TABLE")
</td></tr></table>
#else
</p>
#end
]]></source>
</subsection>
</section>
</body>
</document>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>