FileDocCategorySizeDatePackage
Generator.javaAPI DocApache Tomcat 6.0.14165842Fri Jul 20 04:20:32 BST 2007org.apache.jasper.compiler

Generator

public class Generator extends Object
Generate Java source from Nodes
author
Anil K. Vijendran
author
Danno Ferrin
author
Mandar Raje
author
Rajiv Mordani
author
Pierre Delisle Tomcat 4.1.x and Tomcat 5:
author
Kin-man Chung
author
Jan Luehe
author
Shawn Bayern
author
Mark Roth
author
Denis Benoit Tomcat 6.x
author
Jacob Hookom
author
Remy Maucherat

Fields Summary
private static final Class[]
OBJECT_CLASS
private static final String
VAR_EXPRESSIONFACTORY
private static final String
VAR_ANNOTATIONPROCESSOR
private ServletWriter
out
private ArrayList
methodsBuffered
private FragmentHelperClass
fragmentHelperClass
private ErrorDispatcher
err
private BeanRepository
beanInfo
private org.apache.jasper.JspCompilationContext
ctxt
private boolean
isPoolingEnabled
private boolean
breakAtLF
private String
jspIdPrefix
private int
jspId
private PageInfo
pageInfo
private Vector
tagHandlerPoolNames
private GenBuffer
charArrayBuffer
Constructors Summary
Generator(ServletWriter out, Compiler compiler)
Constructor.

        this.out = out;
        methodsBuffered = new ArrayList();
        charArrayBuffer = null;
        err = compiler.getErrorDispatcher();
        ctxt = compiler.getCompilationContext();
        fragmentHelperClass = new FragmentHelperClass(ctxt
                .getServletClassName()
                + "Helper");
        pageInfo = compiler.getPageInfo();

        /*
         * Temporary hack. If a JSP page uses the "extends" attribute of the
         * page directive, the _jspInit() method of the generated servlet class
         * will not be called (it is only called for those generated servlets
         * that extend HttpJspBase, the default), causing the tag handler pools
         * not to be initialized and resulting in a NPE. The JSP spec needs to
         * clarify whether containers can override init() and destroy(). For
         * now, we just disable tag pooling for pages that use "extends".
         */
        if (pageInfo.getExtends(false) == null) {
            isPoolingEnabled = ctxt.getOptions().isPoolingEnabled();
        } else {
            isPoolingEnabled = false;
        }
        beanInfo = pageInfo.getBeanRepository();
        breakAtLF = ctxt.getOptions().getMappedFile();
        if (isPoolingEnabled) {
            tagHandlerPoolNames = new Vector();
        }
    
Methods Summary
private voidcompileTagHandlerPoolList(Node.Nodes page)
Compiles list of tag handler pool names.


        class TagHandlerPoolVisitor extends Node.Visitor {

            private Vector names;

            /*
             * Constructor
             * 
             * @param v Vector of tag handler pool names to populate
             */
            TagHandlerPoolVisitor(Vector v) {
                names = v;
            }

            /*
             * Gets the name of the tag handler pool for the given custom tag
             * and adds it to the list of tag handler pool names unless it is
             * already contained in it.
             */
            public void visit(Node.CustomTag n) throws JasperException {

                if (!n.implementsSimpleTag()) {
                    String name = createTagHandlerPoolName(n.getPrefix(), n
                            .getLocalName(), n.getAttributes(), n
                            .hasEmptyBody());
                    n.setTagHandlerPoolName(name);
                    if (!names.contains(name)) {
                        names.add(name);
                    }
                }
                visitBody(n);
            }

            /*
             * Creates the name of the tag handler pool whose tag handlers may
             * be (re)used to service this action.
             * 
             * @return The name of the tag handler pool
             */
            private String createTagHandlerPoolName(String prefix,
                    String shortName, Attributes attrs, boolean hasEmptyBody) {
                String poolName = null;

                poolName = "_jspx_tagPool_" + prefix + "_" + shortName;
                if (attrs != null) {
                    String[] attrNames = new String[attrs.getLength()];
                    for (int i = 0; i < attrNames.length; i++) {
                        attrNames[i] = attrs.getQName(i);
                    }
                    Arrays.sort(attrNames, Collections.reverseOrder());
                    for (int i = 0; i < attrNames.length; i++) {
                        poolName = poolName + "_" + attrNames[i];
                    }
                }
                if (hasEmptyBody) {
                    poolName = poolName + "_nobody";
                }
                return JspUtil.makeJavaIdentifier(poolName);
            }
        }

        page.visit(new TagHandlerPoolVisitor(tagHandlerPoolNames));
    
