Hi,
[EMAIL PROTECTED] napsal(a):
Sochor Zdeněk schrieb:
Generally extending components by adding whole bucket of local
property/getter/setter seems not right for me because
it's meant to provide just another feature not used by many people.
Wouldn't it be more cleaner to just use that property as attribute (in
JSF api's speach):
storing/using it from getAttributes() map?
This way it would just be needed to generate TLD/Tag entries, no
customization of component's code needed.
Also renderer has full access to attributes map by default ;)
Nice side-effect to this approach is eventual speeding-up processing
by adding cache to getAttributes() MyFaces map:
storing already resolved values in transient map to avoid multiple
resolving during lifecycle.
The disadvantage of using attributes are:
* all typesafety is lost.
This can be assured in tag/handler, also for JSF 1.2 isn't it handled by
deferred-type declaration in tld?
* the attributes are not self-documenting, like explicit setter/getter
methods are. For code, you can see that a property exists on a class,
but cannot see what attributes might affect its behaviour. And for tags,
the property in the tld tells people that the option exists; hiding it
in an attribute makes it harder to find.
In Tomahawk (1.1 based) there are some hidden lines in one property
which modify other properties thus affecting behavior, so nothing new here.
But generally i have to agree.
So in general I would currently be in favour of properties not attributes.
Just general trend ;)
There's no reason why the setter/getter cannot store data into the
attributes map behind the scenes if that turns out to be a useful
optimisation. By having a setter method, the actual way the data is
stored is hidden; we can then optimise in whatever way works best.
* Use case 3:
I create a new project (eg commons widgets)
With the xml-files approach, I need to create two maven modules, one for
the code and one for the builder stuff. Somehow I need to get access to
all the metadata defined by the core build project (??). I then need to
create metadata files for my project that (somehow) add info about my
new components.
With the doc-annotation approach, I just create a project for my code,
add the builder plugin to my pom, and add annotations to any of my
converters/validators/components. Done.
A question about properties inheritance accross components arise:
i really think that having the same propetry handled by multiple
components in hiearchy is bad (quite common in Tomahawk).
Also the Tomahawk code should use consistent way in components and
tags inheritances.
There should be a way to filter already defined properties in either
approach.
Sorry, I don't understand this comment at all.
With what I am proposing, an ancestor class will define a property (eg
getId/setId) and an annotation will be added on that method definition.
Then the derived class does nothing; the plugin walks the ancestry tree
and figures out that there is an inherited property of that name.
Imagine nowadays "standard'" attribute styleClass, it's defined in
almost all tld tags, but sometimes it's implemented as property in more than
one concrete class in the same hierarchy. Now the question is - which
class should work with it (for me the base), BUT the last concrete class
- used component
will generate its own setter/getter AND tag's setter - is it OK? (for me
NOT).
Also, when i think of class hiearchy and code readability/debug info -
in runtime we'll see pointers to generated class's lines, won't we?
Another thing is generating "middle" components in hiearchy ("->" = extends)
e.g. for 2 components now implemented as basic->extending would be
basic abstract->generated concrete basic and now what:
-> abstract ext. ->generated concrete ext. or
-> concrete ext.
because
abstract basic -> abstract ext. and then generating 2 concrete classes
would lost inheritance (concrete_ext instanceof concrete_basic = false)
* Use case 4:
A JSF newbie browses the myfaces-impl code.
With the xml-files approach, he needs to also browse the xml files in
the build project or alternatively browse the generated code to get any
idea of how things work.
With the doc-annotation approach, the annotations are there for him to
see on the checked-in classes.
This use-case is not clear - it's quite different to look at code to
see how components work and to look at renderers' stuff.
IMO more people are interested in renderers, so both approaches are
almost the same for them.
Agreed, generated components that subclass a package-private base
(core-api) is always going to be confusing. In either case, the renderer
is casting to a type that does not exist until the plugin has been run.
However in all other projects (core-impl, tomahawk, etc) we can have the
component base class public. Then with the doc-annotation approach, the
renderer can cast to that base (non-generated) type, and invoke the
abstract methods. The result is code that will compile correctly after a
direct checkout, even without the plugin having been run. That seems nice.
The same *is* possible with the xml-files approach, but is duplicated
work: the class and its properties have to be defined in the xml files
too. And if the code and xml are not kept correctly in sync, then
problems will occur.
I'd rather go with 1 file = 1 component approach. Syncing anything is
always looking for trouble in future.
Regards, Simon
What about just another approach to all generating - using similar
approach as the old days generator but with twist:
Defining abstract methods in component and in building process rewrite
them with generated ones in the SAME class (obviously kicking abstract
modifier from class).
This applied to the whole svn based source tree would generate new
source dir, which will be then compiled to the real project's output.
This new source dir would be used for debugging purpose only, it would
be re-generated everytime.
Benefits:
for developers:
- see whole source code (of output) to find bugs
- having full IDE support (all methods present on hand-written classes)
- no generated whole classes
for users:
- having clear code (no non-existent classes, no hidden methods)
- direct compilation
- clear class hiearchy
Regards,
Zdenek