Re: [jsr-314-open] [ADMIN] JSF 2.0 Spec Snapshot
by Martin Marinschek
Hi Ed,
my feedback below. I already (wrongly) sent these using my Gmail-address,
but I guess (hope) these mails didn't make it...
3.1.8: should the tree-visitor be mentioned here?
4.1.18.4: shouldn't this reference AfterAddToViewEvent?
5.4.1: seems to have old spec language (language on error handler says that
only predestroy does not call through to it)
6.1.14: managed-bean-scope can now be view on top of none, request, session,
application - can it also be flash? I don't see this mentioned anywhere.
10.3.1.1: in table 10.3, the f:ajax attribute is called event - in several
paragraphs around this, events - which one is true?
also, should I send out the patch-proposal that I made and the follow up
discussions I had with Leonardo to the EG? Pete and Andy seemed to be
interested...
regards,
Martin
15 years, 10 months
Re: [jsr-314-open] JSF 2.0/Facelets public APIs: ComponentHandler
by Andy Schwartz
Ed Burns wrote On 3/4/2009 10:44 PM ET:
> Ok, can you prepare a change-bundle for this approach, the "four very
> small contracts approach", and attach it to issue jsf-spec-public
> 274?
Awesome, thanks for letting me get this in Ed!
I have uploaded the change-bundle to 274 with the following comments:
> The jsf-andy.patch addresses additional requirements raised by Oracle/ADF Faces.
> ADF Faces needs a way to find child handlers by type. In particular, ADF Faces
> needs to be able to locate the following types of handlers by type:
>
> - TextHandlers
> - AttributeHandlers
> - FacetHandlers
>
> Previously this was possible using the Facelets 1.1.x
> TagHandler.findNextByType() API and referencing the above handler types.
> However, both findNextByType() and the above handlers have been moved out of the
> public API in JSF 2.0.
>
> One option would be to move findNextByType() and the above handler
> implementations into the public API, but in order to keep the amount of
> implementation in jsf-api small, we instead decided to add the following four
> interfaces:
>
> 1. javax.faces.webapp.pdl.facelets.tag.TextHandler
>
> This interface is identical to Facelets 1.1.x version. It defines two methods:
>
> - public String getText();
> - public String getText(FaceletContext ctx);
>
>
> 2. javax.faces.webapp.pdl.facelets.tag.AttributeHandler:
>
> This is a new interface that defines a single method:
>
> - public String getAttributeName(FaceletContext ctx);
>
> 3. javax.faces.webapp.pdl.facelets.tag.FacetHandler
>
> This is a new interface that defines a single method:
>
> - public String getFacetName(FaceletContext ctx);
>
> 4. javax.faces.webapp.pdl.facelets.tag.CompositeFacletHandler
>
> This is a new interface that defines a single method:
>
> - public FaceletHandler[] getHandlers();
>
> Note that we decided to introduce #4 as an alternative to introducing a public
> findNextByType(), as CompositeFaceletHandler is sufficient to allow users to
> scan child FaceletHandlers.
>
> The attached patch introduces these new contracts, and also updates the jsf-ri
> accordingly.
>
> Running "ant test.with.container.refresh" passes successfully.
>
Andy
15 years, 10 months
Re: [jsr-314-open] [ADMIN] JSF 2.0 Spec Snapshot
by michael freedman
This version of the spec doesn't seem to include a number of topics we
have been discussing the past few weeks, including page parameters and
Ajax changes (to better run in a portlet environment). When do you
expect a review draft that includes these more recent changes? For the
draft I have the following few comments:
1. Until I hear a yeah or nay I would like to continue to recommend
the changes I proposed making javax.faces.component.UIViewRoot a
NamingContainer that implements portlet namespacing when
run/accessed in portlet requests.
2. Section 14.1 (Ajax): its not clear whether any hidden fields
other than javax.faces.ViewState are included in ajax requests by
jsf.ajax.getViewState. The HTML successful controls doc says they
may be included but that seems too loose. Portlets need some
accommodation to support the following use case:
An Ajax using JSF portlet is included in an Ajax using JSF
consumer page by a consumer defined process that inlines the
portlet. By inlining I mean the consumer parses the portlet
markup, removes/rewrites the target of <form> elements as
hidden fields (to avoid the embeded form problem), and
namespaces all the form's fields so that when the consumers
page is submitted it can decode those fields pertaining to
this portlet. The outcome of this process is the hidden field
name = "javax.faces.ViewState" is rewriten as name =
"ns:javax.faces.ViewState". When the overall page is
submitted we need to ensure this hidden field is submitted
whenever any of the portlet's input fields would also be
submitted. One easy way to do this is to submit all the
hidden fields as part of the form state.
Note: if we make progress on the active discussion regarding
namespacing this field, the
3. Section 14.2.3: typo -- the description references jsf.viewState
but it looks like it means to reference jsf.getViewState.
-Mike-
Roger Kitain wrote:
> I've uploaded a spec snapshot to
>
> https://javaserverfaces-spec-eg.dev.java.net/files/documents/2091/127938/...
>
>
> Please review this in detail, because the next one is going out to JCP
> on March 6, 2009.
>
> Roger
15 years, 10 months
Re: [jsr-314-open] JSF 2.0/Facelets public APIs: ComponentHandler
by Andy Schwartz
Ed -
Ed Burns wrote On 3/4/2009 11:24 AM ET:
> So, how big of a problem is my current approach of "because these
> features would be covered by VAST, and because we don't yet have VAST,
> let's not expose them now" going to be?
>
> Alaxander and Andy, can you *really* not live without the concepts
> suggested in points 3, 4, and 5 in Andy's original email to this thread?
>
> Ed
>
Sorry for not responding earlier... I wanted to take time to make sure
that my understanding of our (ADF Faces) requirements is accurate before
responding. Also, thanks so much for moving ahead with the changes
needed to get ComponentHandler (and isNew(), applyNextHandler()) into
the public API. I definitely appreciate this and I am sure that the
larger JSF/Facelets community will too.
So the predicament that I am facing is that without:
- Some way to find child handlers by type
- Some way specifically to find child text handlers
- Some way specifically to find facet/attribute handlers
I do not see an upgrade path for some of our more complex components
from Facelets 1.1.x to JSF 2.0. Unfortunately several of these
components are used extensively throughout ADF Faces-based
applications. For example, the af:pageTemplate component is used on
just about every page.
While I completely agree about the promise of VAST, and while I am also
excited about the prospects of a quick turnaround on a JSF 2.1, I need
to find some upgrade path to 2.0. Without some solution to the
requirements that we have been discussing, I do not see that path.
In the hopes of finding some way to reduce our requirements, I took a
closer look at the findNextByType() implementation:
> public final static Iterator findNextByType(FaceletHandler
> nextHandler,
> Class type) {
> List found = new ArrayList();
> if (type.isAssignableFrom(nextHandler.getClass())) {
> found.add(nextHandler);
> } else if (nextHandler instanceof CompositeFaceletHandler) {
> FaceletHandler[] h = ((CompositeFaceletHandler)
> nextHandler).getHandlers();
> for (int i = 0; i < h.length; i++) {
> if (type.isAssignableFrom(h[i].getClass())) {
> found.add(h[i]);
> }
> }
> }
> return found.iterator();
>
> }
This is almost doable with the current public APIs, with one
exception. CompositeFaceletHandler is currently in the RI (not API),
which means that here is no way for us iterate over the child handlers.
Instead of exposing a findNextByType() API, another approach to solving
our "some way to find child handlers by type" problem would be either to:
- Move CompositeFaceletHandler into the public API. This class is tiny
- nothing especially controversial here. Or...
- Alternatively, we could define a CompositeFaceletHandler interface in
the public API, if we do not want to move the implementation over.
So, assuming we do not want to support findNextType() in the public API,
I think that the minimal way to address the ADF Faces requirements would be:
- Define a CompositeFaceletHandler interface with a single method:
getHandlers().
- Move the existing (two method) TextHandler interface into the public API.
- Define a FacetHandler interface in the public API. (This could either
be a marker interface, or, even better, define a single method -
getFacetName().)
- Define an AttributeHandler interface in the public API. (This could
either be a marker interface, or, possibly with a single method -
getAttributeName().)
Adding these 4 very small contracts to the JSF 2.0 public API -
contracts that are already public in Facelets 1.1.x - would enable us
(ADF Faces) to port our Faclets 1.1.x TagHandler/ComponentHandler
implementations up to JSF 2.0, and thus allow Oracle/ADF Faces users to
adopt JSF 2.x more quickly. While I appreciate the concerns about
getting too bogged down in Facelets-specific solutions ahead of VAST, I
don't think that adding these APIs should complicate the path to VAST in
any significant way.
Is there any chance that can reconsider our 2.0 plans - ie. any chance
that we can get these contracts in for 2.0? This would greatly help
Oracle/ADF Faces and our ability to adopt JSF 2.0. I am not sure
whether other frameworks/components have the same requirements, but
since these APIs are present in the currently available version of
Facelets, it is likely that others may benefit from this as well.
Of course, since I know that time is an issue, I would be more than
happy to help out in any way (eg. help with the spec or reference
implementation) if it would make it easier to get this in for 2.0.
And, again, sorry about the last minute nature of this request - I
realize that this would have been easier if I had caught these
requirements sooner.
Andy
15 years, 10 months
[jsr-314-open] JSF and REST
by Pete Muir
We recently had (another) discussion on REST on the seam-dev mailing
list and Bill (who has written the JBoss JAX-RS impl) said this, which
I thought was quite interesting for some JSF future version.
Begin forwarded message:
> There's some established workarounds for overloading POST as some
> clients can't do PUT, DELETE, etc. Like a specific header or query
> parameter. I just haven't implemented these yet.
>
> Pete Muir wrote:
>> Bill, agreed on all these things - JSF2 no longer overloads POST
>> for GET (which it did previously), adds good support for
>> statelessness and unique URIs for a resource through page actions.
>> However I don't think full REST is possible in JSF (not overloading
>> POST for PUT/DELETE).
--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete
15 years, 10 months
Re: [jsr-314-open] JSF 2.0/Facelets public APIs: ComponentHandler
by Pete Muir
On 4 Mar 2009, at 16:26, Ed Burns wrote:
>>>>>> On Wed, 04 Mar 2009 15:27:20 +0000, Pete Muir
>>>>>> <pmuir(a)REDHAT.COM> said:
>
> AS> 1. ComponentSupport.isNew()
>
> PM> I agree, this should be in.
>
> Yes. It is.
>
> AS> 2. ComponentHandler.applyNextHandler()
>
> PM> And this one too.
>
> Yes. It is. Pete, I assume by your lack of comment on points 3, 4,
> and
> 5, that you have no opinion on the inclusion of those points.
> Correct?
Yes. These two are the ones I have worked with, and those that we use
in Seam - the others I can't comment on whether having them public is
necessary or not.
--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete
15 years, 10 months
Re: [jsr-314-open] JSF 2.0/Facelets public APIs: ComponentHandler
by Pete Muir
On 4 Mar 2009, at 04:29, Ed Burns wrote:
> Gang -
>
> Ed and I spoke about this yesterday. Ed has come up with a solution
> that will allow us to restore ComponentHandler to the public API
> without also having to pull the entire implementation into the API.
> The solution leverages a new TagHandlerHelper contract - the public
> ComponentHandler class will delegate all of the thorny work to a
> TagHandlerHelper. The actual TagHandlerHelper implementation will
> live in the JSF implementation.
>
> I think that this is a good compromise that balances the needs for a
> ComponentHandler base class with the desire to keep the API as free
> of implementation as possible. Thanks very much Ed for getting this
> solution in even at this late date!
>
> Last night I took a closer look at the new public ComponentHandler
> API (in the Mojarra trunk) and also at Trinidad/ADF Faces
> ComponentHandler (and ComponentSupport) usage. I found a few diffs
> between the legacy Facelets APIs and the JSF 2.0 APIs that I wanted
> to share with the EG.
>
> 1. ComponentSupport.isNew()
>
> This API was present in legacy Facelets but as far as I can tell is
> no longer present in JSF 2.0. Custom handler implementations use
> this method to determine whether a component is newly created. If
> the component is newly created, the handler might do some work to
> further initialize the component. On the other hand, if the
> component is not newly created, the handler might instead short-
> circuit and not muck with the component.
>
> This is a fairly common use case (shows up in both Trinidad and ADF
> Faces), so I think we need something here - if not a public API,
> then at least a recommended alternative. Note that
> ComponentSupport.isNew() actually has a trivial implementation:
>
>> public final static boolean isNew(UIComponent component) {
>> return component != null && component.getParent() == null;
>> }
>
> So one option would be to replace calls to ComponentSupport.isNew()
> with code like the above. Though of course that does mean pushing
> some assumptions about component tree wiring out into user code.
I agree, this should be in.
>
>
> 2. ComponentHandler.applyNextHandler()
>
> The legacy Facelets ComponentHandler contract included the following
> API:
>
>> protected void applyNextHandler(FaceletContext ctx, UIComponent c)
>
> Though this is not present on our new JSF 2.0 ComponentHandler class.
>
> ComponentHandler implementations typically override this if they
> need to do pre/post-processing before/after the child tags are
> applied.
>
> I think we should be able to add this back into the JSF 2.0
> ComponentHandler fairly easily. Just need the
> TagHandlerHelper.apply() implementation to call back into the
> ComponentHandler to apply the next handler. (I think we are going
> to need to do this anyway, since the ComponentHandler has the
> reference to the next handler.)
And this one too.
>
>
> 3. TagHandler.findNextByType()
>
> The legacy Facelets TagHandler contract included the following API:
>
>> protected final Iterator findNextByType(Class type)
>
> It appears this method is no longer present in the JSF 2.0 API.
>
> Custom TagHandler implementations need access to this API in cases
> where they need to perform special processing of their children.
> ADF Faces has a number of cases where we need to do this, so I would
> like to see if we can restore this API.
>
> Note that this method is not specific to ComponentHandler - non-
> component TagHandlers may need this as well.
>
> 4. TextHandler interface
>
> The typical way to to support TagHandlers (or ComponentHandlers) of
> the form:
>
> <foo>some text here</foo>
>
> Is to use findNextByType() in conjunction with the TextHandler
> interface.
>
> For example, the VerbatimHandler does this:
>
>> StringBuffer content = new StringBuffer();
>> Iterator iter =
>> TagHandlerImpl.findNextByType(this.nextHandler,
>> TextHandler.class);
>> while (iter.hasNext()) {
>> TextHandler text = (TextHandler) iter.next();
>> content.append(text.getText(ctx));
>> }
>
> Without having access to the TextHandler interface, it is not
> possible to implement handlers that process child text.
>
> Fortunately TextHandler is just a trivial interface with two methods:
>
> - public String getText();
> - public String getText(FaceletContext ctx);
>
> And this interface is already present in the JSF 2.0 - but off in
> the ri. Can we promote this out of the ri and into the API so that
> we can enable support for tags that contain text? I don't see any
> way to support this use case without access to the TextHandler
> interface.
>
> 5. FacetHandler, AttributeHandler
>
> Okay, these two are probably fairly ADF Faces-specific... ADF Faces
> has its own page template component. Usage looks something like this:
>
>> <af:pageTemplate template="path/to/some/template/file">
>> <f:attribute name="foo" value="bar">
>> <f:facet name="foobar">
>> <h:outputText value="Hello, World!"/>
>> </f:facet>
>> </af:pageTemplate>
>
>
> In the ComponentHandler subclass for <af:pageTemplate>, we perform
> some pre-processing of attributes/facets before we process the
> template file. In order to do this, we call findNextByType() twice
> - once with AttributeHandler.class to find all of the attributes,
> and then a second time with FacetHandler.class to grab all of the
> facets.
>
> This works beautifully in legacy Facelets, where FacetHandler/
> AttributeHandler are public classes, but not so well in JSF 2.0,
> since these classes are no longer part of the public API.
>
> I understand the desire not to include these handler implementation
> classes in the public API - ie. I understand why we want to keep as
> much implementation as possible in the ri and not in the API.
> However, assuming we cannot expose the existing FacetHandler/
> AttributeHandler classes in the API... Is there any chance that we
> can add marker interfaces to the public API? (Doesn't have
> necessarily have to be a marker interface - an FacetHandler
> interface that returns the facet name would be tremendously useful
> for us.) If we can have some way to find child attributes/facets,
> this would allow us to port our af:pageTemplate component to JSF
> 2.0. Since this is a key component for us - used throughout Oracle
> products - being able to support will definitely help Oracle's
> ability to upgrade to JSF 2.0.
>
> Oh, of course, if we are willing to attempt to get these last minute
> additions in, in the interest of time I would be more than happy to
> provide patches/changebundles/spec prose for these APIs!
>
> Andy
>
> Andy Schwartz wrote On 2/27/2009 7:39 PM ET:
>> Gang -
>>
>> I realize that it is way beyond late for me to be sending this
>> email, but I think that this issue is significant enough that it is
>> worth raising even at this late point.
>>
>> Last year when we discussed which Facelets classes should be
>> included in the JSF 2.0 API, one of the questions was whether
>> ComponentHandler (and ComponentConfig/Support) should be included
>> in the public API. At the time I asked that these be included as
>> Trinidad makes use of these API (or, in the case of
>> ComponentSupport, parts of these APIs). However, Ed was reluctant
>> to add these to the JSF 2.0 public API. I believe the reasoning was:
>>
>> 1. Our new composite components functionality should dramatically
>> reduce the # of cases where component authors need to write custom
>> tag handlers.
>> 2. In cases where custom tag handlers are necessary, custom
>> component author can implement their own handler solution, perhaps
>> by extending TagHandler instead of ComponentHandler.
>>
>> While #1 might be an option for many custom components, it is not
>> really an option for our existing Trinidad (and ADF Faces)
>> components. These are Java-based components/APIs with Java-based
>> Renderers - in many cases very complex Java Renderers. Composite
>> components are not a solution here.
>>
>> Unfortunately I did not have time to take a closer look a #2 until
>> very recently. On closer examination, it seems to me that re-
>> implementing the functionality provided by ComponentHandler is non-
>> trivial - and possibly even impossible to do in a portable way (ie.
>> without depending on JSF implementation details).
>>
>> The non-trivial part to re-implementing a ComponentHandler is
>> providing a replacement for the component tree wiring logic. This
>> includes behavior such as:
>>
>> - Searching the parent component to see whether an existing
>> component is present. (ComponentSupport.findChildByTagId())
>> - Marking existing components for deletion.
>> (ComponentSupport.markForDeletion())
>> - Marking component instances as being newly created.
>> (ComponentSupport.MARK_CREATED)
>> - Cleaning up orphaned components.
>> (ComponentSupport.finalizeForDeletion())
>> - Creating the implicit wrapper component for facets with multiple
>> children. (ComponentSupport.addComponent())
>>
>> Also, when adding newly created components into the component tree,
>> there is some internal communication between FacetHandler and
>> ComponentHandler regarding where the newly created component should
>> be inserted (as indicated by FacetHandler.KEY). However, this
>> communication is currently implementation-specific - a replacement
>> ComponentHandler implementation cannot participate in this wiring
>> without depending on internal behavior.
>>
>> Yikes! This is a very large burden to place on custom component
>> authors. Comparing this to JSP land, this is basically the
>> equivalent of asking custom component authors to re-implement
>> UIComponentClassicTagBase - clearly something that we would never
>> expect component authors to be required to do.
>>
>> Looking at the original documentation for Facelets, it seems clear
>> that ComponentHandler is considered to be part of the public API:
>>
>> https://facelets.dev.java.net/nonav/docs/dev/docbook.html#dev-meta-
>> component
>>
>> Similarly, the Apress "Myfaces and Facelets" book treats
>> ComponentHandler as a public API and includes a section devoted to
>> writing custom ComponentHandlers.
>>
>> I am concerned that by excluding this ComponentHandler the JSF 2.0
>> public API, we are taking away a long-standing Facelets public API,
>> and in the process, making it significantly more difficult for
>> component authors to upgrade existing components to JSF 2.0,
>> something we clearly want to avoid (ie. we want to keep the
>> migration path as smooth as possible to encourage upgrading).
>>
>> I am of course particularly concerned about the impact that this
>> might have on the ability to upgrade Trinidad/ADF Faces to JSF 2.0
>> (selfish, yes). But my concerns are not limited to Trinidad/ADF
>> Faces... I did some poking around and I see that other component
>> sets have the same dependency on ComponentHandler. For example,
>> RichFaces has some handlers that extend ComponentHandler:
>>
>> http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/...
>>
>> As does Tomahawk:
>>
>> http://myfaces.apache.org/tomahawk-project/tomahawk12/apidocs/org/apache/...
>>
>> I suspect that any custom component that needs to perform
>> specialized attribute processing - including components which
>> support MethodExpression-based attributes - is going to need to
>> extend (or, at the moment, re-implement) ComponentHandler. Rather
>> than potentially placing obstacles in the way of upgrading these
>> components to 2.0, I would like to ask that we re-think our
>> decision to not include ComponentHandler in the JSF 2.0 public API.
>>
>> For the sake of completeness, just wanted to add... Here at Oracle
>> we recently started an effort to move our ADF Faces JSP tags over
>> to Facelets. As part of this effort we found a few other Facelets
>> APIs that would be tremendously helpful to our cause, but are not
>> currently in the JSF 2.0 public API. These include:
>>
>> - com.sun.facelets.tag.TagDecorator
>> - com.sun.facelets.tag.jsf.core.AttributeHandler
>> - com.sun.facelets.tag.jsf.core.FacetHandler
>>
>> I can of course explain the use case for these in more detail, but
>> seems like it would be best to save that for another email.
>>
>> So, thoughts on ComponentHandler? Is there any way that we can
>> possibly get this into the 2.0 API before we ship?
>>
>> Again, I do appreciate how late it is to be raising this (again).
>> I am sorry about the last minute nature of this request.
>>
>> Andy
--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete
15 years, 10 months
Re: [jsr-314-open] Issue? Uniqueness of the ViewState parameter id.
by michael freedman
By the way, how are JSF Ajax solutions dealing with the multi-form case
in JSF 1.2? Is there a consistent strategy? Is it often overlooked?
For all on the list, for whatever environment you know the strategy for,
please post. I will collate into a matrix, afterwards.
-Mike-
Roger Kitain wrote:
> For Ajax, here is what we do w.r.t javax.faces.viewState:
>
> If an update element is found in the response with the identifier
> javax.faces.ViewState:
>
> <update id="javax.faces.ViewState">
> <![CDATA[...]]>
> </update>
>
> Include this state in the document as follows:
>
> * Extract this <update> element's CDATA contents from the response.
> * If the document contains an element with the identifier
> javax.faces.ViewState replace its contents with the CDATA contents.
> * For each <form> element in the document:
> o If the <form> element contains an <input> element with the
> identifier javax.faces.ViewState, replace the <input> element contents
> with the <update> element's CDATA contents.
> o If the <form> element does not contain an element with the
> identifier javax.faces.ViewState, create an <input> element of the
> type hidden, with the identifier javax.faces.ViewState, set its
> contents to the <update> element's CDATA contents, and add the <input>
> element as a child to the <form> element.
>
> -roger
>
> michael freedman wrote:
>> Alexandr is also right, there maybe Ajax related problems as well at
>> least in the portlet case. Doesn't the PPR processing need to update
>> the ViewState after a partial request? Do we expect (by spec) all
>> impls to manage the viewstate in a javascript variable and have the
>> various hidden fields pull this value on full page submits? Or might
>> impls try and push the updated ViewState into the hidden field? If
>> the later won't they have problems in a multi-form page? If the
>> former, what can we do to account for the portlet situation where I
>> have multiple portlets on a page each with distinct ViewState? I.e.
>> if the portlet renders a JSF view its ViewState is distinct from
>> another portlet (rendering a JSF view) incorporated into the page.
>> -Mike-
>>
>> Pete Muir wrote:
>>> At least in JSF1.2 Mike is correct, the hidden form field written
>>> out to set the viewstate parameter has the same id for each form,
>>> which means the HTML is not well formed and would not pass an HTML
>>> validator.
>>>
>>> I remember coming across this before and raising it with someone -
>>> perhaps Ryan or Ed?
>>>
>>> On 26 Feb 2009, at 21:19, Alexandr Smirnov wrote:
>>>
>>>> Faces allows as many form on page as you wish. The fields with
>>>> state do
>>>> not mixeed as they as are unique per form. This is not a problem for
>>>> Portlet applications, because only one hidden field submitted by form.
>>>> But that could be problem for an AJAX case, there client-side script
>>>> have to found appropriate state field to include in
>>>> HttpServletRequest.
>>>>
>>>> michael freedman wrote:
>>>>> From the looks of things in JSF 1.2 (and I imagine this hasn't
>>>>> changed
>>>>> in 2.0), JSF's hidden field holding the view state parameter is
>>>>> written using a static id/name. I.e. the id of the field isn't
>>>>> namespaced by its containers. Though not a common case, Faces does
>>>>> allow multiple (separate) form tags in a page, right? In that
>>>>> situation aren't we violating strict HTML rules requiring id
>>>>> uniqueness? Why does the id need to be static? Can't we make this
>>>>> unique?
>>>>> -Mike-
>>>
>>> --
>>> Pete Muir
>>> http://www.seamframework.org
>>> http://in.relation.to/Bloggers/Pete
15 years, 10 months
Re: [jsr-314-open] JSF 2.0/Facelets public APIs: ComponentHandler
by Alaxander Smirnov
I agree - the RichFaces library uses all of these methods also.
There is only one concern for me. The current implementation of the
findNextByType(Class type) / TextHandler does not allows to have any
XML elements inside the tag:
<f:verbatim> This <b>is</b> a text</f:verbatim> does not works. That API
should be replaced by the something else with same functionality as JSP
BodyTag has.
Ed Burns wrote:
> Gang -
>
> Ed and I spoke about this yesterday. Ed has come up with a solution
> that will allow us to restore ComponentHandler to the public API
> without also having to pull the entire implementation into the API.
> The solution leverages a new TagHandlerHelper contract - the public
> ComponentHandler class will delegate all of the thorny work to a
> TagHandlerHelper. The actual TagHandlerHelper implementation will
> live in the JSF implementation.
>
> I think that this is a good compromise that balances the needs for a
> ComponentHandler base class with the desire to keep the API as free of
> implementation as possible. Thanks very much Ed for getting this
> solution in even at this late date!
>
> Last night I took a closer look at the new public ComponentHandler API
> (in the Mojarra trunk) and also at Trinidad/ADF Faces ComponentHandler
> (and ComponentSupport) usage. I found a few diffs between the legacy
> Facelets APIs and the JSF 2.0 APIs that I wanted to share with the EG.
>
> 1. ComponentSupport.isNew()
>
> This API was present in legacy Facelets but as far as I can tell is no
> longer present in JSF 2.0. Custom handler implementations use this
> method to determine whether a component is newly created. If the
> component is newly created, the handler might do some work to further
> initialize the component. On the other hand, if the component is not
> newly created, the handler might instead short-circuit and not muck
> with the component.
>
> This is a fairly common use case (shows up in both Trinidad and ADF
> Faces), so I think we need something here - if not a public API, then
> at least a recommended alternative. Note that
> ComponentSupport.isNew() actually has a trivial implementation:
>
>> public final static boolean isNew(UIComponent component) {
>> return component != null && component.getParent() == null;
>> }
>
> So one option would be to replace calls to ComponentSupport.isNew()
> with code like the above. Though of course that does mean pushing
> some assumptions about component tree wiring out into user code.
>
> 2. ComponentHandler.applyNextHandler()
>
> The legacy Facelets ComponentHandler contract included the following API:
>
>> protected void applyNextHandler(FaceletContext ctx, UIComponent c)
>
> Though this is not present on our new JSF 2.0 ComponentHandler class.
>
> ComponentHandler implementations typically override this if they need
> to do pre/post-processing before/after the child tags are applied.
>
> I think we should be able to add this back into the JSF 2.0
> ComponentHandler fairly easily. Just need the
> TagHandlerHelper.apply() implementation to call back into the
> ComponentHandler to apply the next handler. (I think we are going to
> need to do this anyway, since the ComponentHandler has the reference
> to the next handler.)
>
> 3. TagHandler.findNextByType()
>
> The legacy Facelets TagHandler contract included the following API:
>
>> protected final Iterator findNextByType(Class type)
>
> It appears this method is no longer present in the JSF 2.0 API.
>
> Custom TagHandler implementations need access to this API in cases
> where they need to perform special processing of their children. ADF
> Faces has a number of cases where we need to do this, so I would like
> to see if we can restore this API.
>
> Note that this method is not specific to ComponentHandler -
> non-component TagHandlers may need this as well.
>
> 4. TextHandler interface
>
> The typical way to to support TagHandlers (or ComponentHandlers) of
> the form:
>
> <foo>some text here</foo>
>
> Is to use findNextByType() in conjunction with the TextHandler interface.
>
> For example, the VerbatimHandler does this:
>
>> StringBuffer content = new StringBuffer();
>> Iterator iter = TagHandlerImpl.findNextByType(this.nextHandler,
>> TextHandler.class);
>> while (iter.hasNext()) {
>> TextHandler text = (TextHandler) iter.next();
>> content.append(text.getText(ctx));
>> }
>
> Without having access to the TextHandler interface, it is not possible
> to implement handlers that process child text.
>
> Fortunately TextHandler is just a trivial interface with two methods:
>
> - public String getText();
> - public String getText(FaceletContext ctx);
>
> And this interface is already present in the JSF 2.0 - but off in the
> ri. Can we promote this out of the ri and into the API so that we can
> enable support for tags that contain text? I don't see any way to
> support this use case without access to the TextHandler interface.
>
> 5. FacetHandler, AttributeHandler
>
> Okay, these two are probably fairly ADF Faces-specific... ADF Faces
> has its own page template component. Usage looks something like this:
>
>> <af:pageTemplate template="path/to/some/template/file">
>> <f:attribute name="foo" value="bar">
>> <f:facet name="foobar">
>> <h:outputText value="Hello, World!"/>
>> </f:facet>
>> </af:pageTemplate>
>
>
> In the ComponentHandler subclass for <af:pageTemplate>, we perform
> some pre-processing of attributes/facets before we process the
> template file. In order to do this, we call findNextByType() twice -
> once with AttributeHandler.class to find all of the attributes, and
> then a second time with FacetHandler.class to grab all of the facets.
>
> This works beautifully in legacy Facelets, where
> FacetHandler/AttributeHandler are public classes, but not so well in
> JSF 2.0, since these classes are no longer part of the public API.
>
> I understand the desire not to include these handler implementation
> classes in the public API - ie. I understand why we want to keep as
> much implementation as possible in the ri and not in the API.
> However, assuming we cannot expose the existing
> FacetHandler/AttributeHandler classes in the API... Is there any
> chance that we can add marker interfaces to the public API? (Doesn't
> have necessarily have to be a marker interface - an FacetHandler
> interface that returns the facet name would be tremendously useful for
> us.) If we can have some way to find child attributes/facets, this
> would allow us to port our af:pageTemplate component to JSF 2.0.
> Since this is a key component for us - used throughout Oracle products
> - being able to support will definitely help Oracle's ability to
> upgrade to JSF 2.0.
>
> Oh, of course, if we are willing to attempt to get these last minute
> additions in, in the interest of time I would be more than happy to
> provide patches/changebundles/spec prose for these APIs!
>
> Andy
>
> Andy Schwartz wrote On 2/27/2009 7:39 PM ET:
>> Gang -
>>
>> I realize that it is way beyond late for me to be sending this email,
>> but I think that this issue is significant enough that it is worth
>> raising even at this late point.
>>
>> Last year when we discussed which Facelets classes should be included
>> in the JSF 2.0 API, one of the questions was whether ComponentHandler
>> (and ComponentConfig/Support) should be included in the public API.
>> At the time I asked that these be included as Trinidad makes use of
>> these API (or, in the case of ComponentSupport, parts of these
>> APIs). However, Ed was reluctant to add these to the JSF 2.0 public
>> API. I believe the reasoning was:
>>
>> 1. Our new composite components functionality should dramatically
>> reduce the # of cases where component authors need to write custom
>> tag handlers.
>> 2. In cases where custom tag handlers are necessary, custom component
>> author can implement their own handler solution, perhaps by extending
>> TagHandler instead of ComponentHandler.
>>
>> While #1 might be an option for many custom components, it is not
>> really an option for our existing Trinidad (and ADF Faces)
>> components. These are Java-based components/APIs with Java-based
>> Renderers - in many cases very complex Java Renderers. Composite
>> components are not a solution here.
>>
>> Unfortunately I did not have time to take a closer look a #2 until
>> very recently. On closer examination, it seems to me that
>> re-implementing the functionality provided by ComponentHandler is
>> non-trivial - and possibly even impossible to do in a portable way
>> (ie. without depending on JSF implementation details).
>>
>> The non-trivial part to re-implementing a ComponentHandler is
>> providing a replacement for the component tree wiring logic. This
>> includes behavior such as:
>>
>> - Searching the parent component to see whether an existing component
>> is present. (ComponentSupport.findChildByTagId())
>> - Marking existing components for deletion.
>> (ComponentSupport.markForDeletion())
>> - Marking component instances as being newly created.
>> (ComponentSupport.MARK_CREATED)
>> - Cleaning up orphaned components.
>> (ComponentSupport.finalizeForDeletion())
>> - Creating the implicit wrapper component for facets with multiple
>> children. (ComponentSupport.addComponent())
>>
>> Also, when adding newly created components into the component tree,
>> there is some internal communication between FacetHandler and
>> ComponentHandler regarding where the newly created component should
>> be inserted (as indicated by FacetHandler.KEY). However, this
>> communication is currently implementation-specific - a replacement
>> ComponentHandler implementation cannot participate in this wiring
>> without depending on internal behavior.
>>
>> Yikes! This is a very large burden to place on custom component
>> authors. Comparing this to JSP land, this is basically the
>> equivalent of asking custom component authors to re-implement
>> UIComponentClassicTagBase - clearly something that we would never
>> expect component authors to be required to do.
>>
>> Looking at the original documentation for Facelets, it seems clear
>> that ComponentHandler is considered to be part of the public API:
>>
>> https://facelets.dev.java.net/nonav/docs/dev/docbook.html#dev-meta-component
>>
>>
>> Similarly, the Apress "Myfaces and Facelets" book treats
>> ComponentHandler as a public API and includes a section devoted to
>> writing custom ComponentHandlers.
>>
>> I am concerned that by excluding this ComponentHandler the JSF 2.0
>> public API, we are taking away a long-standing Facelets public API,
>> and in the process, making it significantly more difficult for
>> component authors to upgrade existing components to JSF 2.0,
>> something we clearly want to avoid (ie. we want to keep the migration
>> path as smooth as possible to encourage upgrading).
>>
>> I am of course particularly concerned about the impact that this
>> might have on the ability to upgrade Trinidad/ADF Faces to JSF 2.0
>> (selfish, yes). But my concerns are not limited to Trinidad/ADF
>> Faces... I did some poking around and I see that other component sets
>> have the same dependency on ComponentHandler. For example, RichFaces
>> has some handlers that extend ComponentHandler:
>>
>> http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/...
>>
>>
>> As does Tomahawk:
>>
>> http://myfaces.apache.org/tomahawk-project/tomahawk12/apidocs/org/apache/...
>>
>>
>> I suspect that any custom component that needs to perform specialized
>> attribute processing - including components which support
>> MethodExpression-based attributes - is going to need to extend (or,
>> at the moment, re-implement) ComponentHandler. Rather than
>> potentially placing obstacles in the way of upgrading these
>> components to 2.0, I would like to ask that we re-think our decision
>> to not include ComponentHandler in the JSF 2.0 public API.
>>
>> For the sake of completeness, just wanted to add... Here at Oracle we
>> recently started an effort to move our ADF Faces JSP tags over to
>> Facelets. As part of this effort we found a few other Facelets APIs
>> that would be tremendously helpful to our cause, but are not
>> currently in the JSF 2.0 public API. These include:
>>
>> - com.sun.facelets.tag.TagDecorator
>> - com.sun.facelets.tag.jsf.core.AttributeHandler
>> - com.sun.facelets.tag.jsf.core.FacetHandler
>>
>> I can of course explain the use case for these in more detail, but
>> seems like it would be best to save that for another email.
>>
>> So, thoughts on ComponentHandler? Is there any way that we can
>> possibly get this into the 2.0 API before we ship?
>>
>> Again, I do appreciate how late it is to be raising this (again). I
>> am sorry about the last minute nature of this request.
>>
>> Andy
15 years, 10 months