Programmatic command contributions

Have you ever faced the task of programmatically adding commands to a given menu? It is not that difficult – when you finally found out ;).
First of all, you need a target menu, whether it is declared or programmatically created does not matter. What you actually need is the menu’s location URI. You may the create an AbstractContributionFactory with the menu’s location URI:

...
AbstractContributionFactory contribFactory = new AbstractContributionFactory ("menu:com.foo.targetmenu?after=targetGroup", null) {
@Override
public void createContributionItems(IServiceLocator locator, IContributionRoot additions) {
// add the contribution using it's source
additions.addContributionItem(createContributionItem(contribSource), null);
}
IMenuService menuService = (IMenuService)getViewSite().getService(IMenuService.class);
menuService.addContributionFactory(locator, contribFactory);
...

The items are added to the IContributionRoot within the factory’s createContributionItems() method. The factory is then registered at the IMenuService and your contributions show up.
For creating an IContributionItem for a given command, you may use the CommandContributionItem class, which takes an CommandContributionItemParameter as constructor parameter. A CommandContributionItemParameter basicly contains all the required data for a command contribution known from the org.eclipse.ui.menus extension point.


private IContributionItem createContributionItem(IServiceLocator locator, Object contribSource) {
CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter(locator, null, "com.foo.the.command.id", SWT.PUSH);
// pimp the item using the contribSource
...
return new CommandContributionItem(contributionItemParameter);
}

There you go.

Cordless on telly is wicked…

Not long ago, I got my brand new LCD television, which is really pretty cool. As my DVD player ‘unfortunately’ quited his job, I additionally needed to buy a BluRay player as well 🙂  – even more really pretty cool. Yesterday, my wife and me went to Hamburg’s main Christmas market right in front of the town hall. We had some time left before we had to go home – so we went looking for DVDs. We entered the shop and I remembered the VGA input slot of my telly – I bought a cable and a cordless keyboard/mouse for my notebook and here I go – cordless on telly!

Eclipse Demo Camp Hamburg – December 2009

Yesterday the Eclipse Demo Camp in Hamburg took place. Awesome 110+ registrations and it felt as if everybody showed up and brought a friend. It was good fun listening to the talks. Jochen Krause from EclipseSource covered Tom Schindl who unfortunately could not attend. Jochen gave a brief overview about e4 which was pretty nice actually. I personally haven’t had the time yet to dive into e4 but it seems to be a very good idea to do so. A lot of things promise to ease the complexity of the 3.x Eclipse Workbench features. Jan Köhnlein then switched to the modeling context and spoke about combining textual and graphical editors for modeling, which was pretty interesting as well.  In order to stick to the EMF topic, Jochen with his RAP talk then demonstrated how to ‘webify’ the common EMF Editor using RAP – And despite the fact that setting up CDO did not really work, he said it really went fast to get that done. Gerd Wütherich and Nils Hartmann were really entertaining when they presented their very own version of Charles Dickens “A Christmas Carol” pointing out “Fifty ways to build your bundle”. Though Gerd and Nils as “Ghosts of Build-Management Past, Present and Future” really had some good input, Ebenezer significantly quited his job as a Build Manager in the end and became an Event Manager which seems to be far more relaxing ;). Ekkehard Gentz had the thankless task of presenting last. But it was definitely worth waiting – Just take a look at the upcoming RedView project and you’ll get what I mean.

Bundles & Libraries

I heard a talk about VIB – Very Important Bundles – today at the W-JAX here in Munich. The speaker pointed out some key features and services (and available solutions) necessary for developing applications in an enterprise context. He also discussed the way bundles should be designed in general. There were two mentioned aspects that made me wonder.

  • Bundles represent a deployment artefact only.
  • Bundles may contain libraries they need, if it is applicable.

For me, a bundle is explicitly not only a deployment artefact. Bundles represent a software component and are therefor an architectual element of the software. They are essential to be able to use public and private API, as Java Packages simply do not serve this need. No need to say that I prefer ‘Required Bundles’ instead of ‘Imported Packages’ :). And turning to libraries, they should be encapsulated in a separate bundle and definetly not included in any bundle containing business code. A big advantage is the reusability of these individual so called ‘library bundles’, for instance logging frameworks or apache commons components. From my point of view, intergrating libraries in a bundle and even exporting them makes their management difficulter than necessary, at least within an enterprise context.