private java.lang.StringcreateJspId()

        if (this.jspIdPrefix == null) {
            StringBuffer sb = new StringBuffer(32);
            String name = ctxt.getServletJavaFileName();
            sb.append("jsp_").append(Math.abs(name.hashCode())).append('_");
            this.jspIdPrefix = sb.toString();
        }
        return this.jspIdPrefix + (this.jspId++);
    
private voiddeclareTemporaryScriptingVars(Node.Nodes page)


        class ScriptingVarVisitor extends Node.Visitor {

            private Vector vars;

            ScriptingVarVisitor() {
                vars = new Vector();
            }

            public void visit(Node.CustomTag n) throws JasperException {

                if (n.getCustomNestingLevel() > 0) {
                    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
                    VariableInfo[] varInfos = n.getVariableInfos();

                    if (varInfos.length > 0) {
                        for (int i = 0; i < varInfos.length; i++) {
                            String varName = varInfos[i].getVarName();
                            String tmpVarName = "_jspx_" + varName + "_"
                                    + n.getCustomNestingLevel();
                            if (!vars.contains(tmpVarName)) {
                                vars.add(tmpVarName);
                                out.printin(varInfos[i].getClassName());
                                out.print(" ");
                                out.print(tmpVarName);
                                out.print(" = ");
                                out.print(null);
                                out.println(";");
                            }
                        }
                    } else {
                        for (int i = 0; i < tagVarInfos.length; i++) {
                            String varName = tagVarInfos[i].getNameGiven();
                            if (varName == null) {
                                varName = n.getTagData().getAttributeString(
                                        tagVarInfos[i].getNameFromAttribute());
                            } else if (tagVarInfos[i].getNameFromAttribute() != null) {
                                // alias
                                continue;
                            }
                            String tmpVarName = "_jspx_" + varName + "_"
                                    + n.getCustomNestingLevel();
                            if (!vars.contains(tmpVarName)) {
                                vars.add(tmpVarName);
                                out.printin(tagVarInfos[i].getClassName());
                                out.print(" ");
                                out.print(tmpVarName);
                                out.print(" = ");
                                out.print(null);
                                out.println(";");
                            }
                        }
                    }
                }

                visitBody(n);
            }
        }

        page.visit(new ScriptingVarVisitor());
    
static java.lang.Stringescape(java.lang.String s)

param
s the input string
return
escaped string, per Java rule


        if (s == null)
            return "";

        StringBuffer b = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '"")
                b.append('\\").append('"");
            else if (c == '\\")
                b.append('\\").append('\\");
            else if (c == '\n")
                b.append('\\").append('n");
            else if (c == '\r")
                b.append('\\").append('r");
            else
                b.append(c);
        }
        return b.toString();
    
private voidgenCommonPostamble()
Common part of postamble, shared by both servlets and tag files.

        // Append any methods that were generated in the buffer.
        for (int i = 0; i < methodsBuffered.size(); i++) {
            GenBuffer methodBuffer = (GenBuffer) methodsBuffered.get(i);
            methodBuffer.adjustJavaLines(out.getJavaLine() - 1);
            out.printMultiLn(methodBuffer.toString());
        }

        // Append the helper class
        if (fragmentHelperClass.isUsed()) {
            fragmentHelperClass.generatePostamble();
            fragmentHelperClass.adjustJavaLines(out.getJavaLine() - 1);
            out.printMultiLn(fragmentHelperClass.toString());
        }

        // Append char array declarations
        if (charArrayBuffer != null) {
            out.printMultiLn(charArrayBuffer.toString());
        }

        // Close the class definition
        out.popIndent();
        out.printil("}");
    
private voidgenPreambleClassVariableDeclarations(java.lang.String className)
Declare tag handler pools (tags of the same type and with the same attribute set share the same tag handler pool) (shared by servlet and tag handler preamble generation) In JSP 2.1, we also scope an instance of ExpressionFactory

        if (isPoolingEnabled && !tagHandlerPoolNames.isEmpty()) {
            for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
                out.printil("private org.apache.jasper.runtime.TagHandlerPool "
                        + tagHandlerPoolNames.elementAt(i) + ";");
            }
            out.println();
        }
        out.printin("private javax.el.ExpressionFactory ");
        out.print(VAR_EXPRESSIONFACTORY);
        out.println(";");
        out.printin("private org.apache.AnnotationProcessor ");
        out.print(VAR_ANNOTATIONPROCESSOR);
        out.println(";");
        out.println();
    
private voidgenPreambleImports()
Generate preamble imports (shared by servlet and tag handler preamble generation)

        Iterator iter = pageInfo.getImports().iterator();
        while (iter.hasNext()) {
            out.printin("import ");
            out.print((String) iter.next());
            out.println(";");
        }

        out.println();
    
private voidgenPreambleMethods()
Declare general-purpose methods (shared by servlet and tag handler preamble generation)

        // Method used to get compile time file dependencies
        out.printil("public Object getDependants() {");
        out.pushIndent();
        out.printil("return _jspx_dependants;");
        out.popIndent();
        out.printil("}");
        out.println();
        
        generateInit();
        generateDestroy();
    
private voidgenPreamblePackage(java.lang.String packageName)
Generate preamble package name (shared by servlet and tag handler preamble generation)

        if (!"".equals(packageName) && packageName != null) {
            out.printil("package " + packageName + ";");
            out.println();
        }
    
private voidgenPreambleStaticInitializers()
Generation of static initializers in preamble. For example, dependant list, el function map, prefix map. (shared by servlet and tag handler preamble generation)

        out.printil("private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();");
        out.println();

        // Static data for getDependants()
        out.printil("private static java.util.List _jspx_dependants;");
        out.println();
        List dependants = pageInfo.getDependants();
        Iterator iter = dependants.iterator();
        if (!dependants.isEmpty()) {
            out.printil("static {");
            out.pushIndent();
            out.printin("_jspx_dependants = new java.util.ArrayList(");
            out.print("" + dependants.size());
            out.println(");");
            while (iter.hasNext()) {
                out.printin("_jspx_dependants.add(\"");
                out.print((String) iter.next());
                out.println("\");");
            }
            out.popIndent();
            out.printil("}");
            out.println();
        }
    
public static voidgenerate(ServletWriter out, Compiler compiler, Node.Nodes page)
The main entry for Generator.

param
out The servlet output writer
param
compiler The compiler
param
page The input page


        Generator gen = new Generator(out, compiler);

        if (gen.isPoolingEnabled) {
            gen.compileTagHandlerPoolList(page);
        }
        if (gen.ctxt.isTagFile()) {
            JasperTagInfo tagInfo = (JasperTagInfo) gen.ctxt.getTagInfo();
            gen.generateTagHandlerPreamble(tagInfo, page);

            if (gen.ctxt.isPrototypeMode()) {
                return;
            }

            gen.generateXmlProlog(page);
            gen.fragmentHelperClass.generatePreamble();
            page.visit(gen.new GenerateVisitor(gen.ctxt.isTagFile(), out,
                    gen.methodsBuffered, gen.fragmentHelperClass, gen.ctxt
                            .getClassLoader(), tagInfo));
            gen.generateTagHandlerPostamble(tagInfo);
        } else {
            gen.generatePreamble(page);
            gen.generateXmlProlog(page);
            gen.fragmentHelperClass.generatePreamble();
            page.visit(gen.new GenerateVisitor(gen.ctxt.isTagFile(), out,
                    gen.methodsBuffered, gen.fragmentHelperClass, gen.ctxt
                            .getClassLoader(), null));
            gen.generatePostamble(page);
        }
    
private voidgenerateConstructor(java.lang.String className)

        out.printil("public " + className + "() {");
        out.printil("}");
        out.println();
    
private voidgenerateDeclarations(Node.Nodes page)
Generates declarations. This includes "info" of the page directive, and scriptlet declarations.


        class DeclarationVisitor extends Node.Visitor {

            private boolean getServletInfoGenerated = false;

            /*
             * Generates getServletInfo() method that returns the value of the
             * page directive's 'info' attribute, if present.
             * 
             * The Validator has already ensured that if the translation unit
             * contains more than one page directive with an 'info' attribute,
             * their values match.
             */
            public void visit(Node.PageDirective n) throws JasperException {

                if (getServletInfoGenerated) {
                    return;
                }

                String info = n.getAttributeValue("info");
                if (info == null)
                    return;

                getServletInfoGenerated = true;
                out.printil("public String getServletInfo() {");
                out.pushIndent();
                out.printin("return ");
                out.print(quote(info));
                out.println(";");
                out.popIndent();
                out.printil("}");
                out.println();
            }

            public void visit(Node.Declaration n) throws JasperException {
                n.setBeginJavaLine(out.getJavaLine());
                out.printMultiLn(new String(n.getText()));
                out.println();
                n.setEndJavaLine(out.getJavaLine());
            }

            // Custom Tags may contain declarations from tag plugins.
            public void visit(Node.CustomTag n) throws JasperException {
                if (n.useTagPlugin()) {
                    if (n.getAtSTag() != null) {
                        n.getAtSTag().visit(this);
                    }
                    visitBody(n);
                    if (n.getAtETag() != null) {
                        n.getAtETag().visit(this);
                    }
                } else {
                    visitBody(n);
                }
            }
        }

        out.println();
        page.visit(new DeclarationVisitor());
    
private voidgenerateDestroy()
Generates the _jspDestroy() method which is responsible for calling the release() method on every tag handler in any of the tag handler pools.


        out.printil("public void _jspDestroy() {");
        out.pushIndent();
        
        if (isPoolingEnabled) {
            for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
                                out.printin((String) tagHandlerPoolNames.elementAt(i));
                                out.println(".release();");
            }
        }
        
        out.popIndent();
        out.printil("}");
        out.println();
    
private voidgenerateInit()
Generates the _jspInit() method for instantiating the tag handler pools. For tag file, _jspInit has to be invoked manually, and the ServletConfig object explicitly passed. In JSP 2.1, we also instantiate an ExpressionFactory


        if (ctxt.isTagFile()) {
            out.printil("private void _jspInit(ServletConfig config) {");
        } else {
            out.printil("public void _jspInit() {");
        }

        out.pushIndent();
        if (isPoolingEnabled) {
            for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
                out.printin(tagHandlerPoolNames.elementAt(i));
                out.print(" = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(");
                if (ctxt.isTagFile()) {
                    out.print("config");
                } else {
                    out.print("getServletConfig()");
                }
                out.println(");");
            }
        }
        
        out.printin(VAR_EXPRESSIONFACTORY);
        out.print(" = _jspxFactory.getJspApplicationContext(");
        if (ctxt.isTagFile()) {
            out.print("config");
        } else {
            out.print("getServletConfig()");
        }
        out.println(".getServletContext()).getExpressionFactory();");

        out.printin(VAR_ANNOTATIONPROCESSOR);
        out.print(" = (org.apache.AnnotationProcessor) ");
        if (ctxt.isTagFile()) {
            out.print("config");
        } else {
            out.print("getServletConfig()");
        }
        out.println(".getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());");

        out.popIndent();
        out.printil("}");
        out.println();
    
private static voidgenerateLocalVariables(ServletWriter out, Node n)

        Node.ChildInfo ci;
        if (n instanceof Node.CustomTag) {
            ci = ((Node.CustomTag) n).getChildInfo();
        } else if (n instanceof Node.JspBody) {
            ci = ((Node.JspBody) n).getChildInfo();
        } else if (n instanceof Node.NamedAttribute) {
            ci = ((Node.NamedAttribute) n).getChildInfo();
        } else {
            // Cannot access err since this method is static, but at
            // least flag an error.
            throw new JasperException("Unexpected Node Type");
            // err.getString(
            // "jsp.error.internal.unexpected_node_type" ) );
        }

        if (ci.hasUseBean()) {
            out
                    .printil("HttpSession session = _jspx_page_context.getSession();");
            out
                    .printil("ServletContext application = _jspx_page_context.getServletContext();");
        }
        if (ci.hasUseBean() || ci.hasIncludeAction() || ci.hasSetProperty()
                || ci.hasParamAction()) {
            out
                    .printil("HttpServletRequest request = (HttpServletRequest)_jspx_page_context.getRequest();");
        }
        if (ci.hasIncludeAction()) {
            out
                    .printil("HttpServletResponse response = (HttpServletResponse)_jspx_page_context.getResponse();");
        }
    
private voidgeneratePageScopedVariables(JasperTagInfo tagInfo)


        // "normal" attributes
        TagAttributeInfo[] attrInfos = tagInfo.getAttributes();
        boolean variableMapperVar = false;
        for (int i = 0; i < attrInfos.length; i++) {
            String attrName = attrInfos[i].getName();
            
            // handle assigning deferred vars to VariableMapper, storing
            // previous values under '_el_ve[i]' for later re-assignment
            if (attrInfos[i].isDeferredValue() || attrInfos[i].isDeferredMethod()) {
                
                // we need to scope the modified VariableMapper for consistency and performance
                if (!variableMapperVar) {
                    out.printil("javax.el.VariableMapper _el_variablemapper = jspContext.getELContext().getVariableMapper();");
                    variableMapperVar = true;
                }
                
                out.printin("javax.el.ValueExpression _el_ve");
                out.print(i);
                out.print(" = _el_variablemapper.setVariable(");
                out.print(quote(attrName));
                out.print(',");
                if (attrInfos[i].isDeferredMethod()) {
                    out.print(VAR_EXPRESSIONFACTORY);
                    out.print(".createValueExpression(");
                    out.print(toGetterMethod(attrName));
                    out.print(",javax.el.MethodExpression.class)");
                } else {
                    out.print(toGetterMethod(attrName));
                }
                out.println(");");
            } else {
                out.printil("if( " + toGetterMethod(attrName) + " != null ) ");
                out.pushIndent();
                out.printin("_jspx_page_context.setAttribute(");
                out.print(quote(attrName));
                out.print(", ");
                out.print(toGetterMethod(attrName));
                out.println(");");
                out.popIndent();
            }
        }

        // Expose the Map containing dynamic attributes as a page-scoped var
        if (tagInfo.hasDynamicAttributes()) {
            out.printin("_jspx_page_context.setAttribute(\"");
            out.print(tagInfo.getDynamicAttributesMapName());
            out.print("\", _jspx_dynamic_attrs);");
        }
    
private voidgeneratePostamble(Node.Nodes page)
Generates the ending part of the static portion of the servlet.

        out.popIndent();
        out.printil("} catch (Throwable t) {");
        out.pushIndent();
        out.printil("if (!(t instanceof SkipPageException)){");
        out.pushIndent();
        out.printil("out = _jspx_out;");
        out.printil("if (out != null && out.getBufferSize() != 0)");
        out.pushIndent();
        out.printil("try { out.clearBuffer(); } catch (java.io.IOException e) {}");
        out.popIndent();

        out
                .printil("if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);");
        out.popIndent();
        out.printil("}");
        out.popIndent();
        out.printil("} finally {");
        out.pushIndent();

        out
                .printil("_jspxFactory.releasePageContext(_jspx_page_context);");

        out.popIndent();
        out.printil("}");

        // Close the service method
        out.popIndent();
        out.printil("}");

        // Generated methods, helper classes, etc.
        genCommonPostamble();
    
private voidgeneratePreamble(Node.Nodes page)
Generates the beginning of the static portion of the servlet.


        String servletPackageName = ctxt.getServletPackageName();
        String servletClassName = ctxt.getServletClassName();
        String serviceMethodName = Constants.SERVICE_METHOD_NAME;

        // First the package name:
        genPreamblePackage(servletPackageName);

        // Generate imports
        genPreambleImports();

        // Generate class declaration
        out.printin("public final class ");
        out.print(servletClassName);
        out.print(" extends ");
        out.println(pageInfo.getExtends());
        out.printin("    implements org.apache.jasper.runtime.JspSourceDependent");
        if (!pageInfo.isThreadSafe()) {
            out.println(",");
            out.printin("                 SingleThreadModel");
        }
        out.println(" {");
        out.pushIndent();

        // Class body begins here
        generateDeclarations(page);

        // Static initializations here
        genPreambleStaticInitializers();

        // Class variable declarations
        genPreambleClassVariableDeclarations(servletClassName);

        // Constructor
        // generateConstructor(className);

        // Methods here
        genPreambleMethods();

        // Now the service method
        out.printin("public void ");
        out.print(serviceMethodName);
        out.println("(HttpServletRequest request, HttpServletResponse response)");
        out.println("        throws java.io.IOException, ServletException {");

        out.pushIndent();
        out.println();

        // Local variable declarations
        out.printil("PageContext pageContext = null;");

        if (pageInfo.isSession())
            out.printil("HttpSession session = null;");

        if (pageInfo.isErrorPage()) {
            out.printil("Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);");
            out.printil("if (exception != null) {");
            out.pushIndent();
            out.printil("response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);");
            out.popIndent();
            out.printil("}");
        }

        out.printil("ServletContext application = null;");
        out.printil("ServletConfig config = null;");
        out.printil("JspWriter out = null;");
        out.printil("Object page = this;");

        out.printil("JspWriter _jspx_out = null;");
        out.printil("PageContext _jspx_page_context = null;");
        out.println();

        declareTemporaryScriptingVars(page);
        out.println();

        out.printil("try {");
        out.pushIndent();

        out.printin("response.setContentType(");
        out.print(quote(pageInfo.getContentType()));
        out.println(");");

        if (ctxt.getOptions().isXpoweredBy()) {
            out.printil("response.addHeader(\"X-Powered-By\", \"JSP/2.1\");");
        }

        out
                .printil("pageContext = _jspxFactory.getPageContext(this, request, response,");
        out.printin("\t\t\t");
        out.print(quote(pageInfo.getErrorPage()));
        out.print(", " + pageInfo.isSession());
        out.print(", " + pageInfo.getBuffer());
        out.print(", " + pageInfo.isAutoFlush());
        out.println(");");
        out.printil("_jspx_page_context = pageContext;");

        out.printil("application = pageContext.getServletContext();");
        out.printil("config = pageContext.getServletConfig();");

        if (pageInfo.isSession())
            out.printil("session = pageContext.getSession();");
        out.printil("out = pageContext.getOut();");
        out.printil("_jspx_out = out;");
        out.println();
    
public voidgenerateSetDynamicAttribute()

        out
                .printil("public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {");
        out.pushIndent();
        /*
         * According to the spec, only dynamic attributes with no uri are to be
         * present in the Map; all other dynamic attributes are ignored.
         */
        out.printil("if (uri == null)");
        out.pushIndent();
        out.printil("_jspx_dynamic_attrs.put(localName, value);");
        out.popIndent();
        out.popIndent();
        out.printil("}");
    
private voidgenerateSetJspContext(javax.servlet.jsp.tagext.TagInfo tagInfo)


        boolean nestedSeen = false;
        boolean atBeginSeen = false;
        boolean atEndSeen = false;

        // Determine if there are any aliases
        boolean aliasSeen = false;
        TagVariableInfo[] tagVars = tagInfo.getTagVariableInfos();
        for (int i = 0; i < tagVars.length; i++) {
            if (tagVars[i].getNameFromAttribute() != null
                    && tagVars[i].getNameGiven() != null) {
                aliasSeen = true;
                break;
            }
        }

        if (aliasSeen) {
            out
                    .printil("public void setJspContext(JspContext ctx, java.util.Map aliasMap) {");
        } else {
            out.printil("public void setJspContext(JspContext ctx) {");
        }
        out.pushIndent();
        out.printil("super.setJspContext(ctx);");
        out.printil("java.util.ArrayList _jspx_nested = null;");
        out.printil("java.util.ArrayList _jspx_at_begin = null;");
        out.printil("java.util.ArrayList _jspx_at_end = null;");

        for (int i = 0; i < tagVars.length; i++) {

            switch (tagVars[i].getScope()) {
            case VariableInfo.NESTED:
                if (!nestedSeen) {
                    out.printil("_jspx_nested = new java.util.ArrayList();");
                    nestedSeen = true;
                }
                out.printin("_jspx_nested.add(");
                break;

            case VariableInfo.AT_BEGIN:
                if (!atBeginSeen) {
                    out.printil("_jspx_at_begin = new java.util.ArrayList();");
                    atBeginSeen = true;
                }
                out.printin("_jspx_at_begin.add(");
                break;

            case VariableInfo.AT_END:
                if (!atEndSeen) {
                    out.printil("_jspx_at_end = new java.util.ArrayList();");
                    atEndSeen = true;
                }
                out.printin("_jspx_at_end.add(");
                break;
            } // switch

            out.print(quote(tagVars[i].getNameGiven()));
            out.println(");");
        }
        if (aliasSeen) {
            out
                    .printil("this.jspContext = new org.apache.jasper.runtime.JspContextWrapper(ctx, _jspx_nested, _jspx_at_begin, _jspx_at_end, aliasMap);");
        } else {
            out
                    .printil("this.jspContext = new org.apache.jasper.runtime.JspContextWrapper(ctx, _jspx_nested, _jspx_at_begin, _jspx_at_end, null);");
        }
        out.popIndent();
        out.printil("}");
        out.println();
        out.printil("public JspContext getJspContext() {");
        out.pushIndent();
        out.printil("return this.jspContext;");
        out.popIndent();
        out.printil("}");
    
private voidgenerateTagHandlerAttributes(javax.servlet.jsp.tagext.TagInfo tagInfo)
Generates declarations for tag handler attributes, and defines the getter and setter methods for each.


        if (tagInfo.hasDynamicAttributes()) {
            out.printil("private java.util.HashMap _jspx_dynamic_attrs = new java.util.HashMap();");
        }

        // Declare attributes
        TagAttributeInfo[] attrInfos = tagInfo.getAttributes();
        for (int i = 0; i < attrInfos.length; i++) {
            out.printin("private ");
            if (attrInfos[i].isFragment()) {
                out.print("javax.servlet.jsp.tagext.JspFragment ");
            } else {
                out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
                out.print(" ");
            }
            out.print(attrInfos[i].getName());
            out.println(";");
        }
        out.println();

        // Define attribute getter and setter methods
        if (attrInfos != null) {
            for (int i = 0; i < attrInfos.length; i++) {
                // getter method
                out.printin("public ");
                if (attrInfos[i].isFragment()) {
                    out.print("javax.servlet.jsp.tagext.JspFragment ");
                } else {
                    out.print(JspUtil.toJavaSourceType(attrInfos[i]
                            .getTypeName()));
                    out.print(" ");
                }
                out.print(toGetterMethod(attrInfos[i].getName()));
                out.println(" {");
                out.pushIndent();
                out.printin("return this.");
                out.print(attrInfos[i].getName());
                out.println(";");
                out.popIndent();
                out.printil("}");
                out.println();

                // setter method
                out.printin("public void ");
                out.print(toSetterMethodName(attrInfos[i].getName()));
                if (attrInfos[i].isFragment()) {
                    out.print("(javax.servlet.jsp.tagext.JspFragment ");
                } else {
                    out.print("(");
                    out.print(JspUtil.toJavaSourceType(attrInfos[i]
                            .getTypeName()));
                    out.print(" ");
                }
                out.print(attrInfos[i].getName());
                out.println(") {");
                out.pushIndent();
                out.printin("this.");
                out.print(attrInfos[i].getName());
                out.print(" = ");
                out.print(attrInfos[i].getName());
                out.println(";");
                if (ctxt.isTagFile()) {
                    // Tag files should also set jspContext attributes
                    out.printin("jspContext.setAttribute(\"");
                    out.print(attrInfos[i].getName());
                    out.print("\", ");
                    out.print(attrInfos[i].getName());
                    out.println(");");
                }
                out.popIndent();
                out.printil("}");
                out.println();
            }
        }
    
private voidgenerateTagHandlerPostamble(javax.servlet.jsp.tagext.TagInfo tagInfo)

        out.popIndent();

        // Have to catch Throwable because a classic tag handler
        // helper method is declared to throw Throwable.
        out.printil("} catch( Throwable t ) {");
        out.pushIndent();
        out.printil("if( t instanceof SkipPageException )");
        out.printil("    throw (SkipPageException) t;");
        out.printil("if( t instanceof java.io.IOException )");
        out.printil("    throw (java.io.IOException) t;");
        out.printil("if( t instanceof IllegalStateException )");
        out.printil("    throw (IllegalStateException) t;");
        out.printil("if( t instanceof JspException )");
        out.printil("    throw (JspException) t;");
        out.printil("throw new JspException(t);");
        out.popIndent();
        out.printil("} finally {");
        out.pushIndent();
        
        // handle restoring VariableMapper
        TagAttributeInfo[] attrInfos = tagInfo.getAttributes();
        for (int i = 0; i < attrInfos.length; i++) {
            if (attrInfos[i].isDeferredMethod() || attrInfos[i].isDeferredValue()) {
                out.printin("_el_variablemapper.setVariable(");
                out.print(quote(attrInfos[i].getName()));
                out.print(",_el_ve");
                out.print(i);
                out.println(");");
            }
        }
        
        // restore nested JspContext on ELContext
        out.printil("jspContext.getELContext().putContext(JspContext.class,super.getJspContext());");
        
        out.printil("((org.apache.jasper.runtime.JspContextWrapper) jspContext).syncEndTagFile();");
        if (isPoolingEnabled && !tagHandlerPoolNames.isEmpty()) {
            out.printil("_jspDestroy();");
        }
        out.popIndent();
        out.printil("}");

        // Close the doTag method
        out.popIndent();
        out.printil("}");

        // Generated methods, helper classes, etc.
        genCommonPostamble();
    
private voidgenerateTagHandlerPreamble(JasperTagInfo tagInfo, Node.Nodes tag)


        // Generate package declaration
        String className = tagInfo.getTagClassName();
        int lastIndex = className.lastIndexOf('.");
        if (lastIndex != -1) {
            String pkgName = className.substring(0, lastIndex);
            genPreamblePackage(pkgName);
            className = className.substring(lastIndex + 1);
        }

        // Generate imports
        genPreambleImports();

        // Generate class declaration
        out.printin("public final class ");
        out.println(className);
        out.printil("    extends javax.servlet.jsp.tagext.SimpleTagSupport");
        out.printin("    implements org.apache.jasper.runtime.JspSourceDependent");
        if (tagInfo.hasDynamicAttributes()) {
            out.println(",");
            out.printin("               javax.servlet.jsp.tagext.DynamicAttributes");
        }
        out.println(" {");
        out.println();
        out.pushIndent();

        /*
         * Class body begins here
         */
        generateDeclarations(tag);

        // Static initializations here
        genPreambleStaticInitializers();

        out.printil("private JspContext jspContext;");

        // Declare writer used for storing result of fragment/body invocation
        // if 'varReader' or 'var' attribute is specified
        out.printil("private java.io.Writer _jspx_sout;");

        // Class variable declarations
        genPreambleClassVariableDeclarations(tagInfo.getTagName());

        generateSetJspContext(tagInfo);

        // Tag-handler specific declarations
        generateTagHandlerAttributes(tagInfo);
        if (tagInfo.hasDynamicAttributes())
            generateSetDynamicAttribute();

        // Methods here
        genPreambleMethods();

        // Now the doTag() method
        out.printil("public void doTag() throws JspException, java.io.IOException {");

        if (ctxt.isPrototypeMode()) {
            out.printil("}");
            out.popIndent();
            out.printil("}");
            return;
        }

        out.pushIndent();

        /*
         * According to the spec, 'pageContext' must not be made available as an
         * implicit object in tag files. Declare _jspx_page_context, so we can
         * share the code generator with JSPs.
         */
        out.printil("PageContext _jspx_page_context = (PageContext)jspContext;");
        
        // Declare implicit objects.
        out.printil("HttpServletRequest request = "
                + "(HttpServletRequest) _jspx_page_context.getRequest();");
        out.printil("HttpServletResponse response = "
                + "(HttpServletResponse) _jspx_page_context.getResponse();");
        out.printil("HttpSession session = _jspx_page_context.getSession();");
        out.printil("ServletContext application = _jspx_page_context.getServletContext();");
        out.printil("ServletConfig config = _jspx_page_context.getServletConfig();");
        out.printil("JspWriter out = jspContext.getOut();");
        out.printil("_jspInit(config);");
        
        // set current JspContext on ELContext
        out.printil("jspContext.getELContext().putContext(JspContext.class,jspContext);");
        
        generatePageScopedVariables(tagInfo);

        declareTemporaryScriptingVars(tag);
        out.println();

        out.printil("try {");
        out.pushIndent();
    
private voidgenerateXmlProlog(Node.Nodes page)
Generates an XML Prolog, which includes an XML declaration and an XML doctype declaration.


        /*
         * An XML declaration is generated under the following conditions: -
         * 'omit-xml-declaration' attribute of <jsp:output> action is set to
         * "no" or "false" - JSP document without a <jsp:root>
         */
        String omitXmlDecl = pageInfo.getOmitXmlDecl();
        if ((omitXmlDecl != null && !JspUtil.booleanValue(omitXmlDecl))
                || (omitXmlDecl == null && page.getRoot().isXmlSyntax()
                        && !pageInfo.hasJspRoot() && !ctxt.isTagFile())) {
            String cType = pageInfo.getContentType();
            String charSet = cType.substring(cType.indexOf("charset=") + 8);
            out.printil("out.write(\"<?xml version=\\\"1.0\\\" encoding=\\\""
                    + charSet + "\\\"?>\\n\");");
        }

        /*
         * Output a DOCTYPE declaration if the doctype-root-element appears. If
         * doctype-public appears: <!DOCTYPE name PUBLIC "doctypePublic"
         * "doctypeSystem"> else <!DOCTYPE name SYSTEM "doctypeSystem" >
         */

        String doctypeName = pageInfo.getDoctypeName();
        if (doctypeName != null) {
            String doctypePublic = pageInfo.getDoctypePublic();
            String doctypeSystem = pageInfo.getDoctypeSystem();
            out.printin("out.write(\"<!DOCTYPE ");
            out.print(doctypeName);
            if (doctypePublic == null) {
                out.print(" SYSTEM \\\"");
            } else {
                out.print(" PUBLIC \\\"");
                out.print(doctypePublic);
                out.print("\\\" \\\"");
            }
            out.print(doctypeSystem);
            out.println("\\\">\\n\");");
        }
    
static java.lang.Stringquote(java.lang.String s)

param
s the input string
return
quoted and escaped string, per Java rule


                                 
        

        if (s == null)
            return "null";

        return '"" + escape(s) + '"";
    
static java.lang.Stringquote(char c)
Single quote and escape a character


        StringBuffer b = new StringBuffer();
        b.append('\'");
        if (c == '\'")
            b.append('\\").append('\'");
        else if (c == '\\")
            b.append('\\").append('\\");
        else if (c == '\n")
            b.append('\\").append('n");
        else if (c == '\r")
            b.append('\\").append('r");
        else
            b.append(c);
        b.append('\'");
        return b.toString();
    
private java.lang.StringtoGetterMethod(java.lang.String attrName)

        char[] attrChars = attrName.toCharArray();
        attrChars[0] = Character.toUpperCase(attrChars[0]);
        return "get" + new String(attrChars) + "()";
    
private java.lang.StringtoSetterMethodName(java.lang.String attrName)

        char[] attrChars = attrName.toCharArray();
        attrChars[0] = Character.toUpperCase(attrChars[0]);
        return "set" + new String(attrChars);