js| templates
Execute Template
The templates discussed here will be executed under three custom tags:
Template:insert
Template:put
Template:get
The Insert label contains a template, but before it is included, the put label stores some information--name, URI, and Boolean values (used to specify whether content is included or shown directly)--about what the template contains. The specified content is included (or displayed) in the Template:get, which is then accessed.
Template:put stores beans in the request area (but not directly) because if two templates use the same content name, a nested template overwrites the contents of the encapsulated template.
To ensure that each template is able to access only its own information, Template:insert retains a hashtable stack. Each insert start tag creates a hashtable and puts it on the stack. The packaged put tags create the beans and save them to the recently established Hashtable. Subsequently, the Bean in the Hashtable is accessed by the get tag in the included template. Figure 4 shows how the stack is preserved.
Figure 4. Store template parameters in the request area click to enlarge (KB)
In Figure 4, each template accesses the correct footer, footer.html, and footer_2.html. If the bean is stored directly in the request area, step 5 in Figure 4 will overwrite the footer bean specified in step 2.
Template Label Execution
Next we will analyze the execution of the three template tags: insert, put, and get. Let's start with Figure 5. This chart illustrates the order in which inserts and put label events are executed when a template is used.
Figure 5. Put and Insert tabs to perform sequentially click to enlarge (KB)
If a template stack does not exist, the insert start tag creates one and places it in the request area. Then a hashtable is also built and placed on the stack.
Each put start tag creates a pageparameter bean and is stored in the hashtable created by the encapsulated insert tag.
The insert end tag contains the template. The template uses a Get tag to access the bean created by the put label. After the template is processed, the hashtable created by the Insert start tag is purged from the stack.
Figure 6 shows the sequential chart of the Template:get.
Figure 6. Get Label order chart click to enlarge (one KB)
Template Label List
The label handler is simple. The Insert Label class--label handler is listed in Example 3.a.
Example 3.a. Inserttag.java
Packagetags.templates;
Import java.util.Hashtable;
Import Java.util.Stack;
Import javax.servlet.jsp.JspException;
Import Javax.servlet.jsp.PageContext;
Import Javax.servlet.jsp.tagext.TagSupport;
public class Inserttagextendstagsupport {
Private stringtemplate;
private stack stack;
Setter Method Fortemplate Property
public void SetTemplate (stringtemplate) {
This.template =template;
}
public int doStartTag () throws Jspexception {
stack = Getstack (); Obtain a reference to Thetemplate stack
Stack.push (New Hashtable ()); Push new Hashtable onto stack
return eval_body_include; Pass Tagbody through unchanged
}
public int Doendtag () throws Jspexception {
try {
Pagecontext.include (template); Includetemplate
}
catch (Exception ex) {//IOException or Servletexception
throw new Jspexception (Ex.getmessage ()); Recast exception
}
Stack.pop (); Pop hashtable off Stack
return eval_page; Evaluate the rest of the page after the tag
}
Taghandlers should always implement release () because
Handlers can is reused by the JSP container
public void release () {
template = null;
stack = null;
}
Public Stack Getstack () {
Try to get stack from request scope
Stack s = (stack) pagecontext.get properties (
"Template-stack",
Pagecontext.request_scope);
If the stack ' s not present, create a new one and
Put it into request scope
if (s = = null) {
s = new Stack ();
Pagecontext.set Property ("Template-stack", S,
Pagecontext.request_scope);
}
return s;
}
}
Example 3.b lists the put label class and label handler:
Example 3.b. Puttag.java
Packagetags.templates;
Import java.util.Hashtable;
Import Java.util.Stack;
Import javax.servlet.jsp.JspException;
Import Javax.servlet.jsp.tagext.TagSupport;
Import Beans.templates.PageParameter;
public class Puttagextendstagsupport {
Private String name, content, direct= "false";
Setter methods for put tag attributes
public void SetName (String s) {name = s;}
public void SetContent (String s) {content = s;}
public void Setdirect (String s) {direct = s;}
public int doStartTag () throws Jspexception {
Obtain a reference to enclosing insert tag
Inserttagparent = (Inserttag) getancestor (
"Tags.templates.InsertTag");
Puttags must is enclosed in a insert tag
if (parent = null)
throw new Jspexception ("Puttag.dostarttag ():" +
"No inserttagancestor");
GetTemplate stack from insert tag
Stacktemplate_stack = Parent.getstack ();
Template stack should never be null
if (Template_stack = null)
throw new Jspexception ("Puttag:notemplate stack");
Peek at Hashtable on the stack
Hashtable params = (Hashtable) template_stack.peek ();
Hashtable should never be null either
if (params = null)
throw new Jspexception ("Puttag:no Hashtable");
Put a new pageparameter in the Hashtable
Params.put (name, new Pageparameter (content, direct);
return skip_body; Not interested in tagbody, if present
}
Taghandlers should always implement release () because
Handlers can is reused by the JSP container
public void release () {
Name = content = Direct = null;
}
Convenience to finding ancestor names with
A specific class name
Privatetagsupport GetAncestor (String className)
Throws Jspexception {
Class Klass = null; Can ' t name variable ' class '
try {
Klass = Class.forName (className);
}
catch (ClassNotFoundException ex) {
throw new Jspexception (Ex.getmessage ());
}
Return (TagSupport) Findancestorwithclass (this, Klass);
}
}
Puttag.dostarttag established a pageparameter bean– listed in example 3.C-and then stored in the request area.
Example 3.C. Pageparameter.java
Package beans.templates;
public class Pageparameter {
Private String content, direct;
public void SetContent (String s) {content = s;}
public void Setdirect (String s) {direct = s;}
Public String getcontent () {return content;}
public Boolean isdirect () {return boolean.valueof (direct). Booleanvalue ();}
Public Pageparameter (string content, string direct) {
this.content = content;
This.direct = direct;
}
}
Pageparameter will be used as a simple placeholder. Let's take a look at the Gettag class and tag handler in example 3.D:
Example 3.D. Gettag.java
Packagetags.templates;
Import java.util.Hashtable;
Import Java.util.Stack;
Import javax.servlet.jsp.JspException;
Import Javax.servlet.jsp.PageContext;
Import Javax.servlet.jsp.tagext.TagSupport;
Import Beans.templates.PageParameter;
public class Gettagextendstagsupport {
private String name;
Setter method for Name attribute
public void SetName (String name) {
THIS.name = name;
}
public int doStartTag () throws Jspexception {
Obtain reference totemplate Stack
Stack stack = (stack) pagecontext.get attribute (
"Template-stack", Pagecontext.request_scope);
Stack should not is null
if (stack = null)
throw new Jspexception ("Gettag.dostarttag ():" +
"NO STACK");
Peek at Hashtable
Hashtable params = (Hashtable) stack.peek ();
Hashtable should not being null
if (params = null)
throw new Jspexception ("Gettag.dostarttag ():" +
"NO HASHTABLE");
Get page parameter from Hashtable
Pageparameter param = (pageparameter) params.get (name);
if (param!= null) {
String content = Param.getcontent ();
if (Param.isdirect ()) {
Print content If direct attribute is true
try {
Pagecontext.getout (). print (content);
}
catch (Java.io.IOException ex) {
throw new Jspexception (Ex.getmessage ());
}
}
else {
Include content if direct attribute is False
try {
Pagecontext.getout (). Flush ();
Pagecontext.include (content);
}
catch (Exception ex) {
throw new Jspexception (Ex.getmessage ());
}
}
}
return skip_body; Not interested in tagbody, if present
}
Taghandlers should always implement release () because
Handlers can is reused by the JSP container
public void release () {
name = NULL;
}
}
Gettag.dostarttag returns the page parameter bean from the request area and obtains the content and direct properties from the bean. The content can then be included or displayed depending on whether the direct attribute value is selected.
Conclusions
Templates are a simple and very useful concept. The packaging layout of the template can minimize the impact of layout changes. and templates can differentiate between different content depending on the user, and can be nested into other templates and JSP pages.