Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Archive for July, 2009

on Jul 29th, 2009REST, the OSGi and ECF way

A few months ago I introduced you to REST. Since then my Google Summer of Code project, REST abstraction for ECF, has been accepted and a lot of work has been done. Scott Lewis and I wanted to make the use of any REST services as simple as possible and whats simpler for a bundle developer than an OSGi service?

First I want to give  you a little code snippet to see how we access a REST based web services:

IConnectContext context = 
     ConnectContextFactory.createUsernamePasswordConnectContext("user", "password");
container.setConnectContextForAuthentication(context);
remoteService = container.getRemoteService(RestService.class.getName());
try {
     remoteService.callSync(new RestRemoteCall("getUserTimeline"));
     TwitterService service = (TwitterService) remoteService.getProxy();
     IUserTimeline timeline = service.getTimeline();
     IUserStatus[] userStatuses = timeline.getUserStatuses();
     // do something with the userStatuses
} catch (ECFException e) {
// handle exception
}

What have we done? We use an ECF container to get an IRemoteService object which we use to call an IRemoteCall with the method getUserTimeline. After this we access the service’s proxy object which is an instance of TwitterService.

As you surely imagine this snippet has something to do with twitter icon wink REST, the OSGi and ECF way

Twitter provides its services over a REST based API. The messages you post to twitter are stored in a timeline because every message has its unique timestamp. To access your own timeline you can use the URL: http://twitter.com/statuses/user_timeline.json. But this URL is not defined in the above code snippet. So where do we define this kind of resource? Therefore we can use our own ECF container. So let us define a TwitterContainer which extends RestContainer.

public class TwitterContainer extends RestContainer {
  public TwitterContainer(ID restId) {
  super(restId);
  Map twitterMethods = new HashMap();
    try {
      twitterMethods.put("getUserTimeline", 
        new GetRestCall(new URI("/statuses/user_timeline.json"),
        "ecf.rest.resource.json.org", 
        new Object[]{"count=2"}, null, 10000));
      registerRestService(new String[] { ITwitter.class.getName() }, 
        new TwitterService(), twitterMethods, null);
    } catch (URISyntaxException e) {
       // handle exception
    } catch (ECFException e) {
        // handle exception
    }
  }
}

As you see, we register a REST service with the timeline URL and a String called “getUserTimeline”. This String acts as a key for a specific REST service and will be associated with an IRemoteCall instance. These values are stored in a Map and registered in the container with an instance of TwitterService. TwitterService is a simple POJO which just needs to implement one interface called IRestResponseProcessor. This is needed because the parsed response has to be passed to an service object. With the parsed response, the service object can almost do everything. For example, bringing up an object model for Twitter’s timeline. If we look back to the first snippet, we see that the service is accessed via the key registered in this container. So we can register as many services we want and simply access them with a container instance at any point.

To put it all in a nutshell, we have to register our REST service as a POJO in an ECF container and just call it. This sounds almost like ordinary OSGi Services doesn’t it?

I have pre implemented two scenarios (twitter and google search) which you can check out at the project page.

I would love to hear your feedback so feel free to post comments or post on the ecf-dev mailing list.

on Jul 29th, 2009Nomenclature and the Evolution of Eclipse

One of the great things about Eclipse is that it evolves, it’s not static. We reinvent ourselves.

From IDE to RCP to Runtime. From Platform to e4 (e.g., the future).

evolution 300x223 Nomenclature and the Evolution of Eclipse

When we evolve, it gives us an opportunity to think about our lexicon.

I recently sent an email to the Eclipse PMC entertaining the idea of deprecating our usage of the word ‘plug-in’:

On last week’s Eclipse Architecture team call, I brought up the ‘plug-in versus bundle’ naming issue. This naming issue also came up at this week’s PDE team call where we had consensus that deprecating the word plug-in would be a good idea. Furthermore, the new components in PDE (e.g., API Tools) have gone out of their way to not call things plug-ins. I also know the Equinox p2 team struggles with naming problems (e.g., calling things software).

My proposal is that we adopt “bundle” and deprecate “plug-in” as the official module term.

If you’re interested in this, please comment on this bug. There’s also another bug open that wants to rename RCP if you’re interested in that too.

I would like to hear from the Eclipse and OSGi communities on what they think. Good or bad idea?

Would you welcome the change?

on Jul 28th, 2009Gradients and Rounded Borders in RAP

