The Source for Java Technology Collaboration
User: Password:



Rémi Forax

Rémi Forax's Blog

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 del.icio.us Digg Digg DZone DZone Furl Furl Reddit 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





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds