The thing is, is not what is the strive for the perfect architecture,
but what is the best way make Trinidad the easiest to use to develop
business applications with (not saying the architecture should not be
solid, just that trying to make an architecture that provides
everyones needs for every use case is not feasible). Adding APIs to
components is not the full solution, and neither is substituting out
core renderers with custom ones.

There will always be use cases where it is necessary for users to want
or need to change specific parts of how core renderers while wanting
the majority of the core renderer's functionality. However this is
done, the user should be able to have access to alter certain things
without hacking dangerously deep into the Trinidad code to do so and
risk backwards compatibility.

Adding API code at the component levels does help, but it will not
address the ability to alter how one component renders for an entire
application. Skinning allows this, to be able to completely re-skin
all of the core components. So there is an extremely good argument to
be able to allow users to extend core renderers.

What about a compromise?

Have renderer wrapper classes or interfaces in trinidad-api and then
have their implementation in the trinidad-impl. Every major area of
the rendered component should have hooks as well as all child renderer
delegation passed into the wrapper (with a default implementation in
impl). For example, take the popup component. I could see hooks for
delegation of the trigger rendering, of the popup itself (title bar,
frame, close button, etc.) and of the popup children.

This way (1) there is a declared standard API for trinidad renderers,
(2) the amount exposed to the API is clearly exposed, (3) making
factory methods for delegating child renderers greatly enhances
extensibility and (4) exposing core areas of rendering components.

One use case would be to change the toolbar of the table. Instead of
having to customize each table used in an application and have
component attributes for changing the select all behavior, a person
could simply override a renderToolbar function.

Maybe something like this for popups:

public abstract class PopupRendererWrapper
{
  private PopupRendererWrapper _base;
  public PopupRendererWrapper(PopupRendererWrapper base) { _base = base; }

  public void renderTitleBar(FacesContext context, RenderingContext
rc, UIComponent component, FacesBean bean)
  {
    _base.renderTitleBar(context, rc, component, bean);
  }
  ...
}

I didn't put a whole lot of thought into this yet, but maybe this will
start some thinking that is a compromise to making the renderers part
of the API with everything public/protected and non-final vs. having
no way to extend the renderers. But the idea is that the renderer just
calls the wrapper functions to do most of the work (basically uses a
delegate renderer to do all the work), but creates its own out-of-the
box version that can be wrapped by a user.

Any of this sound like something to pursue?

-Andrew

Reply via email to