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
>>