blob: 4cffd76796add20972cc58f0a461630bc44fa9c2 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2015 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eric Poirier (Eclipse Foundation) - Initial implementation
*******************************************************************************/
?>
<h1 class="article-title"><?php echo $pageTitle; ?></h1>
<p>
In the previous parts of this tutorial series we described <a
href="http://eclipsesource.com/blogs/2012/05/10/eclipse-4-final-sprint-part-1-the-e4-application-model/">how
to create an application model</a>, <a
href="http://eclipsesource.com/blogs/2012/06/12/eclipse-4-e4-tutorial-part-2/">link
those elements to implementations</a>, how to <a
href="http://eclipsesource.com/blogs/2012/06/26/eclipse-4-e4-tutorial-part-3-extending-the-application-model/">extend
the application model</a> and <a
href="http://eclipsesource.com/blogs/tutorials/eclipse-4-e4-tutorial-part-4-dependency-injection-basics/">details
about dependency injection</a> . All parts of this tutorial are
available now as a <a title="Eclipse 4 Tutorial"
href="http://eclipsesource.com/eclipse4tutorial">downloadable
PDF</a>.<br> This tutorial describes how to do a soft migration
to the Eclipse 4 (e4) programming model. The basic goal of the
tutorial is to enable development using the new concepts such as
Dependency Injection and Annotations, but without first requiring
a complete application migration. Therefore, all existing plugins
and frameworks which require 3.x, can still be used as before.
However, developing new UI components for an application following
the e4 programming model has two major advantages:
</p>
<p>
1. The new components are POJOs and therefore very flexible,
testable and re-usable.<br> 2. If the application is migrated to
the Eclipse 4 Application Platform, these components are ready to
be used in e4.
</p>
<p>Interestingly, the first point is worth taking advantage of, even
if you are sure that Eclipse 4 will not be an option in the near
future. The idea is actually pretty simple and isn’t really new at
all.</p>
<h2>POJOs in 3x</h2>
<p>
The basic concept is to make a clear separation between the code
that you develop for a custom application and the code that binds
your component into the Eclipse workbench. The second group of
code depends on the workbench API and is therefore specific to a
certain Eclipse version, i.e. 3.x or 4.x. The first group of code
does not need to be specific to an Eclipse version and in fact,
doesn’t need to know about the workbench at all.<br> <a
href="http://eclipsesource.com/blogs/wp-content/uploads/2012/11/wrapper.png"><img
class="aligncenter size-medium wp-image-12612" title="wrapper"
src="http://eclipsesource.com/blogs/wp-content/uploads/2012/11/wrapper-300x159.png"
alt="wrapper 300x159 Eclipse 4 (e4) Tutorial Soft migration from 3.x to Eclipse 4 (e4)"
height="159" width="300"></a><br> A good example for the
separation is the implementation of a handler. To implement a
handler in Eclipse 3.x that is bound to a command, you need to
implement the interface IHandler. Let’s look at a typical example
handler in 3.x, which does something with the current selection.
In this example the handler checks if the current selection is of
type “MailAccount”. If this is true, the handler checks if the
user is already logged in and then sends and receives mails.
</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #003399;">Object</span> execute<span
style="color: #009900;">(</span>ExecutionEvent event<span
style="color: #009900;">)</span> <span
style="color: #000000; font-weight: bold;">throws</span> ExecutionException <span
style="color: #009900;">{</span>
ISelection currentSelection <span style="color: #339933;">=</span> HandlerUtil.<span
style="color: #006633;">getCurrentSelection</span><span
style="color: #009900;">(</span>event<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span
style="color: #009900;">(</span>currentSelection <span
style="color: #000000; font-weight: bold;">instanceof</span> IStructuredSelection<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #003399;">Object</span> firstElement <span
style="color: #339933;">=</span> <span
style="color: #009900;">(</span><span
style="color: #009900;">(</span>IStructuredSelection<span
style="color: #009900;">)</span> currentSelection<span
style="color: #009900;">)</span>
.<span style="color: #006633;">getFirstElement</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span
style="color: #009900;">(</span>firstElement <span
style="color: #000000; font-weight: bold;">instanceof</span> MailAccount<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
MailAccount account <span style="color: #339933;">=</span> <span
style="color: #009900;">(</span>MailAccount<span
style="color: #009900;">)</span> firstElement<span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span><span
style="color: #009900;">(</span><span
style="color: #339933;">!</span>account.<span
style="color: #006633;">isLoggedIn</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
account.<span style="color: #006633;">logIn</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
account.<span style="color: #006633;">sendMails</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
account.<span style="color: #006633;">recieveMails</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> <span
style="color: #000066; font-weight: bold;">null</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>
There are three major problems with this design: boilerplate code,
lack of testability and lack of re-usability. Let’s imagine that
you would like to write a test case for this handler. You need to
manually create an ExecutionEvent and also make sure that the
HandlerUtil is available in your test environment. As the
selection in this case is not a plain field, but a property, you
would need to look at the implementation of
HandlerUtil.getCurrentSelection() to find out how to properly
prepare your Mock ExecutionEvent. In the last section, you have
more lines of boilerplate code in the test case. Even if you
manage to create a test case, let’s imagine you want to trigger a
timer-based mail synchronization, meaning that you want to
directly call the execute method. In order to re-use the handler,
you would need to create an ExecutionEvent. If the handler is
within your control, you will probably refactor at this time. But
the handler might be within a framework where you cannot refactor.<br>
The solution for this is pretty simple: we split the code into two
methods. The first deals with all workbench specific parts, i.e.
unpacking the selection. The second method executes the business
logic itself and can, as in this case, be static.
</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #003399;">Object</span> execute<span
style="color: #009900;">(</span>ExecutionEvent event<span
style="color: #009900;">)</span> <span
style="color: #000000; font-weight: bold;">throws</span> ExecutionException <span
style="color: #009900;">{</span>
ISelection currentSelection <span style="color: #339933;">=</span> HandlerUtil.<span
style="color: #006633;">getCurrentSelection</span><span
style="color: #009900;">(</span>event<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span
style="color: #009900;">(</span>currentSelection <span
style="color: #000000; font-weight: bold;">instanceof</span> IStructuredSelection<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #003399;">Object</span> firstElement <span
style="color: #339933;">=</span> <span
style="color: #009900;">(</span><span
style="color: #009900;">(</span>IStructuredSelection<span
style="color: #009900;">)</span> currentSelection<span
style="color: #009900;">)</span>
.<span style="color: #006633;">getFirstElement</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span
style="color: #009900;">(</span>firstElement <span
style="color: #000000; font-weight: bold;">instanceof</span> MailAccount<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
synchronizeAccount<span style="color: #009900;">(</span><span
style="color: #009900;">(</span>MailAccount<span
style="color: #009900;">)</span> firstElement<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> <span
style="color: #000066; font-weight: bold;">null</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">static</span> <span
style="color: #000066; font-weight: bold;">void</span> synchronizeAccount<span
style="color: #009900;">(</span>MailAccount account<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">if</span><span
style="color: #009900;">(</span><span
style="color: #339933;">!</span>account.<span
style="color: #006633;">isLoggedIn</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
account.<span style="color: #006633;">logIn</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
account.<span style="color: #006633;">sendMails</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
account.<span style="color: #006633;">recieveMails</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>
With this design it is much easier to write a test case for the
second method. Additionally, the method can be easily called from
anywhere else, e.g. triggering the timer-based synchronization.
Finally, the code is easier to understand. As a next step, the
second method can be moved out of the handler, for example, into a
plugin which does not have any workbench dependencies.<br>
Applying the same design pattern to views results in the same
advantages. We have one class implementing the workbench specific
parts and one class which can be a POJO. In the following example
the WorkbenchView does all workbench specific parts, including
handling the current selection, while the POJOView is completely
independent.
</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">class</span> WorkbenchView <span
style="color: #000000; font-weight: bold;">extends</span> ViewPart <span
style="color: #009900;">{</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> POJOView pojoView<span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> WorkbenchView<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
pojoView <span style="color: #339933;">=</span> <span
style="color: #000000; font-weight: bold;">new</span> POJOView<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> createPartControl<span
style="color: #009900;">(</span><span
style="color: #003399;">Composite</span> parent<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
pojoView.<span style="color: #006633;">createPartControl</span><span
style="color: #009900;">(</span>parent<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
ISelectionService service <span style="color: #339933;">=</span> <span
style="color: #009900;">(</span>ISelectionService<span
style="color: #009900;">)</span> getSite<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span>.<span
style="color: #006633;">getService</span><span
style="color: #009900;">(</span>
ISelectionService.<span style="color: #000000; font-weight: bold;">class</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
service.<span style="color: #006633;">addSelectionListener</span><span
style="color: #009900;">(</span><span
style="color: #000000; font-weight: bold;">new</span> ISelectionListener<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> selectionChanged<span
style="color: #009900;">(</span>IWorkbenchPart part,
ISelection selection<span style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">if</span> <span
style="color: #009900;">(</span>selection <span
style="color: #000000; font-weight: bold;">instanceof</span> IStructuredSelection<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #003399;">Object</span> firstElement <span
style="color: #339933;">=</span> <span
style="color: #009900;">(</span><span
style="color: #009900;">(</span>IStructuredSelection<span
style="color: #009900;">)</span> selection<span
style="color: #009900;">)</span>
.<span style="color: #006633;">getFirstElement</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
pojoView.<span style="color: #006633;">setInput</span><span
style="color: #009900;">(</span>firstElement<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span><span style="color: #009900;">)</span><span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">}</span>
&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> setFocus<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
pojoView.<span style="color: #006633;">setFocus</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #009900;">}</span>
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">class</span> POJOView <span
style="color: #009900;">{</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> Text text<span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> createPartControl<span
style="color: #009900;">(</span><span
style="color: #003399;">Composite</span> parent<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
text <span style="color: #339933;">=</span> <span
style="color: #000000; font-weight: bold;">new</span> Text<span
style="color: #009900;">(</span>parent, SWT.<span
style="color: #006633;">NONE</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> setFocus<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
text.<span style="color: #006633;">setFocus</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> setInput<span
style="color: #009900;">(</span><span
style="color: #003399;">Object</span> object<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">if</span><span
style="color: #009900;">(</span>object<span
style="color: #339933;">!=</span><span
style="color: #000066; font-weight: bold;">null</span><span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
text.<span style="color: #006633;">setText</span><span
style="color: #009900;">(</span>object.<span
style="color: #006633;">toString</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
&nbsp;
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>Again the POJOView is now very easy to understand, test and
re-use. As an example, the POJOView could be embedded into a JFace
Wizard. Until this point, we have not used any Eclipse 4 specific
concepts; the pattern can be used in plain 3.x. As the wrapper
classes (the one which implements the 3.x interface) always look
pretty similar, it would be easy to provide a few generic
implementations. In the next section we introduce such a generic
implementation that uses dependency injection.</p>
<h2>Dependency Injection in 3.x</h2>
<p>If you separate workbench specific code and custom components as
POJOs, components are easier to re-use and to test, even in 3.x.
However, there are still two disadvantages compared to developing
a component for the Eclipse 4 Application Platform:</p>
<p>
1. The wrapper has to be manually implemented and registered via
an extension point.<br> 2. The implementation of the component
cannot use dependency injection and is therefore not ready to be
used in Eclipse 4.
</p>
<p>Once your application is running on an Eclipse 4.x version there
is a solution for this, even if you still use the 3.x API. The
solution is provided by the 3.x e4 bridge from the e4 tools
project, developed by Tom Schindl. The plugin basically provides
generic wrapper classes, which can be used in a 3.x application.
The wrapper classes allow the definition of a second class which
is a POJO, and implements the corresponding component. The
solution follows the same pattern we describe before, but works in
a generic way and supports dependency injection. At writing,
implementations for Views and Editors are available. To create the
3.x workbench wrapper, one simply inherits from the respective
type, e.g. from DIViewPart to implement a View. The wrapper class
is almost empty. It only has to specify the POJO class that
implements the component.</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">class</span> ExampleViewWrapper <span
style="color: #000000; font-weight: bold;">extends</span> DIViewPart<span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">public</span> ExampleViewWrapper<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">super</span><span
style="color: #009900;">(</span>ExampleView.<span
style="color: #000000; font-weight: bold;">class</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>This class is now registered using the view’s extension point as
is usual in 3.x.</p>
<p>The implementation of the view itself can be a POJO and
dependency injection can therefore be used. In addition to being
quite convenient to program today, in case the component is
migrated to e4, it is ready to be used without any adaptation. In
this case, you can remove the wrapper and the extension and
integrate the POJOView into the application model. As you can see,
the view can use all features of dependency injection, including
injection into the current selection.</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">class</span> ExampleView <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">private</span> <span
style="color: #003399;">Label</span> label<span
style="color: #339933;">;</span>
@Inject
<span style="color: #000000; font-weight: bold;">public</span> ExampleView<span
style="color: #009900;">(</span><span
style="color: #003399;">Composite</span> parent<span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
label <span style="color: #339933;">=</span> <span
style="color: #000000; font-weight: bold;">new</span> <span
style="color: #003399;">Label</span><span
style="color: #009900;">(</span>parent, SWT.<span
style="color: #006633;">NONE</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
label.<span style="color: #006633;">setText</span><span
style="color: #009900;">(</span><span
style="color: #0000ff;">"Hello World"</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
&nbsp;
@Inject
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000066; font-weight: bold;">void</span> setInput<span
style="color: #009900;">(</span>@Optional @Named<span
style="color: #009900;">(</span>IServiceConstants.<span
style="color: #006633;">ACTIVE_SELECTION</span><span
style="color: #009900;">)</span><span
style="color: #003399;">Object</span> input<span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">if</span><span
style="color: #009900;">(</span>input<span
style="color: #339933;">==</span><span
style="color: #000066; font-weight: bold;">null</span><span
style="color: #009900;">)</span><span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">return</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
label.<span style="color: #006633;">setText</span><span
style="color: #009900;">(</span>input.<span
style="color: #006633;">toString</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>
To understand how this works, we look at the simplest case, a
wrapper for a Handler, <a
href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=394341">which
I recently contributed</a>. To simplify the example, we will
ignore the annotation @CanEnable for now. The DIHandler needs to
implement the 3.x IHandler interface allowing it to be registered
with the handler extension point, as is common in 3.x.
Additionally, the DIHandler needs to know about the POJO class it
wraps. This POJO class should be instantiated by the wrapper. To
do this, we use the e4 ContextInjectionFactory. As the application
is running on the compatibility layer, we can retrieve the
EclipseContext as a service and use it to create the class. This
way all fields expected by the Handler are being injected (as is
standard in e4).
</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #000000; font-weight: bold;">class</span> DIHandler <span
style="color: #000000; font-weight: bold;">extends</span> AbstractHandler <span
style="color: #009900;">{</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> Classclazz<span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">private</span> C component<span
style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> DIHandler<span
style="color: #009900;">(</span>Classclazz<span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">this</span>.<span
style="color: #006633;">clazz</span> <span
style="color: #339933;">=</span> clazz<span
style="color: #339933;">;</span>
IEclipseContext context <span style="color: #339933;">=</span> getActiveContext<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
component <span style="color: #339933;">=</span> ContextInjectionFactory.<span
style="color: #006633;">make</span><span
style="color: #009900;">(</span>clazz, context<span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #000000; font-weight: bold;">private</span> <span
style="color: #000000; font-weight: bold;">static</span> IEclipseContext getActiveContext<span
style="color: #009900;">(</span><span
style="color: #009900;">)</span> <span
style="color: #009900;">{</span>
IEclipseContext parentContext <span style="color: #339933;">=</span> <span
style="color: #009900;">(</span>IEclipseContext<span
style="color: #009900;">)</span> PlatformUI.<span
style="color: #006633;">getWorkbench</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span>.<span
style="color: #006633;">getService</span><span
style="color: #009900;">(</span>
IEclipseContext.<span style="color: #000000; font-weight: bold;">class</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">return</span> parentContext.<span
style="color: #006633;">getActiveLeaf</span><span
style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>The only missing piece now is the implementation of the execute
method. It simply uses the InjectionFactory again to invoke the
method of the POJO, which is marked with @Execute:</p>
<div class="wp_syntax">
<table>
<tbody>
<tr>
<td class="code"><pre class="java"
style="font-family: monospace;">
<span style="color: #000000; font-weight: bold;">public</span> <span
style="color: #003399;">Object</span> execute<span
style="color: #009900;">(</span>ExecutionEvent event<span
style="color: #009900;">)</span> <span
style="color: #000000; font-weight: bold;">throws</span> ExecutionException <span
style="color: #009900;">{</span>
<span style="color: #000000; font-weight: bold;">return</span> ContextInjectionFactory.<span
style="color: #006633;">invoke</span><span
style="color: #009900;">(</span>component, Execute.<span
style="color: #000000; font-weight: bold;">class</span>,
getActiveContext<span style="color: #009900;">(</span><span
style="color: #009900;">)</span><span
style="color: #009900;">)</span><span
style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
</pre></td>
</tr>
</tbody>
</table>
</div>
<p>This DIHandler is not very complex and allows wrapping POJO
handlers into the 3.x workbench.</p>
<h2>Conclusion</h2>
<p>This tutorial described an approach for a soft migration from 3.x
to the Eclipse 4 programming model. We started with the concept of
separating the implementation of custom UI components and
workbench specific classes. This improved the re-usability and the
testability of the components. Using the bridge plugin, the e4
tools wrapper classes didn’t have to be implemented manually.
Additionally the DIWrapper enabled the use of dependency injection
even when programming in 3.x. Components developed in this way can
be integrated without any adaptations, into any pure e4
application.</p>
<p>
This tutorial and all other parts of the series are available as a
<a title="Eclipse 4 Tutorial"
href="http://eclipsesource.com/eclipse4tutorial">downloadable
PDF</a>.
</p>
<p>
For more information, contact us:<br> Jonas Helming and Maximilian
Koegel<br> <a href="http://eclipsesource.com/munich">EclipseSource
Munich</a> leads
</p>
<div class="bottomitem">
<h3>About the Authors</h3>
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<img class="author-picture"
src="/community/eclipse_newsletter/2013/february/images/jhelming.jpg"
alt="Jonas Helming" />
</div>
<div class="col-sm-16">
<p class="author-name">
Jonas Helming <br />
<a href="http://eclipsesource.com/">EclipseSource</a>
</p>
<ul class="author-link">
<li><a href="http://eclipsesource.com/blogs/author/jhelming/">Blog</a>
</li>
<li><a href="https://twitter.com/JonasHelming">Twitter</a></li>
<li><a href="<?php echo $original_url; ?>">Original Article</a></li>
</ul>
</div>
</div>
</div>
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<img class="author-picture"
src="/community/eclipse_newsletter/2013/february/images/mjoegel.jpg"
alt="Maximilian Koegel" />
</div>
<div class="col-sm-16">
<p class="author-name">
Maximilian Koegel <br />
<a href="http://eclipsesource.com/">EclipseSource</a>
</p>
<ul class="author-link">
<li><a href="http://eclipsesource.com/blogs/author/mkoegel/">Blog</a>
</li>
<li><a href="https://twitter.com/MKoegel">Twitter</a></li>
<?php echo $og; ?>
</ul>
</div>
</div>
</div>
</div>
</div>