In the previous article Single sourcing with Eclipse RAP we have seen how to develop an Eclipse project and then run it both as a Desktop (RCP) Application an as a Web (RAP) Application.
Now we will see how to go further and develop a database Application with the same dual approach. We will use EMF and Teneo for this, in the same way showed in the series of tutorials “From Model to Persistence” at page EMF Development.
In the following instructions we must make a clear distinction between installing some feature into the IDE or into the Target Platform (RAP in our case). Installing into IDE is performed going to menu Help -> Install New Software, while installing on the Target Platform is made with Window -> Preferences -> Plug-in Development -> Target Platform (see article Single sourcing with Eclipse RAP).
Let’s first start installing on our IDE all needed tools:
Update site: Indigo (included) – http://download.eclipse.org/releases/indigo
Category: Modeling
Feature: EMF – Eclipse Modeling Framework SDK
Update site: Indigo (included) – http://download.eclipse.org/releases/indigo
Category: General Purpose Tools
Feature: All SWT Designer features except SWT Designer XWT Support (requires Eclipse WTP/WST) and all WindowBuilder features except WindowBuilder XML Core
Update site: Elver (to be added) – http://www.elver.org/eclipse/update
Category: Teneo/Texo Dependencies
Feature: All
Update site: Teneo 1.2.0 (to be added) – http://download.eclipse.org/modeling/emf/teneo/updates/1.2.0/interim/
Category: EMF Teneo – Hibernate
Feature: All
Now let’s add on the RAP Target Platform the following (please consider that we already installed Rich Ajax Platform (RAP) Target Components and EMF RAP Target Components in previous tutorial):
Software site: Elver (to be added) – http://www.elver.org/eclipse/update
Category: Teneo/Texo Dependencies
Feature: All
Software site: Teneo 1.2.0 (to be added) – http://download.eclipse.org/modeling/emf/teneo/updates/1.2.0/interim/
Category: EMF Teneo – Hibernate
Feature: All
Ok now we are ready for the single sourcing development phase. For the model we can just Import the model plug-in we made in the tutorial Eclipse EMF: updating the Model. While we can modify our current RCP/RAP application (it.rcpvision.rcprap.application) in the following way.
In the Activator let’s connect to the database and load data (there is a populating section just for the very first time, when the database is just created)
import java.io.IOException; import java.util.Properties; import library.Author; import library.Library; import library.LibraryFactory; import library.LibraryPackage; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.teneo.hibernate.HbDataStore; import org.eclipse.emf.teneo.hibernate.HbHelper; import org.eclipse.emf.teneo.hibernate.resource.HibernateResource; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.hibernate.cfg.Environment; import org.osgi.framework.BundleContext; ... public void start(BundleContext context) throws Exception { super.start(context); plugin = this; loadResource(); } private void loadResource() { // *************** Initialize Teneo Hibernate DataStore ************************************* HbDataStore hbds = (HbDataStore) HbHelper.INSTANCE.createRegisterDataStore("MyDb"); // Set Database properties Properties props = new Properties(); props.setProperty(Environment.DRIVER, "com.mysql.jdbc.Driver"); props.setProperty(Environment.URL, "jdbc:mysql://localhost:3306/test5?createDatabaseIfNotExist=true"); props.setProperty(Environment.USER, "root"); props.setProperty(Environment.PASS, "admin"); props.setProperty(Environment.DIALECT, org.hibernate.dialect.MySQL5Dialect.class.getName()); props.setProperty(Environment.SHOW_SQL, "true"); props.setProperty(Environment.HBM2DDL_AUTO, "update"); hbds.setDataStoreProperties(props); // Register EMF package hbds.setEPackages(new EPackage[] { LibraryPackage.eINSTANCE }); hbds.initialize(); // *************** Initialize Database Content Data ************************************* // (the first time a new Library object container is persisted, otherwise it is just loaded) String uriStr = "hibernate://?"+HibernateResource.DS_NAME_PARAM+"=MyDb"; final URI uri = URI.createURI(uriStr); ResourceSet resourceSet = new ResourceSetImpl(); resource = resourceSet.createResource(uri); try { resource.load(null); if (resource.getContents().size() == 0) { Library library = LibraryFactory.eINSTANCE.createLibrary(); resource.getContents().add(library); Author author = LibraryFactory.eINSTANCE.createAuthor(); author.setName("Ed"); author.setSurname("Merks"); library.getListAuthor().add(author); author = LibraryFactory.eINSTANCE.createAuthor(); author.setName("Lars"); author.setSurname("Vogel"); library.getListAuthor().add(author); author = LibraryFactory.eINSTANCE.createAuthor(); author.setName("Eike"); author.setSurname("Stepper"); library.getListAuthor().add(author); author = LibraryFactory.eINSTANCE.createAuthor(); author.setName("Ralf"); author.setSurname("Sternberg"); library.getListAuthor().add(author); author = LibraryFactory.eINSTANCE.createAuthor(); author.setName("Tom"); author.setSurname("Schindl"); library.getListAuthor().add(author); resource.save(null); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
now rewrite the View like this (as you have learnt in other our tutorials, here we put a TableViewer and bind the content of the loaded EMF resource)
package it.rcpvision.rcprap.application; import library.Author; import library.Library; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.PojoObservables; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.core.databinding.observable.map.IObservableMap; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.part.ViewPart; public class View extends ViewPart { public View() { } public static final String ID = "it.rcpvision.rcprap.application.view"; private TableViewer viewer; private Table table; private WritableList writableList = new WritableList(); private DataBindingContext m_bindingContext; public void createPartControl(Composite parent) { Library library = (Library) Activator.getDefault().getResource().getContents().get(0); writableList.addAll(library.getListAuthor()); parent.setLayout(new GridLayout(1, false)); viewer = new TableViewer(parent, SWT.BORDER | SWT.FULL_SELECTION); table = viewer.getTable(); table.setLinesVisible(true); table.setHeaderVisible(true); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); TableViewerColumn tableViewerColumnName = new TableViewerColumn(viewer, SWT.NONE); TableColumn tblclmnName = tableViewerColumnName.getColumn(); tblclmnName.setWidth(100); tblclmnName.setText("Name"); TableViewerColumn tableViewerColumnSurname = new TableViewerColumn(viewer, SWT.NONE); TableColumn tblclmnSurname = tableViewerColumnSurname.getColumn(); tblclmnSurname.setWidth(100); tblclmnSurname.setText("Surname"); m_bindingContext = initDataBindings(); } public void setFocus() { } protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); // ObservableListContentProvider listContentProvider = new ObservableListContentProvider(); IObservableMap[] observeMap = PojoObservables.observeMaps(listContentProvider.getKnownElements(), Author.class, new String[]{"name", "surname"}); viewer.setLabelProvider(new ObservableMapLabelProvider(observeMap)); viewer.setContentProvider(listContentProvider); // viewer.setInput(writableList); // return bindingContext; } }
you also need the following dependencies in MANIFEST.MF
Require-Bundle: org.eclipse.ui;resolution:=optional, org.eclipse.core.runtime, org.eclipse.rap.ui;resolution:=optional, it.rcpvision.rcptutorial.model, org.eclipse.emf.teneo.hibernate, org.hibernate, com.mysql.jdbc, org.eclipse.emf.ecore.xmi, org.eclipse.core.databinding, org.eclipse.core.databinding.beans, org.eclipse.core.databinding.observable, org.eclipse.core.databinding.property, org.eclipse.jface.databinding;resolution:=optional, org.eclipse.rap.jface.databinding;resolution:=optional
as you see we put other Optional dependencies on both org.eclipse.jface.databinding and org.eclipse.rap.jface.databinding.
If you now run this same source code from the RCP workspace you will see this
while from the RAP workspace you’ll see the following (Note: in both cases you may have to check that the launch has all needed plug-ins/bundles; see “Plug-ins” tab, “Add Required Plug-ins” button in case of RCP and tab “Bundles“, “Add Required Bundles” button in case of RAP)
not bad, don’t you think?
Leave A Comment