- Is the generator XML based or Annotation based?
Annotation
- Is it the POJO or Non POJO?
POJO
- How does it works? let say if I would like to create a slider component with a property called label? What should I do?
You will have to create a POJO class (Meta class), with following two annotations:
1- @Component
2- @property
For example:
@Component(..)
public class SliderMeta
{
@Property
private String label;
}
- Does meta class has to be present in the package where component is going to be reside?
No, meta class can be placed anywhere in the sparkle\src.
- Does meta class go into the jar?
No, meta class will be excluded from the jar and stays in your workplan.
- Does meta class has to have any naming pattern?
Yes, meta class name should be suffixed with Meta (e.g.) TabSetMeta
- How the generator identifies to the meta class?
The generator looks for the class level "Component" annotation.
- What are the required fields of @Component:
- tagName //defines tagname of the component
- componentType //type of the component
- componentClass //fully qualified name for the component class to be generated
- extendsClass //class that has to be extended by the generated component
- What are the optional fields of @Component:
- rendererClass //fully qualified name of the Renderer class, use by the component. (This class has to be created by developer)
- rendererType //type of the renderer
- componentFamily //family of the component
- baseTagClass //defines class extended by the generated tag class. default is UIComponentELTag
- handlerClass //facelets handler class.
- javadoc //javadocs for the component class. Goes into the component class.
- tlddoc //tld docs for the component class. Goes into the Tld documents.
- generatedClass //by default the generated classes are leaf classes, so you can't not override any behavior. If you want to do so then this attribute become handy(e.g.)
@Component (
componentClass="org.icefaces.component.Slider", //this class has to be created by the developer and must extending SliderBase (SliderBase will be generated by the generator)
generatedClass="org.icefaces.component.SliderBase"
extendsClass = "javax.faces.component.UIPanel"
)
So the hierarchy of "Slider.java" would look something like this "Slider->SliderBase->UIPanel->UIComponentBase->UIComponent"
- How the component annotaion would look like if I was to create a slider component extending UIPanel and having a string type of label attribute?
package org.icefaces.component.slider;
@Component(
tagName = "slider",
componentClass = "org.icefaces.component.slider.Slider",
componentType = "com.icesoft.faces.Slider",
extendsClass = "javax.faces.component.UIPanel",
rendererClass = "com.icesoft.component.slider.SliderRenderer"
rendererType = "com.icesoft.faces.SliderRenderer"
)
public class SliderMeta
{
@Property
private String label;
}
- I see now, what artifact will be generated for above meta class?
- component class "Slider.java"
- meta handler class for facelets if required
- tag class "SliderTag.java" extends UIComponentELTag
- Ok, so the component and the tag classes are generated, how about adding their info into the faces-Config.xml, TLD, and facelets taglib?
- The generator take cares all of it so no need to worry about it. Once you defined a meta class, component is good to go.
- I think I have found a limitation, the Slider class is a leaf and its a generated one, how I can override some behavior If I wanted to? Even if I extend the generated one, the generated faces info will ignore my subclass?
<component>
<component-type>com.icesoft.faces.Slider</component-type>
<component-class>org.icefaces.component.slider.Slider</component-class>
</component>
- If you want to override some behavior and don't want leaf class to be generated one, then you can use the "generatedClass" optional property of the @Component annotation (e.g.)
@Component(
.....
componentClass = "org.icefaces.component.slider.Slider",
//just add the following line to the above example
generatedClass = "org.icefaces.component.slider.SliderBase"
)
- So now the generator will create a SliderBase.java with the following hierarchy UIComponent->UIComponentBase->UIPanel->SliderBase and mapping will look like this.
<component>
<component-type>com.icesoft.faces.Slider</component-type>
<component-class>org.icefaces.component.slider.Slider</component-class>
</component>
Now you create a hand coded class named Slider extending SliderBase. You'll get all generated accessor in your hand coded class and override any behavior. The hierarchy of Slider class will look like this:
UIComponent->UIComponentBase->UIPanel->SliderBase->Slider
- Can I add java doc and tld doc to the slider component?
- Yes you can use the tlddoc and javadoc property on the Component annotation.
- Tell me something about the Property annotation?
- In meta class you annotize properties with Property annotation(e.g.)
@Property
private String label;
@Property
private Boolean partialSubmit;
@Property
private Date currentDate;
The generated property will look something like this:
/**
- <p>Set the value of the <code>label</code> property.</p>
*/
public void setLabel(java.lang.String label)
{
getStateHelper().put(PropertyKeys.label, label);
}
/**
- <p>Return the value of the <code>label</code> property.</p>
*/
public java.lang.String getLabel()
{
return (java.lang.String) getStateHelper().eval(PropertyKeys.label);
}
- I can see its already have generlize comments, can I define custom javadoc and tlddc for properties?
- Yes you can use following properties on the Property annotation.
- javadocGet
- javadocSet
- tlddoc
For example:
@Property (
javadocGet="custom comment for get",
javadocSet="custom comment for set",
tlddoc="comments for TLDDOC"
)
private String label;
So the generated property will look something like this:
/**
- <p>Set the value of the <code>label</code> property.</p>
- <p>Contents:custom comment for set</p>
*/
public void setLabel(java.lang.String label)
{
getStateHelper().put(PropertyKeys.label, label);
}
/**
- <p>Return the value of the <code>label</code> property.</p>
- <p>Contents:custom comment for get</p>
*/
public java.lang.String getLabel()
{
return (java.lang.String) getStateHelper().eval(PropertyKeys.label);
}
The Tld doc will look something like this:
<attribute>
<name>label</name>
<description><![CDATA[comments for TLDDOC]]></description>
- How can I define MethodExpression?
- set the isMethodExpression property to true, and if there is an argument use methodExpressionArgument(e.g.)
@Property(
isMethodExpression=true,
methodExpressionArgument="javax.faces.event.ValueChangeEvent"
)
private MethodExpression tabChangeListener;
- You will have to create an inner FacetsMeta class and use Facets and Facet annotation (e.g.)
public class SliderMeta {
@Property
private String label;
@Facets
class FacetsMeta
{
@Facet
UIComponent header;
@Facet
UIComponent body;
@Facet
UIComponent footer;
}
}
Annotation
POJO
You will have to create a POJO class (Meta class), with following two annotations:
1- @Component
2- @property
For example:
@Component(..)
{ @Property private String label; }public class SliderMeta
No, meta class can be placed anywhere in the sparkle\src.
No, meta class will be excluded from the jar and stays in your workplan.
Yes, meta class name should be suffixed with Meta (e.g.) TabSetMeta
The generator looks for the class level "Component" annotation.
@Component (
componentClass="org.icefaces.component.Slider", //this class has to be created by the developer and must extending SliderBase (SliderBase will be generated by the generator)
generatedClass="org.icefaces.component.SliderBase"
extendsClass = "javax.faces.component.UIPanel"
)
So the hierarchy of "Slider.java" would look something like this "Slider->SliderBase->UIPanel->UIComponentBase->UIComponent"
package org.icefaces.component.slider;
@Component(
tagName = "slider",
componentClass = "org.icefaces.component.slider.Slider",
componentType = "com.icesoft.faces.Slider",
extendsClass = "javax.faces.component.UIPanel",
rendererClass = "com.icesoft.component.slider.SliderRenderer"
rendererType = "com.icesoft.faces.SliderRenderer"
)
public class SliderMeta
{ @Property private String label; }<component>
<component-type>com.icesoft.faces.Slider</component-type>
<component-class>org.icefaces.component.slider.Slider</component-class>
</component>
@Component(
.....
componentClass = "org.icefaces.component.slider.Slider",
//just add the following line to the above example
generatedClass = "org.icefaces.component.slider.SliderBase"
)
<component>
<component-type>com.icesoft.faces.Slider</component-type>
<component-class>org.icefaces.component.slider.Slider</component-class>
</component>
Now you create a hand coded class named Slider extending SliderBase. You'll get all generated accessor in your hand coded class and override any behavior. The hierarchy of Slider class will look like this:
UIComponent->UIComponentBase->UIPanel->SliderBase->Slider
@Property
private String label;
@Property
private Boolean partialSubmit;
@Property
private Date currentDate;
The generated property will look something like this:
/**
*/
public void setLabel(java.lang.String label) { getStateHelper().put(PropertyKeys.label, label); }
/**
*/
public java.lang.String getLabel() { return (java.lang.String) getStateHelper().eval(PropertyKeys.label); }
For example:
@Property (
javadocGet="custom comment for get",
javadocSet="custom comment for set",
tlddoc="comments for TLDDOC"
)
private String label;
So the generated property will look something like this:
/**
*/
public void setLabel(java.lang.String label) { getStateHelper().put(PropertyKeys.label, label); }
/**
*/
public java.lang.String getLabel() { return (java.lang.String) getStateHelper().eval(PropertyKeys.label); }
The Tld doc will look something like this:
<attribute>
<name>label</name>
<description><![CDATA[comments for TLDDOC]]></description>
@Property(
isMethodExpression=true,
methodExpressionArgument="javax.faces.event.ValueChangeEvent"
)
private MethodExpression tabChangeListener;
public class SliderMeta {
@Property
private String label;
@Facets
{ @Facet UIComponent header; @Facet UIComponent body; @Facet UIComponent footer; }class FacetsMeta
}