Building the Tag Library
A BrowserInfo object is now available to our pages, and it's up to the authors of the JSP page to make
use of its properties. However, we can try to make things easier for the page designer by designing a set
of custom tags that conditionally include their body content depending on the BrowserInfo data.
We will construct two pairs of tags:
-
Tags that check for a particular boolean browser property, allowing us to conditionally
include content depending on whether a feature (for example, frames) is supported or not.
-
Tags that check for a particular browser, or a particular browser version. For example, a tag
could be made to include its body content if the browser is Internet Explorer 5.5 or higher.
The browser.tld File
When designing a tag library it is often easiest to start with the Tag Library Descriptor (TDL) file, which
lets you sketch out quickly how the tags will function. It starts ordinarily enough:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>browser</short-name>
<uri>http://www.wrox.com/taglib/browser</uri>
<display-name>Browser Compatibility Tags</display-name>
<description>
Wrox Browser Compatibility Tag Library. Use in conjunction with
a filter of type com.wrox.browser.BrowserFilter - see JavaDoc
for details of configuring the filter.
</description>
Our first two tags are very similar. We start with the <browser:supportFor> tag, which will typically
be used as follows:
<browser:supportFor feature="frames">
<%-- Body evaluated only if browser supports frames --%>
</browser:supportFor>
There is also an optional attribute name, which is used to specify the bean name to search for if the filter
is using a value other than the default of "com.wrox.browser":
<tag>
<name>supportFor</name>
<tag-class>com.wrox.browser.SupportForTag</tag-class>
<body-content>JSP</body-content>
<description>
Includes its body content if the detected web browser supports
the specified feature.
</description>
<attribute>
<name>feature</name>
<required>true</required>
<description>
The name of the browser feature to check for.
</description>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<description>
The name used by BrowserFilter to store the browser information.
If this was not customized in web.xml, there is no need to
set this tag attribute.
</description>
</attribute>
</tag>
The second tag is an exact mirror image, only it includes its body if a feature is not supported,
for example:
<browser:noSupportFor feature="frames">
<%-- Body evaluated only if browser supports frames --%>
</browser:noSupportFor>
<tag>
<name>noSupportFor</name>
<tag-class>com.wrox.browser.NoSupportForTag</tag-class>
<body-content>JSP</body-content>
<description>
Includes its body content if the detected web browser does not
support the specified feature.
</description>
<attribute>
<name>feature</name>
<required>true</required>
<description>
The name of the browser feature to check for.
</description>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<description>
The name used by BrowserFilter to store the browser information.
If this was not customized in web.xml, there is no need to
set this tag attribute.
</description>
</attribute>
</tag>
The other two tags are slightly more complex. Let's start with the <browser:is> tag, which includes its
body content if the browser matches the requirements set out in its attributes. Some typical usage
examples might be:
<browser:is browser="IE">
<%-- Body evaluated only if browser is Internet Explorer --%>
</browser:is>
<browser:is browser="IE" majorVer="4" minorVer="0">
<%-- Body evaluated only if browser is Internet Explorer 4.0
or higher --%>
</browser:is>
<browser:is browser="IE" majorVer="4" minorVer="0" exact="true">
<%-- Body evaluated only if browser is Internet Explorer 4.0 --%>
</browser:is>
There is also a name attribute to specify the name to use when searching for the BrowserInfo bean:
<tag>
<name>is</name>
<tag-class>com.wrox.browser.IsTag</tag-class>
<body-content>JSP</body-content>
<description>
Includes its body content if the current browser matches that
specified in the tag attributes.
</description>
<attribute>
<name>browser</name>
<required>false</required>
<description>
The name of the browser.
</description>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<description>
The name used by BrowserFilter to store the browser information.
If this was not customized in web.xml, there is no need to
set this tag attribute.
</description>
</attribute>
<attribute>
<name>majorVer</name>
<required>false</required>
<description>
The name of the major version to check for
</description>
</attribute>
<attribute>
<name>minorVer</name>
<required>false</required>
<description>
The name of the minor version to check for
</description>
</attribute>
<attribute>
<name>exact</name>
<required>false</required>
<description>
Should the version-number check be exact? If false (the
default), any higher version number also matches.
</description>
</attribute>
</tag>
Lastly the <browser:isNot> tag is, as its name suggests, the opposite of <browser:is>, for example:
<browser:isNot browser="lynx">
<%-- Body evaluated only if browser is not Lynx --%>
</browser:isNot>
<tag>
<name>isNot</name>
<tag-class>com.wrox.browser.IsNotTag</tag-class>
<body-content>JSP</body-content>
<description>
Includes its body content if the current browser does not match
that specified in the tag attributes.
</description>
<attribute>
<name>browser</name>
<required>false</required>
<description>
The name of the browser.
</description>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<description>
The name used by BrowserFilter to store the browser information.
If this was not customized in web.xml, there is no need to
set this tag attribute.
</description>
</attribute>
<attribute>
<name>majorVer</name>
<required>false</required>
<description>
The name of the major version to check for
</description>
</attribute>
<attribute>
<name>minorVer</name>
<required>false</required>
<description>
The name of the minor version to check for
</description>
</attribute>
<attribute>
<name>exact</name>
<required>false</required>
<description>
Should the version-number check be exact? If false (the
default), any higher version number also matches. Default
is false.
</description>
</attribute>
</tag>
</taglib>
One could ask whether there is there a need for these tags at all, given that the browser properties are
made available as a bean and could be accessed by any generic flow-control tags. They are useful, for
two reasons:
-
The syntax chosen will make the tags' function quite clear and easy to read.
-
The
<browser:is> and <browser:isNot> tags in particular hide a lot of boolean logic.
Expressing this by combining tags would be painful. XML is poorly adapted to expressing
boolean expressions.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|