JFace Data Binding/PojoBindable
JFace Data Binding |
Home |
How to Contribute |
FAQ |
Snippets |
Concepts |
Binding |
Converter |
Observable |
Realm |
Contents
- 1 Target
- 2 Pojo Bindable in Action
- 2.1 Without Pojo Bindable
- 2.2 With Pojo Bindable
- 2.2.1 Pojo Bindable Java Agent
- 2.2.2 Configure Pojo Bindable Java Agent with -Dbindable.packages
- 2.2.3 Add ASM in your ClassPath
- 2.2.4 Add Eclipse/Core/Runtime in your ClassPath
- 2.2.5 Pojo Transformed with Pojo Bindable
- 2.2.6 Add/Remove PropertyChangeListener with Reflection
- 2.2.7 Add/Remove PropertyChangeListener with BindableAware
- 2.2.8 -Dbindable.debug=true
- 2.2.9 -Dbindable.gen_basedir=D://tmp/
- 2.2.10 -Dbindable.strategy_provider=org...MyBindableStrategyProvider
- 3 Pojo Bindable & JFace Databinding
- 4 @Bindable annotation
- 5 Use another Java Agent
- 6 OSGi Context
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 :
- org.eclipse.core.databinding.pojo.bindable : Pojo Bindable source.
- org.eclipse.core.examples.databinding.pojo.bindable : Pojo Bindable samples.
- org.eclipse.core.tests.databinding.beans.bindable : Pojo Bindable tests.
- bindable-pojo-test : basic sample with Pojo Bindable explained into the section With Pojo Bindable
- com.springsource.org.objectweb.asm : ASM bundle "org.objectweb.asm" version of 3.2.0 getted from SpringSource Enterprise Bundle Repository.
- com.springsource.org.objectweb.asm.commons : ASM Commons bundle "org.objectweb.asm" version of 3.2.0 getted from SpringSource Enterprise Bundle Repository.
- 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 :
- with classic JavaBean, without using Pojo Bindable
- with a pur Pojo by using Pojo Bindable
Without Pojo Bindable
Create a Java Project bindable-pojo-test and create a basic Pojo PojoPerson into package org.eclipse.core.examples.databinding.pojo.bindable.model :
package org.eclipse.core.examples.databinding.pojo.bindable.model; public class PojoPerson { String name = "HelloWorld"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
Create PojoPersonBindableTest class into package org.eclipse.core.examples.databinding.pojo.bindable :
package org.eclipse.core.examples.databinding.pojo.bindable; import org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson; public class PojoPersonBindableTest { public static void main(String[] args) { PojoPerson person = new PojoPerson(); person.setName("New name"); } }
Now we wish observe change of "name" property of the PojoPerson. To do that we must add java.beans.PropertyChangeSupport in our PojoPerson like this :
package org.eclipse.core.examples.databinding.pojo.bindable.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; public class PojoPerson { private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this); String name = "HelloWorld"; public String getName() { return name; } public void setName(String name) { Object oldValue = getName(); Object newValue = name; this.name = name; firePropertyChange("name", oldValue, newValue); } public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(propertyName, listener); } protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } }
You can notice that we do like this :
public void setName(String name) { Object oldValue = getName(); ... }
instead of doing :
public void setName(String name) { Object oldValue = this.name; ... }
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 :
package org.eclipse.core.examples.databinding.pojo.bindable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson; public class PojoPersonBindableTest { public static void main(String[] args) { // Create listener PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out.println("---------- Property PojoPerson changed --------"); System.out.println(" PropertyName=" + event.getPropertyName()); System.out.println(" OldValue=" + event.getOldValue()); System.out.println(" NewValue=" + event.getNewValue()); System.out .println("------------------------------------------"); } }; // Create Pojo instance PojoPerson person = new PojoPerson(); // Add listener person.addPropertyChangeListener("name", listener); // Here Change "name" property of PojoPerson is tracked. person.setName("New name"); // Remove listener person.removePropertyChangeListener("name", listener); // Here Change "name" property of PojoPerson is not tracked. person.setName("New name2"); } }
When you launch PojoPersonBindableTest, console display :
---------- Property PojoPerson changed -------- PropertyName=name OldValue=HelloWorld NewValue=New name ------------------------------------------
This basic sample show you that you must write in your Pojo code, the PropertyChangeSupport to track the change of the property.
With Pojo Bindable
Pojo Bindable give you the capability to track property change with pur Pojo, without coding PropertyChangeSupport. It means that you can use this Pojo content :
package org.eclipse.core.examples.databinding.pojo.bindable.model; public class PojoPerson { String name = "HelloWorld"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
Change class PojoPerson with this previous code (your project doesn't compile because addPropertyChangeListener/removePropertyChangeListener doesn' exist. For the moment comments code line wich call addPropertyChangeListener/removePropertyChangeListener to compile PojoPersonBindableTest Class).
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 :
Premain-Class: org.eclipse.core.databinding.pojo.bindable.agent.Binda bleAgent
To use Pojo Bindable Java Agent (if you are not into OSGi context), you must launch your program with the JVM parameter :
-javaagent:<your path>/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar
This parameter means that you execute the BindableAgent before executing your program. The BindableAgent add a ClassFileTransformer into Instrumentation instance to update class bytecode.
Configure Pojo Bindable Java Agent
Pojo Bindable Java Agent must be configured. The required configuration is to set the property bindable.packages which defines the packages where Pojo are stored in order to Bindable Java Agent change the bytecode only for the Pojo Class. You can configure Pojo Bindable with 3 means :
with JVM parameter -Dbindable.packages
You can configure Bindable Java Agent with JVM parameter -Dbindable.packages with value org.eclipse.core.examples.databinding.pojo.bindable.model like this :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model
with Java code by implementing BindableStrategyProvider
You can configure Bindable Java Agent with Java code BindableStrategyProvider with value org.eclipse.core.examples.databinding.pojo.bindable.model by implementing org.eclipse.core.databinding.pojo.bindable.BindableStrategyProvider interface like this :
package org.eclipse.core.examples.databinding.pojo.bindable.provider; import org.eclipse.core.databinding.pojo.bindable.BindableStrategy; import org.eclipse.core.databinding.pojo.bindable.BindableStrategyProvider; import org.eclipse.core.databinding.pojo.bindable.DefaultBindableStrategy; public class MyBindableStrategyProvider implements BindableStrategyProvider { private DefaultBindableStrategy bindableStrategy = null; public MyBindableStrategyProvider() { bindableStrategy = new DefaultBindableStrategy(null); bindableStrategy .addPackageName("org.eclipse.core.examples.databinding.pojo.bindable.model"); } public BindableStrategy getBindableStrategy() { return bindableStrategy; } }
After you must launch your program with -Dbindable.strategy_provider like this :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.strategy_provider=org.eclipse.core.examples.databinding.pojo.bindable.provider.MyBindableStrategyProvider
with bindable.properties file
You can configure Bindable Java Agent with bindable.properties file'with value org.eclipse.core.examples.databinding.pojo.bindable.model by creating bindable.properties file into src folder with this content :
bindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model
After you can launch your program only with javaagent JVM parameter :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.ja
Configuration properties of Pojo Bindable
bindable.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).
bindable.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.
bindable.strategy_provider=<provider>
Set an implementation of BindableStrategyProvider to configure BindableStrategy with Java code.
bindable.gen_basedir=<path>
Set the path of base dir if you wish generate the result of transformed class into a file.
bindable.debug=<true|false>
If true, display information about BindableAgent and Class Transformation.
Configure Pojo Bindable Java Agent with -Dbindable.packages
Create a lib folder and copy/paste Pojo Bindable Java Agent org.eclipse.core.databinding.pojo.bindable_1.0.0.jar (that you can find into org.eclipse.core.tests.databinding.pojo.bindable/lib folder).
We must define 2 JVM Parametres with our example :
- -javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar : our BindableAgent is stored into lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar.
- -Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model : our Pojo package is org.eclipse.core.examples.databinding.pojo.bindable.model.
To fill JVM Parameters that with Eclipse IDE, click on Run->Run Configurations. Select "PojoPersonBindableTest" launch (from Java Application node) and click on Arguments tabs. Fill VM Arguments textarea with this content :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model
Add ASM in your ClassPath
Click on Run and you will have this error :
Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/Opcodes ... at org.eclipse.core.databinding.pojo.bindable.agent.BindableAgent.premain(BindableAgent.java:67)FATAL ERROR in native method: processing of -javaagent failed ...
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.
Add Eclipse/Core/Runtime in your ClassPath
Run it and error will display :
Caused by: java.lang.NoClassDefFoundError: org/eclipse/core/runtime/IStatus at org.eclipse.core.databinding.pojo.bindable.agent.BindableAgent.getBindableStrategyFromPackages(BindableAgent.java:160) ...
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 :
package org.eclipse.core.examples.databinding.pojo.bindable.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import org.eclipse.core.databinding.pojo.bindable.BindableAware; public class PojoPerson implements BindableAware { private String name = "HelloWorld"; private transient PropertyChangeSupport _bindable_propertyChangeSupport; public String getName() { return name; } public void setName(String name) { String s = getName(); this.name = name; _bindable_getPropertyChangeSupport().firePropertyChange("name", s, getName()); } private PropertyChangeSupport _bindable_getPropertyChangeSupport() { if (_bindable_propertyChangeSupport == null) _bindable_propertyChangeSupport = new PropertyChangeSupport(this); return _bindable_propertyChangeSupport; } public void addPropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(s, propertychangelistener); } public void addPropertyChangeListener( PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener( propertychangelistener); } public void removePropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(s, propertychangelistener); } public void removePropertyChangeListener( PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener( propertychangelistener); } }
As you can see, Bindable Agent add PropertyChangeSupport capability and update bytecode of PojoPerson#setName(String name) to call PropertyChangeSupport#firePropertyChange(String propertyName, Object oldValue, Object newValue).
getter getXXX()/isXXX() required
Here code of setName :
public void setName(String name) { String s = getName(); this.name = name; _bindable_getPropertyChangeSupport().firePropertyChange("name", s, getName()); }
As you can notice, getName() is used into setName to get the old value. It's a restriction to use Pojo Bindable. For boolean primtive type isXXX is required.
public void setBooleanValue(boolean value) { Boolean oldValue = Boolean.valueOf(isBooleanValue()); this.value = value; _bindable_getPropertyChangeSupport().firePropertyChange("booleanValue", oldValue , Boolean.valueOf(isBooleanValue())); }
setter with primitive type
When primitive type is used into setter, The old/new value is converted to Java Object (boolean to java.lang.Boolean, short to java.lang.Short....). Here sampel with short value :
public void setShortValue(short value) { Short oldValue = Short.valueOf(getShortValue()); this.value = value; _bindable_getPropertyChangeSupport().firePropertyChange("shortValue", oldValue , Short.valueOf(getShortValue())); }
Implements BindableAware
You can notice that PojoPerson implements org.eclipse.core.databinding.pojo.bindable.BindableAware interface. Here te content of this BindableAware interface :
package org.eclipse.core.databinding.pojo.bindable; import java.beans.PropertyChangeListener; public interface BindableAware { void addPropertyChangeListener(String propertyName, PropertyChangeListener listener); void addPropertyChangeListener(PropertyChangeListener listener); void removePropertyChangeListener(String propertyName, PropertyChangeListener listener); void removePropertyChangeListener(PropertyChangeListener listener); }
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
- add PropertyChangeListener, we can do that :
try { Method m = person.getClass().getMethod("addPropertyChangeListener", String.class, PropertyChangeListener.class); m.invoke(person, "name", listener); } catch (Exception e) { e.printStackTrace(); }
- remove PropertyChangeListener, we can do that :
try { Method m = person.getClass().getMethod("removePropertyChangeListener", String.class, PropertyChangeListener.class); m.invoke(person, "name", listener); } catch (Exception e) { e.printStackTrace(); }
Update PojoPersonBindableTest like this :
package org.eclipse.core.examples.databinding.pojo.bindable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.Method; import org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson; public class PojoPersonBindableTest { public static void main(String[] args) { // Create listener PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out .println("---------- Property PojoPerson changed --------"); System.out.println(" PropertyName=" + event.getPropertyName()); System.out.println(" OldValue=" + event.getOldValue()); System.out.println(" NewValue=" + event.getNewValue()); System.out .println("------------------------------------------"); } }; // Create Pojo instance PojoPerson person = new PojoPerson(); // Add listener // person.addPropertyChangeListener("name", listener); try { Method m = person.getClass().getMethod("addPropertyChangeListener", String.class, PropertyChangeListener.class); m.invoke(person, "name", listener); } catch (Exception e) { e.printStackTrace(); } // Here Change "name" property of PojoPerson is tracked. person.setName("New name"); // Remove listener // person.removePropertyChangeListener("name", listener); try { Method m = person.getClass().getMethod("removePropertyChangeListener", String.class, PropertyChangeListener.class); m.invoke(person, "name", listener); } catch (Exception e) { e.printStackTrace(); } // Here Change "name" property of PojoPerson is not tracked. person.setName("New name2"); } }
Run the program and you will notice that we can track change of "name" property. If you have this error :
java.lang.NoSuchMethodException: org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson.addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) at java.lang.Class.getMethod(Unknown Source) ...
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.
To add Listener you can cast person instance into BindableAware :
PojoPerson person = new PojoPerson(); // Add listener ((BindableAware) person).addPropertyChangeListener("name", listener);
To avoid having ClassCastException (if you launch your program without javaagent), it's better to test if PojoPerson implements BindableAware :
PojoPerson person = new PojoPerson(); // Add listener if (person instanceof BindableAware) { ((BindableAware) person).addPropertyChangeListener("name", listener); }
Pojo Bindable provides an Helper which do that. You can write :
if (BindableHelper.isBindableAware(person)) { // Add listener ((BindableAware) person).addPropertyChangeListener("name", listener); }
Update PojoPersonBindableTest like this :
package org.eclipse.core.examples.databinding.pojo.bindable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.eclipse.core.databinding.pojo.bindable.BindableAware; import org.eclipse.core.databinding.pojo.bindable.BindableHelper; import org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson; public class PojoPersonBindableTest { public static void main(String[] args) { // Create listener PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out .println("---------- Property PojoPerson changed --------"); System.out.println(" PropertyName=" + event.getPropertyName()); System.out.println(" OldValue=" + event.getOldValue()); System.out.println(" NewValue=" + event.getNewValue()); System.out .println("------------------------------------------"); } }; // Create Pojo instance PojoPerson person = new PojoPerson(); if (BindableHelper.isBindableAware(person)) { // Add listener ((BindableAware) person) .addPropertyChangeListener("name", listener); } // Here Change "name" property of PojoPerson is tracked. person.setName("New name"); if (BindableHelper.isBindableAware(person)) { // Remove listener ((BindableAware) person).removePropertyChangeListener("name", listener); } // Here Change "name" property of PojoPerson is not tracked. person.setName("New name2"); } }
Run it to check that property "name" of pur Pojo PojoPerson can be tracked.
-Dbindable.debug=true
To debug BindableAgent and check your Pojo class is transformed, you can add the parameter into JVM parameters :
-Dbindable.debug=true
If you lanch the previous example with this parameter, console will display :
Status INFO: NO Transformation for class: org/eclipse/core/internal/runtime/LocalizationUtils Status INFO: NO Transformation for class: org/eclipse/core/internal/runtime/CommonMessages Status INFO: Java Bindable Agent called, with configuration: bindable.packages=org/eclipse/core/examples/databinding/pojo/bindable/model bindable.use_annotation=false bindable.debug=true bindable.gen_basedir=D://tmp/ bindable.strategy_provider=null Status INFO: NO Transformation for class: org/eclipse/core/examples/databinding/pojo/bindable/PojoPersonBindableTest Status INFO: NO Transformation for class: org/eclipse/core/examples/databinding/pojo/bindable/PojoPersonBindableTest$1 Status INFO: Transform class: org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson Status INFO: NO Transformation for class: org/eclipse/core/databinding/pojo/bindable/BindableAware ---------- Property PojoPerson changed -------- PropertyName=name OldValue=HelloWorld NewValue=New name ------------------------------------------
You can notice that console display each Class wich must be loaded. The message
Status INFO: NO Transformation for class: ...
means that Class is not transformed.
Status INFO: Transform class: org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson
means that our PojoPerson class is transformed.
You can notice on start of teh console teh configuration of Pojo Bindable :
Status INFO: Java Bindable Agent called, with configuration: bindable.packages=org/eclipse/core/examples/databinding/pojo/bindable/model bindable.use_annotation=false bindable.debug=true bindable.gen_basedir=D://tmp/ bindable.strategy_provider=null
-Dbindable.gen_basedir=D://tmp/
You can if you wish, generate the result of class transformed into file. To do that you must add the parameter into JVM parameters :
-Dbindable.gen_basedir=D://tmp/
Here, result of class transformed will be generate into folder D://tmp/. If you lanch the previous example with this parameter, console will display :
... Status INFO: Transform class: org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson Status INFO: Generate transformed class: org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson into file: D://tmp/org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson.class Status INFO: Transformed class output written to: D://tmp/org/eclipse/core/examples/databinding/pojo/bindable/model/PojoPerson.class ...
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.
package org.eclipse.core.examples.databinding.pojo.bindable.provider; import org.eclipse.core.databinding.pojo.bindable.BindableStrategy; import org.eclipse.core.databinding.pojo.bindable.BindableStrategyProvider; import org.eclipse.core.databinding.pojo.bindable.DefaultBindableStrategy; public class MyBindableStrategyProvider implements BindableStrategyProvider { private DefaultBindableStrategy bindableStrategy = null; public MyBindableStrategyProvider() { bindableStrategy = new DefaultBindableStrategy(null); bindableStrategy .addPackageName("org.eclipse.core.examples.databinding.pojo.bindable.model"); bindableStrategy.setDebugMode(true); // bindableStrategy.setGenBaseDir("D://tmp"); bindableStrategy.setUseAnnotation(false); } public BindableStrategy getBindableStrategy() { return bindableStrategy; } }
Launch Bindable Agent with -Dbindable.strategy_provider like this :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.strategy_provider=org.eclipse.core.examples.databinding.pojo.bindable.provider.MyBindableStrategyProvider
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.
- HelloWorldWithBeansObservables : bind the property "name" of JavaBean Person with SWT UI Text by using BeansObservables. Binding UI <-> Pojo model is available, on other words when JavaBean model change, UI is too updated.
- HelloWorldWithBeansObservablesWithBindableAgent : bind the property "name" of pur Pojo PojoPerson with SWT UI Text by using BeansObservables. Binding UI <-> Pojo model is available, on other words when Pojo model change, UI is too updated. This sampel must be launched with Pojo Bindable Agent.
HelloWorldWithPojoObservables
This sample use pur Pojo :
package org.eclipse.core.examples.databinding.pojo.bindable.model; public class PojoPerson { String name = "HelloWorld"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
In this sample, we bind the property "name" of pur Pojo Person with SWT UI Text by using PojoObservables. Here the code of HelloWorldWithPojoObservables :
package org.eclipse.core.examples.databinding.pojo.bindable.snippets; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.PojoObservables; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; /** * Hello, databinding. Bind POJO with {@link PojoObservables}. Model change * doesn't update UI. */ public class HelloWorldWithPojoObservables { public static void main(String[] args) { Display display = new Display(); final ViewModel viewModel = new ViewModel(); Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { public void run() { final Shell shell = new View(viewModel).createShell(); // The SWT event loop Display display = Display.getCurrent(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } }); // Print the results System.out.println("person.getName() = " + viewModel.getPerson().getName()); } static class ViewModel { // The model to bind private PojoPerson person = new PojoPerson(); public PojoPerson getPerson() { return person; } } // The GUI view static class View { private ViewModel viewModel; private Text name; public View(ViewModel viewModel) { this.viewModel = viewModel; } public Shell createShell() { // Build a UI Display display = Display.getDefault(); Shell shell = new Shell(display); shell.setLayout(new RowLayout(SWT.VERTICAL)); name = new Text(shell, SWT.BORDER); Button changeModelButton = new Button(shell, SWT.BORDER); changeModelButton.setText("Change model"); // Bind it DataBindingContext bindingContext = new DataBindingContext(); PojoPerson person = viewModel.getPerson(); bindingContext.bindValue(SWTObservables.observeText(name, SWT.Modify), PojoObservables.observeValue(person, "name")); changeModelButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { PojoPerson person = viewModel.getPerson(); person.setName("HelloWorld"); } }); // Open and return the Shell shell.pack(); shell.open(); return shell; } } }
When you launch this code, you can see this window :
Binding between SWT Text and Pojo model is done with PojoObservables :
bindingContext.bindValue(SWTObservables.observeText(name, SWT.Modify), BeansObservables.observeValue(person, "name"));
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 :
changeModelButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { PojoPerson person = viewModel.getPerson(); person.setName("HelloWorld"); } });
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 :
bindingContext.bindValue(SWTObservables.observeText(name, SWT.Modify), BeansObservables.observeValue(person, "name"));
Run the HelloWorldWithBeansObservables and you will have this error :
Status WARNING: org.eclipse.core.databinding code=0 Could not attach listener to org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson@743399 java.lang.NoSuchMethodException: org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson.addPropertyChangeListener(java.beans.PropertyChangeListener) java.lang.NoSuchMethodException: org.eclipse.core.examples.databinding.pojo.bindable.model.PojoPerson.addPropertyChangeListener(java.beans.PropertyChangeListener) ...
This exception show you that you must define in the model, methods addPropertyChangeListener and removePropertyChangeListener. PojoPerson become JavaBeanPerson :
package org.eclipse.core.examples.databinding.pojo.bindable.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; public class JavaBeanPerson { // A property... String name = "HelloWorld"; public String getName() { return name; } public void setName(String name) { Object oldValue = this.name; Object newValue = name; this.name = name; firePropertyChange("name", oldValue, newValue); } private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this); public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(propertyName, listener); } protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } }
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).
PojoPerson person = ... ... bindingContext.bindValue(SWTObservables.observeText(name, SWT.Modify), BeansObservables.observeValue(person, "name"));
HelloWorldWithBeansObservablesWithBindableAgent must launch with Bindable Java Agent. To do that, you must :
- Add Bindable Java Agent org.eclipse.core.databinding.pojo.bindable_1.0.0.jar into lib project.
- Add SM in your ClassPath
- configure Bindable Java Agent into 2 JVM parameters :
- -javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar : our BindableAgent is stored into lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar.
- -Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model : our Pojo PojoPerson package is org.eclipse.core.examples.databinding.pojo.bindable.model.
Lanch the program with Bindable JavaAgent filled into JVM Parameters :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model
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.
@Bindable#value
After you can write this to transform setName method and avoid transforming setLogin method :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations; import org.eclipse.core.databinding.pojo.bindable.Bindable; public class UserBindable { private String name; private String login; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLogin() { return login; } @Bindable(value = false) // This method must not be transformed with firePropertyChange. public void setLogin(String login) { this.login = login; } }
You can set @Bindable before class declaration to disable transformation for setXXX method. In this sample setName is not transformed and setLogin is transformed :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations; import org.eclipse.core.databinding.pojo.bindable.Bindable; @Bindable(value = false) // All methods must not be transformed with firePropertyChange. public class UserNotBindable { private String name; private String login; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLogin() { return login; } @Bindable(value = true) // This method MUST ne transformed with firePropertyChange. public void setLogin(String login) { this.login = login; } }
Project org.eclipse.core.tests.databinding.pojo.bindable show you usecase with org.eclipse.core.databinding.pojo.bindable.Bindable annotation.
@Bindable#dependsOn
If you wish manage computed values, you can use @Bindable#dependsOn. You can find TestCase into ComputedValueTest which use model ComputedValueTestEntity
Imagine you have this Pojo :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.computed; import java.beans.PropertyChangeEvent; import org.eclipse.core.databinding.pojo.bindable.annotation.Bindable; public class ComputedValueTestEntity { private double sellingPrice; private double buyingPrice; public ComputedValueTestEntity(double sellingPrice, double buyingPrice) { this.sellingPrice = sellingPrice; this.buyingPrice = buyingPrice; } public double getSellingPrice() { return sellingPrice; } public void setSellingPrice(double sellingPrice) { this.sellingPrice = sellingPrice; } public double getBuyingPrice() { return buyingPrice; } public void setBuyingPrice(double buyingPrice) { this.buyingPrice = buyingPrice; } public double getRatio() { return sellingPrice / buyingPrice; } public boolean isCheapBuyingPrice() { return buyingPrice < 100; } }
Now you want observe changed of the "ratio" property (ComputedValueTestEntity#getRatio()). As you can notice, the method ComputedValueTestEntity#setRatio(double ratio) doesn't exist, because "ratio" property depends on "sellingPrice" and "buyingPrice" properties. So "ratio" change when "sellingPrice" and "buyingPrice" change, on other words when methods setSellingPrice/setBuyingPrice are called.
Imagine you want bind this "ratio" property with a SWT Label. An event PropertyChangeEvent with property name "ratio" must be fired when setSellingPrice/setBuyingPrice methods are called. It means that "ratio" property, depends on call of setSellingPrice and setBuyingPrice methods. You can manage that with Pojo Bindable with @Bindable#dependsOn declared into (ComputedValueTestEntity#getRatio()) getter method like this :
@Bindable(dependsOn = { "sellingPrice", "buyingPrice" }) public double getRatio() { return sellingPrice / buyingPrice; }
After you can observe "ratio" property. Here a sample code to observe it :
PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out .println("---------- Property ComputedValueTestEntity changed --------"); System.out.println(" PropertyName=" + event.getPropertyName()); System.out.println(" OldValue=" + event.getOldValue()); System.out.println(" NewValue=" + event.getNewValue()); System.out .println("------------------------------------------"); } }; // Create ComputedValueTestEntity model ComputedValueTestEntity p = new ComputedValueTestEntity(4, 2); // addPropertyChangeListener to observe ratio (javagent must be used to transform bytecode!!!) ((BindableAware)p).addPropertyChangeListener("ratio", listener); // Change buyingPrice, event is fired with 'ratio' property p.setBuyingPrice(100); // Change sellingPrice, event is fired with 'ratio' property p.setSellingPrice(100);
If you launch this sample with Pojo Bindable Java Agent :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.packages=org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.computed -Dbindable.use_annotation=true
You will see on console :
---------- Property ComputedValueTestEntity changed -------- PropertyName=ratio OldValue=2.0 NewValue=0.04 ------------------------------------------ ---------- Property ComputedValueTestEntity changed -------- PropertyName=ratio OldValue=0.04 NewValue=1.0 ------------------------------------------
For information Pojo Bindable change the bytecode of the Pojo like this :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.computed; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import org.eclipse.core.databinding.pojo.bindable.BindableAware; public class ComputedValueTestEntity implements BindableAware { private double sellingPrice; private double buyingPrice; private transient PropertyChangeSupport _bindable_propertyChangeSupport; private transient double _bindable_setSellingPrice_ratio; private transient double _bindable_setBuyingPrice_ratio; public ComputedValueTestEntity(double sellingPrice, double buyingPrice) { this.sellingPrice = sellingPrice; this.buyingPrice = buyingPrice; } public double getSellingPrice() { return sellingPrice; } public void setSellingPrice(double sellingPrice) { _bindable_beforeDependsOn_setSellingPrice(); Double double1 = Double.valueOf(getSellingPrice()); this.sellingPrice = sellingPrice; _bindable_getPropertyChangeSupport().firePropertyChange("sellingPrice", double1, Double.valueOf(getSellingPrice())); _bindable_afterDependsOn_setSellingPrice(); } public double getBuyingPrice() { return buyingPrice; } public void setBuyingPrice(double buyingPrice) { _bindable_beforeDependsOn_setBuyingPrice(); Double double1 = Double.valueOf(getBuyingPrice()); this.buyingPrice = buyingPrice; _bindable_getPropertyChangeSupport().firePropertyChange("buyingPrice", double1, Double.valueOf(getBuyingPrice())); _bindable_afterDependsOn_setBuyingPrice(); } public double getRatio() { return sellingPrice / buyingPrice; } private PropertyChangeSupport _bindable_getPropertyChangeSupport() { if(_bindable_propertyChangeSupport == null) _bindable_propertyChangeSupport = new PropertyChangeSupport(this); return _bindable_propertyChangeSupport; } public void addPropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(s, propertychangelistener); } public void addPropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(propertychangelistener); } public void removePropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(s, propertychangelistener); } public void removePropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(propertychangelistener); } private void _bindable_beforeDependsOn_setSellingPrice() { _bindable_setSellingPrice_ratio = getRatio(); } private void _bindable_afterDependsOn_setSellingPrice() { _bindable_getPropertyChangeSupport().firePropertyChange("ratio", Double.valueOf(_bindable_setSellingPrice_ratio), Double.valueOf(getRatio())); } private void _bindable_beforeDependsOn_setBuyingPrice() { _bindable_setBuyingPrice_ratio = getRatio(); } private void _bindable_afterDependsOn_setBuyingPrice() { _bindable_getPropertyChangeSupport().firePropertyChange("ratio", Double.valueOf(_bindable_setBuyingPrice_ratio), Double.valueOf(getRatio())); } }
@Bindable#fireEvents
If you wish force fire events, when you call methods you can use @Bindable#fireEvents. You can find TestCase into PeopleTestCase which use model People
Imagine you have this Pojo :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.fireEvents; import java.util.ArrayList; import java.util.Collection; public class People { private Collection<Person> people = null; public void addPerson(Person person) { if (people == null) { people = new ArrayList<Person>(); } people.add(person); } public Collection<Person> getPeople() { return people; } public static class Person { } }
When People#addPerson(Person) is called you want fire events "people" with old/new list of Person to observe changed of the "people" property. You can manage that with Pojo Bindable with @Bindable#fireEvents declared into (People#addPerson(Person)) method like this :
@Bindable(fireEvents = { "people" }) public void addPerson(Person person) { if (people == null) { people = new ArrayList<Person>(); } people.add(person); }
People#getPeople() is required to get the old/new value by using the property "people". After you can observe "people" property. Here a sample code to observe it :
People people = new People(); BindableAware peopleBindable = (BindableAware) people; // Instrumentation was done with successfull, add Listener PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { System.out.println("---------- Property People changed --------"); System.out.println(" PropertyName=" + event.getPropertyName()); System.out.println(" OldValue=" + event.getOldValue()); System.out.println(" NewValue=" + event.getNewValue()); System.out.println("------------------------------------------"); testEvent = event; } }; peopleBindable.addPropertyChangeListener("people", listener);
If you launch this sample with Pojo Bindable Java Agent :
-javaagent:lib/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar -Dbindable.packages=org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.fireEvents -Dbindable.use_annotation=true
You will see on console :
---------- Property People changed -------- PropertyName=people OldValue=null NewValue=[org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.fireEvents.People$Person@92e78c] ------------------------------------------
For information Pojo Bindable change the bytecode of the Pojo like this :
package org.eclipse.core.tests.databinding.pojo.bindable.domain.annotations.fireEvents; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collection; import org.eclipse.core.databinding.pojo.bindable.BindableAware; public class People implements BindableAware { private Collection people; private transient PropertyChangeSupport _bindable_propertyChangeSupport; private transient Collection _bindableFireEvents_addPerson_people; public People() { people = null; } public void addPerson(Person person) { _bindable_beforeFireEvents_addPerson(); if(people == null) people = new ArrayList(); people.add(person); _bindable_afterFireEvents_addPerson(); } public Collection getPeople() { return people; } private PropertyChangeSupport _bindable_getPropertyChangeSupport() { if(_bindable_propertyChangeSupport == null) _bindable_propertyChangeSupport = new PropertyChangeSupport(this); return _bindable_propertyChangeSupport; } public void addPropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(s, propertychangelistener); } public void addPropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(propertychangelistener); } public void removePropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(s, propertychangelistener); } public void removePropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(propertychangelistener); } private void _bindable_beforeFireEvents_addPerson() { _bindableFireEvents_addPerson_people = getPeople(); } private void _bindable_afterFireEvents_addPerson() { _bindable_getPropertyChangeSupport().firePropertyChange("people", _bindableFireEvents_addPerson_people, getPeople()); } public static class Person implements BindableAware { private transient PropertyChangeSupport _bindable_propertyChangeSupport; public Person() { } private PropertyChangeSupport _bindable_getPropertyChangeSupport() { if(_bindable_propertyChangeSupport == null) _bindable_propertyChangeSupport = new PropertyChangeSupport(this); return _bindable_propertyChangeSupport; } public void addPropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(s, propertychangelistener); } public void addPropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().addPropertyChangeListener(propertychangelistener); } public void removePropertyChangeListener(String s, PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(s, propertychangelistener); } public void removePropertyChangeListener(PropertyChangeListener propertychangelistener) { _bindable_getPropertyChangeSupport().removePropertyChangeListener(propertychangelistener); } } }
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.
// Initialize Bindable. static { // Get Instrumentation instance from Instrumentation instrumentation = ??? // Add it Bindable // ClassFileTransformer for Domain POJO. BindableStrategy bindableStrategy = new DefaultBindableStrategy( new String[] { "org.eclipse.core.tests.databinding.pojo.bindable.domain" }); BindableHelper.initialize(bindableStrategy, instrumentation); }
Spring-agent provides for instance InstrumentationSavingAgent :
package org.springframework.instrument; import java.lang.instrument.Instrumentation; public class InstrumentationSavingAgent { private static volatile Instrumentation instrumentation; /** * Save the {@link Instrumentation} interface exposed by the JVM. */ public static void premain(String agentArgs, Instrumentation inst) { instrumentation = inst; } public static Instrumentation getInstrumentation() { return instrumentation; } }
Pojo Bindable include this class, and Instrumentation instance can be getted with the code :
Instrumentation instrumentation = InstrumentationSavingAgent.getInstrumentation();
Once you have the instance you can do :
// Initialize Bindable. static { // Get Instrumentation instance from Instrumentation instrumentation = InstrumentationSavingAgent.getInstrumentation(); // Add it Bindable // ClassFileTransformer for Domain POJO. BindableStrategy bindableStrategy = new DefaultBindableStrategy( new String[] { "org.eclipse.core.tests.databinding.pojo.bindable.domain" }); BindableHelper.initialize(bindableStrategy, instrumentation); }
You can use too SpringInstrumentationProvider from Pojo Bindable like this :
// Initialize Bindable. static { // Get Instrumentation instance from spring-agent and add it Bindable // ClassFileTransformer for Domain POJO. BindableStrategy bindableStrategy = new DefaultBindableStrategy( new String[] { "org.eclipse.core.tests.databinding.pojo.bindable.domain" }); BindableHelper.initialize(bindableStrategy, SpringInstrumentationProvider.INSTANCE); }
OSGi Context
To manage Pojo Bindable into OSGi context, please see Pojo Bindable SVN. It Following the same idea that EclipseLink/Examples/OSGi/Equinox Byte Code Weaving.