dev@woodstock.java.net

Re: Facelets Update and Another Question

From: Gregory Murphy <Gregory.Murphy_at_Sun.COM>
Date: Wed, 28 Feb 2007 09:35:29 -0800

Jason Lee wrote:
>> The processor does assume that it is processing an entire
>> component library. It cannot, for example, generate metadata
>> for one component, and then add an entry for that component
>> in an existing faces-config file. The biggest obstacle to
>> working with existing component libraries, is that you may
>> not have the freedom to annotate the source.
>>
>
> Which is fine with me, as that is the approach I take. With the Sandbox
> stuff, it's pretty much a 1-2 man show, with me doing the bulk of the
> work, so I have pretty much total freedom to annotate all the classes.
> Is the annotations jar available (via maven, for example) somewhere I
> can easily download it in my build process?

You can build the annotations library and processor from source. The
source is in the Woodstock respository, in visualweb/annotations. There
are two NetBeans projects, ./library, and ./processor, each of which
builds its respective JAR file. There is also documentation that
explains how to use the annotations, but it has not yet been moved to
java.net. I'm attaching a copy.

// Gregory



FacesAnnotationProcessingQuickGuide < Main < TWiki


A Quick Guide to Annotating Woodstock JSF Components


The Faces annotation library is used to declare metadata about JSF components. The metadata is used during the build process, to generate auxillary source and configuration files. This document provides guidelines to annotating components, aimed at component developers and those responsible for documenting components.

For more details about the annotations, please see the library javadoc. Reference to the javadoc will be made throughout.


Component authoring


Component developers are responsible for writing and annotating two classes. For every component, there must be a component class and a renderer class, identified via the @Component and @Renderer annotations, respectively. Within the component class, all properties that are not inherited must be identified via the @Property annotation.


Overview of the build process


During the build process, just before compilation, the annotation processor is invoked. The processor examines all source code in the current compilation unit (both run-time and design-time source), and introspects any classes in external libraries on which there are dependencies.

Based on the source annotations found, the processor builds a model of the component library. This model includes a list of all components, a list of all renderers, and information about some auxillary artifacts, like hand-authored tag classes and resolvers. For each component, the model includes information about all properties and events, both those declared explicitly in the component, and those inherited.


The processor then generates new source files and configuration files based on the information that it has gathered. If invoked with the generate.designtime option, it generates a BeanInfo class for each component class. If invoked with the "generate.runtime= option, it generates a tag class for each component class, a faces-config file describing the entire component library, and a taglib descriptor file describing the generated tag classes.


If there are errors in the annotations, an error message will be generated, including in most cases line and column information. If you use NetBeans to build the component library, clicking on the error message will open up the file at the location of the error.


How to annotate a component


Please see the Component javadoc for details about the @Component annotation.


The @Component annotation is placed just before the component class declaration.

In most cases, you will want to provide a display name, a type and a family for your component, e.g.

    @Component(

        displayName="My Component",

        type="com.sun.webui.jsf.MyComponent",

        family="com.sun.webui.jsf.MyComponent")

    public class MyComponent extends UIComponent {

        // ....

    }

Specify an instance name and a tag name only if the defaults result in a keyword conflict. The first sentence of the class javadoc comment will be used as the component's short description. If this is not suitable, you may provide a short description in the annotation.


How to annotate component properties


Please see the Property javadoc for details about the @Property annotation.


Every property that is not inherited must be annotated. The property annotation may be placed just before the private instance variable, the "getter" method, or the "setter" method. In general, it is preferred that the instance variable be annotated.


All property annotation elements have default values, and in most cases, the default values should suffice. It is however a good idea to provide a display name and a reference to a property category. A basic Woodstock property should look something like this:

    /**

     * A property that is mine. I like to use it myself.

     */

    @Property(displayName="My Property", category="Data")

    private String myProperty;

    

    public String getMyProperty();


    public void setMyProperty(String myProperty);

This is a property named "myProperty", of type java.lang.String, with read method name "getMyProperty", write method name "setMyProperty". It is visible in the IDE, and corresponds to the tag attribute "myProperty", which is bindable and optional. The short description for the property is the first line of the preceeding javadoc comment, ie. "A property that is mine".


If a property does not correspond to a tag attribute, the annotation must assert this explicitly:

    @Property(isAttribute=false)

If non-default values are required for the tag attribute, they must be provided in an inner @Attribute annotation. For example, to assign a non-default name to the attribute, one would write something like this:

    @Property(name="myProperty",attribute=@Attribute(name="my-property"))


How to override property annotation values


If your component extends a class (or implements an interface) that provides one or more properties, you may, if you wish, selectively override one or more annotation values. When a property overrides another, its default annotation values are the inherited values. Any values you specify in the child annotation will override inherited values.


For example, assume a super class with the following property:

    @Property(displayName="Parent Property")

    private String myProperty;


    public String getMyProperty() {

        return this.myProperty;

    }

An extending class might override the property like this:

    @Property(displayName="My Property", isAttribute=false)

    public String getMyProperty() {

        return super.getMyProperty();

    }

The property name, instance name, and other values are unchanged, but the display name has been changed to "My Property", and no tag attribute will be associated with the property.


How to annotate a component renderer

Please see the Property javadoc for details about the @Renderer annotation.


Most Woodstock components correspond to a single renderer, and vice versa. In other words, there is a one-to-one correspondance between component class and renderer class. In cases like this, you may use the simplest form of a renderer annotation, which requires that only the component's family be specified:

    @Renderer(@Renders(componentFamily="com.sun.webui.MyComponentFamily"))


Component documentation


The JavaDoc for the component library can be generated using the ant javadoc target. Since component and renderer classes are hand-authored, standard javadoc commenting practices should be followed.


Keep in mind that unless overridden in the annotations, the first sentence of the javadoc comment preceeding a component or property annotation will be used as the short description for the component or property.


By default, the component javadoc comment is used as the description for the component's tag in the taglib configuration file, and the property javadoc comment is used as the attribute description. For the Woodstock build, the tag and attribute descriptions may be supplied in an external taglib file.


The build is currently set up so that the original, hand-authored config files (in runtime/conf) are used to generate the final tag and attribute descriptions.




to top



Copyright © 1999-2007 by the contributing authors. All material on this collaboration platform is the property of the contributing authors. 

Ideas, requests, problems regarding TWiki? Send feedback