Bug 31804 - setParent() is not called on nested tags in a tag file (.tagx)
Summary: setParent() is not called on nested tags in a tag file (.tagx)
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 5.0.31
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-20 16:26 UTC by Firepica
Modified: 2006-09-07 21:19 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Firepica 2004-10-20 16:26:40 UTC
Hi, everybody.

Suppose I have a tag file (.tagx to be precise). I have some custom tags of mine 
included in that tag file. If I override setParent() in such a custom tag, then 
I see, that it's invoked with "null" parameter. Custom tag is a "Classic" tag 
(extends TagSupport).

Simplified example: This tag file is called "submit.tagx"

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:custom="http://my.com/
tags-html" version="2.0" >

    <jsp:directive.tag body-content="empty"/>
    <jsp:directive.attribute name="action" required="true" rtexprvalue="true"/>
    <jsp:directive.attribute name="label" required="true" rtexprvalue="true"/>

    <custom:submit action="${action}" label="${label}" name="submitButton" />

</jsp:root>

In debug output from setParent(Tag) of custom:submit I see, that it's called 
with "null" value.

If, instead of custom:submit, I put there another custom tag, which follows 
SimpleTagSupport model, then setParent(JspTag) is not called at all!!!

I would expect a reference to something, representing translated class of Tag 
File (submit.tagx) is passed.

As the result, tag nesting tree is broken. 

I need to access Struts html:form tag, which is the embracing tag from my inner 
<custom:submit> tag to obtain form name, but this is not possible.

<nested:form action="/Action">
   <ctrl:submit action="save" label="Save"/>
</nested:form>

(where ctrl:submit is submit.tagx)
Comment 1 Jan Luehe 2004-10-20 22:55:30 UTC
I may misunderstand your problem entirely, but I believe the behaviour you are
seeing is expected. 

According to javax.servlet.jsp.tagext.Tag.setParent() javadocs:

     * Set the parent (closest enclosing tag handler) of this tag handler.
     * Invoked by the JSP page implementation object prior to doStartTag().
     *
     * @param t The parent tag, or null.

Since <custom:submit> is not nested inside any custom tag invocation in your
.tagx snippet, NULL is passed to your tag handler's setParent().

Likewise, javax.servlet.jsp.tagext.SimpleTag.setParent() has this:

     * Sets the parent of this tag, for collaboration purposes.
     * <p>
     * The container invokes this method only if this tag invocation is 
     * nested within another tag invocation.
     *
     * @param parent the tag that encloses this tag

Since your SimpleTag isn't nested, the container does not call its setParent()
method at all.

> I would expect a reference to something, representing translated class of Tag 
> File (submit.tagx) is passed.

Your expectation is wrong. You should expect setParent() to be called on your
tag handler, and a non-null argument passed to it, only if your custom tag is
nested inside another custom tag.
Comment 2 Dmitri Blinov 2004-11-17 15:32:21 UTC
> Your expectation is wrong. You should expect setParent() to be called on your
> tag handler, and a non-null argument passed to it, only if your custom tag is
> nested inside another custom tag.

Shouldn't we expect setParent() to be called on <custom:submit> tag handler with
this.getParent() of .tagx file handler? I mean if our .tagx snippet in its term
will ever be nested inside another custom tag at some other place, then
setParent() will be called with this.getParent(), which was set to point to real
parent tag handler in that case.
Comment 3 Dmitri Blinov 2004-11-18 15:35:56 UTC
> Your expectation is wrong. You should expect setParent() to be called on your
> tag handler, and a non-null argument passed to it, only if your custom tag is
> nested inside another custom tag.

Shouldn't we expect setParent() to be called on <custom:submit> tag handler with
this.getParent() of .tagx file handler? I mean if our .tagx snippet in its term
will ever be nested inside another custom tag at some other place, then
setParent() will be called with this.getParent(), which was set to point to real
parent tag handler in that case.

For example I have batch.tag file with the number of <sql:update> tags. Now I
want that those statements would run in the context of <sql:transaction>. If I
simply put 

<sql:transaction>
  <my:batch />
</sql:transaction>

then <sql:update> statements won't be connected with the tag invocation tree
that includes <sql:transaction>.

I do not see any particular reason why enclosed <sql:update> invocations should
be isolated from their enclosing enviromnent... 
Comment 4 Rohan Pinto 2005-01-14 00:05:51 UTC
http://issues.apache.org/bugzilla/show_bug.cgi?id=31804
 
Could someone please advise me on whether this Bug is fixed?
Bugzilla shows this bug to be filed under Tomcat 4.0 I am using Tomcat 5.0.28 
and am having problems when using the jsp:param tag. I get tons of deprecation 
errors.
 
My IDE is jbuilder 2005 and am using :
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04) Java 
HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

 
any tips on whether this bugID is fixed for Tomcat 5.0.28 (or how could it be 
fixed OR a workaround ) would be greatly appreciated.
 
Comment 5 Yoav Shapira 2005-03-25 04:18:36 UTC
Rohan, I would guess this "bug" is not fixed, assuming it's a bug at all.  We're
normally pretty good about closing bugzilla item as resolved/fixed once we
commit the fix to CVS.
Comment 6 Kin-Man Chung 2005-12-10 01:56:50 UTC
The only case where setParent() will be invoked in when its tag is nested in
another tag, such as

<nested:form action="/Action">
   <ctrl:submit action="save" label="Save"/>
</nested:form>

In this case, setParent() will be invoked for <ctrl:sumit> but not
<nested:form>.  This can be easily verified by examining the generated java
files, as I have done for 5.x.  It doen't matter if <ctrl:submit> is a tag file
or not.
Comment 7 roy Wells 2006-08-29 23:24:20 UTC
This isn't working correctly.  However I think the examples given so far have been incomplete.  I will try 
to give a full example.

Lets suppose we have two traditional custom tags, for this example I'm going to use the Spring 2.0 
form tag libraries as they are the ones that led me here.

The first tag is form:form tag, which sets up context to be accessed by nested tags via the setParent 
mechanism.

The second tag is form:label tag, which makes use of the context created by the form:form tag and only 
functions properly when nested within a form:form tag.

So we might have an example jsp as follows.

<form:form> 
  <form:label>hello</form:label>
</form:form>

the generated java file for this jsp would invoke setParent(null) on the form:form tag and would invoke 
setParent([reference to the form tag]) on the label tag.  This would be correct.

Now let us assume that we create a tag file which makes use of the form:label tag because we tired of 
typing "Hello" everywhere.

Our tag file might look like this.

<form:label>Hello</form:label>

and our revised jsp page would look like this.

<form:form>
  <mycustumtag/>
</form:form>

In this case the form:form tag would again get a setParent invoked with null, (still correct) and 
mycustomtag would get it's setParent invoked with the reference to the form:form tag, (also still 
correct), but the form:label tag inside of mycustomtag would get it's setParent method invoked with 
"null".  This is "Not Correct".  The label tag is nested inside of an outer tag and should have it's 
setParent method invoked with the reference to that outer tag.

Here is the logic I would propose for this section of code.

if (myParent == null) {
  // set parent of any top level tags used in tag file to null
} else {
  // set parent of any top level tags used in tag file to "this"
}
Comment 8 Mark Thomas 2006-09-08 04:19:26 UTC
I have read through section JSP.8 and whilst I can't see anything that
explicitly refers to this case:
- tag files are simple tags so should behave in the same way
- tag files currently have their own parent set correctly
- tag files can contain other tags
- not setting the tag file as the parent of tags within the tag file breaks
things like the Spring form tags

Therefore I have committed a patch that fixes this bug. The fix will be in
5.5.20 onwards.