I&#39;ve added this to the JSF 2.1 wishlist on <a href="http://seamframework.org">seamframework.org</a><br><br><a href="http://seamframework.org/Documentation/JSF21#H-ReevaluateComponentReferencingMechanismP2">http://seamframework.org/Documentation/JSF21#H-ReevaluateComponentReferencingMechanismP2</a><br>
<br>-Dan<br><br><div class="gmail_quote">On Thu, May 28, 2009 at 2:49 PM, Andy Schwartz <span dir="ltr">&lt;<a href="mailto:andy.schwartz@oraclecom">andy.schwartz@oracle.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hey Alex -<br>
<br>
Alexandr Smirnov wrote On 5/26/2009 5:41 PM ET:<div class="im"><br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
JSF already has a smart enough code that look components by &#39;id&#39;. Both<br>
&lt;h:outputLabel&gt; and &lt;h:message &gt; use it to lookup target component that<br>
is defined by the &#39;for&#39; attribute, RichFaces library uses the same<br>
strategy and it works very well. It would be better to use a same code<br>
for &lt;f:ajax&gt; tag instead of simple local/global search.<br>
<br>
  <br>
</blockquote>
<br>
<br></div>
Good point. I agree that ideally we should be consistent across the various cases where component attributes refer to other components by id.  I took a closer look at the spec/code for the outputLabel &quot;for&quot; attribute.  The spec is unfortunately vague (and possibly incorrect).  The &quot;for&quot; tag doc simply says:<br>

<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Client identifier of the component for which this element is a label.<br>
</blockquote>
<br>
<br>
Adam logged the following related spec issue on this a couple of years ago:<br>
<br>
<a href="https://javaserverfaces-spec-public.dev.java.net/issues/show_bugcgi?id=266" target="_blank">https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=266</a><br>
<br>
In which Adam says:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The Javadoc for UIMessage and TLDDOC for h:message describes it as one that takes a clientId.  This was<br>
never the intent - this should always have been a relative ID, exactly as in h:outputLabel.  As specified,<br>
h:message is incredibly difficult to use.  IMO, this is an errata, not a spec change, though for backwards<br>
compatibility I&#39;d recommend continuing to look for messages in addition as if &quot;for&quot; were for clientIds.<br>
</blockquote>
<br>
<br>
One thing that is odd is that this implies that outputLabel is correctly specified, though as far as I can tell, both outputLabel and message share the same &quot;for&quot; doc.  (At least the tag doc - perhaps I am missing other doc in the spec itself.)<br>

<br>
Looking at the implementations, MyFaces does the following:<br>
<br>
- Calls findComponent() using the outputLabel/message component as the base component.<br>
- If a component is found, return the id.<br>
- If the component is found, attempt to construct an id manually (via string manipulation).<br>
<br>
So, this is pretty much identical to our f:ajax execute/render id behavior, at least in the case where the id corresponds to a component that can be found in the component tree.  That is:<br>
<br>
 &lt;h:outputLabel for=&quot;foo&quot;/&gt;<br>
<br>
And:<br>
<br>
 &lt;f:ajax execute=&quot;foo&quot;/&gt;<br>
<br>
Will find the same components when running in MyFaces.  (Same goes for the id &quot;:foo&quot;).<br>
<br>
Mojarra starts off similar...<br>
<br>
- Calls findComponent() using the outputLabel/message component as the base component.<br>
<br>
So for cases where a relative id is specified in the same naming container, or an absolute id is specified, both &lt;f:ajax&gt; and &lt;h:outputLabel&gt; behave the same in Mojarra.  However, in the event that the findComponent() call does not find the component, Mojarra then goes on to:<br>

<br>
- Walk up the ancestor chain.<br>
- For each component in the ancestor chain, call findComponent().<br>
- If we reach the root and still haven&#39;t found the matching component, recursively walk over the entire component tree looking for NamingContainers, and call findComponent on each NamingContainer.<br>
<br>
Umm... Yikes.  That&#39;s a lot of component tree walking!<br>
<br>
So, a few issues here:<br>
<br>
1. We need a spec clarification<br>
<br>
MyFaces and Mojarra are providing different behaviors...  As things currently stand, the following code:<br>
<br>
 &lt;f:subview id=&quot;bar&quot;&gt;<br>
   &lt;h:outputLabel for=&quot;foo&quot;&gt;<br>
 &lt;/f:subview&gt;<br>
 &lt;h:inputText id=&quot;foo&quot;/&gt;<br>
