Friday, October 7, 2011

use eclipse EEF as a property sheet for the Graphiti editor


I just dived into the Graphiti project recently because we needed to design a quick and simple graphical editor.
I do not want to get into a war between GMF and Graphiti but that was an opportunity to get to know this framework and GMF has proven having a steep learning curve and I did not have too much time to consume teaching GMF to our Talend colleges in China.
So I decided to make a POC for our own use case with the following requirements :

  • is must be a visual form editor.
  • it has to be very simple
  • allow infinite containment depth
  • you can specify layout to automatically place the components in the containers.
  • be able to edit the selected element properties.
So I decided to create a simple component metamodel using ecore (from the Eclipse Modeling Framework) looking like this.



I then started to follow the Graphiti tutorial available in the Eclipse help. I really invite anyone who wants to start with Graphiti to follow the tutorial, it covers a lot of features provided by Graphiti.

This blog title is about using EEF (Extended Editing Framework) so let's dive into the subject.
Graphiti default editor is able to link with an Eclipse tabbed property sheet that you may declare in your plugin.xml with the org.eclipse.ui.views.properties.tabbed.propertyContributor extension point. 
But you have to it all by yourself. This is where EEF comes into play, why not using the Obeo's contributed set of tools and framework to generate the tabbed property sheets automatically according to our ecore metamodel ? And indeed that is what I did.
here is a screen-cast explaining how I did it.


(here is a youtube link for those who have trouble with screecast-o-matic : http://youtu.be/zbfisZt-FOw)

At 2mn25 there are a couple of files added that make the bridge between EEF and Graphiti.

1) The first file GraphitiEObjectFilter is a section filter to accep displaying the property sheet only when the edited graphiti business object is a EObject :

import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.platform.AbstractPropertySectionFilter;

public class GraphitiEObjectFilter extends AbstractPropertySectionFilter {
 @Override
 protected boolean accept(PictogramElement pe) {
  Object object = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(pe);
  if (object instanceof EObject) {
   return true;
  }
  return false;
 }
}

2) The second file extends an EEF class property sheet section implementation to return the proper EObject from the selection, because Graphiti provides a pictogram element as the selection.

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.eef.runtime.ui.properties.sections.PropertiesEditionSection;
import org.eclipse.gef.EditPart;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;

public class GraphitiPropertyEditionSection extends PropertiesEditionSection {
 @Override
 protected EObject resolveSemanticObject(Object object) {
  if (object instanceof PictogramElement) {
   return Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement((PictogramElement) object);
  }

  EditPart editPart = null;
  if (object instanceof EditPart) {
   editPart = (EditPart) object;
  } else if (object instanceof IAdaptable) {
   editPart = (EditPart) ((IAdaptable) object).getAdapter(EditPart.class);
  }
  if (editPart != null && editPart.getModel() instanceof PictogramElement) {
   return Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement((PictogramElement) editPart.getModel());
  }
  return super.resolveSemanticObject(object);
 }
}

This last file would not be necessary if Graphiti would somehow provide a way to register some adapters to the pictogram element because EEF if a good citizen and the original resolveSemanticObject looks for an EObject adapter (see this issue).

Cheers.

PS : I'd like to thank Volker Wegert that did a GMF to Graphiti convertion of a complex form editor and gave me good advices to get me started.


Monday, July 27, 2009

Automating Unit tests for RCP applications with the Eclipse Test Framework

The initial article that help me in getting my JUnit test to be run automatically with the Eclipse Test Framework can be found on the RCP quickstart site.

The article, the example as well as the comments where very helpfull but not sufficient enought to answer my needs that is why I wanted to publish some of my findings on this blog.
All the following discussion will be base around this piece of ant script:

<ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}">
  <property name="os" value="${baseos}"/>
  <property name="ws" value="${basews}"/>
  <property name="arch" value="${basearch}"/>
  <property name="data-dir" value="${mhdk.root.for.test} -clean -testApplication com.nds.france.mhdk.mhdkmanager.rcp.application" />
  <property name="plugin-name" value="test.all.test.suite" />
  <property name="classname" value="com.nds.test.AllTests" />
</ant>

This is a cut and paste from Patrick Paulin's example but I removed the emma reference as I am only interested in the unit tests.
What I did, as many of you might have done, was to test the example and I could get it running quickly then I adapted it for my own RCP application.

1) -cleanYou may have noticed that the data-dir property is set to a path and ends with -clean.
   <property name="data-dir" value="${mhdk.root.for.test} -clean" />

Actually this is the only way to pass extra parameter(s) to the eclipse application and I incidently removed it as I did not see the reason for it being here.
Do not do that !!!, I ended up with a java.lang.NoClassDefFoundError: junit/framework/TestListener and spent some time figuring this out.
I have not yet understoud why this is compulsory but this does not work otherwise.

2)RCP application test
The way the script is written does not actually execute your RCP application, but rather launch the org.eclipse.test.coretestapplication application that will load your plugin and run the test class specifyed as plugin-name.You may change the target attribute if you want to perform graphical tests that require a workbench to be created using the value : ui-test, this will launch the org.eclipse.test.uitestapplication.
But what if your application does some specific initialisation when it is started, like mine that uses the workspace (-data) as a specialzed area for accessing data?
If you need your application plugin Activator or your application class to be called before the unit test starts you may then extend the data-dir value with -testApplication such as:

<property name="data-dir" value="${my.workspace} -clean -testApplication com.my.application.id">

3) debug all this
If you want to debug your test while launching them using the ant script or even want to debug the test framework just to see what happens you can always add the following property to the task that launches the unit test.
<property name="extraVMargs" value="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=1716">

This will start the eclipse wirtual machine and stop right before the first byte code is executed waiting for a debugger connection to attach to the process.
Go to the Debug dialog box in Eclipse and create a new Remove Java Application configuration with the following parameters.
Connection type : Standard(Socket Attach)
Host : localhost
Port : 1716 (identical to the one in the extraVMargs property)



You may have to configure the source tab if you want the debugger to display the source code of your application or of the Eclipse Test Framework.

4) No space in folders name
Last but not least...
Do NOT use spaces in folder's name, the Eclipse Test Framework and scripts do not like them at all and it took me some time to figure this out.

That is for now, I hope that sharing of my experience will help other people automating their unit test with RCP applications.

Tuesday, April 28, 2009

SWT Visual Editor

This project in the Eclipse foundation has not followed the Eclipse yearly release since Eclipse 3.2 (2006) see here.

This really is a shame as for designers visual editing is a real time saver for those who do not want to fiddle around with layering elements with code, I found that beginner developpers face problems writing hardcoded GUIs.

But it seems that a french compagny called Soyatech did the porting on Eclipse 3.4 and if you carrefully look at their web site there is also a port for Eclipse 3.3 that seems to work quiet well.