in src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/Generator.java [1631:1770]
public void visit(Node.CustomTag n) throws JasperException {
// Use plugin to generate more efficient code if there is one.
if (n.useTagPlugin()) {
generateTagPlugin(n);
return;
}
TagHandlerInfo handlerInfo = getTagHandlerInfo(n);
// Create variable names
String baseVar = createTagVarName(n.getQName(), n.getPrefix(), n
.getLocalName());
String tagEvalVar = "_jspx_eval_" + baseVar;
String tagHandlerVar = "_jspx_th_" + baseVar;
String tagPushBodyCountVar = "_jspx_push_body_count_" + baseVar;
// If the tag contains no scripting element, generate its codes
// to a method.
ServletWriter outSave = null;
Node.ChildInfo ci = n.getChildInfo();
if (ci.isScriptless() && !ci.hasScriptingVars()) {
// The tag handler and its body code can reside in a separate
// method if it is scriptless and does not have any scripting
// variable defined.
String tagMethod = "_jspx_meth_" + baseVar;
// Generate a call to this method
out.printin("if (");
out.print(tagMethod);
out.print("(");
if (parent != null) {
out.print(parent);
out.print(", ");
}
out.print("_jspx_page_context");
if (pushBodyCountVar != null) {
out.print(", ");
out.print(pushBodyCountVar);
}
out.println("))");
out.pushIndent();
out.printil((methodNesting > 0) ? "return true;" : "return;");
out.popIndent();
// Set up new buffer for the method
outSave = out;
/*
* For fragments, their bodies will be generated in fragment
* helper classes, and the Java line adjustments will be done
* there, hence they are set to null here to avoid double
* adjustments.
*/
GenBuffer genBuffer = new GenBuffer(n,
n.implementsSimpleTag() ? null : n.getBody());
methodsBuffered.add(genBuffer);
out = genBuffer.getOut();
methodNesting++;
// Generate code for method declaration
out.println();
out.pushIndent();
out.printin("private boolean ");
out.print(tagMethod);
out.print("(");
if (parent != null) {
out.print("javax.servlet.jsp.tagext.JspTag ");
out.print(parent);
out.print(", ");
}
out.print("PageContext _jspx_page_context");
if (pushBodyCountVar != null) {
out.print(", int[] ");
out.print(pushBodyCountVar);
}
out.println(")");
out.printil(" throws Throwable {");
out.pushIndent();
// Initilaize local variables used in this method.
if (!isTagFile) {
out
.printil("PageContext pageContext = _jspx_page_context;");
}
out.printil("JspWriter out = _jspx_page_context.getOut();");
generateLocalVariables(out, n);
}
if (n.implementsSimpleTag()) {
generateCustomDoTag(n, handlerInfo, tagHandlerVar);
} else {
/*
* Classic tag handler: Generate code for start element, body,
* and end element
*/
generateCustomStart(n, handlerInfo, tagHandlerVar, tagEvalVar,
tagPushBodyCountVar);
// visit body
String tmpParent = parent;
parent = tagHandlerVar;
boolean isSimpleTagParentSave = isSimpleTagParent;
isSimpleTagParent = false;
String tmpPushBodyCountVar = null;
if (n.implementsTryCatchFinally()) {
tmpPushBodyCountVar = pushBodyCountVar;
pushBodyCountVar = tagPushBodyCountVar;
}
boolean tmpIsSimpleTagHandler = isSimpleTagHandler;
isSimpleTagHandler = false;
visitBody(n);
parent = tmpParent;
isSimpleTagParent = isSimpleTagParentSave;
if (n.implementsTryCatchFinally()) {
pushBodyCountVar = tmpPushBodyCountVar;
}
isSimpleTagHandler = tmpIsSimpleTagHandler;
generateCustomEnd(n, tagHandlerVar, tagEvalVar,
tagPushBodyCountVar);
}
if (ci.isScriptless() && !ci.hasScriptingVars()) {
// Generate end of method
if (methodNesting > 0) {
out.printil("return false;");
}
out.popIndent();
out.printil("}");
out.popIndent();
methodNesting--;
// restore previous writer
out = outSave;
}
}