Now flip-flopping to the other side..  :)

I disagree that well thought out extension points decrease flexibility in the renderer. It's all about granularity. Some larger components (such as the table) have some clearly defined pieces. I don't think anybody is arguing about the need to extend inputText, people want to extend the most complex components. For example, in table there are header cells and content cells. Certain protected API's encodeHeaderCells and encodeContentCells could be exposed without too much trouble and the encodeAll methods could very quickly turn into a call to the various encodes. Therefore, if someone wanted to put the header row at the bottom, it would be simple to override the encodeAll method to call the encodeContentCells first and the encodeHeaderCells second. Making things general like this wouldn't hurt the renderers IMO, and although it wouldn't allow the granularity that some would hope for, it could strike a good balance between ease of extendability and flexibility for the renderers.

As for the delegate or wrapper ideas, I'm intrigued by this, I'm just not sure, again, of the feasibility without these API's. Truthfully, it would have been nice if Faces defined some generic pieces for various types of renderers. Indeed if the interfaces were flexible enough the needs of all the renderkits could be supported with varying degrees of effort. But alas they don't.

Scott

Andrew Robinson wrote:
Yes, much clearer. In a previous email on this thread, I had an idea
on creating an alias wrapper for faces beans. The idea being that I
could essentially rename the "title" property of the faces bean to
"value" so I could use the output text renderer to print the title as
it would a normal tr:outputText.

I am all for different approaches to this, as I am not sure my
proposal is that wonderful. Yes, I could see and interface being used
as you mention with the requirement that a renderer for type X
implement interface Y, but that would be more restrictive, wouldn't
it? The aliasing of the faces bean, and the ability to only expose
certain properties with such an object is just one proposal.

Frankly, I dislike writing "protected SomeObject
getSomeProperty(FacesBean bean)" methods in renderers, as it seems to
be quite unnecessary when the FacesBean has the information that is
needed to perform this logic without making all these methods (it has
the property type, the default value and access to get the current
value). I do see their use, but I think that a better solution could
be found. Perhaps in some abstraction of the FacesBean in the
renderer?

-Andrew

On Mon, Apr 14, 2008 at 11:03 AM, Simon Lessard
<[EMAIL PROTECTED]> wrote:
Hello Andrew,

Ok, let say we have a renderer that renders a custom layout with an
inputText showing the component's value and allowing to alter it. Since we
don't want to reinvent the wheel, we need to reuse the inputText renderer.
So, somewhere in the code we'll see something like :

delegateRenderer(context, rc, component, bean, _simpleInputTextRenderer);

This is where it gets fishy and why findTypeConstants exists (and I assume
while cloneWithType / TypedRenderer were created in the first place). If you
get the renderer instance from the render kit, or from a direct new using
the default constructor for that matter, the renderer will be initialized
with CoreInputText.TYPE property keys, but my custom component does not use
that type, it rather use MyComponent.TYPE. So, the FacesBean instance passed
to delegateRenderer will be using that latter type and there's absolutely no
guarantee (actually it's pure luck if it is) that the PropertyKey instance
found by the renderer in its findTypeConstants for the value property is
going to be the same than the one from my custom type. So, normally in the
current delegate model, we instanciate the delegate renderer using the
protected constructor receiving a FacesBean.Type instance so that it
initialize itself with the right PropertyKey for our use. We can probably
workaround that issue using the cloneWithType(newFacesBean.Type)
functionality of TypedRenderer, bu that's not the only use case we have.

Sometimes, the custom component does not support or do not want to expose
one of the attribute (for example onclick) on the renderer sub-part. When
such circumstances show up, we create a private inner renderer class
extending the one we need to delegate to and override the getter method
(getOnclick(FacesBean)) of the property we don't want to render on the
sub-part. I currently see no way to achieve that using renderers found from
the render kit.


Clearer ?

~ Simon



On Mon, Apr 14, 2008 at 12:49 PM, Andrew Robinson
<[EMAIL PROTECTED]> wrote:
Forgot to say that in my example, I have "TestSubRendererHeader" as a
renderer type. So the registered renderer for this type should have
knowledge on how to appropriately render a header for this component
type. So in this case, the contract is the FacesBean having a "header"
property set or having a "top" faces present.

Or am I still off base in your concern?

On Mon, Apr 14, 2008 at 10:45 AM, Andrew Robinson

<[EMAIL PROTECTED]> wrote:



Simon,

 Frankly I do not understand #2, sorry. Could you explain what the
 problem is in a different way? Perhaps I just have not seen something
 in the current code that does something that you are referring to. I
 was hoping that someone besides myself would understand what you said
 better and provide an answer.

 The code I presented works AFAIK like the current sub-renderer
 Trinidad architecture where a sub-renderer gets the property values,
 and the knowledge of existence of  properties by querying the
 FacesBean instance, not the component. Therefore, to mask, rename or
 change the value of a property passed to a sub-renderer, would the
 developer not wrap, extend or present the FacesBean in some way to the
 sub-renderer to make those abstractions?

 Or am I really not understanding your concern correctly?

 -Andrew

 On Mon, Apr 14, 2008 at 10:37 AM, Simon Lessard

<[EMAIL PROTECTED]> wrote:

Hello Andrew,
 >
 > Your examples don't handle concern #2 of my reply.
 >
 >
 > Regards,
 >
 > ~ Simon



 >  2. How do we privately extends those renderer like
 > > >  > TheSpecificDelegateRenderer does? I see no way and it's quite
critic
 > as some
 > > >  > renderers use that pattern in order to inhibit a given
property or to
 > infer
 > > >  > it from a different attribute of the original component. Well,
saying
 > that I
 > > >  > see no way is not exactly true. It could be possible to have
those
 > renderers
 > > >  > implement an interface defining a clone method (a bit like
 > TypedRenderer)
 > > >  > receiving a kind of Accessors object to get its attribute
values
 > from.
 > > >  > However, I'm a bit wary of the performance impact of such
structure
 > and it
 > > >  > wouldn't necessarily fix all issues either. Anyone has any
idea how
 > to deal
 > > >  > with that?


Reply via email to