FileDocCategorySizeDatePackage
Generator.javaAPI DocGlassfish v2 API162642Fri May 04 22:32:52 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

Fields Summary
private static final Class[]
OBJECT_CLASS
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 boolean
genBytes
private PageInfo
pageInfo
private Vector
tagHandlerPoolNames
private GenBuffer
arrayBuffer
Constructors Summary
Generator(ServletWriter out, Compiler compiler)
Constructor.

        this.out = out;
        methodsBuffered = new ArrayList();
        arrayBuffer = null;
        err = compiler.getErrorDispatcher();
        ctxt = compiler.getCompilationContext();
        fragmentHelperClass =
            new FragmentHelperClass(ctxt.getFullClassName(),
                                    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();
        genBytes = pageInfo.getBuffer() == 0 &&
                   ctxt.getOptions().genStringAsByteArray();
        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.makeXmlJavaIdentifier(poolName);
            }
        }

        page.visit(new TagHandlerPoolVisitor(tagHandlerPoolNames));
    
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 (arrayBuffer != null) {
            out.printMultiLn(arrayBuffer.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)


        if (isPoolingEnabled) {
            if (!tagHandlerPoolNames.isEmpty()) {
                for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
                    out.printil(
                        "private org.apache.jasper.runtime.TagHandlerPool "
                            + tagHandlerPoolNames.elementAt(i)
                            + ";");
                }
                out.println();
            }
        }

        out.printil("private org.apache.jasper.runtime.ResourceInjector "
                    + "_jspx_resourceInjector;");
        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
        /* GlassFish Issue 812
        out.printil("public java.util.List getDependants() {");
	 */
        // START GlassFish Issue 812
        out.printil("public Object getDependants() {");
        // END GlassFish Issue 812
        out.pushIndent();
        out.printil("return _jspx_dependants;");
        out.popIndent();
        out.printil("}");
        out.println();

        // Method to get bytes from String
        if (genBytes) {
            out.printil("private static byte[] _jspx_getBytes(String s) {");
            out.pushIndent();
            out.printil("try {");
            out.pushIndent();
            out.printil("return s.getBytes(_jspx_encoding);");
            out.popIndent();
            out.printil("} catch (java.io.UnsupportedEncodingException ex) {");
            out.printil("}");
            out.printil("return null;");
            out.popIndent();
            out.printil("}");
            out.println();

            // Generate code to see if the response encoding has been set
            // differently from the encoding declared in the page directive.
            // Note that we only need to do the test once.  The assumption
            // is that the encoding cannot be changed once some data has been
            // written.
            out.printil("private boolean _jspx_same_encoding(String encoding) {");
            out.pushIndent();
            out.printil("if (! _jspx_encoding_tested) {");
            out.pushIndent();
            out.printil("_jspx_gen_bytes = _jspx_encoding.equals(encoding);");
            out.printil("_jspx_encoding_tested = true;");
            out.popIndent();
            out.printil("}");
            out.printil("return _jspx_gen_bytes;");
            out.popIndent();
            out.printil("}");
            out.println();
        }

        generateTagHandlerInit();
        generateTagHandlerDestroy();
    
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.Vector _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.Vector(");
            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();
        }

        // Codes to support genStringAsByteArray option
        // Generate a static variable for the initial response encoding
        if (genBytes) {
            // first get the respons encoding
            String contentType = pageInfo.getContentType();
            String encoding = "ISO-8859-1";
            int i = contentType.indexOf("charset=");
            if (i > 0)
                encoding = contentType.substring(i+8);

            // Make sure the encoding is supported
            // Assume that this can be determined at compile time
            try {
                "testing".getBytes(encoding);
                out.printin("private static final String _jspx_encoding = ");
                out.print(quote(encoding));
                out.println(";");
                out.printil("private boolean _jspx_gen_bytes = true;");
                out.printil("private boolean _jspx_encoding_tested;");
            } catch (java.io.UnsupportedEncodingException ex) {
                genBytes = false;
            }
        }
    
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.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.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(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 static voidgenerateLocalVariables(ServletWriter out, Node n, boolean genBytes)

        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() || genBytes) {
            out.printil(
                "HttpServletResponse response = (HttpServletResponse)_jspx_page_context.getResponse();");
        }
    
private voidgeneratePageScopedVariables(JasperTagInfo tagInfo)


        // "normal" attributes
        TagAttributeInfo[] attrInfos = tagInfo.getAttributes();
        for (int i = 0; i < attrInfos.length; i++) {
            String attrName = attrInfos[i].getName();
            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(");");
            if (attrInfos[i].isDeferredValue()) { 
                // If the attribute is a deferred value, also set it to an EL
                // variable of the same name.
                out.printin("org.apache.jasper.runtime.PageContextImpl.setValueVariable(");
                out.print("_jspx_page_context, ");
                out.print(quote(attrName));
                out.print(", ");
                out.print(toGetterMethod(attrName));
                out.println(");");
            }
                
            if (attrInfos[i].isDeferredMethod()) {
                // If the attribute is a deferred method, set a wrapped
                // ValueExpression to an EL variable of the same name.
                out.printin("org.apache.jasper.runtime.PageContextImpl.setMethodVariable(");
                out.print("_jspx_page_context, ");
                out.print(quote(attrName));
                out.print(", ");
                out.print(toGetterMethod(attrName));
                out.println(");");
            }
            out.popIndent();
            out.println("}");
        }

        // 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("out.clearBuffer();");
        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(
                "response.setStatus(((Integer)request.getAttribute(\"javax.servlet.error.status_code\")).intValue());");
        }

        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.setHeader(\"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.printil("_jspx_resourceInjector = (org.apache.jasper.runtime.ResourceInjector) application.getAttribute(\"com.sun.appserv.jsp.resource.injector\");");
        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
        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(";");
            out.popIndent();
            out.printil("}");
            out.println();
        }
    
private voidgenerateTagHandlerDestroy()
Generates the _jspDestroy() method which is responsible for calling the release() method on every tag handler in any of the tag handler pools.


        if (!isPoolingEnabled || tagHandlerPoolNames.isEmpty()) {
            return;
        }

        out.printil("public void _jspDestroy() {");
        out.pushIndent();
        for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
            out.printin((String)tagHandlerPoolNames.elementAt(i));
            out.println(".release();");
        }
        out.popIndent();
        out.printil("}");
        out.println();
    
private voidgenerateTagHandlerInit()
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.


        if (!isPoolingEnabled || tagHandlerPoolNames.isEmpty()) {
            return;
        }

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

        out.pushIndent();
        for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
            out.printin((String)tagHandlerPoolNames.elementAt(i));
            out.print(
                " = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(");
            if (ctxt.isTagFile()) {
                out.print("config");
            } else {
                out.print("getServletConfig()");
            }
            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();
        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();");
        if (isPoolingEnabled && !tagHandlerPoolNames.isEmpty()) {
            out.printil("_jspInit(config);");
        }
        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);