myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonardo Uribe <lu4...@gmail.com>
Subject Re: UIComponentClassicTagBase componentId strategy
Date Mon, 23 Mar 2009 22:21:17 GMT
Hi

Look this issue:

http://issues.apache.org/jira/browse/MYFACES-1834

regards

Leonardo Uribe

On Mon, Mar 23, 2009 at 3:08 PM, Simon Lessard <simon.lessard.3@gmail.com>wrote:

> Hi all,
>
> I'm currently working on a project using MyFaces without Facelets and we
> have some problems when dealing with includes and I want to see if it's on
> our side on in MyFaces. The issue is that I get ids looking like:
> "popDelj_id_1" when I really want it to be "popDel". I traced the code and
> found the following in UIComponentClassicTagBase:
>
> private String createUniqueId(FacesContext context, UIComponent parent)
> throws JspException
> {
>     String id = getId();
>     if (id == null)
>     {
>         id = getFacesJspId();
>     }
>     else if (isIdDuplicated(id))
>     {
>         if (isInAnIterator)
>         {
>             setId(createNextId(id));
>             id = getId();
>         }
> ...
>
> So, in my case getId() returns "popDel" so the first if fails and
> isIdDuplicated(id) gets called:
>
> private boolean isIdDuplicated(String componentId)
> {
>     boolean result = false;
>     if (_parentClassicTag != null)
>     {
>         if (_parentClassicTag.isInAnIterator)
>         {
>             return true;
>         }
> ...
>
> In my case, the tag indeed has a parent and the parent is marked as in an
> iterator. This last part is wrong, although it IS in an included page
> there's no iteration component anywhere in the hierarchy relative to the
> popDel. So I went and checked what set the isInIterator attribute and found
> the following method, called automatically when the setJspId method gets
> called:
>
> private void checkIfItIsInAnIterator(String jspId)
> {
>     Set<String> previousJspIdsSet = getPreviousJspIdsSet();
>
>     if (previousJspIdsSet.contains(jspId) || isIncludedOrForwarded())
>     {
>         isInAnIterator = true;
>     }
>     else
>     {
>         previousJspIdsSet.add(jspId);
>         isInAnIterator = false;
>     }
> }
>
> Now, since jspId is local to the page and my component exists in an
> included page, the jspId received by the method is indeed already used in
> the request, and the isIncludedOrForwarded would return true anyway even if
> the Set wasn't containing the id. So now it gets back up to the first code
> snippet and the following gets executed:
>
> setId(createNextId(id));
> id = getId();
>
> where createNextId concatenate my id with a generated one. I can understand
> why that's needed in a foreach, however I don't see why this is needed in
> case of includes, especially if it was itself placed within a
> NamingContainer like a <f:subview/>. Am I missing anything or is that a bug?
> From My point of view I'd say it's a bug and would modify the
> getPreviousJspIdsSet method to return a Set local to the closest
> NamingContainer and remove the isIncludedOrForwarded completely so that the
> code would still work in case someone included a page without using a
> <f:subview/>.
>
> Can anyone confirm or infirm?
>
>
> Thanks,
>
> ~ Simon
>
> p.s. I thought about posting that on dev list, but since I'm not sure if it
> works as designed and since I found it while being a user, I post it here.
>

Mime
View raw message