Hi Costin,
> More info:
>
> The page is:
>
> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
>
> <logic:iterate id="id1" name="name1" property="prop1">
> <logic:iterate id="id2" name="name2" property="prop2">
> Foo
> </logic:iterate>
> </logic:iterate>
>
> I get:
>
> a$jsp.java:75:25:75:25: Error: No entity named "id2" was found in this
> environment.
>
> And the generated code is:
> .....
> /* ---- logic:iterate ---- */
> java.lang.Object _jspx_id2_1;
> _jspx_id2_1 = id2;
> org.apache.struts.taglib.logic.IterateTag
> _jspx_th_logic_iterate_1 = (org.apache.struts.taglib.logic.IterateTag)
>
_jspx_tagPool_logic_iterate_property_name_id.get(org.apache.struts.taglib.logic.
> IterateTag.class);
>
> ....
>
> No 'id2' is ever declared.
I was unable to reproduce the problem where a scripting variable is being
declared multiple times. That used to be a bug with Jasper, which we
fixed in Jasper2.
However, I was able to reproduce the above problem with nested
<logic:iterate> tags where 'id2' is never declared.
The nested <logic:iterate> did not declare any of its NESTED scripting
variables, since it assumed that those had already been declared by the
encapsulating <logic:iterate>. This approach did not take into account
the case where a tag's TEI determines the name of a scripting
variable from the tag's "id" attribute.
Attached is a patch that fixes the problem. Kin-Man has volunteered
to apply it. I still don't seem to have commit privileges for tomcat.
Let me know if you still run into any problems.
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
? build.properties
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/compiler/Generator.java,v
retrieving revision 1.30
diff -u -r1.30 Generator.java
--- src/share/org/apache/jasper/compiler/Generator.java 13 Jun 2002 22:56:11 -0000
1.30
+++ src/share/org/apache/jasper/compiler/Generator.java 21 Jun 2002 00:20:17 -0000
@@ -1467,14 +1467,21 @@
/*
* 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
+ * nesting level of zero). If the custom tag does have a custom nesting
+ * level greater than 0, this method declares a scripting variable
+ * derived from the tag's "id" attribute (if present), only if its
+ * scope is NESTED and it does not match the "id" attribute of any of
+ * the enclosing tags of the same (custom) type.
+ *
+ * Additionally, a NESTED scripting variable is declared only if it
+ * has not already been declared in the same Java
+ * scope of 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) {
+
+ if (n.getCustomNestingLevel() > 0 && !n.hasUnnestedIdAttribute()) {
return;
}
@@ -1485,17 +1492,42 @@
}
if (varInfos != null) {
- for (int i=0; i<varInfos.length; i++) {
- 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());
+ if (n.getCustomNestingLevel() == 0) {
+ // Declare *any* scripting variables with NESTED scope
+ for (int i=0; i<varInfos.length; i++) {
+ 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 {
+ /*
+ * Declare only scripting variable (with NESTED scope)
+ * derived from unnested "id" attribute
+ */
+ String idAttr = n.getAttributeValue("id");
+ for (int i=0; i<varInfos.length; i++) {
+ 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())
+ && idAttr.equals(name)) {
+ out.printin(varInfos[i].getClassName());
+ out.print(" ");
+ out.print(name);
+ out.println(" = null;");
+ nestedVars.put(name, n.getParent());
+ break;
+ }
}
}
}
@@ -1518,14 +1550,16 @@
}
}
}
- }
+ }
}
/*
- * 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.
+ * This method is called as part of the custom tag's start element.
+ *
+ * If the given custom tag has a custom nesting level greater than 0,
+ * declare temporary variables where the current values of the tag's
+ * scripting variables may be saved, so these values may be restored
+ * in the tag's end element.
*/
private void declareTemporaryScriptingVariables(Node.CustomTag n) {
if (n.getCustomNestingLevel() == 0) {
@@ -1573,12 +1607,13 @@
}
/*
- * 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.
+ * This method is called as part of the custom tag's start element.
+ *
+ * If the given custom tag has a custom nesting level greater than 0,
+ * save the values of all its scripting variables to temporary
+ * variables, so the scripting variables may be synchronized
+ * without affecting the values they had at the tag's start element.
+ * Those values will be restored when the tag's end element is reached.
*/
private void saveScriptingVariables(Node.CustomTag n) {
if (n.getCustomNestingLevel() == 0) {
@@ -1619,9 +1654,11 @@
}
/*
- * 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.
+ * This method is called as part of the custom tag's end element.
+ *
+ * If the given custom tag has a custom nesting level greater than 0,
+ * restore its scripting variables to their original values that were
+ * saved in the tag's start element.
*/
private void restoreScriptingVariables(Node.CustomTag n) {
if (n.getCustomNestingLevel() == 0) {
Index: src/share/org/apache/jasper/compiler/Node.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v
retrieving revision 1.14
diff -u -r1.14 Node.java
--- src/share/org/apache/jasper/compiler/Node.java 13 Jun 2002 22:56:11 -0000
1.14
+++ src/share/org/apache/jasper/compiler/Node.java 21 Jun 2002 00:20:18 -0000
@@ -673,7 +673,8 @@
private String tagHandlerPoolName;
private TagInfo tagInfo;
private VariableInfo[] varInfos;
- private int nestingLevel;
+ private int customNestingLevel;
+ private boolean hasUnnestedIdAttribute;
public CustomTag(Attributes attrs, Mark start, String name,
String prefix, String shortName,
@@ -683,7 +684,8 @@
this.prefix = prefix;
this.shortName = shortName;
this.tagInfo = tagInfo;
- this.nestingLevel = computeCustomNestingLevel();
+ this.customNestingLevel = computeCustomNestingLevel();
+ this.hasUnnestedIdAttribute = determineHasUnnestedIdAttribute();
}
public void accept(Visitor v) throws JasperException {
@@ -789,15 +791,25 @@
}
/*
- * Gets this custom tag's nesting level.
+ * Returns true if this custom tag has an "id" attribute that does
+ * not match the "id" attribute of any of its enclosing parent tags of
+ * the same custom tag type, and false otherwise.
+ */
+ public boolean hasUnnestedIdAttribute() {
+ return hasUnnestedIdAttribute;
+ }
+
+ /*
+ * Gets this custom tag's custom nesting level, which is given as
+ * the number of times this custom tag is nested inside itself.
*/
public int getCustomNestingLevel() {
- return nestingLevel;
+ return customNestingLevel;
}
/*
- * Computes this custom tag's nesting level, which corresponds to the
- * number of times this custom tag is nested inside itself.
+ * Computes this custom tag's custom nesting level, which corresponds
+ * to the number of times this custom tag is nested inside itself.
*
* Example:
*
@@ -829,6 +841,38 @@
p = p.parent;
}
return n;
+ }
+
+ /*
+ * Checks to see if this custom tag has an "id" attribute that does
+ * not match the "id" attribute of any of its enclosing parent tags of
+ * the same custom tag type.
+ */
+ private boolean determineHasUnnestedIdAttribute() {
+ boolean unnested = false;
+
+ String id = getAttributeValue("id");
+ if (id != null) {
+ if (customNestingLevel == 0) {
+ // tag not nested inside itself
+ unnested = true;
+ } else {
+ Node p = parent;
+ while (p != null) {
+ if ((p instanceof Node.CustomTag)
+ && name.equals(((Node.CustomTag) p).name)
+ && id.equals(p.getAttributeValue("id"))) {
+ break;
+ }
+ p = p.parent;
+ }
+ if (p == null) {
+ unnested = true;
+ }
+ }
+ }
+
+ return unnested;
}
}
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:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>