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 ?
JSFTemplating is not the project which is attempting to use the
Woodstock annotations -- it's the JSF RI Sandbox components.
JSFTemplating, however, does define the Renderer. So annotating the
JSFT renderer isn't an option.
However, JSFT "can" provide some default faces-config.xml values which
can pre-define a renderer-type *AND* component-family so that any
component wanting to use it could just use those keys... but that
defeats the purpose of Renderers in JSF. There would be no way to Map
the UIComponent to a different Renderer or to distinguish 1
JSFTemplating-based Renderer from another.
> 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 ?
No it would not. There is no Renderer .java class to annotate for the
RI sandbox developer... or any other developer that uses JSFT's
Template-based Renderer.
> 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.
What I am suggesting here does not attempt to get away from the
faces-config.xml file at all. The goal is to reduce the number of files
a component developer needs to touch to create a component. With my
proposed annotation change, I can get rid of touching the
faces-config.xml file -- although the component developer, or end-user
of the component developer's component can add a faces-config.xml file
mapping to point to a different Renderer or do other faces-config.xml
file things to that or other components. I'm not trying to remove the
faces-config.xml file, just automate its creation.
Ken
>
>
> -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
>