tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pete Gordon <PGor...@fourthchannel.com>
Subject Re: [PATCH] Custom tag scripting variables
Date Thu, 11 Jul 2002 14:44:03 GMT
Jan, 

I found another issue, while trying to port our application from weblogic.
It seems that if you have declared variables with the same name in tags that
are nested (even when the tags are different tags) it creates the same
problem where the code cannot be compiled.  The fix is going to have to not
only look for self nested tags, but self nested tags that declare the same
variable names.  If the short tag name was added to the variable name in
addition to the counter that was added with the patch, I think it would fix
the problem.  But the first declaration needs the tag it is being declared
for specified. 

example: 

<fci:collection>     //declares iPerPage variables 
	<fci:element>  //declares a iPerPage variable 
	</fci:element> 
</fci:collection> 

Pete Gordon 

On Wednesday, June 12, 2002, at 05:59 PM, Jan Luehe wrote: 


> As discussed with Kin-Man, the following patch (for Jasper2) 
> addresses two issues related to scripting variables exposed by 
> custom tags (via TagExtraInfo class or TLD): 
> 
> ISSUE 1: 
> +++++++ 
> According to the JSP spec, scripting variables with scope AT_BEGIN 
> or AT_END are supposed to be visible from the begin element or end 
> element, respectively, of the custom tag that is exposing them, all 
> the way to the *end* of the page. This currently is not the case. 
> 
> The attached patch addresses this problem by determining the AT_BEGIN 
> and AT_END scripting variables of any custom tag and declaring them as 
> local variables of the _jspService() method. 
> 
> 
> ISSUE 2: 
> +++++++ 
> If a custom tag exposing scripting variables is nested inside 
> itself, its scripting variables get declared multiple times within the 
> same scope of the generated code, resulting in compilation 
> errors. This problem has been filed as bug #8926 (Synopsis: "Duplicate 
> variable definition in generated Java source, related to custom tag 
> scripting variable"). 
> 
> The attached patch addresses this problem by declaring AT_BEGIN and 
> AT_END scripting variables once (as local variables of the 
> _jspService() method, see above), and declaring NESTED scripting 
> variables only at the outermost nesting level of their custom tag, 
> where "nesting level" corresponds the number of times the custom tag is 
> nested inside itself. 
> 
> Example: 
> 
>   <g:h> 
>     <a:b> -- nesting level 0, declares NESTED scripting variables 
>       <c:d> 
>         <e:f> 
>           <a:b> -- nesting level 1, saves scripting variables 
>             <a:b> -- nesting level 2, saves scripting variables 
>             </a:b> -- restores scripting variables 
>           </a:b> -- restores scripting variables 
>           <a:b> -- nesting level 1, saves scripting variables 
>           </a:b> -- restores scripting variables 
>         </e:f> 
>       </c:d> 
>     </a:b> 
>     <a:b> -- nesting level 0, does not declare any NESTED scripting
> variables 
>     </a:b> 
>   </g:h> 
> 
> If <a:b> exposes any NESTED scripting variables, those variables are 
> going to be declared only once in the generated code, namely by the 
> *first* <a:b> at nesting level 0. 
> 
> Any <a:b> with a nesting level > 0 saves (in its begin element) the 
> current values of all its scripting variables to locale variables (named 
> for the scripting variable and the custom tag's nesting level) before 
> synchronizing the scripting variables as defined by the JSP spec. In 
> its end element, the custom tag restores the original values of the 
> scripting variables (that is, the values the scripting variables had when 
> the tag's begin element was encountered). 
> 
> 
> In addition, this patch stores a custom tag's scripting variables with 
> the custom tag itself, so the scripting variables don't need to be 
> determined over and over again. 
> This has resulted in two new accessor methods for Node.CustomTag: 
> 
> 	public TagVariableInfo[] getTagVariableInfos() 
> 	public VariableInfo[] getVariableInfos() 
> 
> 
> Let me know if there are any problems with this patch. 
> 
> 
> Thanks, 
> 
> 
> Jan 
> 
> Executing ssh-askpass to query the password... 
> Warning: Remote host denied X11 forwarding, perhaps xauth program could
> not be run on the server side. 
> ? build.properties 
> ? build 
> ? src/share/org/apache/jasper/compiler/Generator.java.SAVE 
> cvs server: Diffing . 
> cvs server: Diffing doc 
> cvs server: Diffing src 
> cvs server: Diffing src/bin 
> cvs server: Diffing src/share 
> cvs server: Diffing src/share/org 
> cvs server: Diffing src/share/org/apache 
> cvs server: Diffing src/share/org/apache/jasper 
> cvs server: Diffing src/share/org/apache/jasper/compiler 
> Index: src/share/org/apache/jasper/compiler/Generator.java 
> =================================================================== 
> RCS file:
> /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compil
> er/Generator.java,v 
> retrieving revision 1.23 
> diff -u -r1.23 Generator.java 
> --- src/share/org/apache/jasper/compiler/Generator.java	10 Jun 2002
> 21:08:30 -0000	1.23 
> +++ src/share/org/apache/jasper/compiler/Generator.java	12 Jun 2002
> 21:49:23 -0000 
> @@ -184,13 +184,15 @@ 
>  	     */ 
>  	    public void visit(Node.CustomTag n) throws JasperException { 
>  		 
> +		// Create tag handler pool name and assign it to node 
>  		String name = createTagHandlerPoolName(n.getPrefix(), 
> -							n.getShortName(), 
> -							n.getAttributes()); 
> +						       n.getShortName(), 
> +						       n.getAttributes()); 
>  		n.setTagHandlerPoolName(name); 
>  		if (!names.contains(name)) { 
>  		    names.add(name); 
>  		} 
> + 
>  		visitBody(n); 
>  	    } 
> 
> @@ -235,6 +237,80 @@ 
>  	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) 
> +	    throws JasperException { 
> + 
> +	class ScriptingVariableDeclarationVisitor extends Node.Visitor { 
> + 
> +	    /* 
> +	     * Vector keeping track of which scripting variables have
> already 
> +	     * been declared 
> +	     */ 
> +	    private Vector scriptVars; 
> + 
> +	    /* 
> +	     * Constructor. 
> +	     */ 
> +	    public ScriptingVariableDeclarationVisitor() { 
> +		scriptVars = 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); 
> +			} 
> +		    } 
> +		} 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); 
> +			} 
> +		    } 
> +		} 
> + 
> +		visitBody(n); 
> +	    } 
> +	} 
> + 
> +	page.visit(new ScriptingVariableDeclarationVisitor()); 
> +    } 
> + 
>      /** 
>       * Generates the destroy() method which is responsible for calling
> the 
>       * release() method on every tag handler in any of the tag handler
> pools. 
> @@ -376,6 +452,10 @@ 
>          if (maxTagNesting > 0) { 
>  	    out.printil("JspxState _jspxState = new JspxState();"); 
>          } 
> +	out.println(); 
> + 
> +	declareAtBeginAtEndScriptingVariables(page); 
> +	out.println(); 
> 
>  	out.printil("try {"); 
>  	out.pushIndent(); 
> @@ -470,14 +550,26 @@ 
>  	private ServletWriter out; 
>  	private MethodsBuffer methodsBuffer; 
> 
> +	/* 
> +	 * Maps temporary scripting variable to parent of custom tag that 
> +	 * declared it 
> +	 */ 
> +	private Hashtable tmpVars; 
> + 
> +	// Maps NESTED scripting var to parent of custom tag that declared
> it 
> +	private Hashtable nestedVars; 
> + 
>  	/** 
>  	 * Constructor. 
>  	 */ 
> -	public GenerateVisitor(ServletWriter out, MethodsBuffer
> methodsBuffer) { 
> +	public GenerateVisitor(ServletWriter out, 
> +			       MethodsBuffer methodsBuffer) { 
>  	    this.out = out; 
>  	    this.methodsBuffer = methodsBuffer; 
>  	    handlerInfos = new Hashtable(); 
>  	    tagVarNumbers = new Hashtable(); 
> +	    tmpVars = new Hashtable(); 
> +	    nestedVars = new Hashtable(); 
>  	} 
> 
>  	/** 
> @@ -976,16 +1068,8 @@ 
> 
>          public void visit(Node.CustomTag n) throws JasperException { 
> 
> -	    TagLibraryInfo tagLibInfo = (TagLibraryInfo) 
> -		pageInfo.getTagLibraries().get(n.getPrefix()); 
> -	    TagInfo tagInfo = tagLibInfo.getTag(n.getShortName()); 
> - 
> -	    // Get info on scripting variables created/manipulated by tag 
> -	    VariableInfo[] varInfos =
> tagInfo.getVariableInfo(n.getTagData()); 
> -	    TagVariableInfo[] tagVarInfos = tagInfo.getTagVariableInfos(); 
> - 
> -	    Hashtable handlerInfosByShortName 
> -		= (Hashtable) handlerInfos.get(n.getPrefix()); 
> +	    Hashtable handlerInfosByShortName = (Hashtable) 
> +		handlerInfos.get(n.getPrefix()); 
>  	    if (handlerInfosByShortName == null) { 
>  		handlerInfosByShortName = new Hashtable(); 
>  		handlerInfos.put(n.getPrefix(), handlerInfosByShortName); 
> @@ -993,8 +1077,11 @@ 
>  	    TagHandlerInfo handlerInfo = (TagHandlerInfo) 
>  		handlerInfosByShortName.get(n.getShortName()); 
>  	    if (handlerInfo == null) { 
> -		handlerInfo = new TagHandlerInfo(n,
> tagInfo.getTagClassName(), 
> -						 ctxt.getClassLoader(),
> err); 
> +		handlerInfo = new TagHandlerInfo( 
> +		                            n, 
> +
> n.getTagInfo().getTagClassName(), 
> +					    ctxt.getClassLoader(), 
> +					    err); 
>  		handlerInfosByShortName.put(n.getShortName(), handlerInfo); 
>  	    } 
> 
> @@ -1008,8 +1095,9 @@ 
>  	    // to a method. 
>  	    ServletWriter outSave = null; 
>  	    MethodsBuffer methodsBufferSave = null; 
> -	    if (n.isScriptless() && varInfos == null && 
> -			(tagVarInfos == null || tagVarInfos.length == 0)) { 
> +	    if (n.isScriptless() && n.getVariableInfos() == null && 
> +			(n.getTagVariableInfos() == null 
> +			 || n.getTagVariableInfos().length == 0)) { 
>  		// The tag handler and its body code can reside in a
> separate 
>  		// method if it is scriptless and does not have any
> scripting 
>  		// variable defined. 
> @@ -1073,20 +1161,19 @@ 
>  	    } 
> 
>  	    // Generate code for start tag, body, and end tag 
> -	    generateCustomStart(n, varInfos, tagVarInfos, handlerInfo, 
> -				tagHandlerVar, tagEvalVar); 
> +	    generateCustomStart(n, handlerInfo, tagHandlerVar, tagEvalVar); 
> 
>  	    String tmpParent = parent; 
>  	    parent = tagHandlerVar; 
>  	    visitBody(n); 
> 
>  	    parent = tmpParent; 
> -	    generateCustomEnd(n, varInfos, tagVarInfos, 
> -			      handlerInfo.getTagHandlerClass(),
> tagHandlerVar, 
> -			      tagEvalVar); 
> +	    generateCustomEnd(n, handlerInfo.getTagHandlerClass(), 
> +			      tagHandlerVar, tagEvalVar); 
> 
> -	    if (n.isScriptless() && varInfos == null && 
> -			(tagVarInfos == null || tagVarInfos.length == 0)) { 
> +	    if (n.isScriptless() && n.getVariableInfos() == null && 
> +	    		(n.getTagVariableInfos() == null 
> +			 || n.getTagVariableInfos().length == 0)) { 
>  		// Generate end of method 
>  		out.popIndent(); 
>  		out.printil("}"); 
> @@ -1202,23 +1289,33 @@ 
>  	} 
> 
>  	private void generateCustomStart(Node.CustomTag n, 
> -					 VariableInfo[] varInfos, 
> -					 TagVariableInfo[] tagVarInfos, 
>  					 TagHandlerInfo handlerInfo, 
>  					 String tagHandlerVar, 
>  					 String tagEvalVar) 
>  	                    throws JasperException { 
> 
> +	    Class tagHandlerClass = handlerInfo.getTagHandlerClass(); 
> + 
>  	    n.setBeginJavaLine(out.getJavaLine()); 
>  	    out.printin("/* ----  "); 
>  	    out.print(n.getName()); 
>  	    out.println(" ---- */"); 
> 
> -	    Class tagHandlerClass = handlerInfo.getTagHandlerClass(); 
> - 
>              boolean implementsTryCatchFinally = 
>                  TryCatchFinally.class.isAssignableFrom(tagHandlerClass); 
> 
> +	    /* 
> +	     * Declare variables where current contents of scripting
> variables 
> +	     * will be temporarily saved 
> +	     */ 
> +	    declareTemporaryScriptingVariables(n); 
> + 
> +	    // Declare scripting variables with NESTED scope 
> +	    declareNestedScriptingVariables(n); 
> + 
> +	    // Save current value of scripting variables if required 
> +	    saveScriptingVariables(n); 
> + 
>  	    out.printin(tagHandlerClass.getName()); 
>  	    out.print(" "); 
>  	    out.print(tagHandlerVar); 
> @@ -1245,9 +1342,8 @@ 
>  	    boolean isBodyTag 
>  		= BodyTag.class.isAssignableFrom(tagHandlerClass); 
> 
> -	    // Declare and synchronize AT_BEGIN scripting variables 
> -	    syncScriptingVariables(varInfos, tagVarInfos, n.getTagData(), 
> -				   VariableInfo.AT_BEGIN, true); 
> +	    // Synchronize AT_BEGIN scripting variables 
> +	    syncScriptingVariables(n, VariableInfo.AT_BEGIN); 
> 
>  	    if (n.getBody() != null) { 
>  		out.printin("if ("); 
> @@ -1295,23 +1391,21 @@ 
>  		} 
>  	    } 
> 
> - 
> -	    // Declare and synchronize NESTED scripting variables 
> -	    syncScriptingVariables(varInfos, tagVarInfos, n.getTagData(), 
> - 				   VariableInfo.NESTED, true); 
> +	    // Synchronize NESTED scripting variables 
> +	    syncScriptingVariables(n, VariableInfo.NESTED); 
> 
>  	    // Synchronize AT_BEGIN scripting variables 
> -	    syncScriptingVariables(varInfos, tagVarInfos, n.getTagData(), 
> -				   VariableInfo.AT_BEGIN, false); 
> +	    syncScriptingVariables(n, VariableInfo.AT_BEGIN); 
>  	}; 
>  	 
>  	private void generateCustomEnd(Node.CustomTag n, 
> -				       VariableInfo[] varInfos, 
> -				       TagVariableInfo[] tagVarInfos, 
> -				       Class tagHandlerClass, 
> +				       Class tagHandlerClass,  
>  				       String tagHandlerVar, 
>  				       String tagEvalVar) { 
> 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> + 
>  	    boolean implementsIterationTag =  
>  		IterationTag.class.isAssignableFrom(tagHandlerClass); 
>  	    boolean implementsBodyTag =  
> @@ -1327,8 +1421,7 @@ 
>  	    } 
> 
>  	    // Synchronize AT_BEGIN scripting variables 
> -	    syncScriptingVariables(varInfos, tagVarInfos, n.getTagData(), 
> -				   VariableInfo.AT_BEGIN, false); 
> +	    syncScriptingVariables(n, VariableInfo.AT_BEGIN); 
> 
>  	    if (n.getBody() != null) { 
>  		if (implementsBodyTag) { 
> @@ -1373,35 +1466,234 @@ 
>  		out.print(tagHandlerVar); 
>  		out.println(");"); 
>                  out.popIndent(); 
> -                out.printil("}"); 
> +                out.println("}"); 
>              } else { 
>                  out.printin(n.getTagHandlerPoolName()); 
> -                out.println(".reuse("); 
> -		out.printin(tagHandlerVar); 
> +                out.print(".reuse("); 
> +		out.print(tagHandlerVar); 
>  		out.println(");"); 
>  	    } 
> 
> -	    // Declare and synchronize AT_END variables 
> -	    syncScriptingVariables(varInfos, tagVarInfos, n.getTagData(), 
> -				   VariableInfo.AT_END, true); 
> +	    // Synchronize AT_END variables 
> +	    syncScriptingVariables(n, VariableInfo.AT_END); 
> + 
> +	    restoreScriptingVariables(n); 
> 
>  	    n.setEndJavaLine(out.getJavaLine()); 
>  	} 
> 
> -	private void syncScriptingVariables(VariableInfo[] varInfos, 
> -					    TagVariableInfo[] tagVarInfos, 
> -					    TagData tagData, 
> -					    int scope, 
> -					    boolean declare) { 
> +	/* 
> +	 * Declares any NESTED scripting variables of the given custom tag, 
> +	 * if the given custom tag is not nested inside itself (i.e, has a 
> +	 * nesting level of zero). In addition, a NESTED scripting variable
> is  
> +	 * declared only if it has not already been declared in the same
> scope 
> +	 * in the generated code, that is, if this custom tag's parent is 
> +	 * different from the parent of the custom tag that may already have
> 
> +	 * declared this variable. 
> +	 */ 
> +	private void declareNestedScriptingVariables(Node.CustomTag n) { 
> +	    if (n.getCustomNestingLevel() > 0) { 
> +		return; 
> +	    } 
> + 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
>  	    if ((varInfos == null) && (tagVarInfos == null)) { 
>  		return; 
>  	    } 
> + 
>  	    if (varInfos != null) { 
>  		for (int i=0; i<varInfos.length; i++) { 
> -		    if (varInfos[i].getScope() == scope) { 
> -			if (declare && varInfos[i].getDeclare()) { 
> -			    out.printin(varInfos[i].getClassName() + " "); 
> +		    if ((varInfos[i].getScope() == VariableInfo.NESTED) 
> +			    && varInfos[i].getDeclare()) { 
> +			String name = varInfos[i].getVarName(); 
> +			Node parent = (Node) nestedVars.get(name); 
> +			if ((parent == null) || (parent != n.getParent())) {
> 
> +			    out.printin(varInfos[i].getClassName()); 
> +			    out.print(" "); 
> +			    out.print(name); 
> +			    out.println(";"); 
> +			    nestedVars.put(name, n.getParent()); 
> +			} 
> +		    } 
> +		} 
> +	    } 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()); 
>  			} 
> +			Node parent = (Node) nestedVars.get(name); 
> +			if ((parent == null) || (parent != n.getParent())) {
> 
> +			    out.printin(tagVarInfos[i].getClassName()); 
> +			    out.print(" "); 
> +			    out.print(name); 
> +			    out.println(";"); 
> +			    nestedVars.put(name, n.getParent()); 
> +			} 
> +		    } 
> +		} 
> +	    } 
> +	} 
> + 
> +	/* 
> +	 * For every scripting variable exposed by this custom tag, declares
> 
> +	 * a variable where the current value of the scripting variable may 
> +	 * be saved, so it can later be restored in this custom tag's end 
> +	 * element. 
> +	 */ 
> +	private void declareTemporaryScriptingVariables(Node.CustomTag n) { 
> +	    if (n.getCustomNestingLevel() == 0) { 
> +		return; 
> +	    } 
> + 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
> +	    if ((varInfos == null) && (tagVarInfos == null)) { 
> +		return; 
> +	    } 
> + 
> +	    if (varInfos != null) { 
> +		for (int i=0; i<varInfos.length; i++) { 
> +		    String tmpVarName = "_jspx_" + varInfos[i].getVarName() 
> +			+ "_" + n.getCustomNestingLevel(); 
> +		    Node parent = (Node) tmpVars.get(tmpVarName); 
> +		    if ((parent == null) || (parent != n.getParent())) { 
> +			out.printin(varInfos[i].getClassName()); 
> +			out.print(" "); 
> +			out.print(tmpVarName); 
> +			out.println(";"); 
> +			tmpVars.put(tmpVarName, n.getParent()); 
> +		    } 
> +		} 
> +	    } else { 
> +		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(); 
> +		    Node parent = (Node) tmpVars.get(tmpVarName); 
> +		    if ((parent == null) || (parent != n.getParent())) { 
> +			out.printin(tagVarInfos[i].getClassName()); 
> +			out.print(" "); 
> +			out.print(tmpVarName); 
> +			out.println(";"); 
> +			tmpVars.put(tmpVarName, n.getParent()); 
> +		    } 
> +		} 
> +	    } 
> +	} 
> + 
> +	/* 
> +	 * For each scripting variable of a custom tag with a nesting level 
> +	 * greater than 0, save its value to a temporary variable so that
> the 
> +	 * scripting variable can be synchronized inside the nested custom
> tag 
> +	 * without affecting the value it had at the start element of the 
> +	 * custom tag, which will be restored when the end element of the 
> +	 * custom tag is reached. 
> +	 */ 
> +	private void saveScriptingVariables(Node.CustomTag n) { 
> +	    if (n.getCustomNestingLevel() == 0) { 
> +		return; 
> +	    } 
> + 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
> +	    if ((varInfos == null) && (tagVarInfos == null)) { 
> +		return; 
> +	    } 
> + 
> +	    if (varInfos != null) { 
> +		for (int i=0; i<varInfos.length; i++) { 
> +		    String varName = varInfos[i].getVarName(); 
> +		    String tmpVarName = "_jspx_" + varName + "_" 
> +			+ n.getCustomNestingLevel(); 
> +		    out.printin(tmpVarName); 
> +		    out.print(" = "); 
> +		    out.print(varName); 
> +		    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()); 
> +		    } 
> +		    String tmpVarName = "_jspx_" + varName + "_" 
> +			+ n.getCustomNestingLevel(); 
> +		    out.printin(tmpVarName); 
> +		    out.print(" = "); 
> +		    out.print(varName); 
> +		    out.println(";"); 
> +		} 
> +	    } 
> +	} 
> + 
> +	/* 
> +	 * For each scripting variable of a custom tag with a nesting level 
> +	 * greater than 0, restore its original value that was saved in the 
> +	 * start element of the custom tag. 
> +	 */ 
> +	private void restoreScriptingVariables(Node.CustomTag n) { 
> +	    if (n.getCustomNestingLevel() == 0) { 
> +		return; 
> +	    } 
> + 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
> +	    if ((varInfos == null) && (tagVarInfos == null)) { 
> +		return; 
> +	    } 
> + 
> +	    if (varInfos != null) { 
> +		for (int i=0; i<varInfos.length; i++) { 
> +		    String varName = varInfos[i].getVarName(); 
> +		    String tmpVarName = "_jspx_" + varName + "_" 
> +			+ n.getCustomNestingLevel(); 
> +		    out.printin(varName); 
> +		    out.print(" = "); 
> +		    out.print(tmpVarName); 
> +		    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()); 
> +		    } 
> +		    String tmpVarName = "_jspx_" + varName + "_" 
> +			+ n.getCustomNestingLevel(); 
> +		    out.printin(varName); 
> +		    out.print(" = "); 
> +		    out.print(tmpVarName); 
> +		    out.println(";"); 
> +		} 
> +	    } 
> +	} 
> + 
> +	/* 
> +	 * Synchronizes the scripting variables of the given custom tag for 
> +	 * the given scope. 
> +	 */ 
> +	private void syncScriptingVariables(Node.CustomTag n, int scope) { 
> +	    TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); 
> +	    VariableInfo[] varInfos = n.getVariableInfos(); 
> + 
> +	    if ((varInfos == null) && (tagVarInfos == null)) { 
> +		return; 
> +	    } 
> + 
> +	    if (varInfos != null) { 
> +		for (int i=0; i<varInfos.length; i++) { 
> +		    if (varInfos[i].getScope() == scope) { 
>  			out.printin(varInfos[i].getVarName()); 
>  			out.print(" = ("); 
>  			out.print(varInfos[i].getClassName()); 
> @@ -1412,14 +1704,11 @@ 
>  		} 
>  	    } else { 
>  		for (int i=0; i<tagVarInfos.length; i++) { 
> -		    String name = tagVarInfos[i].getNameGiven(); 
> -		    if (name == null) { 
> -			name = tagData.getAttributeString( 
> -
> tagVarInfos[i].getNameFromAttribute()); 
> -		    } 
>  		    if (tagVarInfos[i].getScope() == scope) { 
> -			if (declare && tagVarInfos[i].getDeclare()) { 
> -			    out.printin(tagVarInfos[i].getClassName() + "
> "); 
> +			String name = tagVarInfos[i].getNameGiven(); 
> +			if (name == null) { 
> +			    name = n.getTagData().getAttributeString( 
> +
> tagVarInfos[i].getNameFromAttribute()); 
>  			} 
>  			out.printin(name); 
>  			out.print(" = ("); 
> Index: src/share/org/apache/jasper/compiler/JspDocumentParser.java 
> =================================================================== 
> RCS file:
> /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compil
> er/JspDocumentParser.java,v 
> retrieving revision 1.1.1.1 
> diff -u -r1.1.1.1 JspDocumentParser.java 
> --- src/share/org/apache/jasper/compiler/JspDocumentParser.java	28
> Mar 2002 18:46:15 -0000	1.1.1.1 
> +++ src/share/org/apache/jasper/compiler/JspDocumentParser.java	12
> Jun 2002 21:49:23 -0000 
> @@ -62,7 +62,7 @@ 
> 
>  import java.io.*; 
>  import java.util.Hashtable; 
> -import javax.servlet.jsp.tagext.TagLibraryInfo; 
> +import javax.servlet.jsp.tagext.*; 
>  import javax.xml.parsers.SAXParserFactory; 
>  import javax.xml.parsers.ParserConfigurationException; 
>  import javax.xml.parsers.SAXParser; 
> @@ -401,13 +401,14 @@ 
>          if (tagLibInfo == null) { 
>              return null; 
>  	} 
> -        if (tagLibInfo.getTag(shortName) == null) { 
> +        TagInfo tagInfo = tagLibInfo.getTag(shortName); 
> +	if (tagInfo == null) { 
>  	    throw new SAXException(err.getString("jsp.error.bad_tag", 
>  						 shortName, prefix)); 
>  	} 
> 
>  	return new Node.CustomTag(attrs, start, qName, prefix, shortName, 
> -				  parent); 
> +				  tagInfo, parent); 
>      } 
> 
>      /* 
> Index: src/share/org/apache/jasper/compiler/Node.java 
> =================================================================== 
> RCS file:
> /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compil
> er/Node.java,v 
> retrieving revision 1.12 
> diff -u -r1.12 Node.java 
> --- src/share/org/apache/jasper/compiler/Node.java	8 Jun 2002 00:14:35
> -0000	1.12 
> +++ src/share/org/apache/jasper/compiler/Node.java	12 Jun 2002 21:49:23
> -0000 
> @@ -62,7 +62,7 @@ 
> 
>  import java.util.*; 
>  import java.io.CharArrayWriter; 
> -import javax.servlet.jsp.tagext.TagData; 
> +import javax.servlet.jsp.tagext.*; 
>  import org.xml.sax.Attributes; 
>  import org.apache.jasper.JasperException; 
> 
> @@ -670,13 +670,19 @@ 
>  	private boolean hasIncludeAction; 
>  	private boolean hasSetProperty; 
>  	private String tagHandlerPoolName; 
> +	private TagInfo tagInfo; 
> +	private VariableInfo[] varInfos; 
> +	private int nestingLevel; 
> 
>  	public CustomTag(Attributes attrs, Mark start, String name, 
> -			 String prefix, String shortName, Node parent) { 
> +			 String prefix, String shortName, 
> +			 TagInfo tagInfo, Node parent) { 
>  	    super(attrs, start, parent); 
>  	    this.name = name; 
>  	    this.prefix = prefix; 
>  	    this.shortName = shortName; 
> +	    this.tagInfo = tagInfo; 
> +	    this.nestingLevel = computeCustomNestingLevel(); 
>  	} 
> 
>  	public void accept(Visitor v) throws JasperException { 
> @@ -714,6 +720,7 @@ 
>  	 
>  	public void setTagData(TagData tagData) { 
>  	    this.tagData = tagData; 
> +	    this.varInfos = tagInfo.getVariableInfo(tagData); 
>  	} 
> 
>  	public TagData getTagData() { 
> @@ -752,14 +759,68 @@ 
>  	    return hasSetProperty; 
>  	} 
> 
> +	public void setTagHandlerPoolName(String s) { 
> +	    tagHandlerPoolName = s; 
> +	} 
> + 
>  	public String getTagHandlerPoolName() { 
>  	    return tagHandlerPoolName; 
>  	} 
> 
> -	public void setTagHandlerPoolName(String s) { 
> -	    tagHandlerPoolName = s; 
> +	public TagInfo getTagInfo() { 
> +	    return tagInfo; 
> +	} 
> + 
> +	public TagVariableInfo[] getTagVariableInfos() { 
> +	    return tagInfo.getTagVariableInfos(); 
>  	} 
> 
> +	public VariableInfo[] getVariableInfos() { 
> +	    return varInfos; 
> +	} 
> + 
> +	/* 
> +	 * Gets this custom tag's nesting level. 
> +	 */ 
> +	public int getCustomNestingLevel() { 
> +	    return nestingLevel; 
> +	} 
> + 
> +	/* 
> +	 * Computes this custom tag's nesting level, which corresponds to
> the 
> +	 * number of times this custom tag is nested inside itself. 
> +	 * 
> +	 * Example: 
> +	 *  
> +	 *  <g:h> 
> +	 *    <a:b> -- nesting level 0 
> +	 *      <c:d> 
> +	 *        <e:f> 
> +	 *          <a:b> -- nesting level 1 
> +	 *            <a:b> -- nesting level 2 
> +	 *            </a:b> 
> +	 *          </a:b> 
> +	 *          <a:b> -- nesting level 1 
> +	 *          </a:b> 
> +	 *        </e:f> 
> +	 *      </c:d> 
> +	 *    </a:b> 
> +	 *  </g:h> 
> +	 *  
> +	 * @return Custom tag's nesting level 
> +	 */ 
> +	private int computeCustomNestingLevel() { 
> +	    int n = 0; 
> +	    Node p = parent; 
> +	    while (p != null) { 
> +		if ((p instanceof Node.CustomTag) 
> +		        && name.equals(((Node.CustomTag) p).name)) { 
> +		    n++; 
> +		} 
> +		p = p.parent; 
> +	    } 
> +	    return n; 
> +	} 
>      } 
> 
>      /** 
> Index: src/share/org/apache/jasper/compiler/Parser.java 
> =================================================================== 
> RCS file:
> /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compil
> er/Parser.java,v 
> retrieving revision 1.4 
> diff -u -r1.4 Parser.java 
> --- src/share/org/apache/jasper/compiler/Parser.java	7 Jun 2002 20:04:27
> -0000	1.4 
> +++ src/share/org/apache/jasper/compiler/Parser.java	12 Jun 2002 21:49:24
> -0000 
> @@ -704,7 +704,8 @@ 
>  	    reader.reset(start); 
>  	    return false; 
>  	} 
> -        if (tagLibInfo.getTag(shortTagName) == null) { 
> +        TagInfo tagInfo = tagLibInfo.getTag(shortTagName); 
> +	if (tagInfo == null) { 
>  	    err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix); 
>  	} 
> 
> @@ -716,7 +717,7 @@ 
>  	if (reader.matches("/>")) { 
>  	    // EmptyElemTag ::= '<' Name ( S Attribute )* S? '/>'# 
>  	    new Node.CustomTag(attrs, start, tagName, prefix, shortTagName, 
> -			       parent); 
> +			       tagInfo, parent); 
>  	    return true; 
>  	} 
>  	 
> @@ -729,10 +730,10 @@ 
>  	// Looking for a body, it still can be empty; but if there is a 
>  	// a tag body, its syntax would be dependent on the type of 
>  	// body content declared in TLD. 
> -	String bc = ((TagLibraryInfo)
> taglibs.get(prefix)).getTag(shortTagName).getBodyContent(); 
> +	String bc = tagInfo.getBodyContent(); 
> 
>  	Node tagNode = new Node.CustomTag(attrs, start, tagName, prefix, 
> -					  shortTagName, parent); 
> +					  shortTagName, tagInfo, parent); 
>  	// There are 3 body content types: empty, jsp, or tag-dependent. 
>  	if (bc.equalsIgnoreCase(TagInfo.BODY_CONTENT_EMPTY)) { 
>  	    if (!reader.matchesETag(tagName)) { 
> cvs server: Diffing src/share/org/apache/jasper/core 
> cvs server: Diffing src/share/org/apache/jasper/logging 
> cvs server: Diffing src/share/org/apache/jasper/resources 
> cvs server: Diffing src/share/org/apache/jasper/runtime 
> cvs server: Diffing src/share/org/apache/jasper/servlet 
> cvs server: Diffing src/share/org/apache/jasper/util 
> cvs server: Diffing src/share/org/apache/jasper/xmlparser 
> 
> -- 
> To unsubscribe, e-mail:
> <mailto:tomcat-dev-unsubscribe@jakarta.apache.org> 
> For additional commands, e-mail:
> <mailto:tomcat-dev-help@jakarta.apache.org> 
> 
> 
Pete Gordon 
fourthchannel  
1275 Kinnear Road  
Columbus, OH 43212 
Work: 614-340-1447 
Fax: 614-340-1449 
Email: pgordon@fourthchannel.com 

Customer Support: 866-205-1440 
Web: 
www.fourthchannel.com 
  

--
To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>


Mime
View raw message