We try hard to enable a “sexy” look and feel for Rich Ajax Platform (RAP) applications. However, without rounded borders and gradients you can hardly create a website that look modern. Take this dialog as an example:

before2 Gradients and Rounded Borders in RAP

It looks so much better with rounded borders on Shell, Control and with these Button gradients:

after1 Gradients and Rounded Borders in RAP

The latter screenshot has been taken from the current RAP development stream. These features were challenging to implement but we eventually came up with a solution. The interesting part is that it’s not image based. Instead of creating a bunch of images (one for every corner and side), all you have to do is define your border radius in the CSS style sheet.

How does it work?

We are using vector graphics (SVG/VML) in the browser. This works with all browsers supported by RAP (FF2+, IE6+, Safari 3.1+, etc.) without any add-ons. Check it out on our examples demo.

And how does the CSS look like? For gradients we followed the CSS syntax implemented by Webkit-based browsers as Safari and Chrome. Besides a start color and an end color, you can also define any number of intermediate steps. We only support vertical linear gradients in the first version, but this will change. By the way, we proposed to use the same syntax for styling in e4.

  background-image: gradient(
    linear, left top, left bottom,
    from( #ffffff ),
    color-stop( 48%, #f0f0f0 ),
    color-stop( 52%, #e0e0e0 ),
    to( #cccccc )
  );

For rounded borders we followed the CSS 3 syntax. You can set rounded borders using the new border-radius property (even a different radius for every corner is possible).

  border: 2px solid #005092;
  border-radius: 6px;

Both features are available in the RAP CVS and will be included in the 1.3 M1 release shipped in August.

Enjoy!

on Jul 28th, 2009Teamwork, Innovation and Diversity

I was really impressed with this article from today’s NY Times:

Netflix Competitors Learn the Power of Teamwork

I was particularly fond of this quote:

The biggest lesson learned, according to members of the two top teams, was the power of collaboration. It was not a single insight, algorithm or concept that allowed both teams to surpass the goal … Instead, they say, the formula for success was to bring together people with complementary skills and combine different methods of problem-solving

I think it provides an excellent example of the benefits received due to open collaboration (with distributed, diverse teams). Furthermore, I think it identifies a powerful and sustainable value creation and commercialization approach for open source projects.

What do you think? I think Eclipse does some of this already, but how can we improve things?

on Jul 27th, 2009Eclipse Galileo Podcasts

James Sugrue from DZone put together a nice set of podcasts around the Eclipse Galileo release.

If people have time, I highly recommend you check them out.

Enjoy!

on Jul 23rd, 2009OSGi, Dynamics and Eclipse

I often hear this question…

“Why does Eclipse prompt me to restart if it’s a dynamic OSGi-based application?”

restart 300x112 OSGi, Dynamics and Eclipse

As a user, you’re presented with a few choices: no, apply changes (I’m feeling lucky) or yes (please restart).

To answer this question, let me tell you a story. Back in the day, Eclipse had its own module system… things that you see these days in the MANIFEST.MF file were all in the plugin.xml file:

eclipseplugin 300x186 OSGi, Dynamics and Eclipse

These old plug-ins were lazy, but not dynamic in the OSGi sense. New plug-ins could come, but nothing would ever go away. In the the PDE team, we like to use the analogy of a play. So imagine a play where all the actors come out for their parts… but they never leave the stage. With the adoption of OSGi, Eclipse was able to go fully dynamic and actors can now leave the stage (and come back again!).

However, Eclipse still had to support these old plug-ins even though we moved our runtime to OSGi. How we did this is another story, but it involves translating the old plugin.xml files to OSGi manifest files on the fly.

Since we supported the old plug-in model, we had to prompt for restart. I consider this the historical reason of why the restart dialog exists. Now let me tell you the more serious reason.

The practical reason is that most people don’t code for dynamics still. Even though the Eclipse RCP stack is fully dynamic aware there may be pieces out there that aren’t. Whether it’s Eclipse code or someone else’s code, it doesn’t matter. It just takes one bundle that isn’t dynamic aware to potentially mess things up. To illustrate what it means to be dynamic aware or not, let’s look at some real code from Eclipse.

/**
 * Manages argument selectors (choosers) for string variables.
 *
 * @since 3.0
 */
public class StringVariablePresentationManager {
 
	/**
	 * String variable presentation extension point identifier
	 * (value <code>"stringVariablePresentations"</code>).
	 *
	 * @since 3.0
	 */
	public static final String EXTENSION_POINT_STRING_VARIABLE_PRESENTATIONS =
            "stringVariablePresentations"; //$NON-NLS-1$
 
	// default manager
	private static StringVariablePresentationManager fgManager;
 
	// extension point attributes
	public static final String ATTR_NAME = "variableName"; //$NON-NLS-1$
	public static final String ATTR_ARGUMENT_SELECTOR = "argumentSelector"; //$NON-NLS-1$
 
	/**
	 * Table of configuration elements for variable presentations,
	 * keyed by variable name.
	 */
	private Map fConfigurations;
 
	/**
	 * Returns the singleton string variable presentation manager.
	 *
	 * @return the singleton string variable presentation manager
	 */
	public static StringVariablePresentationManager getDefault() {
		if (fgManager == null) {
			fgManager = new StringVariablePresentationManager();
		}
		return fgManager;
	}
 
	/**
	 * Returns an argument selector contributed for the given
	 * variable, or <code>null</code> if none.
	 *
	 * @param variable string substitution variable
	 * @return argument selector or <code>null</code>
	 */
	public IArgumentSelector getArgumentSelector(IStringVariable variable) {
		IConfigurationElement element =
                   (IConfigurationElement) fConfigurations.get(variable.getName());
		if (element != null) {
			try {
				return (IArgumentSelector)element.createExecutableExtension(
                                   ATTR_ARGUMENT_SELECTOR);
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		}
		return null;
	}
 
	/**
	 * Constructs the manager, loading extensions.
	 */
	private StringVariablePresentationManager() {
		initialize();
	}
 
	/**
	 * Load extensions
	 */
	private void initialize() {
		fConfigurations = new HashMap();
		IExtensionPoint point= Platform.getExtensionRegistry().getExtensionPoint(
                   DebugUIPlugin.getUniqueIdentifier(),
                   EXTENSION_POINT_STRING_VARIABLE_PRESENTATIONS);
		IConfigurationElement elements[]= point.getConfigurationElements();
		for (int i = 0; i &lt; elements.length; i++) {
			IConfigurationElement element = elements[i];
			String name= element.getAttribute(ATTR_NAME);
			if (name == null) {
				continue;
			}
			fConfigurations.put(name, element);
		}
	}
}

Can you tell what’s potentially wrong with the above code?

Extensions are only read when the object is initialized. The code above doesn’t handle extensions in a dynamic fashion so if new bundles come and provide more string variables, the code above won’t see them. Now imagine this pattern applied to some user interface code where you could contribute menu entries. If the manager was already initialized and your bundle providing entries came along at a later time, you wouldn’t see your menu entry contribution until the system restarted.

How do we make this code dynamic aware? Well, let’s look at another real example from Eclipse:

public final class KeywordRegistry implements IExtensionChangeHandler {
 
	private static final String ATT_ID = "id"; //$NON-NLS-1$
	private static final String ATT_LABEL = "label"; //$NON-NLS-1$
	private static KeywordRegistry instance;
	private static final String TAG_KEYWORD = "keyword"; //$NON-NLS-1$
 
	/**
	 * Return the singleton instance of the <code>KeywordRegistry</code>.
	 *
	 * @return the singleton registry
	 */
	public static KeywordRegistry getInstance() {
		if (instance == null) {
			instance = new KeywordRegistry();
		}
 
		return instance;
	}
 
	/**
	 * Map of id-&gt;labels.
	 */
	private Map internalKeywordMap = new HashMap();
 
	/**
	 * Private constructor.
	 */
	private KeywordRegistry() {
		IExtensionTracker tracker = PlatformUI.getWorkbench().getExtensionTracker();
                tracker.registerHandler(this,
                     ExtensionTracker.createExtensionPointFilter(getExtensionPointFilter()));
		IExtension[] extensions = getExtensionPointFilter().getExtensions();
		for (int i = 0; i &lt; extensions.length; i++) {
			addExtension(PlatformUI.getWorkbench().getExtensionTracker(),
					extensions[i]);
		}
	}
 
	public void addExtension(IExtensionTracker tracker, IExtension extension) {
		IConfigurationElement[] elements = extension.getConfigurationElements();
		for (int i = 0; i &lt; elements.length; i++) {
			if (elements[i].getName().equals(TAG_KEYWORD)) {
				String name = elements[i].getAttribute(ATT_LABEL);
				String id = elements[i].getAttribute(ATT_ID);
				internalKeywordMap.put(id, name);
				PlatformUI.getWorkbench().getExtensionTracker().registerObject(
						extension, id, IExtensionTracker.REF_WEAK);
			}
		}
	}
 
	private IExtensionPoint getExtensionPointFilter() {
		return Platform.getExtensionRegistry().getExtensionPoint(
				PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_KEYWORDS);
	}
 
	/**
	 * Return the label associated with the given keyword.
	 *
	 * @param id the keyword id
	 * @return the label or <code>null</code>
	 */
	public String getKeywordLabel(String id) {
		return (String) internalKeywordMap.get(id);
	}
 
	public void removeExtension(IExtension extension, Object[] objects) {
		for (int i = 0; i &lt; objects.length; i++) {
			if (objects[i] instanceof String) {
				internalKeywordMap.remove(objects[i]);
			}
		}
	}
}

The above code is dynamic aware via IExtensionChangeHandler, notice the addExtension(...) and removeExtension(...) methods. These methods handle extensions coming and going which we would expect in a fully dynamic system.

Note, this dynamics problem applies to any OSGi system… not just Eclipse. Any OSGi system where your bundles come and go that may or may not be dynamic aware can cause problems.

How do we solve this problem? Well, the first step would be to know whether a bundle that we’re going to install and activate is dynamic aware. At the moment we have no idea. I could imagine a solution where there could be a new header: Dynamic-Aware: true

This header would give OSGi provisioning systems some metadata to make a intelligent decision whether a restart would be required or not. For now, in my opinion, the safest decision is always to prompt to restart and leave the decision in the hands of the user. In the future, I hope that we can shed this with improved education and provisioning metadata.

In summary, the problem of why Eclipse prompts you to restart is two-fold: there’s a historical reason due to the old plug-in model but there’s also the other problem of educating people how to write dynamic aware bundles. In the end, it only takes one bad bundle to ruin the dynamics of your OSGi system.

on Jul 20th, 2009Equinox OSGi Webinar Online

As Jeff McAffer noted, the webinar on OSGi we did a couple weeks ago is finally online.

We decided to break it up in a series of six parts for your viewing pleasure.

Part 1 – History and Vision

osgipt1 300x224 Equinox OSGi Webinar Online

Part 2 – Fundamental Concepts

osgipt2 300x224 Equinox OSGi Webinar Online

Part 3 – OSGi Tooling

osgipt3 300x224 Equinox OSGi Webinar Online

Part 4 – OSGi Services

osgipt4 300x224 Equinox OSGi Webinar Online

Part 5 – ServiceTracker and Declarative Services

osgipt5 300x225 Equinox OSGi Webinar Online

Part 6 – Deploying OSGi Systems and Q&A

osgipt6 300x224 Equinox OSGi Webinar Online

Enjoy.

on Jul 17th, 2009OSGi and Equinox Webinar Posted

Last week Chris Aniszczyk and I did a free three hour OSGi and Equinox Jumpstart webinar.

Yesterday we posted the whole thing as a six part series of movies on the EclipseSource webcast site.

Check it out and let us know what you think!

osgiwebinar 300x225 OSGi and Equinox Webinar Posted

The webinar was aimed at people who’ve heard the buzz around OSGi but still don’t have a great feel for what it is, what you do with it and how it helps. We covered a pretty broad range of topics from the overall vision and context for OSGi to key concepts like bundles, classloading and componentization as well as PDE tools for writing bundles. Quite a bit of time was spent talking about services and best practices, in particular declarative services (though we did not have enough time to talk about OSGi distributed services). We also spent time talking about p2 provisioning of OSGi bundles and showed some of the scenarios where OSGi’s dynamic module system shine.

Overall the response was great.  We were experimenting a bit with the format and basically did thirty minute chunks covering a topic and then a few minutes to cover questions that people typed in. Several hundred people signed up from all over the world and turnout on the day was awesome. The format seemed to be compelling as even though the webinar was pretty long (we were completely wiped by the end) the vast majority of the attendees stayed to the end.

The EclipseSource team has been doing a number of webinars over the past months including some on RAP single sourcing, p2 and our Yoxos products. We have a plan for more webinars including ones on ECF, Zest and other projects in which we are involved. 

Stay tuned for details!

on Jul 14th, 2009OSGi Import Package and Split Package Woes

Since OSGi developers gained influence in the Eclipse development and trainings discussion… many words have been said in favour of declaring dependencies via Import-Package instead of Require-Bundle.

The concept of Import-Package is quite appealing. In today’s world, Java itself doesn’t have a concept for modules so we depend on OSGi for modularity. Actual dependencies on the Java side are specified on the class and package level. So it feels more natural to specify what you need via Import-Package instead of where you want something from via Require-Bundle.

As an experienced Eclipse developer dealing with many large projects… I’ve lost some enthusiasm for Import-Package. All those different bundles and their dependencies are difficult enough to grasp for newcomers. Require-Bundle has better tooling support in Eclipse and less complexity in general… so I recommend to use Require-Bundle unless someone needs the improved flexibility of Import-Package.

What’s the reason for my attitude?

Recently I spent some time with a single-sourcing a RAP/RCP project. Having different target platforms for the same bundles is a perfect example where you need the flexibility of Import-Package. Flexibility is good, right? So I went ahead and declared all dependencies as Import-Package.

Now imagine you have declared an Import-Package to the org.eclipse.ui bundle, being sure that org.eclipse.ui is exported in your target.

Everything is fine, right? So far so good in the typical Eclipse RCP case.

However, it’s not so fine if you try it with RAP although you’ll find that bundle org.eclipse.rap.ui.workbench exports the org.eclipse.ui package.

So the situation is:

my.bundle imports org.eclipse.ui
org.eclipse.rap.ui.workbench exports org.eclipse.ui

However, your bundle just won’t be resolved due to a missing Import-Package constraint on org.eclipse.ui.

The diagnostics in Equinox don’t help much either… it just tells you exactly the above imports and exports. I don’t know if there are better tools out there to diagnose issues.

The reason for this behavior is a concept in Java called split packages. It allows the same package to be declared across several bundles… giving each split a special name. So it’s something like a sub-package concept for packages. Although it is discouraged in the OSGi specification… it is used by the Eclipse workbench and other areas where there has been a lot of refactoring and Require-Bundle usage.

The correct import declaration in my.bundle would be

Import-Package: org.eclipse.ui; ui.workbench="split"

Why does it work in the RCP target case?

It wouldn’t if your target platform contains RCP only. However, most RCP applications have the bundle org.eclipse.ui.ide in their target platform which exports another split of the org.eclipse.ui package. OSGi only resolves split packages if at least two exported split packages can be found.

Knowing this… I now can safely use Import-Package for my single-sourced applications. However, I don’t see a way how I possibly could recommend this to students in my training courses or new people to OSGi in general. I’d need to tell them “Look, Require-Bundle is something that has been used in Eclipse for awhile, mostly for legacy reasons. We don’t recommend its use any more. Import-Package is better if you want looser coupling between bundles. However, be aware of the pain split packages can cause.”

I guess my gripe is that split packages make things complicated and we need better tooling to support them.

How are other people handling split packages in the wild?

on Jul 14th, 2009Groovy, Eclipse Commands and Expressions

During my last project I had the dubious joy to work with a boatload of command framework expressions (activeWhen, enabledWhen). I appreciate the need for such a framework… don’t go through the overhead of loading all the classes for dozens of plugins to determine which commands are available… and instead use a lightweight alternative inside the plugin.xml file. This neatly sidesteps all the osgi class loading runtime overhead, making the eclipse experience fast and snappy. And I have to admit I am a sucker for speed. So I am on board with the concept but how things work in practice aren’t optimal in my opinion.

I’m not a big fan of XML in general and the idea of writing code in XML gives me the shivers. I have written enough XSLT to know pain… in copious amounts. We already have a long-established notation for formal expressions: programming languages. There is a very good reason Java’s syntax (or that of any other popular programming language) looks nothing like XML.

One argument that proponents of XML often make is that you usually shouldn’t have to look at XML at all. Well, I think they are wrong. The XML leaks through the cracks way too often. As a developer I am probably more exposed to that than the average user but nevertheless I still have to put up with it. Sometimes there may be a layer of GUI eye candy in between, but for something as specific as an expression editor… the standard extension editor just doesn’t cut it for me.

With a quick look at the following image: Tell me when the expression is true. Oh right, you can’t – the expression is distributed over several tree nodes.

groovy exp 001 Groovy, Eclipse Commands and Expressions

Classic expressions

Now let’s look at the XML. Only slightly better, but at least you can see everything at once. Still clocking in at 6 elements, the signal to noise ratio is abysmally low.

<handler
	class="groovy.expressions.handlers.SampleClassicHandler"
	commandId="groovy.expressions.commands.sampleCommand">
 <enabledWhen>
	<or>
	   <with variable="activePartId">
		  <not>
			  <equals value="groovy.expressions.navigationView" />
		  </not>
	   </with>
	   <with variable="selection">
		  <count value="2" />
	   </with>
	</or>
 </enabledWhen>
</handler>

To put my money code where my mouth is… so I tried to implement a more elegant solution to the problem. Note though that this is just a proof of concept hacked together in my spare time. I wanted to integrate a scripting language with the command framework so that expressions could be written as small snippets of code. The ecosystem of scripting languages is quite prolific at the moment, so there is a lot of choice. But choice is good right? I settled for Groovy since I had done some embedding experiments with it before. But I am convinced that other scripting languages would work just as well.

Hooking up the groovy runtime was a snap, adding another expression type (creatively named “groovy”) was easy as well. I found out before long that I had to specify which command variables to use. The first reason for that was that I had to bind these command variables to groovy variables – although this could also have been achieved with some propertyMissing trickery. The more compelling reason was that the command framework had to known when to re-evaluate the expression, i.e. when relevant variables had changed. The resulting expression now looks like this:

<handler
	class="groovy.expressions.handlers.SampleGroovyHandler"
	commandId="groovy.expressions.commands.sampleCommandGroovy">
 <enabledWhen>
	<groovy using="selection,activePartId">
	activePartId != "groovy.expressions.navigationView" || selection.size() == 2
	</groovy>
 </enabledWhen>
</handler>

Quite a bit more readable, eh? Notice the “using” attribute specifying the used variables mentioned above. It might even be possible to compute these variables by traversing the syntax tree of the expression. This feature is offered by some scripting engines and would mean we could completely drop the “using” attribute. The rest is just plain groovy code, and I’m sure most of you will have no problem understanding an expression like that.

Next I want to discuss some of the caveats and advantages of this approach.

Caveats:

Needs a scripting engine
As far as I know, Java 1.6 ships with a Rhino interpreter so that could be an option for the future. Other small scripting engines (e.g. BeanShell) could be integrated as well. That is unless the big bad licensing monster rears its ugly head.

Might need standardization
As mentioned above there is a whole plethora of scripting languages available right now on the JVM, so choosing “the one” might be a problem. Another option of course would be to delegate to JSR 223 and let the user decide.

Yet another language?
There might some developer resistance concerning yet another language to learn. While this is certainly a concern, some scripting options are very close Java (Groovy and particularly BeanShell come to mind). I would argue that the current XML expression language is “yet another language” to learn as well – and a cumbersome and ill-specified one at that.

Advantages:

Legible expressions
As mentioned above, the expression is much easier to parse for developers. The machine doesn’t care either way, but software should not only be list of machine-operable instructions but also as a means of documentation and communication. The current implementation falls way short in that regard.

Debuggable
Ever tried to debug a highly nested XML expression? Not fun, let me tell you. With “scripted” expressions in the worst case you can pepper your code with println statements. In the best case you can set breakpoints on your expression code editor. The latter would probably be quite a bit of work but I don’t think it is totally infeasible.

More powerful
I haven’t looked into it too deeply but the current expression engine is probably a turing tarpit eager for prey. A “proper” scripting language would gives us a well understood, turing-complete way to describe complex expressions. It would also make it easier to factor common functionality into shared functions in order to reduce coupling and repetition.

Improved Testability
A scripting environment might also make it easier to write and execute unit tests on the expression to verify its correctness. While this also possible with the current expression engine, it is quite a bit of work to get up and running. With scripted expressions one could fairly easily set up the variables and run a minimal execution wrapper around the expression code to test its behaviour in a classical JUnit test.

I put up the code on the github here. Basically the application is your vanilla RCP Mail example. The meat of the code is in org.eclipse.core.internal.expressions.GroovyExpression. Apart from the mucking in the expression engine, the only thing I did was add two commands and handlers with the same activeWhen semantics, but once described as classic XML and once expressed as Groovy code. Have a look, I’m looking forward to your comments and critique.

© EclipseSource 2008 - 2011