jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] Re: [jsr-344-experts] FaceletFactory.createComponent(...) ?

From: Leonardo Uribe <lu4242_at_gmail.com>
Date: Tue, 12 Jun 2012 17:09:28 +0200

Hi

I have found this weird example:

http://stackoverflow.com/questions/10853177/how-to-use-the-includehandler-inside-my-custom-component

The revelant code is this:

<h:form>
    <h:commandButton value="include" action="#{bean.include}" />
</h:form>
<h:panelGroup id="include" />

public void include() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    FaceletContext faceletContext = (FaceletContext)
facesContext.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
    faceletContext.includeFacelet(facesContext.getViewRoot().findComponent("include"),
"include.xhtml");
}

The reporter says that hack works, but it shouldn't. Why? because
FaceletContext should only live on build view time, and the action
occur in invoke application phase. The template engine creates
FaceletContext instance when process composite components or apply
templates, so the FaceletContext instance used here is the last one
used. Which one is? it could be anyone.

And? well, expose FaceletFactory or add a method like
FaceletFactory.createComponent(...) leave the spec open to these kind
of ugly hacks.

But note the interesting part behind this trick. What the user want is
a way to "inject" programatically "something" into the component tree
from a bean. Isn't that the intention behind
JAVASERVERFACES_SPEC_PUBLIC-599? of course!.

This issue becomes related to the conditions where you can manipulate
the component tree programmatically, specifically "when" it is valid
to do such manipulation. If the intention is add a composite component
directly in a component tree, the call must warrant the generated ids
used should be stable and no facelet generated ids should be used at
all, so the algorithm can consider this as a programmatic addition
(the algorithm for c:if addition/deletion should skip them).

regards,

Leonardo Uribe

2012/6/12 Leonardo Uribe <lu4242_at_gmail.com>:
> Hi
>
> Checking some JSF 2.2 javadoc, I notice this method:
>
> UIComponent FaceletFactory.createComponent(String taglibURI, String
> tagName, Map<String,Object> attributes)
>
> There is no javadoc, only a reference to this issue:
>
> http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-599
> Application.createComponent(): compcomp via namespace+compname
>
> The issue is closed as fixed, but there is not any description at all.
> This raises some questions?
>
> 1. Is that the right place to put that method? The description of
> FaceletFactory says this:
>
> ".... FaceletFactory for producing Facelets relative to the context of
> the underlying implementation. ..."
>
> It does not have sense to me. If I want a way to create a component
> using the namespace/compname or something like that, Isn't that
> responsibility more related to the ViewDeclarationLanguage?
>
> 2. Why expose FaceletFactory? In my opinion, FaceletFactory is a
> detail of facelets VDL implementation, right? The "power" to create
> facelets is from facelets VDL. If that so, why don't include an
> abstract class called
>
> public abstract class
> javax.faces.view.facelets.FaceletsViewDeclarationLanguage extends
> javax.faces.view.ViewDeclarationLanguage
>
> and add the methods that are now in FaceletFactory there? Maybe
> createComponent(String taglibURI, String tagName, Map<String,Object>
> attributes) qualify to be included directly in
> ViewDeclarationLanguage.
>
> 3. JAVASERVERFACES_SPEC_PUBLIC-599 description says something like this:
>
>>> I feel there is value in the ability to instantiate an EzComp object
>>> in Java so that a component tree can be built in a backing bean (or
>>> other Class). JSF must be doing this in the background through
>>> Facelets, so providing this ability in Java should not be too difficult.
>
> the problem here is it does not specify where and when the component
> is created: inside a component "binding" property? in a
> @PostConstruct? in an actionListener?. For each one there are
> different considerations. Also, it is necessary to check that the
> generated ids does not clash with other existing ones in the component
> tree. I can see this is only the tip of the iceberg.
>
> 4. Is this topic really closed? Some months ago I sent a message with
> this topic:
>
> [jsr344-experts] JAVASERVERFACES_SPEC_PUBLIC-611 FIXED expose
> FaceletFactory and Facelet classes
>
> No response so far.
>
> Suggestions are welcome.
>
> regards,
>
> Leonardo Uribe