PUBLIC OBJECT

Extensible Properties for the Java Language

Remi Forax is leading some research on hacking in properties into the JVM. Richard Bair's latest post has inspired me to write about how I think observable properties could be implemented.

I would like properties to be extensible, so that all the generic boilerplate (not just get/set) can be applied:

public class Person {
   private @Property(ObservableProperty.class) String surname;
}`</pre>
...where ObservableProperty implements a chain-of-command interface for setting properties:
<pre>`interface Property&lt;B,T&gt; {
    /** the delegate holds the 'real' property that we're just decorating */
    public void setDelegate(Property&lt;B,T&gt; delegate);
    /** @param name the bean property name, such as surname */
    public void setName(String name);
    public T get(B bean);
    public void set(B bean, T value);
}`</pre>
... and ObservableProperty is implemented something like this:
<pre>`public class ObservableProperty&lt;B extends Observable,T&gt; implements Property&lt;B,T&gt; {
    private Property&lt;B,T&gt; delegate;
    private String name;
    public void setDelegate(Property&lt;B,T&gt; delegate) { 
        this.delegate = delegate; 
    }
    public void setName(String name) {
         this.name = name;
    }
    public T get(B bean) { 
        return delegate.get(bean);
    }
    public void set(B bean, T value) {
        T old = delegate.get(bean);
        delegate.set(bean, value);
        firePropertyChange(bean.getListeners(), name, old, get(bean));
    }
}`</pre>

The real power of this approach is chaining decorators:
<pre>`   private @Property(ObservableProperty.class, NotNullProperty.class) String surname;
   private @Property(ObservableProperty.class, EmailAddressProperty.class) String emailAddress;
   private @Property(TransactionalProperty.class) long id;

This approach makes code better because it is declarative. We are telling the API what to do, not how to do it.