<br>
Is not going to be portable across JSF implementations.<br>
<br>
2. The idea of doing so many findComponent() calls worries me.<br>
<br>
A case that we should be able to handle efficiently is having an &lt;f:ajax&gt; tag attached to a component (eg. an &lt;h:commandButton&gt;) that is being stamped out repeatedly (eg. in an &lt;h:data&gt; component).  It is possible that the &lt;f:ajax&gt; execute/render lists may contain multiple execute/render ids each.  In this case, we would end up doing possibly many findComponent() calls each time the component is stamped out - ie. for each row in a table.  Perhaps with very small component trees this may be acceptable, but I can easily see this becoming inefficient as the size of the component tree grows.<br>

<br>
Personally I would like to see an approach that optimizes common cases to avoid unnecessary findComponent() calls.  For example, there may be cases where we could:<br>
<br>
- Take the id that we are provided.<br>
- Perform some string manipulation to derive the desired id (eg. append the id to the nearest naming container&#39;s client id).<br>
- Return the derived id.  (No findComponent() calls).<br>
<br>
Or, if we want to provide diagnostic capabilities:<br>
<br>
- When project stage is development, after we have derived the id, call findComponent() to verify that the referenced component is present.<br>
<br>
We may not be able to derive ids in this fashion for all case, but it seems to me that this should work okay for simple &quot;relative&quot; ids - eg.  execute=&quot;foo&quot;.<br>
<br>
3. We should re-evaluate our component referencing mechanisms for 2.1.<br>
<br>
For example, I believe that we should provide a way to explicitly address components in ancestor naming containers, rather than rely on an expensive implicit search mechanism.  Trinidad provides a way to do this - we use the &quot;::&quot; prefix to indicate that we should pop up one level in the naming container hierarchy (similar to &quot;..&quot; for directory paths).<br>

<br>
Dan mentioned earlier in the thread:<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Frankly, for JSF 2.1, I would like to see us go to an XPath-like syntax (or jQuery) to find components because component IDs in JSF just plain suck.<br>
</blockquote>
<br></div>
Not sure what the best solution is, but I agree with Dan that we should take another look at this.<br>
<br>
4. Does &lt;f:ajax&gt; actually need to perform id processing/encoding at render time?<br>
<br>
&lt;f:ajax&gt;/AjaxBehavior currently send all execute/render ids to the client - which means:<br>
<br>
- Lots of findComponent() calls at render time.<br>
- Lots of content bloating.<br>
<br>
However, as Alex has suggested in the past, this may be unnecessary.  Instead of sending these ids back and forth to/from the client, we should be able to enhance our Behavior mechanism to give the Behavior that triggered a postback the first crack at processing the request...  So, for example, this would allow AjaxBehavior to enhance the PartialViewContext&#39;s execute/render lists early on during the Faces lifecycle (when processing a postback).  No need to send the ids to the client at all.  The cost of doing this is one extra tree visit, which seems like a reasonable trade-off.<br>

<br>
Let&#39;s revisit this one 2.1.<br><font color="#888888">
<br>
Andy<br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Dan Allen<br>Senior Software Engineer, Red Hat | Author of Seam in Action<br><br><a href="http://mojavelinux.com">http://mojavelinux.com</a><br><a href="http://mojavelinux.com/seaminaction">http://mojavelinux.com/seaminaction</a><br>
<a href="http://in.relation.to/Bloggers/Dan">http://in.relation.to/Bloggers/Dan</a><br><br>NOTE: While I make a strong effort to keep up with my email on a daily<br>basis, personal or other work matters can sometimes keep me away<br>
from my email. If you contact me, but don&#39;t hear back for more than a week,<br>it is very likely that I am excessively backlogged or the message was<br>caught in the spam filters.  Please don&#39;t hesitate to resend a message if<br>
you feel that it did not reach my attention.<br>