From OAW to MWE…

I’m currently migrating a model driven project from OAW to MWE. While changing all package declarations in the workflow and finding the right MWE counterpart elements is not too complicated, keeping the whole automated building thing working is not as easy as I thought though. The model export from UML to XMI is still bound to the OAW packages, so the export and generate steps need to be separated and executed back-to-back… pretty tricky but necessary… If you face the task of migrating an oaw project, maybe these blog entries from Karsten Thoms or Ekkehard Gentz help you a little.

Eclipse Commands: Cut, Copy and Paste

I came around the requirement to enable the default cut, copy and paste function as menu entries within the main menubar. When adding the commands org.eclipse.ui.edit.cut, org.eclipse.ui.edit.copy and org.eclipse.ui.edit.paste to my menubar using the org.eclipse.ui.menus extension point. Unfortunately, these menu entries where disabled all the time. This was pretty comprehensible, as there was no active handler available. So I did register an appropriate handler (working like the Eclipse WidgetMethodHandler) using the IHandlerService. It takes the currently focussed element and checks whether this Control has the necessary cut(), copy() or paste() method to invoke and calls the required method on execution. So far, so good, my menu entries were now enabled – at least sometimes?!? The reason for that was the isHandled() method of my handler which returns true only if the method is available on the currently focussed element.

/** {@inheritDoc} */
@Override
public boolean isHandled() {
return isTargetMethodAvailable(Display.getCurrent().getFocusControl());
}

As the enablement state is determined only on the context part’s (IWorkbenchPart) activation, the state is only requested once for the default focus Control of the part. So the state of the commands stays the same for the whole part activation. Additionally, a ‘no active handler available’ exception is thrown, if the menu entry is selected with a focussed Control not supporting the method. Bad luck.

So, what to do now? I ended up registering a focus Listener for all elements of the part to keep the command state in sync with the handler state.


// create a listener for tracking the focus
final Listener listener = new Listener() {
/** {@inheritDoc} */
@Override
public void handleEvent(Event event) {
ICommandService commandService = (ICommandService)workbenchPart.getSite().getService(ICommandService.class);
commandService.refreshElements(commandId, null);
}
};

The refreshElements() method calls the updateElement() method of active handlers for the given command ID implementing the IElementUpdater interface. So I let my handler implement that interface, the interface method simply fired an HandlerEvent stating that the enabled state changed.

/** {@inheritDoc} */
@Override
public void updateElement(UIElement element, Map parameters) {
fireHandlerChanged(new HandlerEvent(this, true, false));
}

The only thing left to do was to implement the isEnabled() method which is used to determine the commands enablement state.

/** {@inheritDoc} */
@Override
public boolean isEnabled() {
return isTargetMethodAvailable(Display.getCurrent().getFocusControl());
}

There you are, it works!

Model View Presenter, Passive View & DI

After three days of interesting conversations I’m off to my November holidays. This is a very calm and silent time which leaves a lot time for interesting thoughts.

Denmark

Denmark

I heard a talk about testing RCP Applications on Wednesday shortly before I left Munich which was pretty interesting. Ralf Ebert outlined a way of designing GUIs to ease testing by applying the Model View Presenter pattern in combination with the Passiv View pattern. Basicly it introduces a presenter which mediates between the ‘Model’ and the ‘View’. The model includes all data and logic, e.g. adding two numbers. The view simply displays everything. The presenter connects input and widgets and delegates calls from the UI to the model’s logic. This allows mocking the view’s behaviour and simply test the logic within the model.

The testing aspect sounds interesting, but something else comes a long with that design. In distributed systems, the view usually calls some logic from serverside services. That means, the view has to somehow access a service instance by using some context holding component. Now, what about making the view part of this service structure and provide the service via DI. Usually (in Spring terms 😉 ) this means hooking the view into the service container, which is pretty bad (if even possible) as they are controlled by the platform. But using a so called view model (at least I tend to call it like that) solves that. The model (and even the presenter) may be hooked easily to the container, which makes interaction quite easy.

Nice idea, what do you think?

A wicked blog about software architectur, Eclipse and Eclipse RCP