Hi

I have checked this topic of the wiki
http://wiki.apache.org/myfaces/Code_Generation:
Generating base classes instead of templatesAnd based on some work with
tomahawk I have some observations to do:

*".......Note that (in a feature that may surprise some Java developers) it
appears quite valid for a class to have a package-scoped parent; the class
can still be subclassed or instantiated from outside the package. It
inherits public and protected members from its package-scoped parent which
can be called as normal. The only constraint is that it cannot be cast to
its parent type, as this is not accessible (although the Class object for
that type can still be obtained). It is not yet known whether inserting such
a package-scoped ancestor class into the ancestry of a component class in
the javax.faces package scope would be acceptable to the JSF TCK or not. If
the TCK accepts this, then the approach of generating a base class could
also be applied to myfaces core components......".
*
In some cases doing something like this:

abstract class AbstractHtmlInputText
        extends javax.faces.component.html.HtmlInputText
        implements UserRoleAware, DisplayValueOnlyCapable
{

works but in other cases do not, It throws an exception like this:

java.lang.IllegalAccessException: Class
javax.faces.component._ComponentAttributesMap can not access a member of
class org.apache.myfaces.custom.tabbedpane.AbstractHtmlPanelTabbedPane with
modifiers "public abstract"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
    at java.lang.reflect.Method.invoke(Method.java:588)
    at javax.faces.component._ComponentAttributesMap.getComponentProperty
(_ComponentAttributesMap.java:390)
    at javax.faces.component._ComponentAttributesMap.put
(_ComponentAttributesMap.java:311)
    at javax.faces.component.UIComponent.setValueExpression(UIComponent.java
:112)
    at
org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPaneTag.setProperties(
HtmlPanelTabbedPaneTag.java:389)
    at javax.faces.webapp.UIComponentELTag.createComponent(
UIComponentELTag.java:100)

There are some methods on java api that use reflection to set some
variables, and fails if the parent class is not public, so I do not believe
that this approach works for myfaces core api, and pass the TCK.

*"....With this setup, we have the question of which source directory the
generated base class gets written to. Option (1) is to write it to a
generated-source dir, option (2) is to write it to the normal source
dir....."
*
*".....Question: When there are multiple source trees for a module, does
maven build against them all simultaneously? That is, if a normal source
file references a source file in the generated-source tree which itself
references a source file in the normal source tree, does this work?..."
*
Yes, this works and it is awesome. One successful example is this hierarchy
used for t:schedule

javax.faces.UIComponentBase
-----------myfaces core api
org.apache.myfaces.custom.schedule.AbstractUIScheduleBase    ----------- on
src/main/java
org.apache.myfaces.custom.schedule.UIScheduleBase
------------ generated on target/maven-faces-plugin/main/java
org.apache.myfaces.custom.schedule.UISchedule
------------ on src/main/java
org.apache.myfaces.custom.schedule.HtmlSchedule
------------ generated on target/maven-faces-plugin/main/java

On eclipse I works like if all files were on the same directory. Code
completion works using base classes (with templates do not!).

Generate in src/main/java or in target/maven-faces-plugin/main/java is
transparent for the IDE. If we generate in src/main/java, the generated code
will mix with hand written code, if we translate generated code to a
separate directory on src/main/java technically it is equivalent to generate
in target/maven-faces-plugin/main/java.

In conclusion: Actually 100%  of the components in tomahawk (I have only a
problem with t:tree2 that can be solved with more work) can use abstract
classes aproach (with some little modifications on myfaces-faces-plugin).
The list of modifications is this. :

- component-includes parameter on component-extension
- component-serial-uid parameter on component-extension
- is-get-local-method-scope and is-get-local-method parameters on
property-extension to generate automatically getLocalXXX method
- is-set-method-scope and is-set-method parameters on property-extension to
generate automatically isSetXXXX method.

regards

Leonardo Uribe

Reply via email to