luehe       2002/08/16 16:18:54

  Modified:    jasper2/src/share/org/apache/jasper/compiler Compiler.java
                        Generator.java Node.java
  Added:       jasper2/src/share/org/apache/jasper/compiler
                        ScriptingVariabler.java
  Log:
  Added compilation step which determines, for every custom tag, the
  scripting variables that need to be declared. For example, if a custom
  action is nested, it must not redeclare the AT_BEGIN variables of its
  encapsulating action, etc.
  
  Scripting variables are now generated at the appropriate places,
  according to their scope.
  
  Revision  Changes    Path
  1.27      +6 -3      
jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java
  
  Index: Compiler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Compiler.java     12 Aug 2002 21:58:48 -0000      1.26
  +++ Compiler.java     16 Aug 2002 23:18:54 -0000      1.27
  @@ -248,6 +248,9 @@
        // this compilation unit.
        TagFileProcessor.loadTagFiles(this, pageNodes);
   
  +     // Determine which custom tag needs to declare which scripting vars
  +     ScriptingVariabler.set(pageNodes);
  +
        // generate servlet .java file
        Generator.generate(writer, this, pageNodes);
           writer.close();
  
  
  
  1.66      +107 -121  
jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java
  
  Index: Generator.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- Generator.java    12 Aug 2002 17:55:45 -0000      1.65
  +++ Generator.java    16 Aug 2002 23:18:54 -0000      1.66
  @@ -247,73 +247,60 @@
                return poolName;
            }
        }
  -
  +     
        page.visit(new TagHandlerPoolVisitor(tagHandlerPoolNames));
       }
  - 
  -    /*
  -     * For every custom tag, declares its scripting variables with AT_BEGIN
  -     * and AT_END scopes.
  -     */
  -    private void declareAtBeginAtEndScriptingVariables(Node.Nodes page)
  +
  +    private void declareTemporaryScriptingVars(Node.Nodes page)
            throws JasperException {
   
  -     class ScriptingVariableDeclarationVisitor extends Node.Visitor {
  +     class ScriptingVarVisitor extends Node.Visitor {
   
  -         /*
  -          * Vector keeping track of which scripting variables have already
  -          * been declared
  -          */
  -         private Vector scriptVars;
  +         private Vector vars;
   
  -         /*
  -          * Constructor.
  -          */
  -         public ScriptingVariableDeclarationVisitor() {
  -             scriptVars = new Vector();
  +         ScriptingVarVisitor() {
  +             vars = new Vector();
            }
   
            public void visit(Node.CustomTag n) throws JasperException {
   
  -             TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
  -             VariableInfo[] varInfos = n.getVariableInfos();
  -
  -             if ((varInfos == null) && (tagVarInfos == null)) {
  -                 visitBody(n);
  -             }
  -
  -             if (varInfos != null) {
  -                 for (int i=0; i<varInfos.length; i++) {
  -                     int scope = varInfos[i].getScope();
  -                     String varName = varInfos[i].getVarName();
  -                     if (((scope == VariableInfo.AT_BEGIN)
  -                                          || (scope == VariableInfo.AT_END))
  -                             && varInfos[i].getDeclare()
  -                             && !scriptVars.contains(varName)) {
  -                         out.printin(varInfos[i].getClassName());
  -                         out.print(" ");
  -                         out.print(varName);
  -                         out.println(" = null;");
  -                         scriptVars.add(varName);
  +             if (n.getCustomNestingLevel() > 0) {
  +                 TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
  +                 VariableInfo[] varInfos = n.getVariableInfos();
  +
  +                 if (varInfos != null) {
  +                     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++) {
  -                     int scope = tagVarInfos[i].getScope();
  -                     String varName = tagVarInfos[i].getNameGiven();
  -                     if (varName == null) {
  -                         varName = n.getTagData().getAttributeString(
  -                                        tagVarInfos[i].getNameFromAttribute());
  -                     }
  -                     if (((scope == VariableInfo.AT_BEGIN)
  -                                          || (scope == VariableInfo.AT_END))
  -                             && tagVarInfos[i].getDeclare()
  -                             && !scriptVars.contains(varName)) {
  -                         out.printin(tagVarInfos[i].getClassName());
  -                         out.print(" ");
  -                         out.print(varName);
  -                         out.println(" = null;");
  -                         scriptVars.add(varName);
  +                 } else if (tagVarInfos != null) {
  +                     for (int i=0; i<tagVarInfos.length; i++) {
  +                         String varName = tagVarInfos[i].getNameGiven();
  +                         if (varName == null) {
  +                             varName = n.getTagData().getAttributeString(
  +                                     tagVarInfos[i].getNameFromAttribute());
  +                         }
  +                         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(";");
  +                         }
                        }
                    }
                }
  @@ -322,7 +309,7 @@
            }
        }
   
  -     page.visit(new ScriptingVariableDeclarationVisitor());
  +     page.visit(new ScriptingVarVisitor());
       }
   
       /**
  @@ -481,7 +468,7 @@
           out.printil("JspWriter _jspx_out = null;");
        out.println();
   
  -     declareAtBeginAtEndScriptingVariables(page);
  +     declareTemporaryScriptingVars(page);
        out.println();
   
        out.printil("try {");
  @@ -1863,18 +1850,16 @@
            out.printin("/* ----  ");
            out.print(n.getName());
            out.println(" ---- */");
  -         out.printil("{");
  -         out.pushIndent();
   
  -         // Declare scripting variables with NESTED scope
  -         declareNestedScriptingVariables(n);
  +         // Declare AT_BEGIN scripting variables
  +         declareScriptingVars(n, VariableInfo.AT_BEGIN);
   
            /*
             * Save current values of scripting variables, so that the 
             * scripting variables may be synchronized without affecting their
             * original values
             */
  -         saveScriptingVariables(n);
  +         saveScriptingVars(n);
   
            out.printin(tagHandlerClass.getName());
            out.print(" ");
  @@ -1906,10 +1891,12 @@
            out.print(tagHandlerVar);
            out.println(".doStartTag();");
   
  -         // Synchronize AT_BEGIN and NESTED scripting variables
            if (!n.implementsBodyTag()) {
  -             syncScriptingVariables(n, VariableInfo.AT_BEGIN);
  -             syncScriptingVariables(n, VariableInfo.NESTED);
  +             // Synchronize AT_BEGIN scripting variables
  +             syncScriptingVars(n, VariableInfo.AT_BEGIN);
  +             // Declare and synchronize NESTED scripting variables
  +             declareScriptingVars(n, VariableInfo.NESTED);
  +             syncScriptingVars(n, VariableInfo.NESTED);
            }
   
            if (n.getBody() != null) {
  @@ -1919,6 +1906,9 @@
                out.pushIndent();
                
                if (n.implementsBodyTag()) {
  +                 // Declare NESTED scripting variables
  +                 declareScriptingVars(n, VariableInfo.NESTED);
  +
                    out.printin("if (");
                    out.print(tagEvalVar);
                    out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) 
{");
  @@ -1931,8 +1921,8 @@
                    out.println(".doInitBody();");
   
                    // Synchronize AT_BEGIN and NESTED scripting variables
  -                 syncScriptingVariables(n, VariableInfo.AT_BEGIN);
  -                 syncScriptingVariables(n, VariableInfo.NESTED);
  +                 syncScriptingVars(n, VariableInfo.AT_BEGIN);
  +                 syncScriptingVars(n, VariableInfo.NESTED);
                    
                    out.popIndent();
                    out.printil("}");
  @@ -1959,8 +1949,8 @@
   
                // Synchronize AT_BEGIN and NESTED scripting variables
                if (n.implementsBodyTag()) {
  -                 syncScriptingVariables(n, VariableInfo.AT_BEGIN);
  -                 syncScriptingVariables(n, VariableInfo.NESTED);
  +                 syncScriptingVars(n, VariableInfo.AT_BEGIN);
  +                 syncScriptingVars(n, VariableInfo.NESTED);
                }
   
                out.printil("if (evalDoAfterBody != 
javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)");
  @@ -1997,9 +1987,12 @@
            }
            out.popIndent();
   
  -         // Synchronize AT_BEGIN and AT_END scripting variables
  -         syncScriptingVariables(n, VariableInfo.AT_BEGIN);
  -         syncScriptingVariables(n, VariableInfo.AT_END);
  +         // Synchronize AT_BEGIN scripting variables
  +         syncScriptingVars(n, VariableInfo.AT_BEGIN);
  +
  +         // Declare and synchronize AT_END scripting variables
  +         declareScriptingVars(n, VariableInfo.AT_END);
  +         syncScriptingVars(n, VariableInfo.AT_END);
   
            // TryCatchFinally
            if (n.implementsTryCatchFinally()) {
  @@ -2027,9 +2020,7 @@
                   out.println("}");
            }
   
  -         restoreScriptingVariables(n);
  -         out.popIndent();
  -         out.printil("}");
  +         restoreScriptingVars(n);
   
            n.setEndJavaLine(out.getJavaLine());
        }
  @@ -2053,7 +2044,7 @@
             * scripting variables may be synchronized without affecting their
             * original values
             */
  -         saveScriptingVariables(n);
  +         saveScriptingVars(n);
   
            out.printin(tagHandlerClass.getName());
            out.print(" ");
  @@ -2100,8 +2091,8 @@
            out.println(".doTag();");
   
            // Synchronize AT_BEGIN and AT_END scripting variables
  -         syncScriptingVariables(n, VariableInfo.AT_BEGIN);
  -         syncScriptingVariables(n, VariableInfo.AT_END);
  +         syncScriptingVars(n, VariableInfo.AT_BEGIN);
  +         syncScriptingVars(n, VariableInfo.AT_END);
   
            // TryCatchFinally
            if (n.implementsTryCatchFinally()) {
  @@ -2119,44 +2110,35 @@
                   out.println("}");
            }
   
  -         restoreScriptingVariables(n);
  +         restoreScriptingVars(n);
            out.popIndent();
            out.printil("}");
   
            n.setEndJavaLine(out.getJavaLine());
        }
   
  -     /*
  -      * Declares any NESTED scripting variables of the given custom tag.
  -      */
  -     private void declareNestedScriptingVariables(Node.CustomTag n) {
  -
  -         TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
  -         VariableInfo[] nestedVarInfos = n.getNestedVariableInfos();
  -         if ((nestedVarInfos == null) && (tagVarInfos == null)) {
  -             return;
  -         }
  -
  -         if (nestedVarInfos != null) {
  -             for (int i=0; i<nestedVarInfos.length; i++) {
  -                 String name = nestedVarInfos[i].getVarName();
  -                 out.printin(nestedVarInfos[i].getClassName());
  -                 out.print(" ");
  -                 out.print(name);
  -                 out.println(" = null;");
  -             }
  -         } else {
  -             for (int i=0; i<tagVarInfos.length; i++) {
  -                 if ((tagVarInfos[i].getScope() == VariableInfo.NESTED)
  -                         && tagVarInfos[i].getDeclare()) {
  -                     String name = tagVarInfos[i].getNameGiven();
  -                     if (name == null) {
  -                         name = n.getTagData().getAttributeString(
  -                                    tagVarInfos[i].getNameFromAttribute());
  +     private void declareScriptingVars(Node.CustomTag n, int scope) {
  +         
  +         Vector vec = n.getScriptingVars(scope);
  +         if (vec != null) {
  +             for (int i=0; i<vec.size(); i++) {
  +                 Object elem = vec.elementAt(i);
  +                 if (elem instanceof VariableInfo) {
  +                     VariableInfo varInfo = (VariableInfo) elem;
  +                     out.printin(varInfo.getClassName());
  +                     out.print(" ");
  +                     out.print(varInfo.getVarName());
  +                     out.println(" = null;");
  +                 } else {
  +                     TagVariableInfo tagVarInfo = (TagVariableInfo) elem;
  +                     String varName = tagVarInfo.getNameGiven();
  +                     if (varName == null) {
  +                         varName = n.getTagData().getAttributeString(
  +                                        tagVarInfo.getNameFromAttribute());
                        }
  -                     out.printin(tagVarInfos[i].getClassName());
  +                     out.printin(tagVarInfo.getClassName());
                        out.print(" ");
  -                     out.print(name);
  +                     out.print(varName);
                        out.println(" = null;");
                    }
                }
  @@ -2172,7 +2154,7 @@
         * end element. This way, the scripting variables may be synchronized
         * by the given tag without affecting their original values.
         */
  -     private void saveScriptingVariables(Node.CustomTag n) {
  +     private void saveScriptingVars(Node.CustomTag n) {
            if (n.getCustomNestingLevel() == 0) {
                return;
            }
  @@ -2185,18 +2167,20 @@
   
            if (varInfos != null) {
                for (int i=0; i<varInfos.length; i++) {
  +                 if (varInfos[i].getScope() == VariableInfo.AT_END)
  +                     continue;
                    String varName = varInfos[i].getVarName();
                    String tmpVarName = "_jspx_" + varName + "_"
                        + n.getCustomNestingLevel();
  -                 out.printin(varInfos[i].getClassName());
  -                 out.print(" ");
  -                 out.print(tmpVarName);
  +                 out.printin(tmpVarName);
                    out.print(" = ");
                    out.print(varName);
                    out.println(";");
                }
            } else {
                for (int i=0; i<tagVarInfos.length; i++) {
  +                 if (tagVarInfos[i].getScope() == VariableInfo.AT_END)
  +                     continue;
                    String varName = tagVarInfos[i].getNameGiven();
                    if (varName == null) {
                        varName = n.getTagData().getAttributeString(
  @@ -2204,9 +2188,7 @@
                    }
                    String tmpVarName = "_jspx_" + varName + "_"
                        + n.getCustomNestingLevel();
  -                 out.printin(tagVarInfos[i].getClassName());
  -                 out.print(" ");
  -                 out.print(tmpVarName);
  +                 out.printin(tmpVarName);
                    out.print(" = ");
                    out.print(varName);
                    out.println(";");
  @@ -2221,7 +2203,7 @@
         * restore its scripting variables to their original values that were
         * saved in the tag's start element.
         */
  -     private void restoreScriptingVariables(Node.CustomTag n) {
  +     private void restoreScriptingVars(Node.CustomTag n) {
            if (n.getCustomNestingLevel() == 0) {
                return;
            }
  @@ -2234,6 +2216,8 @@
   
            if (varInfos != null) {
                for (int i=0; i<varInfos.length; i++) {
  +                 if (varInfos[i].getScope() == VariableInfo.AT_END)
  +                     continue;
                    String varName = varInfos[i].getVarName();
                    String tmpVarName = "_jspx_" + varName + "_"
                        + n.getCustomNestingLevel();
  @@ -2244,6 +2228,8 @@
                }
            } else {
                for (int i=0; i<tagVarInfos.length; i++) {
  +                 if (tagVarInfos[i].getScope() == VariableInfo.AT_END)
  +                     continue;
                    String varName = tagVarInfos[i].getNameGiven();
                    if (varName == null) {
                        varName = n.getTagData().getAttributeString(
  @@ -2263,7 +2249,7 @@
         * Synchronizes the scripting variables of the given custom tag for
         * the given scope.
         */
  -     private void syncScriptingVariables(Node.CustomTag n, int scope) {
  +     private void syncScriptingVars(Node.CustomTag n, int scope) {
            TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
            VariableInfo[] varInfos = n.getVariableInfos();
   
  
  
  
  1.25      +62 -68    
jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java
  
  Index: Node.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Node.java 15 Aug 2002 19:12:09 -0000      1.24
  +++ Node.java 16 Aug 2002 23:18:54 -0000      1.25
  @@ -889,7 +889,7 @@
        private TagFileInfo tagFileInfo;
        private Class tagHandlerClass;
        private VariableInfo[] varInfos;
  -     private VariableInfo[] nestedVarInfos;
  +     private TagVariableInfo[] nestedTagVarInfos;
        private int customNestingLevel;
           private ChildInfo childInfo;
        private boolean implementsIterationTag;
  @@ -897,6 +897,11 @@
        private boolean implementsTryCatchFinally;
        private boolean implementsSimpleTag;
        private boolean implementsDynamicAttributes;
  +     private Vector atBeginScriptingVars;
  +     private Vector atEndScriptingVars;
  +     private Vector nestedScriptingVars;
  +     private Node.CustomTag customTagParent;
  +     private Integer numCount;
   
        public CustomTag(Attributes attrs, Mark start, String name,
                         String prefix, String shortName,
  @@ -909,7 +914,7 @@
            this.tagInfo = tagInfo;
            this.tagFileInfo = tagFileInfo;
            this.tagHandlerClass = tagHandlerClass;
  -         this.customNestingLevel = computeCustomNestingLevel();
  +         this.customNestingLevel = makeCustomNestingLevel();
               this.childInfo = new ChildInfo();
   
            if (tagHandlerClass != null) {
  @@ -923,8 +928,7 @@
                    SimpleTag.class.isAssignableFrom(tagHandlerClass);
                this.implementsDynamicAttributes = 
                    DynamicAttributes.class.isAssignableFrom(tagHandlerClass);
  -         }
  -         else if (tagFileInfo != null) {
  +         } else if (tagFileInfo != null) {
                // get the info from tag file
                this.implementsIterationTag = false;
                this.implementsBodyTag = false;
  @@ -975,7 +979,6 @@
        public void setTagData(TagData tagData) {
            this.tagData = tagData;
            this.varInfos = tagInfo.getVariableInfo(tagData);
  -         determineNestedVarInfos();
        }
   
        public TagData getTagData() {
  @@ -1034,8 +1037,56 @@
            return varInfos;
        }
   
  -     public VariableInfo[] getNestedVariableInfos() {
  -         return nestedVarInfos;
  +     public void setCustomTagParent(Node.CustomTag n) {
  +         this.customTagParent = n;
  +     }
  +
  +     public Node.CustomTag getCustomTagParent() {
  +         return this.customTagParent;
  +     }
  +
  +     public void setNumCount(Integer count) {
  +         this.numCount = count;
  +     }
  +
  +     public Integer getNumCount() {
  +         return this.numCount;
  +     }
  +
  +     public void setScriptingVars(Vector vec, int scope) {
  +         switch (scope) {
  +         case VariableInfo.AT_BEGIN:
  +             this.atBeginScriptingVars = vec;
  +             break;
  +         case VariableInfo.AT_END:
  +             this.atEndScriptingVars = vec;
  +             break;
  +         case VariableInfo.NESTED:
  +             this.nestedScriptingVars = vec;
  +             break;
  +         }
  +     }
  +
  +     /*
  +      * Gets the scripting variables for the given scope that need to be
  +      * declared.
  +      */
  +     public Vector getScriptingVars(int scope) {
  +         Vector vec = null;
  +
  +         switch (scope) {
  +         case VariableInfo.AT_BEGIN:
  +             vec = this.atBeginScriptingVars;
  +             break;
  +         case VariableInfo.AT_END:
  +             vec = this.atEndScriptingVars;
  +             break;
  +         case VariableInfo.NESTED:
  +             vec = this.nestedScriptingVars;
  +             break;
  +         }
  +
  +         return vec;
        }
   
        /*
  @@ -1105,7 +1156,7 @@
         * 
         * @return Custom tag's nesting level
         */
  -     private int computeCustomNestingLevel() {
  +     private int makeCustomNestingLevel() {
            int n = 0;
            Node p = parent;
            while (p != null) {
  @@ -1116,63 +1167,6 @@
                p = p.parent;
            }
            return n;
  -     }
  -
  -     /*
  -      * Determines all the scripting variables with NESTED scope contained
  -      * in this custom action's VariableInfo[] that are not already
  -      * contained in the VariableInfo[] of a custom action of the same type
  -      * in the parent chain.
  -      */
  -     private void determineNestedVarInfos() {
  -
  -         if (varInfos == null) {
  -             return;
  -         }
  -
  -         Vector vec = new Vector();
  -
  -         if (customNestingLevel == 0) {
  -             // tag not nested inside itself
  -             for (int i=0; i<varInfos.length; i++) {
  -                 if (varInfos[i].getScope() == VariableInfo.NESTED
  -                         && varInfos[i].getDeclare()) {
  -                     vec.add(varInfos[i]);
  -                 }
  -             }
  -         } else {
  -             for (int i=0; i<varInfos.length; i++) {
  -                 if (varInfos[i].getScope() != VariableInfo.NESTED
  -                         || !varInfos[i].getDeclare()) {
  -                     continue;
  -                 }
  -                 Node p = parent;
  -                 boolean found = false;
  -                 while ((p != null) && !found) {
  -                     if ((p instanceof Node.CustomTag)
  -                             && name.equals(((Node.CustomTag) p).name)) {
  -                         VariableInfo[] parentVarInfos
  -                             = ((Node.CustomTag) p).getVariableInfos();
  -                         for (int j=0; j<parentVarInfos.length; j++) {
  -                             if (varInfos[i].getVarName().equals(
  -                                         parentVarInfos[j].getVarName())) {
  -                                 found = true;
  -                                 break;
  -                             }
  -                         }
  -                     }
  -                     p = p.parent;
  -                 }
  -                 if (p == null) {
  -                     vec.add(varInfos[i]);
  -                 }
  -             }                   
  -         }
  -
  -         if (vec.size() > 0) {
  -             nestedVarInfos =
  -                 (VariableInfo[]) vec.toArray(new VariableInfo[vec.size()]);
  -         }
        }
       }
   
  
  
  
  1.1                  
jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ScriptingVariabler.java
  
  Index: ScriptingVariabler.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ScriptingVariabler.java,v
 1.1 2002/08/16 23:18:54 luehe Exp $
   * $Revision: 1.1 $
   * $Date: 2002/08/16 23:18:54 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  package org.apache.jasper.compiler;
  
  import java.util.*;
  import javax.servlet.jsp.tagext.*;
  import org.apache.jasper.JasperException;
  
  /**
   * Class responsible for determining the scripting variables that every
   * custom action needs to declare.
   *
   * @author Jan Luehe
   */
  public class ScriptingVariabler {
  
      private static final Integer MAX_SCOPE = new Integer(Integer.MAX_VALUE);
  
      /*
       * Assigns an identifier (of type integer) to every custom tag, in order
       * to help identify, for every custom tag, the scripting variables that it
       * needs to declare.
       */
      static class CustomTagCounter extends Node.Visitor {
  
        private int count;
        private Node.CustomTag parent;
  
        public void visit(Node.CustomTag n) throws JasperException {
            n.setCustomTagParent(parent);
            Node.CustomTag tmpParent = parent;
            parent = n;
            visitBody(n);
            parent = tmpParent;
            n.setNumCount(new Integer(count++));
        }
      }
  
      /*
       * For every custom tag, determines the scripting variables it needs to
       * declare. 
       */
      static class ScriptingVariableVisitor extends Node.Visitor {
  
        private Hashtable scriptVars;
  
        public ScriptingVariableVisitor() {
            scriptVars = new Hashtable();
        }
  
        public void visit(Node.CustomTag n) throws JasperException {
            setScriptingVars(n, VariableInfo.AT_BEGIN);
            setScriptingVars(n, VariableInfo.NESTED);
            visitBody(n);
            setScriptingVars(n, VariableInfo.AT_END);
        }
  
        private void setScriptingVars(Node.CustomTag n, int scope) {
  
            TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
            VariableInfo[] varInfos = n.getVariableInfos();
            if (tagVarInfos == null && varInfos == null) {
                return;
            }
  
            Vector vec = new Vector();
  
            Integer ownRange = null;
            Node.CustomTag parent = n.getCustomTagParent();
            if (parent == null)
                ownRange = MAX_SCOPE;
            else
                ownRange = parent.getNumCount();
  
            if (tagVarInfos != null) {
                for (int i=0; i<tagVarInfos.length; i++) {
                    if (tagVarInfos[i].getScope() != scope
                            || !tagVarInfos[i].getDeclare()) {
                        continue;
                    }
                    String varName = tagVarInfos[i].getNameGiven();
                    if (varName == null) {
                        varName = n.getTagData().getAttributeString(
                                        tagVarInfos[i].getNameFromAttribute());
                    }
  
                    if (scope == VariableInfo.AT_BEGIN 
                            || scope == VariableInfo.AT_END
                            || (scope == VariableInfo.NESTED
                                && !n.implementsBodyTag())) {
                        Integer currentRange =
                            (Integer) scriptVars.get(varName);
                        if (currentRange == null
                                || ownRange.compareTo(currentRange) > 0) {
                            scriptVars.put(varName, ownRange);
                            vec.add(tagVarInfos[i]);
                        }
                    } else {
                        // scope equals NESTED AND node implements BodyTag
                        if (n.getCustomNestingLevel() == 0) {
                            vec.add(tagVarInfos[i]);
                        }
                    }
                }
            } else {
                for (int i=0; i<varInfos.length; i++) {
                    if (varInfos[i].getScope() != scope
                            || !varInfos[i].getDeclare()) {
                        continue;
                    }
                    String varName = varInfos[i].getVarName();
  
                    if (scope == VariableInfo.AT_BEGIN 
                            || scope == VariableInfo.AT_END
                            || (scope == VariableInfo.NESTED
                                && !n.implementsBodyTag())) {
                        Integer currentRange =
                            (Integer) scriptVars.get(varName);
                        if (currentRange == null
                                || ownRange.compareTo(currentRange) > 0) {
                            scriptVars.put(varName, ownRange);
                            vec.add(varInfos[i]);
                        }
                    } else {
                        // scope equals NESTED AND node implements BodyTag
                        if (n.getCustomNestingLevel() == 0) {
                            vec.add(tagVarInfos[i]);
                        }
                    }
                }
            }
  
            n.setScriptingVars(vec, scope);
        }
      }
  
      public static void set(Node.Nodes page) throws JasperException {
        page.visit(new CustomTagCounter());
        page.visit(new ScriptingVariableVisitor());
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to