Expressions are used in extension points that have to decide which extension is responsible for which of object. The most popular examples where they are used are the [[Platform Command Framework]], and the [[Common Navigator Framework]]. Depending on the extension implementation, expressions are used to decide any number of things. Examples:

+

Expressions are used in extension points that have to decide things based on a context, but without loading the plugin implementing that decision. The most popular examples where they are used are the [[Platform Command Framework]], and the [[Common Navigator Framework]]. Depending on the extension implementation, expressions are used to decide any number of things. Examples:

* Should an context menu be enabled and/or visible in a context menu

* Should an context menu be enabled and/or visible in a context menu

−

* Should which implementation for a command handler to use depending on the current context

+

* Which implementation for a command handler to use depending on the current context

* Which label provider to use for an object

* Which label provider to use for an object

* Which content provider can provide children for an object in a tree

* Which content provider can provide children for an object in a tree

Line 118:

Line 118:

<source lang="xml">

<source lang="xml">

<visibleWhen>

<visibleWhen>

−

<'''iterate ifEmpty="false"'''>

+

<iterate ifEmpty="false">

<instanceof

<instanceof

value="org.acme.navigator.RootObject">

value="org.acme.navigator.RootObject">

Line 126:

Line 126:

</source>

</source>

−

This iterates over all elements in the colleciton and tests if all elements are an instance of <code>org.acme.navigator.RootObject</code>. Note the <code>ifEmpty="false"</code>: this tells the expression framework that the evaluation should be false for an empty selection, which defaults to <code>true</code> (good tip: check this if you happen to see lots and lots of stuff in your context menu that should not be there, your selection might be empty).

+

This iterates over all elements in the collection and tests if all elements are an instance of <code>org.acme.navigator.RootObject</code>. Note the <code>ifEmpty="false"</code>: this tells the expression framework that the evaluation should be false for an empty selection, which defaults to <code>true</code> (good tip: check this if you happen to see lots and lots of stuff in your context menu that should not be there, your selection might be empty).

Count and iterate have always worked against java.util.Collection. The count and iterate elements can also be used on any variable that adapts to <code>org.eclipse.core.expressions.ICountable</code> or <code>org.eclipse.core.expressions.IIterable</code>, or implements these interfaces directly.

Count and iterate have always worked against java.util.Collection. The count and iterate elements can also be used on any variable that adapts to <code>org.eclipse.core.expressions.ICountable</code> or <code>org.eclipse.core.expressions.IIterable</code>, or implements these interfaces directly.

−

== Additional Variables ==

== Additional Variables ==

Line 137:

Line 136:

* '''activePart''': the currently active part (could f.i. be an instance of <code>org.eclipse.ui.navigator.CommonNavigator</code>)

* '''activePart''': the currently active part (could f.i. be an instance of <code>org.eclipse.ui.navigator.CommonNavigator</code>)

* '''activePartId''': the id of the currently active part (like org.acme.navigator)

* '''activePartId''': the id of the currently active part (like org.acme.navigator)

−

* '''activePartId''': the id of the currently active editor

+

* '''activeEditorId''': the id of the currently active editor

* '''activeWorkbenchWindowShell''': the currently active shell

* '''activeWorkbenchWindowShell''': the currently active shell

Line 224:

Line 223:

One of the more esotheric operators. It is comparable to the <code>with</code> operator, but it allows resolving the variable dynamically and to pass additional arguments needed to resolve the argument. For example to resolve the plug-in descriptor for a specific plug-in, the following expression can be used:

One of the more esotheric operators. It is comparable to the <code>with</code> operator, but it allows resolving the variable dynamically and to pass additional arguments needed to resolve the argument. For example to resolve the plug-in descriptor for a specific plug-in, the following expression can be used:

+

<source lang="xml">

<source lang="xml">

<visibleWhen>

<visibleWhen>

Line 231:

Line 231:

<visibleWhen>

<visibleWhen>

</source>

</source>

−

The actual resolving is delegated to the evaluation context.

+

+

The actual resolving is delegated to the evaluation context (see <code>IVariableResolver</code>). As of eclipse 3.5, there is no implementation in either the command framework or the common navigator framework for IVariableResolver, so the <code><resolve></code> operator is of no use for them.

== systemTest ==

== systemTest ==

Line 261:

Line 262:

== with ==

== with ==

−

Selects a variable different than the default varible for evaluation. Can, and should, contain nested elements. Example:

+

Selects a variable different than the default variable for evaluation. Can, and should, contain nested elements. Example:

Latest revision as of 14:42, 23 October 2012

Expressions are declarative or programmatic expressions based on the org.eclipse.core.expressions plugin. They are declared in plugin.xml and evaluated by the Expressions Framework. The advantages of declaring an expression in plugin.xml are:

Lazy loading: Expressions can be evaluated without loading the plug-in

Where they are useful

Expressions are used in extension points that have to decide things based on a context, but without loading the plugin implementing that decision. The most popular examples where they are used are the Platform Command Framework, and the Common Navigator Framework. Depending on the extension implementation, expressions are used to decide any number of things. Examples:

Should an context menu be enabled and/or visible in a context menu

Which implementation for a command handler to use depending on the current context

