Monthly Archive for: ‘June, 2010’

Eclipse 4.0: Dependency Injection and OSGi Declarative Services

2

In my last post I explained how easy it is to inject your own objects. For the common use case that you want to specify an interface attribute but want an object being injected I showed a simple solution using a little factory. Another way of doing this is the use of OSGi declarative services (DS). But instead of creating a declarative service that implements the service interface you create a declarative service for a helper object that just registers your implementation class for the needed interface with the ContextInjectionFactory. So, the ContactPresentation code looks like this now:

...
	private IContactView contactView;

	@Inject
	public ContactPresenter(IContactView contactView) {
		this.contactView = contactView;
...

The xml for the declarative service is in OSGI-INF/views.xml:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
               name="org.eclipse.e4.demo.contacts.mvp.views">
   <implementation class="...mvp.views.ContactViewCreationFunction"/>
   <service>
      <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
   </service>
   <property name="service.context.key" type="String"
      value="...contacts.mvp.presenters.ContactPresenter$IContactView"/>
</scr:component>

The implementation class provides the interface org.eclipse.e4.core.contexts.IContextFunction and an additional property with the name service.context.key specifies the actual interface that the contact function is going to register. Here is the simple code for the ContactViewCreationFunction:

public class ContactViewCreationFunction extends ContextFunction {
	@Override
	public Object compute(IEclipseContext context) {
		return ContextInjectionFactory.make(ContactView.class, context);
	}
}

The only thing the ContactViewCreationFunction does is to bind the ConatcsView class to the context, using the above service.context.key to know the interface. I will check in the code soon, stay tuned…

It’s very important that you don’t forget to add the 2 manifest headers in the manifest.mf:

Service-Component: OSGI-INF/views.xml
Bundle-ActivationPolicy: lazy

I would like to thank Tom Schindl for giving me the tip not to forget the lazy Bundle-ActivationPolicy!

Have Fun

Kai
Follow me on Twitter

Eclipse 4.0: Inject your OWN Objects

10

One of the great new features of Eclipse 4.0 is the use of dependency injection (DI). The new architecture does not use Singletons at all, but injects all the necessary objects in a given context. For example, a view is a POJO now and the necessary parent composite is injected:

public class ContactView implements IContactView {

	@Inject
	public ContactView(Composite parent) {
...

But how could you use DI to inject your own objects? It’s easy and straight forward: Just annotate the object (A) that needs your own object (B) injected with @Inject, either on attribute or on method level. The nice thing about this is that all available injectable objects (e.g. from the context) will automatically injected into (B). As an example, you could create a presenter that is not interested in UI toolkit (e.g. SWT) specific stuff but needs a view (that is interested in the SWT parent composite).

public class ContactPresenter {
	public interface IContactView {
              ...
	}

	private IContactView contactView;

	@Inject
	public ContactPresenter(ContactView contactView) {
....

The flaw in this example is: the presenter gets a concrete ContactView object rather than an IContactView interface injected. The easiest way for getting around this is to introduce a little factory that gets a concrete object injected and returns the desired interface:

public class ContactViewFactory {
	@Inject
	ContactView contactView;

	public IContactView getContactView() {
		return contactView;
	}
}

Now the presenter just lets the factory be injected and gets the IContactView interface:

	private IContactView contactView;

	@Inject
	public ContactPresenter(ContactViewFactory contactViewFactory) {
		contactView = contactViewFactory.getContactView();

Another way would be to provide an OSGi declarative service that registers a class for a given interface with the ContextInjectionFactory. This is how the services like the selection service are registered. Right now, I could not get this working (inject a ContactView to a needed IContactView), but as soon as I find out why or how, I’ll blog about it.

If you want to check out example code from cvs, take a look at the classes DetailsView and DetailComposite in the e4 contacts demo (host: dev.eclipse.org, repository path: /cvsroot/eclipse, user:anonymous, path to bundle: e4/org.eclipse.e4.ui/examples/org.eclipse.e4.demo.contacts).

Have Fun

Kai
Follow me on Twitter

Eclipse 4.0: Automatically created Theme Switching Menu/Toolbar

3

Recently I took a look at Tom Schindl’s great e4 SimpleIDE demo and found his implementation for an automatically created “Theme” menu. I liked it so much that I could not resist and adopted Tom’s implementation to my e4 contacts demo. I pimped it a bit so that theme icons in the menu as well as a theme switching toolbar are supported. The idea is that all themes defined with the extension point org.eclipse.e4.ui.css.swt.theme are checked at startup and the application’s workbench model is updated dynamically. If there is a png file for a corresponding css, it will be treated automatically as theme icon. For example: dark-gradient.css and dark-gradient.png correspond. The result in the user interface are an automatically created “Theme” menu and an icon-based theme toolbar.

How does it work?

First we need a couple of themes,  the e4 contacts demo currently comes with 3 themes:

<extension point="org.eclipse.e4.ui.css.swt.theme">
  <theme
     basestylesheeturi="css/dark-gradient.css"
     id="org.eclipse.e4.demo.contacts.themes.darkgradient"
     label="Dark Gradient Theme">
  </theme>
  <theme
      basestylesheeturi="css/bright-gradient.css"
      id="org.eclipse.e4.demo.contacts.themes.brightgradient"
      label="Bright Gradient Theme">
  </theme>
  <theme
      basestylesheeturi="css/blue-gradient.css"
      id="org.eclipse.e4.demo.contacts.themes.blue"
      label="Blue Gradient Theme">
  </theme>
</extension>

Then we use the extension point org.eclipse.e4.workbench.model to add a model contribution. We need a “processor” to contribute dynamically to the workbench model. The contacts demo provides two processors, one for the menu and the other for the toolbar. To specify which already existing model element should be injected as dependency in the processor’s Java object, we specify an element with a id. In the applications workbench model these ids belong to the main menu bar and the main toolbar.

   <extension
         id="modelContribution"
         point="org.eclipse.e4.workbench.model">
      <processor
            beforefragment="true"
            class="org.eclipse.e4.demo.contacts.processors.MenuThemeProcessor">
         <element
               id="menu:org.eclipse.ui.main.menu">
         </element>
      </processor>
      <processor
            beforefragment="true"
            class="org.eclipse.e4.demo.contacts.processors.ToolbarThemeProcessor">
         <element
               id="toolbar:org.eclipse.ui.main.toolbar">
         </element>
      </processor>
   </extension>

Now we have to implement the Processors in Java. As most classes in e4, a processor is a pure POJO and gets the necessary stuff injected. Since I wanted to provide two processors in the contacts demo, I split the work into an AbstractThemeProcessor and two concrete implementations for the menu and the toolbar. The AbstractThemeProcesor’s method execute() gets invoked because it is annotated with @Execute.

public abstract class AbstractThemeProcessor {

	@Execute
	public void process() {
...

The main task of the abstract class is to get the ThemingEngine and the command used for switching the theme (this is defined regularly in the workbench model). Then it loops though all available themes and invokes the processTheme method of the concrete implementations. As an example, here is the code snippet of the ToolbarThemeProcessor that shows how the toolbar is injected and toolbar items are added dynamically.

public class ToolbarThemeProcessor extends AbstractThemeProcessor {

	@Inject
	@Named("toolbar:org.eclipse.ui.main.toolbar")
	private MToolBar toolbar;

	@Override
	protected void processTheme(String name, MCommand switchCommand,
			MParameter themeId, String iconURI) {
		MHandledToolItem toolItem = MMenuFactory.INSTANCE
				.createHandledToolItem();
		toolItem.setCommand(switchCommand);
		toolItem.getParameters().add(themeId);
		if (iconURI != null) {
			toolItem.setIconURI(iconURI);
		}
		toolbar.getChildren().add(toolItem);
	}
...

The code for the MenuThemeProcessor is very similar. If you want to play around with running code, download e4 1.0 RC0 and check out the latest version of my contacts demo from cvs (host: dev.eclipse.org, repository path: /cvsroot/eclipse, user:anonymous, path to bundle: e4/org.eclipse.e4.ui/examples/org.eclipse.e4.demo.contacts).

Have Fun

Kai
Follow me on Twitter

New Video: Nature at Lago Maggiore

In June 2010 my family and I have spent a nice week at the “Lago Maggiore” in Italy. This short video (7 minutes) shows the beautiful architecture of our hotel “Residenza Patrizia” in Cannobio, the flowers and nature of the botanic gardens “Villa Taranto” and a hike through the impressive Verzasca valley. The film was shot with a Canon HF10, all the scenes you see in the video are not modified in color/contrast. For editing I used Cyberlink PowerDirector 8. As in my last film I also created and recorded the music myself, using Cubase 4 AI. If you ever plan to visit Lago Maggiore or just like nature I hope you enjoy the video.

Below you find a low-resultion embedded version of the video. If you want to see it in high resolution (1280 x 720), what I really recommend, please visit my Vimeo page.

Nature at Lago Maggiore from Kai Toedter on Vimeo.

Have Fun

Kai
Follow me on Twitter

Eclipse 4.0 RCP: Dynamic CSS Theme Switching

22

The css theming capabilities of the Eclipse 4.0 SDK are improving. Especially the mechanism to implement a dynamic theme switcher is much easier now. If you want to implement a css theme switcher, you just need to contribute to the extension point org.eclipse.e4.ui.css.swt.theme. Here is an example from my e4 contacts demo for declaring two themes:

<extension
 point="org.eclipse.e4.ui.css.swt.theme">
 <theme
    basestylesheeturi="css/dark-gradient.css"
    id="org.eclipse.e4.demo.contacts.themes.darkgradient"
    label="Dark Gradient Theme">
 </theme>
 <theme
    basestylesheeturi="css/bright-gradient.css"
    id="org.eclipse.e4.demo.contacts.themes.brightgradient"
    label="Bright Gradient Theme">
 </theme>
</extension>

Then you need to specify a handler that does the actual theme switching. Here is the whole handler code for switching to the dark gradient theme:

public class DarkThemeHandler {

   @Execute
   public void execute(IThemeEngine engine) {
      engine.setTheme("org.eclipse.e4.demo.contacts.themes.darkgradient");
   }
}

Use the workbench model to bind this handler to a menu or tool bar item — that’s it. The two screenshots show the results when dynamically switching between the dark and the bright theme.

Kai
Follow me on Twitter