@Active in e4


Having discussed yesterday with Alex Blewitt and Lars Vogel on what @Active is I thought it might make sense to explain it in a short blog post.

Let’s start with the question Alex posted on twitter: “Which is preferable; using @Named(ACTIVE_SHELL) or @Active shell

Answer: they are completely different things!

Before we understand why we need to know more about the IEclipseContext and how it works:

  1. There’s not a single context but a hierarchy of context
  2. Child-Contexts have access to informations of themselves and their parent(s)

So if we have code like this:

public class MyBean {
  private IEclipseContext owner;
  private String parentValue;
  private String childValue;
	
  @Inject
  public MyBean(IEclipseContext owner) {
    this.owner = owner;
  }

  @Inject
  void setParentValue(@Optional @Named("parent_value") String value) {
    this.parentValue = value;
  }

  @Inject
  void setChildValue(@Optional @Named("child_value") String value) {
    this.childValue = value;
  }
	
  void print() {
    System.err.println(owner.toString() + ": parent = " + parentValue + "; child: " + childValue);
  }
}
IEclipseContext rootContext = EclipseContextFactory.getServiceContext(FrameworkUtil.getBundle(getClass()).getBundleContext());
rootContext.set("parent_value","Hello Parent");

MyBean p = ContextInjectionFactory.make(MyBean.class, rootContext);
p.print(); // OSGi context for bundle: test.di.active: parent = Hello Parent; child: null

IEclipseContext childContext_1 = rootContext.createChild("Child 1");
childContext_1.set("child_value","Hello Child 1");
MyChildBean c1 = ContextInjectionFactory.make(MyBean.class, childContext_1);
c1.print(); // Child 1: parent = Hello Parent; child: Hello Child 1

Anyone working with e4 knows about this already so it should be clear.

To understand now @Active you have to know a much less know thing about the IEclipseContext hierarchy:

The notion of an activeBranch/activeContext

when working in e4 you do not recognize this but the framework switches the activeContext based on which area of your UI currently has the input focus by calling IEclipseContext#activateBranch. Lets extend our example a bit:

IEclipseContext childContext_1 = rootContext.createChild("Child 2");
childContext_1.set("child_value","Hello Child 2");
MyChildBean c1 = ContextInjectionFactory.make(MyBean.class, childContext_2);
c2.print(); // Child 2: parent = Hello Parent; child: Hello Child 2

childContext_1.activateBranch();
p.print(); // // OSGi context for bundle: test.di.active: parent = Hello Parent; child: null

childContext_2.activateBranch();
p.print(); // // OSGi context for bundle: test.di.active: parent = Hello Parent; child: null

Now let’s modify the bean code using @Active

public class MyBean {
  @Inject
  void setChildValue(@Optional @Named("child_value") @Active String value) {
    this.childValue = value;
  }
}

if we now execute the code once more we’ll get the following out put for the last 2 p.print() statements from above:

OSGi context for bundle: test.di.active: parent = Hello Parent; child: Hello Child 1
OSGi context for bundle: test.di.active: parent = Hello Parent; child: Hello Child 2

This means @Active works in the opposite direction of the IEclipseContext hierarchy and instances created on a parent context can track values from their active child using it!

About these ads

No comments yet... Be the first to leave a reply!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 733 other followers

%d bloggers like this: