package foo;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
/**
MyClassicTag.java
Clasic Tag Handler by Sandeep Desai (http://www.thedesai.net/sandeep)
Pre JSP 2.0 style Tag Handlers
Tag instance maybe reused
interface JspTag
interface SimpleTag extends JspTag
interface Tag extends JspTag
void setPageContext(PageContext)
void setParent(Tag)
Tag getParent()
int doStartTag() throws JspException // SKIP_BODY, EVAL_BODY_INCLUDE
int doEndTag() throws JspException // SKIP_PAGE, EVAL_PAGE
void release()
interface IterationTag extends Tag
int doAfterBody() throws JspException // SKIP_BODY, EVAL_BODY_AGAIN
interface BodyTag extends IterationTag
void doInitBody()
void setBodyContent(BodyContent)
class TagSupport implements IterationTag, Serializable
PageContext pageContext
static findAncestorWithClass(String name , Class)
class BodyTagSupport extends TagSupport implements BodyTag
Extend either TagSupport or BodyTagSupport
Classic tags lifecycle
1) Load class
2) Instantiate class with no arg constructor (container may reuse instances)
3) Call the setPageContext(PageContext)
4) If nested tag call setParent(Tag)
5) If tag has attributes call attribute setters
6) call doStartTag()
7) if tag is not declared empty in DD and tag has body
and doStartTag() returns EVAL_BODY_INCLUDE
then body is executed
8) if body content evaluated call doAfterBody()
9) call doEndTag()
Classic lifecycle with TagSupport
int status = doStartTag(); // default is SKIP_BODY
if (status == SKIP_BODY)
doEndTag();
if (status == EVAL_BODY_INCLUDE && !empty body) {
do {
evaluate body;
status = doAfterBody();
} while (status != SKIP_BODY);
}
status = doEndTag();
if (status == EVAL_PAGE)
evaluate rest of page;
if (status == SKIP_PAGE)
skip rest of page;
Classic lifecycle with BodyTagSupport
int status = doStartTag(); // default is EVAL_BODY_BUFFERED
if (status == SKIP_BODY)
doEndTag();
if (status == EVAL_BODY_BUFFERED && !empty body) {
setBodyContent();
doInitBody();
}
if (status == EVAL_BODY_INCLUDE && !empty body) {
do {
evaluate body;
status = doAfterBody();
} while (status != SKIP_BODY);
}
status = doEndTag();
if (status == EVAL_PAGE)
evaluate rest of page;
if (status == SKIP_PAGE)
skip rest of page;
*/
public class MyClassicTag extends TagSupport {
public MyClassicTag() {
System.out.println("^^^^ MyClassicTag()");
}
// unlike Simple Tag does not throw IOException
public int doStartTag() throws JspException {
System.out.println("^^^^ doStartTag");
JspWriter out = pageContext.getOut();
try {
out.println("MyClassicTag doStartTag() called");
out.flush();
} catch (IOException e) {
throw new JspException(e);
}
if (showCars == null)
return SKIP_BODY; // Don't evaluate body if one
else {
index = 0; // initialize here as we container may reuse instance
// we need to duplicate this code here and in do AfterBody
// as the body is processed between doStartTag and doAfterBody
pageContext.setAttribute("car", cars[index]);
++index;
return EVAL_BODY_INCLUDE; //
}
}
public int doAfterBody() throws JspException {
if (index < cars.length) {
pageContext.setAttribute("car", cars[index]);
++index;
return EVAL_BODY_AGAIN; // container will write body and call doAfterBody
}
else return SKIP_BODY;
}
public int doEndTag() throws JspException {
System.out.println("^^^ doEndTag");
JspWriter out = pageContext.getOut();
try {
out.println("MyClassicTag doEndTag() called");
out.flush();
} catch (IOException e) {
throw new JspException(e);
}
return EVAL_PAGE; // evaluate rest page
// SKIP_PAGE like SkipPageException will not evaluate rest of page
}
public void release() { } // clean up tag
public void showCars(String showCars) {
this.showCars = showCars;
}
private String showCars;
private String[] cars = {"Honda Accord", "Toyota Camry" };
private int index = 0;
}