|
<taglib:tutorial lesson="4">
In this lesson, we will look at writing collaborating Tags.
1 Lesson 4, Writing Collaborating Tags
In this lesson, we will look at writing collaborating Tags. There are numerous ways that Tags can be designed to collaborate on tasks. For example, one Tag could add a certain value to the page scope, and another Tag can then look for this value for further processing. Or one Tag could hold a certain value, and a child Tag could look up his parent and ask the parent for this value.
What we are about to do is close to the last example. But instead of having a child Tag use its getParent() method to get hold of its parent Tag, we will use the static findAncestorWithClass() method of the TagSupport class. This way, we make it possible for other Tags to be in use between our Tag and the ancestor Tag that we want to collaborate with. The parent Tag and its child Tag will together give us a switch/case functionality.
 Figure 1: The SwitchTag will extend the TagSupport class and will it its turn be extended by the CaseTag.
The static method findAncestorWithClass() method of the SupportTag uses the getParent() method of Tag instances to traverse the Tags present above the current Tag until it encounters the start of the JSP page, or that it finds an instance of the specified Tag. If no such Tag is found, the method will return null.
Throughout this lesson, we will continue to use the
setup previously defined for this tutorial. You should feel comfortable about the TagSupport class and the Tag interface before starting on this lesson.
2 Creating the Switch Tag
We will start with creating the parent Tag that we will use for setting the value to match in the child Tag (CaseTag). We will extend the TagSupport class in order to limit the number of methods that we have to write.
 Figure 2: The SwitchTag will extend the TagSupport class overriding the doStartTag method and add a attribute named value.
-
In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'SwitchTag.java' with the following content:
package com.acme.tag;
import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.*;
public class SwitchTag extends TagSupport { String value;
public SwitchTag() { super(); }
public void setValue(String value) { this.value=value; }
public String getValue() { return value; }
|
Listing 1: Starting off the Tag
Above, we define a Tag that holds the state of an attribute called value. It also holds access methods for setting and getting this value.
-
Continue with the following method and end the Tag:
public int doStartTag() throws JspTagException{ return EVAL_BODY_INCLUDE; } }
|
Listing 2: Overriding the doEndTag method of SupportTag
The method above will make sure that the Tag will evaluate its body. Except for this method, we don't want to do anything different than the default behaviour of the TagSupport class, and thereby end of with a very small amount of actual code rows in our class.
|
By now, your SwitchTag.java should look like this. Store the sourcecode in the /WEB-INF/classes/com/acme/tag/ directory as SwitchTag.java
|
-
Compile the Tag.
3 Creating the Case Tag
With the parent Tag in place, we will now create the child Tag. As the child tag will accept an attribute to match with the attribute given to its parent, we can save ourselves valuable time by extending the Switch Tag and override the methods originating in the SupportTag class to give us the functionality that we want.
 Figure 3: The SwitchTag will extend the CaseTag class overriding the doStartTag method with a implementation that will verify that the Tag usage is incapsuled in a CaseTag usage.
The Case Tag will expect a value that it will try to match with its parent Tags (Switch) value. If the value matches, the body of the Case Tag will be parsed.
-
In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'CaseTag.java' with the following content:
package com.acme.tag;
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*;
public class CaseTag extends SwitchTag {
|
Listing 3: Class definition
Above, we define that the CaseTag will extend the SwitchTag, which will give this Tag the necessary methods to change the state of the held attribute called value.
-
Define a constructor:
public CaseTag() { super(); }
|
Listing 4: Adding a constructor
-
Continue with the following:
public int doStartTag() throws JspTagException { SwitchTag parent=(SwitchTag)findAncestorWithClass(this,SwitchTag.class); if(parent==null) { throw new JspTagException("Case Tag without Switch Tag"); }
|
Listing 5: Overriding the doSartTag method of the SwitchTag
Above, we use the static findAncestorWithClass() method of the TagSupport class to look for a parent SwitchTag. If no such Tag is found, a JspTagException will be thrown.
-
Continue with the following:
try { if(parent.getValue().equals(getValue())) { return EVAL_BODY_INCLUDE; } else { return SKIP_BODY; }
|
Listing 6: Compare the values of this Tag and its parent SwitchTag
In the code above, we will tell the Container to evaluate the CaseTags body if the value held by the CaseTag matches the value held by its parent SwitchTag.
-
Continue with the following:
} catch(NullPointerException e) { if(parent.getValue()==null && getValue()==null) { return EVAL_BODY_INCLUDE; } else { return SKIP_BODY; } } } }
|
Listing 7: NPE handling
Above, we make sure to catch any NPE:s caused by either the value held by the SwitchTag or the CaseTag being null. If such an Exception is thrown, we check if both values are null (that would make them equal) or not.
|
By now, your CaseTag.java should look like this. Store the sourcecode in the /WEB-INF/classes/com/acme/tag/ directory as CaseTag.java
|
-
Compile the Tag.
4 Update the Tag Library Descriptor
5 Presenting your new Tag
In order to use your new Tags, you will need a JSP page that uses it.
-
Create a new file called 'switch.jsp' in your '/taglib-tutorial-web/' directory with the following content:
<%@ taglib uri="mytags" prefix="mt" %> <HTML> <HEAD> <TITLE>Switch Example</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <P>This example will show how to use collaborating Tags.</P> <mt:switch value="dark"> <mt:case value="light"> <P>This is light.</P> </mt:case> <mt:case value="Dark"> <P>This is Dark.</P> </mt:case> <mt:case value="dark"> <P>This is dark.</P> </mt:case> </mt:switch> </BODY> </HTML>
|
Listing 10: A sample JSP page
-
Make sure that you store your file as 'switch.jsp' in your '/taglib-tutorial-web/' directory.
|
By now, your switch.jsp should look like
this. Store the file in the
taglib-tutorial-web/ directory as
switch.jsp.
|
6 Using your new Tag
We are now ready to use our Tag.
|
Open the URL
http://localhost/taglib/switch.jsp in a normal web browser. Hopefully the result looks like
this.
|
Continue with lesson 5, "Writing TEI classes".
Copyright ©
2005 IronFlare AB
|