The more I think about this the more confused I get as to why changing
a very specific annotation processor is the solution.
JSF defines two strategies for rendering components. One is with a renderkit
and the flexibility it offers . It defines a second strategy where
components render themselves.
Your design appears to fall into the second strategy. In fact why
doesn's the template component superclass
implement the template rendering as well ?
You don't need the a renderer at all as you claim, it just becomes part
of your
inherited component behavior.
We know that the current annotation processor supports components that
do not have a
a renderkit renderer. Unfortunately the processor reports warnings
because of this
but that is because of its specific nature.
Just curious, what happens if a Woodstock component were to add the
@Renderer
annotation in error or is it appropriate in any way for the Woodstock
components ?
This really flies in the face of the strategy to have renderkits for the
Woodstock components
as well as JSF.
This makes me think even more so that if your components don't utililize
renderers in a
renderkit, then they are either components that are not rendered, or
they render themselves.
-rick
richard ratta wrote:
>
>
> Ken Paulsen wrote:
>
>>
>>
>> richard ratta wrote:
>>
>>> I would like to see real requirements for this change, a little more
>>> on what
>>> is needed and why this change satisfies those requirements.
>>>
>>>> The motivation for this new feature is to be able to skip creating
>>>> a new Renderer for a component entirely. Jason Lee and I are
>>>> experimenting around with the Woodstock annotations +
>>>> JSFTemplating's TemplateRenderer to create components. I think
>>>> this is a good combination that reduces development to 2 files:
>>>> UIComponent file, and a template file. However, the current
>>>> annotations require a Renderer class to be present to place a
>>>> @Renderer annotation... and we don't have such a file in our
>>>> environment.
>>>
>>>
>>>
>>> This rationalization really isn't very clear, technically speaking.
>>>
>>> I also don't see the relationship between a renderer-type and the
>>> renderer-class which is the relationship
>>> JSF defines. There is no relationship in JSF between a Component and
>>> a renderer-class. It is
>>>
>>> component-family
>>> renderer-type
>>> renderer-class
>>>
>>> And we have created complexities by dynamically changing a
>>> component's renderer-type
>>> at runtime based on the "type of request"; "normal" or "ajax".
>>>
>>
>> Hi Rick,
>>
>> Yes, JSF supports an N to N mapping between UIComponent and
>> Renderers. You can map N components to a single Renderer, or 1
>> UIComponent can end up being server by N different Renderers. In
>> order for this to work, as you pointed out, there cannot exist a
>> hard-coded relationship between the UIComponent class and the
>> Renderer class.
>>
>> For this reason this solution is not perfect... however, in my
>> scenario there is only 1 Java file, yet I'd like to take advantage of
>> the code generation done by the annotations so I can alleviate
>> developers of the need to write ANY xml in the faces-config.xml
>> file. I don't see any other practical way to do this w/ the current
>> Woodstock annotations / development environment.
>>
>> Also, if you look at the @annotations as the "default" generated
>> faces-config.xml file. Then this change *ONLY* provides a *default*
>> mapping between the UIComponent and 1 possible Renderer. I see this
>> as VERY valuable in my use case. Let me elaborate on my use case....
>>
>> I have a template that might look something like:
>>
>> myComp.jsf:
>>
>> <span id="$this{componentId}"><b>$property{value}</b></span>
>>
>> Ok... that's a VERY simple component that wraps the "value" property
>> of the component in a span w/ bold tags... but valid... see my TSS
>> article for a much more complicated example
>> (http://www.theserverside.com/tt/articles/article.tss?l=JSFTemplateComponent).
>>
>>
>> I then have a UIComponent that is something like:
>>
>> public class MyComp extends TemplateInsertComponentBase implements
>> NamingContainer {
>> public MyComp() {
>> super();
>> setRendererType("com.sun.MyComp");
>> setLayoutDefinitionKey("jsftemplating/myComp.jsf");
>> }
>>
>> public String getFamily() {
>> return "com.sun.MyComp";
>> }
>> }
>>
>> I don't have ANY other files for the component... however, I would
>> like to use Woodstock annotations to further simplify this so that I
>> don't have to configure the *faces-config.xml* file or write a *JSP
>> tag class*. With the current annotations I can't quite do this
>> because I do NOT have a Renderer class
>
>
> then what is
> 'rendererClass="com.sun.jsftemplating.renderer.TemplateRenderer"' ?
> Why not just annotate that renderer, to support the family,
> "com.sun.Template" with renderer
> type "com.sun.Template", and have anyone that wants to use you
> "templates" make their component
> belong to that family ?
>
> Currently the annotation processor does enforce a 1 to 1 mapping and
> that is what I would rather
> see fixed so that it supports the JSF mapping possibilities.
>
> Adding other arbitraty rules and annotations just makes the
> annotations more cofusing.
> If they followed the JSF spec with respect to mapping components to
> renderers then
> it is easier to understand since it follows a standard specification.
> That should solve your use case as well, no ?
>
> I'm surprised everyone wants to get away from faces-config.xml. It
> seemed pretty useful to
> me to be able to map and define meta-data for compoents, unfortunately
> we didn't conform to
> it more strictly.
>
>
> -rick
>
>> where I can put the @Renderer annotation. With my proposed change, I
>> can add
>> *rendererClass="com.sun.jsftemplating.renderer.TemplateRenderer"* to
>> the @Component annotation and everything works.
>>
>> Does this make more sense?
>>
>> If we can do this... I'd like to write a java.sun.com article
>> explaining how this is done. My TSS article has already generated a
>> lot of interest, I think combining this with the Woodstock
>> annotations offers a solution that a lot of people would be
>> interested in.
>>
>>> See more inline
>>>
>>
>> ... (see below)
>>
>>>
>>> - RendersInfo(Map annotationValueMap) {
>>> + RendersInfo(Map annotationValueMap, String className) {
>>> this.annotationValueMap = annotationValueMap;
>>> + this.className = className;
>>> }
>>>
>>> You are changing an existing interface here.
>>> Any existing code that relies on the previous interface will break.
>>> You have to support the original interface as well as the new one.
>>
>>
>>
>> Yes, you are correct. However, this is a class that is used
>> (indirectly) by APT only during compile time and doesn't manifest
>> itself at all during runtime (afaik). So unless someone has extended
>> the framework Woodstock has to develop their own JSF annotations AND
>> directly instantiates this static inner class
>> (DeclaredRendererInfo.RendersInfo), then this isn't a problem.
>>
>> Nevertheless, I'd be happy to support the old single-argument
>> constructor as well since this is easy to do and good practice.
>>
>> Ken
>>
>>>
>>> -rick
>>
>>
>>
>>
>>
>>
>>
>>> Ken Paulsen wrote:
>>>
>>>>
>>>> I would like to commit a minor change to the annotations woodstock
>>>> provides. The change allows a @Component annotation to take a
>>>> "rendererClass" attribute to specify a Renderer that should be used
>>>> to Renderer the UIComponent.
>>>>
>>>> The motivation for this new feature is to be able to skip creating
>>>> a new Renderer for a component entirely. Jason Lee and I are
>>>> experimenting around with the Woodstock annotations +
>>>> JSFTemplating's TemplateRenderer to create components. I think
>>>> this is a good combination that reduces development to 2 files:
>>>> UIComponent file, and a template file. However, the current
>>>> annotations require a Renderer class to be present to place a
>>>> @Renderer annotation... and we don't have such a file in our
>>>> environment.
>>>>
>>>> I have run the annotation processor before and after this change
>>>> and compared the results. There is no difference at all (as there
>>>> shouldn't be since it only adds an optional property which isn't
>>>> currently present on any Woodstock components).
>>>>
>>>> The diffs are attached. Please let me know if you have any
>>>> objections to me checking in this change. Or if I should check it
>>>> in somewhere other than the HEAD.
>>>>
>>>> Thanks!
>>>>
>>>> Ken
>>>>
>>>> woodstock/annotations> cvs -q diff -u
>>>> Index: library/src/com/sun/faces/annotation/Component.java
>>>> ===================================================================
>>>> RCS file:
>>>> /cvs/woodstock/annotations/library/src/com/sun/faces/annotation/Component.java,v
>>>>
>>>> retrieving revision 1.1
>>>> diff -u -r1.1 Component.java
>>>> --- library/src/com/sun/faces/annotation/Component.java 15 Feb 2007
>>>> 21:47:16 -0000 1.1
>>>> +++ library/src/com/sun/faces/annotation/Component.java 31 Aug 2007
>>>> 21:28:05 -0000
>>>> @@ -134,6 +134,8 @@
>>>> * is set to false), then providing a value for this element
>>>> has no effect.
>>>> */
>>>> public String tagRendererType() default "";
>>>> +
>>>> + public String rendererClass() default "";
>>>>
>>>> /**
>>>> * An optional short description of this component, typically
>>>> used as a tool
>>>> Index: library/src/com/sun/faces/annotation/Renderer.java
>>>> ===================================================================
>>>> RCS file:
>>>> /cvs/woodstock/annotations/library/src/com/sun/faces/annotation/Renderer.java,v
>>>>
>>>> retrieving revision 1.1
>>>> diff -u -r1.1 Renderer.java
>>>> --- library/src/com/sun/faces/annotation/Renderer.java 15 Feb 2007
>>>> 21:48:01 -0000 1.1
>>>> +++ library/src/com/sun/faces/annotation/Renderer.java 31 Aug 2007
>>>> 21:28:05 -0000
>>>> @@ -82,6 +82,8 @@
>>>> @Target(ElementType.ANNOTATION_TYPE)
>>>> public @interface Renders {
>>>>
>>>> + public String rendererClass() default "";
>>>> +
>>>> /**
>>>> * The renderer type for this component and renderer
>>>> combination. If
>>>> * this annotation contains a single component family, and
>>>> a renderer type
>>>> Index: processor/src/com/sun/faces/mirror/DeclaredRendererInfo.java
>>>> ===================================================================
>>>> RCS file:
>>>> /cvs/woodstock/annotations/processor/src/com/sun/faces/mirror/DeclaredRendererInfo.java,v
>>>>
>>>> retrieving revision 1.1
>>>> diff -u -r1.1 DeclaredRendererInfo.java
>>>> ---
>>>> processor/src/com/sun/faces/mirror/DeclaredRendererInfo.java
>>>> 15 Feb 2007 21:56:49 -0000 1.1
>>>> +++
>>>> processor/src/com/sun/faces/mirror/DeclaredRendererInfo.java
>>>> 31 Aug 2007 21:28:06 -0000
>>>> @@ -44,9 +44,10 @@
>>>> this.annotationValueMap = annotationValueMap;
>>>> renderings = new ArrayList<RendersInfo>();
>>>> if (this.annotationValueMap.containsKey(VALUE)) {
>>>> + String qn = decl.getQualifiedName();
>>>> for (Object value : (List)
>>>> this.annotationValueMap.get(VALUE)) {
>>>> Map nestedAnnotationValueMap = (Map) value;
>>>> - renderings.add(new
>>>> RendersInfo(nestedAnnotationValueMap));
>>>> + renderings.add(new
>>>> RendersInfo(nestedAnnotationValueMap, qn));
>>>> }
>>>> }
>>>> }
>>>> @@ -60,15 +61,28 @@
>>>> */
>>>> static public class RendersInfo {
>>>>
>>>> + static String RENDERER_CLASS = "rendererClass";
>>>> static String RENDERER_TYPE = "rendererType";
>>>> static String COMPONENT_FAMILY = "componentFamily";
>>>>
>>>> Map annotationValueMap;
>>>> + String className;
>>>>
>>>
>>>> + /**
>>>> + * The renderer class (the qualified name by default).
>>>> + */
>>>> + public String getRendererClass() {
>>>> + if
>>>> (this.annotationValueMap.containsKey(RENDERER_CLASS)) {
>>>> + return (String)
>>>> this.annotationValueMap.get(RENDERER_CLASS);
>>>> + }
>>>> + return this.className;
>>>> + }
>>>> +
>>>> /**
>>>> * The renderer type.
>>>> */
>>>> Index:
>>>> processor/src/com/sun/faces/mirror/FacesAnnotationProcessor.java
>>>> ===================================================================
>>>> RCS file:
>>>> /cvs/woodstock/annotations/processor/src/com/sun/faces/mirror/FacesAnnotationProcessor.java,v
>>>>
>>>> retrieving revision 1.2
>>>> diff -u -r1.2 FacesAnnotationProcessor.java
>>>> ---
>>>> processor/src/com/sun/faces/mirror/FacesAnnotationProcessor.java
>>>> 9 Jun 2007 13:35:41 -0000 1.2
>>>> +++
>>>> processor/src/com/sun/faces/mirror/FacesAnnotationProcessor.java
>>>> 31 Aug 2007 21:28:08 -0000
>>>> @@ -197,6 +197,30 @@
>>>> this.declaredComponentSet.add(componentInfo);
>>>>
>>>> this.declaredClassMap.put(typeDecl.getQualifiedName(), componentInfo);
>>>> typeInfo = componentInfo;
>>>> + // Check to see if this annotation also
>>>> specifies a Renderer
>>>> + Object rendererClass =
>>>> annotationValueMap.get("rendererClass");
>>>> + if ((rendererClass != null)
>>>> + &&
>>>> !rendererClass.toString().equals("")) {
>>>> + // Create the "Renders" Map
>>>> + Map renders = new HashMap();
>>>> + renders.put("rendererClass",
>>>> rendererClass);
>>>> + Object type =
>>>> annotationValueMap.get("tagRendererType");
>>>> + if ((type == null) ||
>>>> type.toString().equals("")) {
>>>> + type = annotationValueMap.get("type");
>>>> + }
>>>> + renders.put("rendererType", type);
>>>> + ArrayList families = new ArrayList();
>>>> +
>>>> families.add(annotationValueMap.get("family"));
>>>> + renders.put("componentFamily", families);
>>>> +
>>>> + List list = new ArrayList();
>>>> + list.add(renders);
>>>> + Map rendererMap = new HashMap();
>>>> + rendererMap.put("value", list);
>>>> + DeclaredRendererInfo rendererInfo =
>>>> + new
>>>> DeclaredRendererInfo(rendererMap, (ClassDeclaration) typeDecl);
>>>> +
>>>> this.declaredRendererSet.add(rendererInfo);
>>>> + }
>>>> } else if
>>>> (typeDecl.getAnnotation(Renderer.class) != null) {
>>>> // This is a renderer class
>>>> Map<String,Object> annotationValueMap =
>>>> Index:
>>>> processor/src/com/sun/faces/mirror/generator/FacesConfig.template
>>>> ===================================================================
>>>> RCS file:
>>>> /cvs/woodstock/annotations/processor/src/com/sun/faces/mirror/generator/FacesConfig.template,v
>>>>
>>>> retrieving revision 1.2
>>>> diff -u -r1.2 FacesConfig.template
>>>> ---
>>>> processor/src/com/sun/faces/mirror/generator/FacesConfig.template
>>>> 17 Feb 2007 23:50:09 -0000 1.2
>>>> +++
>>>> processor/src/com/sun/faces/mirror/generator/FacesConfig.template
>>>> 31 Aug 2007 21:28:08 -0000
>>>> @@ -52,7 +52,7 @@
>>>> <renderer>
>>>> <component-family>${componentFamily}</component-family>
>>>> <renderer-type>${rendering.rendererType}</renderer-type>
>>>> -
>>>> <renderer-class>${rendererInfo.qualifiedName}</renderer-class>
>>>> +
>>>> <renderer-class>${rendering.rendererClass}</renderer-class>
>>>> </renderer>
>>>> #end
>>>> #end
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe_at_woodstock.dev.java.net
>>>> For additional commands, e-mail: dev-help_at_woodstock.dev.java.net
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_woodstock.dev.java.net
>>> For additional commands, e-mail: dev-help_at_woodstock.dev.java.net
>>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_woodstock.dev.java.net
> For additional commands, e-mail: dev-help_at_woodstock.dev.java.net
>