Which label provider to use for an object

Which content provider can provide children for an object in a tree

It is also possible to use the expression framework in custom extension points.

Declaration of Expressions

First of all, an expression must be defined in plugin.xml. Here is an example for an enablement expression in the common navigator framework:

Note how the <or> element contains three elements: two <instanceof> and one <adapt>. The <adapt> contains one further <test> element; what they all do will be explained later. For now just focus on the structure of the expression: when it is evaluated, the result of the instanceof and the adapt tests will be logically or-ed because they are nested in a <or> element. The same expression could also be written as follows in a polish pseudo-notation:

Re-Usable expressions

Sometimes you will end up with having the same expression in many different places. When one of them changes, you have to change them all. Obviously, this is inefficient and not very handy - let alone error prone. You can get around this problem by using definitions and re-use expressions that are declared elsewhere.

The expression from the example above can be declared using the org.eclipse.core.expressions.definitions extension point, and then re-used using the <reference> element:

The definition can be declared in any plug-in, and then cross-referenced from all other plugins. They don't even have to have a dependency on each other.

Evaluation Context

An expression alone means nothing without the object that is being tested. Which object that is, and what it contains, is defined by the evaluation context. The content of the evaluation context depends on who is initiating the evaluation.

An evaluation context contains:

The default variable

Optional additional variables

Usually, expressions check the default variable in the evaluation context. However, it is possible for an expression to select a specific variable from the context using the <with> element (examples below).

A common source for confusion are the different default variables provided by the Common Navigator Framework and the Platform Command Framework. While the command framework provides a collection containing the current selection as the default variable, the navigator framework just uses the current object in the tree. For this reason, you cannot use the same expression for both frameworks.

Evaluation of Collections

When dealing with a collection, you usually want to test against the contents of the collection, and not the collection itself. For this case, the expressions framework provides <iterate> and <count>. They require an iterable object to work (otherwise they fail with an error message on the console).

The default variable in the command framework always contains a collection with the current selection. It might be empty, contain just one element (like an ITextSelection), or contain the elements of an IStructuredSelection.

The following expression will work for the common navigator framework, but not for the commands framework:

This iterates over all elements in the collection and tests if all elements are an instance of org.acme.navigator.RootObject. Note the ifEmpty="false": this tells the expression framework that the evaluation should be false for an empty selection, which defaults to true (good tip: check this if you happen to see lots and lots of stuff in your context menu that should not be there, your selection might be empty).

Count and iterate have always worked against java.util.Collection. The count and iterate elements can also be used on any variable that adapts to org.eclipse.core.expressions.ICountable or org.eclipse.core.expressions.IIterable, or implements these interfaces directly.

Additional Variables

An evaluation context (at least the ones provided by eclipse core) usually contains a whole bunch of additional variables, like:

activePart: the currently active part (could f.i. be an instance of org.eclipse.ui.navigator.CommonNavigator)

activePartId: the id of the currently active part (like org.acme.navigator)

activeEditorId: the id of the currently active editor

activeWorkbenchWindowShell: the currently active shell

The variables are defined in ISources (try Ctrl+Shift+T to open that one from within JDT) and there are others. Note that not all those variables actually contain something at runtime, and that some of them might not be set in the context.

Operators of the expressions framework

Currently, the expression framework supports a total of 13 operation elements. Some of them can have further operations in them (like <adapt>). If that is the case, the result of the nested operations will be logically and-ed.

adapt

Checks if the evaluated object is either an instance of, or adapts to the given class. Can contain nested elements that will be logically and-ed. See AdaptExpression.evaluate().

and / or / not

The usual boolean operators, can contain nested elements. Do what they say on the tin.

count

Used to count the elements in a collection. Cannot contain nested elements, but can be used in combination with <iterate>. <count> has one argument "value", wich can be one of the following:

*: matches any number (even 0)

?: one or none

!: none

+: one or more

-NN): less than NN (NN is an integer)

(NN-: greater than NN

NN: exactly NN

So, the following example will match all collections that contain 2 elements:

<visibleWhen><countvalue="2"/></visibleWhen>

In combination with <iterate>, you can count the elements in the collection that match the expression inside the iterate statement. For example, to match all collections that contain two or more ContainerObject objects, use:

reference

resolve

One of the more esotheric operators. It is comparable to the with operator, but it allows resolving the variable dynamically and to pass additional arguments needed to resolve the argument. For example to resolve the plug-in descriptor for a specific plug-in, the following expression can be used:

The actual resolving is delegated to the evaluation context (see IVariableResolver). As of eclipse 3.5, there is no implementation in either the command framework or the common navigator framework for IVariableResolver, so the <resolve> operator is of no use for them.

systemTest

Tests against the system properties (see java.lang.System.getProperties()).

Note that this example would declare a property tester for the properties org.acme.matchesPattern and org.acme.equalsPattern, and could be extended to any number of additional properties. The name of the property to be used from a <test> operator is always combined from namespace and one of the property names, the properties belong to that namespace. This allows for two plugins (siblings) to define the same property without ambiguity.

The concrete implementation of the property tester has to extend PropertyTester. Look around, you will find existing property testers to get you started with your own.