Work is underway to support binding with Pojo by using BeansObservable WITHOUT coding firePropertyChange (into setter method)/addPropertyChangeListener/removePropertyChangeListener. For the last version of Pojo Bindable, plese see [[/PojoBindableSVN|Pojo Bindable SVN]] section oterwise, see (for the moment) [https://bugs.eclipse.org/bugs/show_bug.cgi?id=307417 Bug 307417]-

+

Work is underway to support binding with Pojo by using BeansObservable WITHOUT coding firePropertyChange (into setter method)/addPropertyChangeListener/removePropertyChangeListener. For the last version of Pojo Bindable, plese see [[/PojoBindableSVN|Pojo Bindable SVN]] section otherwise, see (for the moment) [https://bugs.eclipse.org/bugs/show_bug.cgi?id=307417 Bug 307417]-

Target

Work is underway to support binding with Pojo by using BeansObservable WITHOUT coding firePropertyChange (into setter method)/addPropertyChangeListener/removePropertyChangeListener. For the last version of Pojo Bindable, plese see Pojo Bindable SVN section otherwise, see (for the moment) Bug 307417-
you can find 7 plug-in projects that provide Pojo Bindable :

com.springsource.org.objectweb.asm.tree : ASM Tree bundle "org.objectweb.asm" version
of 3.2.0 getted from SpringSource Enterprise Bundle Repository. This bundle is not required for Pojo Bindable but just required for com.springsource.org.objectweb.asm.commons bundle.

Pojo Bindable in Action

Before explaining how use Pojo Bindable with JFace Databinding, take a simple example with Pojo. You can find sources of this project into the bindable-pojo-test project that you can download on Bug 307417. In this section we will observe a property change of a Pojo. To do that we will do :

Indead, Experience has shown that sometimes getter methods do not simply return the field value especially in JPA entities. Further, field names could be totally different than the setter/getter method names. This is the reason that getter method is used to get the old value, rather than accessing the field.

By adding java.beans.PropertyChangeSupport in our Pojo, we can observe change of the "name" property of our Pojo (wich become a JavaBean). Update PojoPersonBindableTest code like this :

Pojo Bindable Java Agent

Pojo Bindable is a Java Agent (works only with java.version>=5) which change bytecode of the Pojo to add PropertyChangeSupport. Just for your Information, you can find the Bindable Java Agent into class org.eclipse.core.databinding.pojo.bindable.agent.BindableAgent (which define premain method) and where this class is filled into MANIFEST.MF :

This parameter means that you execute the BindableAgent before executing your program. The BindableAgent add a ClassFileTransformer into Instrumentation instance to update class bytecode.

-Dbindable.packages=<your model package>

BindableAgent requires the property "bindable.packages" to know which Class owned "bindable.packages", must be transformed to add PropertyChangeSupport. If you have several packages you can use ';' character as delimiter (ex : Dbindable.packages=com.example.package1;com.example.package2).

-Dbindable.use_annotation=<true|false>

BindableAgent use "bindable.use_annotation" property to see if @Bindable annotation must be used or not. This property is not required and by default the value is false.

-Dbindable.strategy_provider=<provider>

Set an implementation of BindableStrategyProvider to configure BindableStrategy with Java code.

-Dbindable.gen_basedir=<path>

Set the path of base dir if you wish generate the result of transformed class into a file.

Dbindable.debug=<true|false>

If true, display information about BindableAgent and Class Transformation.

This error means that you must add ObjectWeb ASM in your ClassPath. Indead Pojo Bindable use ObjectWeb ASM 3.2.0 to change bytecode. You can download ASM here or use ASM bundle com.springsource.org.objectweb.asm ASM bundle com.springsource.org.objectweb.asm.commons (ASM OSGified) that you can find into the Pojo Bindable projects. For our example you can copy/paste ASM Jars (that you can find on bindable-pojo-test) com.springsource.org.objectweb.asm-3.2.0.jar and com.springsource.org.objectweb.asm.commons-3.2.0.jar into lib folder and add it into Class Path project.

This erro means that you must add Eclipse/Core/Runtime into your ClassPath because Pojo Bindable use org.eclipse.core.runtime.IStatus to log messages (like ILogger from JFace Databinding). Add
org.eclipse.equinox.common_*.jar into lib and add it into Class Path project (you can find this Jar org.eclipse.equinox.common_3.4.0.v20080421-2006.jar on bindable-pojo-test).

Run it and error must disappear.

Pojo Transformed with Pojo Bindable

At this time, when PojoPerson Class is loaded, BindableAgent transform bytecode with this content :

Add/Remove PropertyChangeListener with Reflection

BindableAgent must transform our Pojo bytecode with PropertyChangeSupport on Class loading of our PojoPerson. Method PojoPerson#addPropertyChangeListener and PojoPerson#removePropertyChangeListener are not available when PojoPersonBindableTest is coding. So we can use Reflection to

It means that BindableAgent doesn't execute transformation. Please check your parameter bindable.packages and if you execute your programm with -javaagent.

Add/Remove PropertyChangeListener with BindableAware

Reflection works very well but the code is awfull. Into section Pojo Transformed with Pojo Bindable we can see that our PojoPerson implements
org.eclipse.core.databinding.pojo.bindable.BindableAware interface. To avoid using Reflection, we can cast our PojoPerson with this interface. To use this interface you must add Pojo Bindable Agent in your ClassPath. Add org.eclipse.core.databinding.pojo.bindable_1.0.0.jar library in your ClassPath.

You can check that you have D://tmp/org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson.class file generated. You can decompile it to check that this class implements BindableAware interface.

-Dbindable.strategy_provider=org...MyBindableStrategyProvider

We have configured BindableAgent with several JVM parameters (-Dbindable.packages, -Dbindable.debug...), but it's possible to configure it with Java code. To do that create a class wich implements
org.eclipse.core.databinding.pojo.bindable.BindableStrategyProvider interface. You can found sample org.eclipse.core.examples.databinding.pojo.bindable.provider.MyBindableStrategyProvider
into org.eclipse.core.examples.databinding.pojo.bindable bundle.

You can find that into the launch/HelloWorldWithBeansObservablesWithBindableAgentProvider.launch

Pojo Bindable & JFace Databinding

In this section we will use Pojo Bindable with JFace Databinding. It explain examples of the project org.eclipse.core.examples.databinding.pojo.bindable. In this project you can find 3 samples into org.eclipse.core.examples.databinding.pojo.bindable.snippets package :

HelloWorldWithPojoObservables : bind the property "name" of pur Pojo Person with SWT UI Text by using PojoObservables. Binding UI -> Pojo model is only available, on other words when Pojo model change, UI is not updated.

SWT Text is filled with "HelloWord" wich come from of the initial value of the PojoPerson. When UI is changed, property "name" of the Pojo is updated. To check that, change UI Text with "a" value. and close the window, console display the value of "name" property of the Pojo :

person.getName() = a

In this sample there is "Change model" button which change "name" property of Pojo model with "HelloWorld" value :

If you update the UI with "a" value and you click on "Change model" button, UI is not updated with new value of the model Pojo.

HelloWorldWithBeansObservables

We have seen that with PojoObservables we can manage only UI -> Model but not UI <- Model (UI is initialized with Model but when Model change, UI is not updated). To manage UI <- Model, we must use BeansObservables. Copy paste HelloWorldWithPojoObservables and rename it with HelloWorldWithBeansObservables. Update PojoObservables with BeansObservables :

Use JavaBeanPerson inseatd of PojoPerson and launch HelloWorldWithBeansObservables. Error will disappear, and when you wil click on "Change Model", SWT UI will be updated with "HelloWorld" value comminf from the Model.

HelloWorldWithBeansObservablesWithBindableAgent

Here we will use Pojo Bindable to use pur Pojo with BeansObservables. Class HelloWorldWithBeansObservablesWithBindableAgent use BeansObservables although our model is a pur Pojo (without addPropertyChangeListener/removeropertyChangeListener methods).

You can find this launch into \launch\HelloWorldWithBeansObservablesWithBindableAgent.launch. Launch HelloWorldWithBeansObservablesWithBindableAgent and you will notice that UI<->Model is available by using pur Pojo.

@Bindable annotation

Sometimes you have "set" method into your model Pojo and you will NOT transform setXXX method by calling PropertyChangeSupport. To do that you can use @Bindable annotation. For instance :

At first you must available @Bindable annotation with JVM parameters bindable.use_annotation=true. After you can write this to transform setName method and avoid transforming setLogin method :

Project org.eclipse.core.tests.databinding.pojo.bindable show you usecase with org.eclipse.core.databinding.pojo.bindable.Bindable annotation.

Use another Java Agent

Only one Java Agent can be filled into JVM parameter -javaagent. If you wish using another Java Agent (like spring-agent.jar), the only thing to do is to find a mean to get the instance of Instrumentation and initialize
Pojo Bindable BEFORE loading Class model wich must be transformed.