Wire EMF Databinding RCP
THIS IS AN ARTICLE WORK IN PROGRESS (Bug 195163)
Contents
- 1 Abstract/Requirements Definition
- 2 Setup the Toolchain
- 3 Application Design
- 3.1 Plugin-Design
- 3.1.1 at.bestsolution.addressbook
- 3.1.2 at.bestsolution.addressbook.ui
- 3.1.3 at.bestsolution.addressbook.ui.theme
- 3.1.4 at.bestsolution.addressbook.core
- 3.1.5 at.bestsolution.addressbook.core.model
- 3.1.6 at.bestsolution.addressbook.core.datasource
- 3.1.7 at.bestsolution.addressbook.core.datasource.xmi
- 3.1.8 at.bestsolution.addressbook.core.datasource.iBatis
- 3.2 Plugin Overview
- 3.3 Domain Model
- 3.1 Plugin-Design
- 4 Hands on practice or „Let's begin our journey“
Abstract/Requirements Definition
I'm trying to implement a fairly simple address book application on top of RCP using frameworks provided by Eclipse in 3.3. There's also focus on how to structure and design an RCP to be as extensible and as flexible as possible, including theming, internationalization, datastorage independency, ... .
Setup the Toolchain
- Eclipse 3.3 for RCP-Developers (available from http://www.eclipse.org/downloads)
- EMF using the Update-Manager (Help>Software Updates>Find and Install)
- Derby-Plugins (available from http://db.apache.org/derby/derby_downloads.html)
To install:- Stop your eclipse (if running)
- Unzip „derby.zip“s (as of this writing derby_core_plugin_10.2.2.485682.zip and derby_ui_plugin_1.1.0.zip) into your %ECLIPSE_HOME/plugin directory
- Start up eclipse
- iBatis (available from http://ibatis.apache.org)
- Fetch application icons (e.g. available from http://websvn.kde.org/trunk/KDE/kdelibs/pics/oxygen/ using your favorite SVN-Client)
- (Optional) Visual-Database Design
- Install Clay for Eclipse (available from http://www.azzurri.jp/en/software/clay/)
- Download Clay-Utils used for creation of DDL and documentation (available from http://publicsvn.bestsolution.at/repos/java/clayUtils/release/at.bestsolution.clayutils-nodeps-0.0.7.jar)
- DDL-Utils to create database DDL for any database you want (available from http://db.apache.org/ddlutils)
- (Optional) Subclipse for Version-Control (available from http://subclipse.tigris.org)
Application Design
Plugin-Design
at.bestsolution.addressbook
The main RCP-Application
at.bestsolution.addressbook.ui
This plugin provides the UI bits (ViewPart, ...) for the addressbook application.
at.bestsolution.addressbook.ui.theme
This plugin addresses the themeability of the application by providing a plugable theme-API. It will by default provide a standard theme.
at.bestsolution.addressbook.core
This plugin provides the none GUI bits for the application like Command-Definitions, handlers, ...
at.bestsolution.addressbook.core.model
This plugin provides the model implementation created using EMF
at.bestsolution.addressbook.core.datasource
This plugin will provide the API to provide plugable datasources in our case
at.bestsolution.addressbook.core.datasource.xmi
This plugin provides a datasource implementation on top of XMI (directly supported by EMF)
at.bestsolution.addressbook.core.datasource.iBatis
This plugin provides a datasource implementation on top of iBatis
Plugin Overview
Domain Model
The domain model is fairly simple and can be represented by 2 classes as shown in the diagram below. The only interesting thing is that there's a bidirectional relationship between Person(Attribute: primaryAddress) and Address(Attribute: person).
Hands on practice or „Let's begin our journey“
Implementing at.bestsolution.addressbook.core.model
Create an EMF-Project
- Open the "New Project Wizard"
- Select Eclipse Modeling Framework
- Name the project "at.bestsolution.addressbook.core.model"
- The resulting workspace looks like this
Create the Ecore-Model
Create the Ecore file
- Select Example EMF Model Creation Wizards > Ecore Model
- Name the model "addressbook.ecore"
- Open the Properties-View (Window > Show View > Others ...)
- Select the root node currently shown in the editor as null
- Editing the properties in the property view
Create the Classes and Attributes
Now we have to add our Domain-Objects Person
and Address
to the Ecore-Model:
- Right click on the
addressbook
-package you have created above and select "New Child > EClass" - Set the following properties (in the Properties View)
Name:Person
- Right click the
Person
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:surname
EType:EString
- Right click the
Person
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:givenname
EType:EString
- Right click the
Person
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:birthday
EType:EDate
- Right click on the
addressbook
-package you have created above and select "New Child > EClass" - Set the following properties (in the Properties View)
Name:Address
- Right click the
Address
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:street
EType:EString
- Right click the
Address
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:zip
EType:EString
- Right click the
Address
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:city
EType:EString
- Right click the
Address
and select "New Child > EAttribute" - Set the following properties (in the Properties View)
Name:country
EType:EString
You'll notice that the types used for the attributes are not the standard classes provided by the JDK but wrappers defined by EMF. EMF provides wrappers for the most import JDK classes.
After having done this your model should look like the following:
EMF holds META-Informations about your model and that's why all classes part of an Ecore-model have to be known to EMF. Those META-Informations are used by EMF to do fancy things but can also be of use for you when you want to get informations about an your model (or the model of someone different).
There are different ways to get EMF to recognize classes:
- You create a new
EClass
in your model - You define a new
EData Type
to wrap an existing class e.g. provided by the JDK
EMF Background Information:
- EClass: This represents a Class in EMF terminology TODO more information about EClass
- EAttribute: This represents an Attribute in EMF terminology TODO more information about EAttribute You'll notice that the types used for the attributes are not the standard classes provided by the JDK but wrappers defined by EMF. EMF provides wrappers for the most import JDK classes and want to use another classes coming from the JDK you'll have to add an
EData Type
to your Ecore-model. We'll see this later on.
Model the (bidirectional) relation ship between Person and Address
Next thing we have to model is the bidirectional relation between Person and Address like we defined it in our UML-Class Diagramm. In EMF such a relation can be expressed as an EReference in conjunction with an EOpposite:
- Right click the Person and select "New Child > EReference"
- Set the following properties (in the Properties View)
Name:primaryAddress
EType:Address
Containment:true
- Right click the Address and select "New Child > EReference"
- Set the following properties (in the Properties View)
Name:person
EType:Person
EOpposite:primaryAddress
Transient:true
The Ecore model should look like this now:
Model PropertyChangeSupport for Databinding
At this point we have implemented our original Domain-Model in Ecore but we are not finished because when we are working with JFace' Databinding Framework that ships with 3.3 we need to follow the JavaBean specification which means our domain objects have to implement java.bean.PropertyChangeSupport
.
The best way to model this is that all our Domain-Model-Objects inherit from a super-class named BaseObject.
Because there are no wrapper for the Classes and Interfaces needed to implement PropertyChangeSupport
and friends we need to create them our own by defining "EData Types
":
- Right click on the addressbook-package you have created above and select "New Child > EData Type"
- Set the following properties (in the Properties View)
Name:PropertyChangeSupport
Instance Class Name:java.beans.PropertyChangeSupport
- Right click on the addressbook-package you have created above and select „New Child > EData Type“
- Set the following properties (in the Properties View)
Name:PropertyChangeListener
Instance Class Name:java.beans.PropertyChangeListener
- Right click on the addressbook-package you have created above and select „New Child > EData Type“
- Set the following properties (in the Properties View)
Name:PropertyChangeEvent
Instance Class Name:java.beans.PropertyChangeEvent
Now we are able to create our BaseObject
:
- Right click on the
addressbook
-package you have created above and select "New Child > EClass" - Set the following properties (in the Properties View)
Name:BaseObject
- Right click the
BaseObject
and select „New Child > EAttribute“ - Set the following properties (in the Properties View)
Name:id
Etype:EInt
- Right click the
BaseObject
and select „New Child > EAttribute“ - Set the following properties (in the Properties View)
Name:propertyChangeSupport
Etype:PropertyChangeSupport
Changeable:false
- Right click the
BaseObject
and select „New Child > EOperation“ - Set the following properties (in the Properties View)
Name:addPropertyChangeListener
- Right click the
addPropertyChangeListene
r and select „New Child > EParameter“ - Set the following properties (in the Properties View)
Name:listener
Etype:PropertyChangeListener
- Right click the
BaseObject
and select „New Child > EOperation“ - Set the following properties (in the Properties View)
Name:removePropertyChangeListener
- Right click the
removePropertyChangeListene
r and select „New Child > EParameter“ - Set the following properties (in the Properties View)
Name:listener
Etype:PropertyChangeListener
The final Ecore-Diagramm looks like this: