 |
Property and interceptors
Posted by forax on January 11, 2007 at 08:10 AM | Comments (15)
Since my last post,
Cay Horstmann
has recalled that properties are intended for tools
and
Hans Muller
bid up
by saying that property syntax is useless
without a way to define bound properties.
Interceptors and bound properties
What Hans want is some kind of interceptor.
An interceptor is an object or a method that can trap access
to a property. In Java, these objects are implemented
either using java.lang.reflect.Proxy or by
bytecode enhancement using a
VM
agent or a special classloader.
It is interresting to know that
bean interceptors are already defined in
EJB
3 spec (JSR-220).
So for me, instead of trying to re-invent the wheel, we could
perhaps transpose the concept of server side interceptors
in Swing world.
We 'just' need an equivalent to an EJB container for
swing application.
I think the concept of transaction can be borrow
in the same time, it could liberate us
from invokeLater and SwingWorker.
So in my opinion, adding bound properties
to the language is a bad idea.
I prefer to let that job to
Beans Binding
experts group (JSR 295) and its leader Scott Violet.
So is property syntax usefull ?
I think that even if bound properties are not managed
by the compiler, we need a property syntax
at least to insert a special attribute in the bytecode
that will be recognize by the reflection runtime
to provide property objects at runtime.
Property interceptor by the compiler
But if you think that this kind of AOP must
be done by the compiler, i propose
to allow to declare two a special methods
named set* and get* (the star is not a typo)
that can be used instead of a particular getter
or setter.
By example, a bean that declares two bound properties
background and foreground in that way
could be written like that :
public class MyBean {
public property Color background;
public property Color foreground;
public void set*(Property property,Object value) {
Object oldValue=property.get(this);
super();
SwingPropertySupport.firePropertyChange(property,
oldValue,property.get(this));
}
}
The compiler will generate foreground or background
setters by duplicate the set* code
for each setter.
java.lang.reflect.Property is the reflection
counterpart of a property at runtime
(I've just rename the Stephen Colebourne's property object to a more Java-like name),
super() in that context means set the property value
(pretty ugly isn't it) and
SwingPropertySupport is a new class that allow to
add/remove PropertyChangeListener for any
property of any bean.
To Link a property to a listener, we can use
MyBean bean=...
SwingPropertySupport.addPropertyChangeListener(
bean,"background",new PropertyChangeListener() {
...
});
Cheers,
Rémi
P.S : to the little Peter, you can't return a gift :)
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Is your proposal compatible with all the properties, which already exist in the swing API nowadays? The javabeans/swing enthusiasts wont accept any proposal, which is not compatible with what we have at the moment.
Posted by: fatihc on January 11, 2007 at 08:37 AM
-
I think it's much more powerful if you could declare the property as 'Observable' and have the tools manage firing the events. Similarly, you could declare that you want null-checks or protective copies made in the same way.
I described a potential way to do this here.
Posted by: jessewilson on January 11, 2007 at 09:08 AM
-
Rémi,
Suppose that 75% of your property-containing classes had the same set* implementation - that's still needless duplication. What made you prefer this idea to the PropertyStrategy one I concocted in the comments to another post?
Ricky.
Posted by: ricky_clarkson on January 11, 2007 at 09:54 AM
-
Your last example demonstrates exactly what we need to get away from - a hard coded string property name in application code. This is not compiler-checked, and very vulnerable to breaking.
It seems to me that most attempts to code-generate methods on the bean end up in messy syntax, and will always disappoint someone.
I'm pretty sure that the best solution, if there is one appropriate for the language at all, is a combination of the property API I'm proposing with some of Jesse's ideas.
Posted by: scolebourne on January 11, 2007 at 09:55 AM
-
Further, sticking with set* for a moment, I could imagine a generic implementation:
public <T> void set*(Property<T> property,T value) {
T oldValue=property.get(this);
super();
SwingPropertySupport.firePropertyChange(property,
oldValue,property.get(this));
}
I'd rather not lose the type info, if possible
Posted by: ricky_clarkson on January 11, 2007 at 09:57 AM
-
Wouldn't it be even more interesting if this was a propose for a metaprogramming facility? :D
Posted by: ronaldtm on January 11, 2007 at 10:42 AM
-
@fathic, yes, you can see more details
here.
@jessewilson, basically what you propose i someting that
was rejected by JSR 175 expert group i.e attach an implementation
to annotations.
I prefer just providing simple properties with reflection and
let people use it to implement an extension of the bean spec.
@scolebourne, i will love to use something like
MyBean.foreground.property but if the type of foreground
declare a field (or a property) named 'property', i have an ambiguity.
If you have a solution, i will please to see it.
@ricky, the object Property taken as argument will be created by calling getProperty(String name) on the current class. And i don't see how this method can return a Property<T>.
@ronaldtm, meta-programming is a word like mutimedia, it have
too many significations. Could you elaborate a bit more ?
Posted by: forax on January 11, 2007 at 11:55 AM
-
Remi, what I meant was exactly what ricky_clarkson has commented on your previous blog. You answered "i prefer hoping that swing code will be retrofited to use property instead of trying to infer it". I would also prefer this, but I do not see a chance SUN will ever do this. It would break too many widespread tools which depend on Swing properties as they are currently (read "break" as "need rewrite for supporting new properties"). The impact of this would be too big.
Posted by: fatihc on January 11, 2007 at 12:42 PM
-
"What Hans want is some kind of interceptor." Just for the record,
I'm not sure if I want anything in this realm (I would like an HDTV
with a REALLY big screen though). I definitely wasn't asking for
support for aspects; not that there's anything wrong with aspects.
The point of
my response
to the original property keyword proposal was just that it didn't
address the main boilerplate I put up with when writing properties
and it seemed to be aimed at the relatively uninteresting problem of defining
classes that were little more than glorified C structs. I think it
would be unwise to provide language support for one kind of property.
I'd rather not see developers ham-stringing themselves just to take
advantage of the new feature.
Posted by: hansmuller on January 11, 2007 at 01:25 PM
-
Remi, I've blogged again about property literals to help clarify my thoughts - http://jroller.com/page/scolebourne?entry=more_detail_on_property_literals. Contact me via stephen**joda.org if you're interested in helping out, perhaps by enhancing the compiler for property literals?
On the broader point, I'm probably with the view that trying to define a C# or annotation style syntax to cover all the possible variations of get/set and other code-generated methods is not viable. The only way to cover all the possibilities will be an OO design as a number of people have suggested.
Posted by: scolebourne on January 11, 2007 at 04:22 PM
-
I meant some sort of 'fallback' method, like ruby's and groovy's.
'void set*()' just looked like that, some sort of generic method block that declares many methods based on other metadata.
But well, don't take me so serious, I was kidding :)
Posted by: ronaldtm on January 12, 2007 at 03:22 AM
-
@ronaldtm, yes, i was thinking exactly to that kind of methods
when i write this entry.
@fathic, the impact is not that high,
all java.util has been retroffited to use generics
and that was done withtout any tools
I think we can do something like that for swing property.
Hans, i agree with you that bound properties need to be taken
into account, but i still think that this kind of property need
to be represented by an object, obtained by
reflexion, by a property litteral syntax or compiler generated.
Posted by: forax on January 12, 2007 at 03:57 AM
-
I also like the property literal idea. I haven't surveyed all of the
proposals however I'd hope that someone has proposed something like
MyBean.properties.foo or MyBean.class.foo.property or something else
that makes it possible to safely refer to a property, without a
string. In addition to providing access to an object that could
expose the properties meta-data and get/set methods, I'd like to be
able to use such a literal in a PropertyChangeListener, e.g.:
public void propertyChange(PropertyChangeEvent e) {
if (MyBean.properties.foo == e.getProperty()) {
// respond to a change in the foo property
}
}
Posted by: hansmuller on January 12, 2007 at 01:26 PM
-
You still don't address the concern that properties should be able to be defined as readonly or writeonly as well as read/write, nor that the type of the local entity storing the data might be different from the type you want to return.
Posted by: jwenting on January 15, 2007 at 02:27 AM
-
Hans, i would like to, a kind of
java.lang.reflect.Property. One problem with litterals
is that if you want to do that correctly you need a VM support.
@jwenting, at this time, final means readonly property and
there is no support for writeonly property. By default, properties
are read/write. If the type of the field differ from the type of the getter,
you can declare an abstract property and write your getter as you want.
Posted by: forax on January 15, 2007 at 03:06 AM
|