Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.jasper.compiler;
  
  import static org.jboss.web.JasperMessages.MESSAGES;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Set;
  import java.util.Vector;
  
  
Generate Java source from Nodes

Author(s):
Anil K. Vijendran
Danno Ferrin
Mandar Raje
Rajiv Mordani
Pierre Delisle Tomcat 4.1.x and Tomcat 5:
Kin-man Chung
Jan Luehe
Shawn Bayern
Mark Roth
Denis Benoit Tomcat 6.x
Jacob Hookom
Remy Maucherat
  
  
  class Generator {
  
      private static final Class[] OBJECT_CLASS = { Object.class };
  
      private static final String VAR_EXPRESSIONFACTORY =
          System.getProperty("org.apache.jasper.compiler.Generator.VAR_EXPRESSIONFACTORY""_el_expressionfactory");
      private static final String VAR_INSTANCEMANAGER =
          System.getProperty("org.apache.jasper.compiler.Generator.VAR_INSTANCEMANAGER""_jsp_instancemanager");
  
      /* System property that controls if the requirement to have the object
       * used in jsp:getProperty action to be previously "introduced"
       * to the JSP processor (see JSP.5.3) is enforced.
       */ 
      private static final boolean STRICT_GET_PROPERTY = Boolean.valueOf(
              System.getProperty(
                      "org.apache.jasper.compiler.Generator.STRICT_GET_PROPERTY",
                      "true")).booleanValue();
  
      private ServletWriter out;
  
      private ArrayList methodsBuffered;
  
  
      private ErrorDispatcher err;
  
     private BeanRepository beanInfo;
 
     private Set<StringvarInfoNames;
 
     private JspCompilationContext ctxt;
 
     private boolean isPoolingEnabled;
 
     private boolean breakAtLF;
 
     private String jspIdPrefix;
 
     private int jspId;
 
     private PageInfo pageInfo;
 
     private Vector<StringtagHandlerPoolNames;
 
     private GenBuffer charArrayBuffer;

    

Parameters:
s the input string
Returns:
quoted and escaped string, per Java rule
 
     static String quote(String s) {
 
         if (s == null)
             return "null";
 
         return '"' + escape(s) + '"';
     }

    

Parameters:
s the input string
Returns:
escaped string, per Java rule
 
     static String escape(String s) {
 
         if (s == null)
             return "";
 
         StringBuilder b = new StringBuilder();
         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();
     }

    
Single quote and escape a character
 
     static String quote(char c) {
 
         StringBuilder b = new StringBuilder();
         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 String createJspId() throws JasperException {
         if (this. == null) {
             StringBuilder sb = new StringBuilder(32);
             String name = .getServletJavaFileName();
             sb.append("jsp_").append(Math.abs(name.hashCode())).append('_');
             this. = sb.toString();
         }
         return this. + (this.++);
     }

    
Generates declarations. This includes "info" of the page directive, and scriptlet declarations.
 
     private void generateDeclarations(Node.Nodes pagethrows JasperException {
 
         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 nthrows JasperException {
 
                 if () {
                     return;
                 }
 
                 String info = n.getAttributeValue("info");
                 if (info == null)
                     return;
 
                  = true;
                 .printil("public String getServletInfo() {");
                 .pushIndent();
                 .printin("return ");
                 .print(quote(info));
                 .println(";");
                 .popIndent();
                 .printil("}");
                 .println();
             }
 
             public void visit(Node.Declaration nthrows JasperException {
                 n.setBeginJavaLine(.getJavaLine());
                 .printMultiLn(new String(n.getText()));
                 .println();
                 n.setEndJavaLine(.getJavaLine());
             }
 
             // Custom Tags may contain declarations from tag plugins.
             public void visit(Node.CustomTag nthrows 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);
                 }
             }
         }
 
         .println();
         page.visit(new DeclarationVisitor());
     }

    
Compiles list of tag handler pool names.
 
     private void compileTagHandlerPoolList(Node.Nodes page)
             throws JasperException {
 
         class TagHandlerPoolVisitor extends Node.Visitor {
 
             private Vector names;
 
             /*
              * Constructor
              *
              * @param v Vector of tag handler pool names to populate
              */
             TagHandlerPoolVisitor(Vector v) {
                  = 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 nthrows JasperException {
 
                 if (!n.implementsSimpleTag()) {
                     String name = createTagHandlerPoolName(n.getPrefix(), n
                             .getLocalName(), n.getAttributes(), 
                             n.getNamedAttributeNodes(), n.hasEmptyBody());
                     n.setTagHandlerPoolName(name);
                     if (!.contains(name)) {
                         .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 shortNameAttributes attrsNode.Nodes namedAttrs,
                     boolean hasEmptyBody) {
                 String poolName = null;
 
                 poolName = "_jspx_tagPool_" + prefix + "_" + shortName;
                 if (attrs != null) {
                     String[] attrNames =
                         new String[attrs.getLength() + namedAttrs.size()];
                     for (int i = 0; i < attrNames.lengthi++) {
                         attrNames[i] = attrs.getQName(i);
                     }
                     for (int i = 0; i < namedAttrs.size(); i++) {
                         attrNames[attrs.getLength() + i] =
                             ((NamedAttributenamedAttrs.getNode(i)).getQName();
                     }
                     Arrays.sort(attrNames, Collections.reverseOrder());
                     if (attrNames.length > 0) {
                         poolName = poolName + "&";
                     }
                     for (int i = 0; i < attrNames.lengthi++) {
                         poolName = poolName + "_" + attrNames[i];
                     }
                 }
                 if (hasEmptyBody) {
                     poolName = poolName + "_nobody";
                 }
                 return JspUtil.makeJavaIdentifier(poolName);
             }
         }
 
         page.visit(new TagHandlerPoolVisitor());
     }
 
     private void declareTemporaryScriptingVars(Node.Nodes page)
             throws JasperException {
 
         class ScriptingVarVisitor extends Node.Visitor {
 
             private Vector vars;
 
             ScriptingVarVisitor() {
                  = new Vector();
             }
 
             public void visit(Node.CustomTag nthrows JasperException {
                 // XXX - Actually there is no need to declare those
                 // "_jspx_" + varName + "_" + nestingLevel variables when we are
                 // inside a JspFragment.
 
                 if (n.getCustomNestingLevel() > 0) {
                     TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
                     VariableInfo[] varInfos = n.getVariableInfos();
 
                     if (varInfos.length > 0) {
                         for (int i = 0; i < varInfos.lengthi++) {
                             String varName = varInfos[i].getVarName();
                             String tmpVarName = "_jspx_" + varName + "_"
                                     + n.getCustomNestingLevel();
                             if (!.contains(tmpVarName)) {
                                 .add(tmpVarName);
                                 .printin(varInfos[i].getClassName());
                                 .print(" ");
                                 .print(tmpVarName);
                                 .print(" = ");
                                 .print(null);
                                 .println(";");
                             }
                         }
                     } else {
                         for (int i = 0; i < tagVarInfos.lengthi++) {
                             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 (!.contains(tmpVarName)) {
                                 .add(tmpVarName);
                                 .printin(tagVarInfos[i].getClassName());
                                 .print(" ");
                                 .print(tmpVarName);
                                 .print(" = ");
                                 .print(null);
                                 .println(";");
                             }
                         }
                     }
                 }
 
                 visitBody(n);
             }
         }
 
         page.visit(new ScriptingVarVisitor());
     }

    
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
 
     private void generateInit() {
 
         if (.isTagFile()) {
             .printil("private void _jspInit(ServletConfig config) {");
         } else {
             .printil("public void _jspInit() {");
         }
 
         .pushIndent();
         if () {
             for (int i = 0; i < .size(); i++) {
                 .printin(.elementAt(i));
                 .print(" = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(");
                 if (.isTagFile()) {
                     .print("config");
                 } else {
                     .print("getServletConfig()");
                 }
                 .println(");");
             }
         }
 
         .print(" = _jspxFactory.getJspApplicationContext(");
         if (.isTagFile()) {
             .print("config");
         } else {
             .print("getServletConfig()");
         }
         .println(".getServletContext()).getExpressionFactory();");
 
         .printin();
         .print(" = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(");
         if (.isTagFile()) {
             .print("config");
         } else {
             .print("getServletConfig()");
         }
         .println(");");
 
         .popIndent();
         .printil("}");
         .println();
     }

    
Generates the _jspDestroy() method which is responsible for calling the release() method on every tag handler in any of the tag handler pools.
 
     private void generateDestroy() {
 
         .printil("public void _jspDestroy() {");
         .pushIndent();
 
         if () {
             for (int i = 0; i < .size(); i++) {
                                 .printin((String.elementAt(i));
                                 .println(".release();");
             }
         }
 
         .popIndent();
         .printil("}");
         .println();
     }

    
Generate preamble package name (shared by servlet and tag handler preamble generation)
 
     private void genPreamblePackage(String packageNamethrows JasperException {
         if (!"".equals(packageName) && packageName != null) {
             .printil("package " + packageName + ";");
             .println();
         }
     }

    
Generate preamble imports (shared by servlet and tag handler preamble generation)
 
     private void genPreambleImports() throws JasperException {
         Iterator iter = .getImports().iterator();
         while (iter.hasNext()) {
             .printin("import ");
             .print((Stringiter.next());
             .println(";");
         }
 
         .println();
     }

    
Generation of static initializers in preamble. For example, dependant list, el function map, prefix map. (shared by servlet and tag handler preamble generation)
 
     private void genPreambleStaticInitializers() throws JasperException {
         .printil("private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();");
         .println();
 
         // Static data for getDependants()
         .printil("private static java.util.List _jspx_dependants;");
         .println();
         List dependants = .getDependants();
         Iterator iter = dependants.iterator();
         if (!dependants.isEmpty()) {
             .printil("static {");
             .pushIndent();
             .printin("_jspx_dependants = new java.util.ArrayList(");
             .print("" + dependants.size());
             .println(");");
             while (iter.hasNext()) {
                 .printin("_jspx_dependants.add(\"");
                 .print((Stringiter.next());
                 .println("\");");
             }
             .popIndent();
             .printil("}");
             .println();
         }
     }

    
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
 
     private void genPreambleClassVariableDeclarations(String className)
             throws JasperException {
         if ( && !.isEmpty()) {
             for (int i = 0; i < .size(); i++) {
                 .printil("private org.apache.jasper.runtime.TagHandlerPool "
                         + .elementAt(i) + ";");
             }
             .println();
         }
         .printin("private javax.el.ExpressionFactory ");
         .print();
         .println(";");
         .printin("private org.apache.tomcat.InstanceManager ");
         .print();
         .println(";");
         .println();
     }

    
Declare general-purpose methods (shared by servlet and tag handler preamble generation)
 
     private void genPreambleMethods() throws JasperException {
         // Method used to get compile time file dependencies
         .printil("public Object getDependants() {");
         .pushIndent();
         .printil("return _jspx_dependants;");
         .popIndent();
         .printil("}");
         .println();
 
         generateInit();
         generateDestroy();
     }

    
Generates the beginning of the static portion of the servlet.
 
     private void generatePreamble(Node.Nodes pagethrows JasperException {
 
         String servletPackageName = .getServletPackageName();
         String servletClassName = .getServletClassName();
         String serviceMethodName = .;
 
         // First the package name:
         genPreamblePackage(servletPackageName);
 
         // Generate imports
         genPreambleImports();
 
         // Generate class declaration
         .printin("public final class ");
         .print(servletClassName);
         .print(" extends ");
         .println(.getExtends());
         .printin("    implements org.apache.jasper.runtime.JspSourceDependent");
         if (!.isThreadSafe()) {
             .println(",");
             .printin("                 SingleThreadModel");
         }
         .println(" {");
         .pushIndent();
 
         // Class body begins here
         generateDeclarations(page);
 
         // Static initializations here
 
         // Class variable declarations
         genPreambleClassVariableDeclarations(servletClassName);
 
         // Constructor
         // generateConstructor(className);
 
         // Methods here
         genPreambleMethods();
 
         // Now the service method
         .printin("public void ");
         .print(serviceMethodName);
         .println("(HttpServletRequest request, HttpServletResponse response)");
         .println("        throws java.io.IOException, ServletException {");
 
         .pushIndent();
         .println();
 
         // Local variable declarations
         .printil("PageContext pageContext = null;");
 
         if (.isSession())
             .printil("HttpSession session = null;");
 
         if (.isErrorPage()) {
             .printil("Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);");
             .printil("if (exception != null) {");
             .pushIndent();
             .printil("response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);");
             .popIndent();
             .printil("}");
         }
 
         .printil("ServletContext application = null;");
         .printil("ServletConfig config = null;");
         .printil("JspWriter out = null;");
         .printil("Object page = this;");
 
         .printil("JspWriter _jspx_out = null;");
         .printil("PageContext _jspx_page_context = null;");
         .println();
 
         declareTemporaryScriptingVars(page);
         .println();
 
         .printil("try {");
         .pushIndent();
 
         .printin("response.setContentType(");
         .print(quote(.getContentType()));
         .println(");");
 
         if (.getOptions().isXpoweredBy()) {
             .printil("response.addHeader(\"X-Powered-By\", \"JSP/2.2\");");
         }
 
         
                 .printil("pageContext = _jspxFactory.getPageContext(this, request, response,");
         .printin("\t\t\t");
         .print(quote(.getErrorPage()));
         .print(", " + .isSession());
         .print(", " + .getBuffer());
         .print(", " + .isAutoFlush());
         .println(");");
         .printil("_jspx_page_context = pageContext;");
 
         .printil("application = pageContext.getServletContext();");
         .printil("config = pageContext.getServletConfig();");
 
         if (.isSession())
             .printil("session = pageContext.getSession();");
         .printil("out = pageContext.getOut();");
         .printil("_jspx_out = out;");
         .println();
     }

    
Generates an XML Prolog, which includes an XML declaration and an XML doctype declaration.
 
     private void generateXmlProlog(Node.Nodes page) {
 
         /*
          * 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 = .getOmitXmlDecl();
         if ((omitXmlDecl != null && !JspUtil.booleanValue(omitXmlDecl))
                 || (omitXmlDecl == null && page.getRoot().isXmlSyntax()
                         && !.hasJspRoot() && !.isTagFile())) {
             String cType = .getContentType();
             String charSet = cType.substring(cType.indexOf("charset=") + 8);
             .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 = .getDoctypeName();
         if (doctypeName != null) {
             String doctypePublic = .getDoctypePublic();
             String doctypeSystem = .getDoctypeSystem();
             .printin("out.write(\"<!DOCTYPE ");
             .print(doctypeName);
             if (doctypePublic == null) {
                 .print(" SYSTEM \\\"");
             } else {
                 .print(" PUBLIC \\\"");
                 .print(doctypePublic);
                 .print("\\\" \\\"");
             }
             .print(doctypeSystem);
             .println("\\\">\\n\");");
         }
     }
 
     /*
      * Generates the constructor. (shared by servlet and tag handler preamble
      * generation)
      */
     private void generateConstructor(String className) {
         .printil("public " + className + "() {");
         .printil("}");
         .println();
     }

    
A visitor that generates codes for the elements in the page.
 
     class GenerateVisitor extends Node.Visitor {
 
         /*
          * Hashtable containing introspection information on tag handlers:
          * <key>: tag prefix <value>: hashtable containing introspection on tag
          * handlers: <key>: tag short name <value>: introspection info of tag
          * handler for <prefix:shortName> tag
          */
         private Hashtable handlerInfos;
 
         private Hashtable tagVarNumbers;
 
         private String parent;
 
         private boolean isSimpleTagParent// Is parent a SimpleTag?
 
         private String pushBodyCountVar;
 
         private String simpleTagHandlerVar;
 
         private boolean isSimpleTagHandler;
 
         private boolean isFragment;
 
         private boolean isTagFile;
 
         private ServletWriter out;
 
         private ArrayList methodsBuffered;
 
         private FragmentHelperClass fragmentHelperClass;
 
         private int methodNesting;
 
         private TagInfo tagInfo;
 
         private ClassLoader loader;
 
         private int charArrayCount;
 
         private HashMap textMap;

        
Constructor.
 
         public GenerateVisitor(boolean isTagFileServletWriter out,
                 ArrayList methodsBuffered,
                 FragmentHelperClass fragmentHelperClassClassLoader loader,
                 TagInfo tagInfo) {
 
             this. = isTagFile;
             this. = out;
             this. = methodsBuffered;
             this. = fragmentHelperClass;
             this. = loader;
             this. = tagInfo;
              = 0;
              = new Hashtable();
              = new Hashtable();
              = new HashMap();
         }

        
Returns an attribute value, optionally URL encoded. If the value is a runtime expression, the result is the expression itself, as a string. If the result is an EL expression, we insert a call to the interpreter. If the result is a Named Attribute we insert the generated variable name. Otherwise the result is a string literal, quoted and escaped.

Parameters:
attr An JspAttribute object
encode true if to be URL encoded
expectedType the expected type for an EL evaluation (ignored for attributes that aren't EL expressions)
 
         private String attributeValue(Node.JspAttribute attrboolean encode,
                 Class expectedType) {
             String v = attr.getValue();
             if (!attr.isNamedAttribute() && (v == null))
                 return "";
 
             if (attr.isExpression()) {
                 if (encode) {
                     return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode(String.valueOf("
                             + v + "), request.getCharacterEncoding())";
                 }
                 return v;
             } else if (attr.isELInterpreterInput()) {
                 v = JspUtil.interpreterCall(this.vexpectedType,
                         attr.getEL().getMapName(), false);
                 if (encode) {
                     return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
                             + v + ", request.getCharacterEncoding())";
                 }
                 return v;
             } else if (attr.isNamedAttribute()) {
                 return attr.getNamedAttributeNode().getTemporaryVariableName();
             } else {
                 if (encode) {
                     return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
                             + quote(v) + ", request.getCharacterEncoding())";
                 }
                 return quote(v);
             }
         }


        
Prints the attribute value specified in the param action, in the form of name=value string.

Parameters:
n the parent node for the param action nodes.
 
         private void printParams(Node nString pageParamboolean literal)
                 throws JasperException {
 
             class ParamVisitor extends Node.Visitor {
                 String separator;
 
                 ParamVisitor(String separator) {
                     this. = separator;
                 }
 
                 public void visit(Node.ParamAction nthrows JasperException {
 
                     .print(" + ");
                     .print();
                     .print(" + ");
                     .print("org.apache.jasper.runtime.JspRuntimeLibrary."
                             + "URLEncode(" + quote(n.getTextAttribute("name"))
                             + ", request.getCharacterEncoding())");
                     .print("+ \"=\" + ");
                     .print(attributeValue(n.getValue(), trueString.class));
 
                     // The separator is '&' after the second use
                      = "\"&\"";
                 }
             }
 
             String sep;
             if (literal) {
                 sep = pageParam.indexOf('?') > 0 ? "\"&\"" : "\"?\"";
             } else {
                 sep = "((" + pageParam + ").indexOf('?')>0? '&': '?')";
             }
             if (n.getBody() != null) {
                 n.getBody().visit(new ParamVisitor(sep));
             }
         }
 
         public void visit(Node.Expression nthrows JasperException {
             n.setBeginJavaLine(.getJavaLine());
             .printin("out.print(");
             .printMultiLn(n.getText());
             .println(");");
             n.setEndJavaLine(.getJavaLine());
         }
 
         public void visit(Node.Scriptlet nthrows JasperException {
             n.setBeginJavaLine(.getJavaLine());
             .printMultiLn(n.getText());
             .println();
             n.setEndJavaLine(.getJavaLine());
         }
 
         public void visit(Node.ELExpression nthrows JasperException {
             n.setBeginJavaLine(.getJavaLine());
             if (!.isELIgnored() && (n.getEL() != null)) {
                 .printil("out.write("
                         + JspUtil.interpreterCall(this.n.getType() + "{"
                                 + new String(n.getText()) + "}"String.class,
                                 n.getEL().getMapName(), false) + ");");
             } else {
                 .printil("out.write("
                         + quote(n.getType() + "{" + new String(n.getText()) + "}") + ");");
             }
             n.setEndJavaLine(.getJavaLine());
         }
 
         public void visit(Node.IncludeAction nthrows JasperException {
 
             String flush = n.getTextAttribute("flush");
             Node.JspAttribute page = n.getPage();
 
             boolean isFlush = false// default to false;
             if ("true".equals(flush))
                 isFlush = true;
 
             n.setBeginJavaLine(.getJavaLine());
 
             String pageParam;
             if (page.isNamedAttribute()) {
                 // If the page for jsp:include was specified via
                 // jsp:attribute, first generate code to evaluate
                 // that body.
                 pageParam = generateNamedAttributeValue(page
                         .getNamedAttributeNode());
             } else {
                 pageParam = attributeValue(pagefalseString.class);
             }
 
             // If any of the params have their values specified by
             // jsp:attribute, prepare those values first.
             Node jspBody = findJspBody(n);
             if (jspBody != null) {
                 prepareParams(jspBody);
             } else {
                 prepareParams(n);
             }
 
             
                     .printin("org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "
                             + pageParam);
             printParams(npageParampage.isLiteral());
             .println(", out, " + isFlush + ");");
 
             n.setEndJavaLine(.getJavaLine());
         }

        
Scans through all child nodes of the given parent for <param> subelements. For each <param> element, if its value is specified via a Named Attribute (<jsp:attribute>), generate the code to evaluate those bodies first.

If parent is null, simply returns.

 
         private void prepareParams(Node parentthrows JasperException {
             if (parent == null)
                 return;
 
             Node.Nodes subelements = parent.getBody();
             if (subelements != null) {
                 for (int i = 0; i < subelements.size(); i++) {
                     Node n = subelements.getNode(i);
                     if (n instanceof Node.ParamAction) {
                         Node.Nodes paramSubElements = n.getBody();
                         for (int j = 0; (paramSubElements != null)
                                 && (j < paramSubElements.size()); j++) {
                             Node m = paramSubElements.getNode(j);
                             if (m instanceof Node.NamedAttribute) {
                                 generateNamedAttributeValue((Node.NamedAttributem);
                             }
                         }
                     }
                 }
             }
         }

        
Finds the <jsp:body> subelement of the given parent node. If not found, null is returned.
 
         private Node.JspBody findJspBody(Node parent) {
            Node.JspBody result = null;
            Node.Nodes subelements = parent.getBody();
            for (int i = 0; (subelements != null) && (i < subelements.size()); i++) {
                Node n = subelements.getNode(i);
                if (n instanceof Node.JspBody) {
                    result = (Node.JspBodyn;
                    break;
                }
            }
            return result;
        }
        public void visit(Node.ForwardAction nthrows JasperException {
            Node.JspAttribute page = n.getPage();
            n.setBeginJavaLine(.getJavaLine());
            .printil("if (true) {"); // So that javac won't complain about
            .pushIndent(); // codes after "return"
            String pageParam;
            if (page.isNamedAttribute()) {
                // If the page for jsp:forward was specified via
                // jsp:attribute, first generate code to evaluate
                // that body.
                pageParam = generateNamedAttributeValue(page
                        .getNamedAttributeNode());
            } else {
                pageParam = attributeValue(pagefalseString.class);
            }
            // If any of the params have their values specified by
            // jsp:attribute, prepare those values first.
            Node jspBody = findJspBody(n);
            if (jspBody != null) {
                prepareParams(jspBody);
            } else {
                prepareParams(n);
            }
            .printin("_jspx_page_context.forward(");
            .print(pageParam);
            printParams(npageParampage.isLiteral());
            .println(");");
            if ( || ) {
                .printil("throw new SkipPageException();");
            } else {
                .printil(( > 0) ? "return true;" : "return;");
            }
            .popIndent();
            .printil("}");
            n.setEndJavaLine(.getJavaLine());
            // XXX Not sure if we can eliminate dead codes after this.
        }
        public void visit(Node.GetProperty nthrows JasperException {
            String name = n.getTextAttribute("name");
            String property = n.getTextAttribute("property");
            n.setBeginJavaLine(.getJavaLine());
            if (.checkVariable(name)) {
                // Bean is defined using useBean, introspect at compile time
                Class bean = .getBeanType(name);
                String beanName = JspUtil.getCanonicalName(bean);
                java.lang.reflect.Method meth = JspRuntimeLibrary
                        .getReadMethod(beanproperty);
                String methodName = meth.getName();
                
                        .printil("out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString("
                                + "((("
                                + beanName
                                + ")_jspx_page_context.findAttribute("
                                + "\""
                                + name + "\"))." + methodName + "())));");
            } else if (! || .contains(name)) {
                // The object is a custom action with an associated
                // VariableInfo entry for this name.
                // Get the class name and then introspect at runtime.
                
                        .printil("out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString"
                                + "(org.apache.jasper.runtime.JspRuntimeLibrary.handleGetProperty"
                                + "(_jspx_page_context.findAttribute(\""
                                + name
                                + "\"), \""
                                + property
                                + "\")));");
            } else {