<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TechJava &#187; TechJava &#8211; Articles on Eclipse</title>
	<atom:link href="http://www.techjava.de/topics/category/eclipse/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techjava.de</link>
	<description>Journal on Java Technology</description>
	<lastBuildDate>Fri, 29 Mar 2013 23:40:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Xtext 2.0 Milestone Installation</title>
		<link>http://www.techjava.de/topics/2011/04/xtext-2-0-milestone-installation/</link>
		<comments>http://www.techjava.de/topics/2011/04/xtext-2-0-milestone-installation/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 19:45:02 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[dependency]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[mwe]]></category>
		<category><![CDATA[p2]]></category>
		<category><![CDATA[xtend]]></category>
		<category><![CDATA[xtext]]></category>
		<category><![CDATA[xtext 2.0]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=749</guid>
		<description><![CDATA[If you are interested in Xtext and its new features introduced in the upcomming version 2.0 you might want to install and try them out. Since it will be officially realeased together with Eclipse Indigo, you have to execute some manual steps. In order to be able to install the new feature, you will require [...]]]></description>
			<content:encoded><![CDATA[<p>If you are interested in Xtext and its new features introduced in the upcomming version 2.0 you might want to install and try them out. Since it will be officially realeased together with Eclipse Indigo, you have to execute some manual steps. In order to be able to install the new feature, you will require to enter two additional update sites into you update manager and download the update site containing xtext itself. The following steps worked for me:</p>
<ul>
<li>Download 
<a  href="http://www.eclipse.org/downloads/packages/eclipse-classic-362/heliossr2" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/downloads/packages/eclipse-classic-362/heliossr2');" >Eclipse 3.6.1 Classic</a></li>
<li>Add the tow following Update Sites to the Update Manager: <br />
Xpand: 
<a  href="http://download.eclipse.org/modeling/m2t/xpand/updates/nightly/" onclick="javascript:pageTracker._trackPageview('/external/download.eclipse.org/modeling/m2t/xpand/updates/nightly/');" >http://download.eclipse.org/modeling/m2t/xpand/updates/nightly/</a><br />
MWE:   
<a  href="http://download.eclipse.org/modeling/emft/mwe/updates/nightly/" onclick="javascript:pageTracker._trackPageview('/external/download.eclipse.org/modeling/emft/mwe/updates/nightly/');" > http://download.eclipse.org/modeling/emft/mwe/updates/nightly/</a>
  </li>
<li>Download the TMF 2.0 M6 Update Site from 
<a  href="http://www.eclipse.org/modeling/tmf/downloads/" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/modeling/tmf/downloads/');" >Eclipse TMF Site</a> and add it as a local update site</li>
<li>Install all TMF Features from the archive update site</li>
<li>Restart Eclipse and Enjoy Xtext 2.0!</li>
</ul>
<p>Thanks to Dennis Huebner 
<a  href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329719" onclick="javascript:pageTracker._trackPageview('/external/bugs.eclipse.org/bugs/show_bug.cgi');" >for the hints&#8230;</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2011/04/xtext-2-0-milestone-installation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Validating JFace Databinding with JSR-303</title>
		<link>http://www.techjava.de/topics/2011/02/validating-jface-databinding-jsr-303/</link>
		<comments>http://www.techjava.de/topics/2011/02/validating-jface-databinding-jsr-303/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 09:22:39 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[bean validation]]></category>
		<category><![CDATA[constraint]]></category>
		<category><![CDATA[databinding]]></category>
		<category><![CDATA[IValidator]]></category>
		<category><![CDATA[jface]]></category>
		<category><![CDATA[jsr 303]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[validator]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=726</guid>
		<description><![CDATA[JFace Databinding enables an easy binding between values inside of data models and SWT/JFace widgets. No more boring listeners to implement &#8211; just create observables and connect them using the data binding context. There are several brilliant articles written about it. My favorites are those from Ralf Ebert and Lars Vogel. One of the interesting [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float: right; margin: 10px;" title="binding" src="http://www.techjava.de/wp-content/uploads/binding-150x150.jpg" alt="" width="150" height="150" /><br />
JFace Databinding enables an easy binding between values inside of data models and SWT/JFace widgets. No more boring listeners to implement &#8211; just create observables and connect them using the data binding context. There are several brilliant articles written about it. My favorites are those from 
<a  href="http://www.ralfebert.de/rcpbuch/jface_data_binding/" onclick="javascript:pageTracker._trackPageview('/external/www.ralfebert.de/rcpbuch/jface_data_binding/');" >Ralf Ebert</a> and 
<a  href="http://www.vogella.de/articles/EclipseDataBinding/article.html" onclick="javascript:pageTracker._trackPageview('/external/www.vogella.de/articles/EclipseDataBinding/article.html');" >Lars Vogel</a>.</p>
<p>One of the interesting aspects of databinding is data validation. The update strategies, responsible for propagation of changes in models or in widgets can be supplied with validators, making sure that the data changes are legal. In the same time the 
<a  href="http://jcp.org/en/jsr/detail?id=303" onclick="javascript:pageTracker._trackPageview('/external/jcp.org/en/jsr/detail');" >JSR-303 Bean Validation</a> specification focuses on a modern standardized way of data validation. In this post, I combine these subjects and use JSR-303 in JFace Databinding Validators.</p>
<p>One of the core insights of the JSR-303 is the idea of annotation of data validation constraints on data itself. It is indeed a good observation, that validation code strongly relies on the data structure and semantics. To follow this idea consequently, the application developer should care of validation during implementation of business logic as less as possible. A much better idea is to encapsulate the entire validation into domain-specific types. Let me demonstrate it by example, imagine the following class:</p>
<pre class="brush: java; title: ; notranslate">
public class Customer {
  private String name;
  private String address;
  private String zip;
  private String city;
}
</pre>
<p>This is perfectly reasonable, but now consider not only the data storage/transport aspects, but also the validation aspects. A standard approach would be to use the following validator logic, in the databinding:</p>
<pre class="brush: java; highlight: [5,6,7,8,9,10,11,12,13,14,20,21,22,23,24,25,26,27,28,29]; title: ; notranslate">
public class CustomerComposite {
[...]
  public void bindValues(Customer model, DataBindingContext dbc) {
    UpdateValueStrategy m2t = new UpdateValueStrategy();
    m2t.setAfterGetValidator(new IValidator() {
      @Override
      public IStatus validate(Object value) {
        String name = (String) value;
        if (name == null || Helper.isRegex(name, &quot;[A-Za-z -]*&quot;)) {
          return ValidationStatus.error(&quot;Wrong name&quot;);
        }
          return ValidationStatus.ok();
        }
      });
    dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(namefield),
      BeanProperties.value(Customer.class, &quot;name&quot;).observe(model),
      new UpdateValueStrategy(), m2t);

    m2t = new UpdateValueStrategy();
    m2t.setAfterGetValidator(new IValidator() {
      @Override
      public IStatus validate(Object value) {
        String zipCode = (String) value;
        if (zipCode == null || zipCode.length() &gt; 5 || zipCode.length() &lt; 5 || Helper.isRegex(zipCode, &quot;[0-9]*&quot;)) {
          return ValidationStatus.error(&quot;Wrong zip code&quot;);
        }
          return ValidationStatus.ok();
        }
      });
    dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(zipfield),
      BeanProperties.value(Customer.class, &quot;zip&quot;).observe(model),
      new UpdateValueStrategy(), m2t);
  [...]
  }
</pre>
<p>Pretty much code, and rememeber that JFace Databinding code like this can not be reused in other parts of the application. Let&#8217;s put the validation logic on the data declaration in a way how JSR-303 proposes to do this:</p>
<pre class="brush: java; title: ; notranslate">
public class Customer {
  @NotNull
  @Pattern(regexp = &quot;[A-Za-z -]*&quot;)
  private String name;
  private String addressLine;
  @Size(min=1, max=5)
  @Pattern(regexp = &quot;[0-9]*&quot;)
  private String zip;
  @NotNull
  @Pattern(regexp = &quot;[A-Za-z -]*&quot;)
  private String city;
}
</pre>
<p>As a next step, let us develop an update strategy factory which create update strategies with embedded Validator for JSR-303 Bean Validation constaints.</p>
<pre class="brush: java; title: ; notranslate">
public class BeanValidator implements IValidator {
  private ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

  @Override
  public IStatus validate(Object value) {
    Set&lt;ConstraintViolation&lt;Object&gt;&gt; violations = factory.getValidator().validate(value,
      new Class&lt;?&gt;[] { Default.class });
    if (violations.size() &gt; 0) {
      List&lt;IStatus&gt; statusList = new ArrayList&lt;IStatus&gt;();
      for (ConstraintViolation&lt;Object&gt; cv : violations) {
        statusList.add(ValidationStatus.error(cv.getMessage()));
      }
      return new MultiStatus(Activator.PLUGIN_ID, IStatus.ERROR,
        statusList.toArray(new IStatus[statusList.size()]), &quot;Validation errors&quot;, null);
    }
    return ValidationStatus.ok();
  }
}

public class StrategyFactory {
 public static UpdateValueStrategy getStrategy() {
   UpdateValueStrategy strategy = new UpdateValueStrategy();
   strategy.setAfterConvertValidator(new BeanValidator());
   return strategy;
 }
}
</pre>
<p>Using the <code>StrategyFactory</code>, the validation code inside of the composite becomes trivial:</p>
<pre class="brush: java; title: ; notranslate">
public class CustomerComposite {
[...]
  public void bindValues(Customer model, DataBindingContext dbc) {
    dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(namefield),
      BeanProperties.value(Customer.class, &quot;name&quot;).observe(model),
      new UpdateValueStrategy(), StrategyFactory.getStrategy());

    dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(zipfield),
     BeanProperties.value(Customer.class, &quot;zip&quot;).observe(model),
     new UpdateValueStrategy(), StrategyFactory.getStrategy());
 [...]
}
</pre>
<p>An important property of the introduced validation approach is the fact, that it can be reused in other application layers (e.G. in service layer, or in data access layer). In other words you can use the same validation logic across the entire application and just remain valid&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2011/02/validating-jface-databinding-jsr-303/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Guicy Mocks in Eclipse RCP</title>
		<link>http://www.techjava.de/topics/2010/11/guicy-mocks/</link>
		<comments>http://www.techjava.de/topics/2010/11/guicy-mocks/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 23:42:52 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Enterprise Systems]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[business delegate]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[eclipse rcp]]></category>
		<category><![CDATA[extension point]]></category>
		<category><![CDATA[google guice]]></category>
		<category><![CDATA[java enterprise]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[plug-in]]></category>
		<category><![CDATA[service locator]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=699</guid>
		<description><![CDATA[Abstract Development of Eclipse RCP as a rich client of the multi-tier Java Enterprise application becomes an an interesting alternative to other frontend technologies. An important aspect is the ability to develop and test the frontend independent from the backend. In this article, an approach for testing and de-coupling of server and client development in [...]]]></description>
			<content:encoded><![CDATA[<p>
<a  href="http://www.techjava.de/wp-content/uploads/juice.gif" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/juice.gif');" ><img style="float: right;" title="Google Guice" src="http://www.techjava.de/wp-content/uploads/juice.gif" alt="Google Guice" width="200" height="214" /></a></p>
<h2>Abstract</h2>
<p>Development of Eclipse RCP as a rich client of the multi-tier Java Enterprise application becomes an an interesting alternative to other frontend technologies. An important aspect is the ability to develop and test the frontend independent from the backend. In this article, an approach for testing and de-coupling of server and client development in Eclipse RCP is introduced.</p>
<h2>Business Delegate, Service Locator and Dependency Injection</h2>
<p>In a Java multi-tier application, the business logic is implemented in form of server-hosted components (EJB, Spring Beans, OSGi Services, etc&#8230;). In this example, the EJB Backend is used, but it can be easily replaced with other technologies mentioned previously. A rich client is connected to the server using some remoting technology and contains a local storage for the client-specific state, which allows to build more complex and reactive applications. A common approach to hide the aspects of remote invocations on the client side is the use of 
<a  href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/BusinessDelegate.html" onclick="javascript:pageTracker._trackPageview('/external/java.sun.com/blueprints/corej2eepatterns/Patterns/BusinessDelegate.html');" >Business Delegate</a> enterprise design pattern. My favorite way of implementing it is to define the technology-independent business interface (POJI = Plain Old Java Interface) and implement it on the server side by the server beans and on the client side by the business delegates. This article uses the following business interface as example:</p>
<pre class="brush: java; title: ; notranslate">
public interface MyBusinessService extends BaseBusinessService {

	/**
	 * Full qualified name of the interface (used for Binding).
	 */
	String IF_FQN = &quot;....MyBusinessService&quot;;

	/**
	 * Does something on server.
	 *
	 * @param parameter Parameter of invocation.
	 * @return Result of execution.
	 */
	List&lt;OperationResultDto&gt; doSomeStuff(ParameterDto parameter);
}
</pre>
<p>The delegates make use of the 
<a  href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html" onclick="javascript:pageTracker._trackPageview('/external/java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html');" >Service Locator</a> design pattern. Here is an example, how the implementation of the Base Facade can look like, which is a superclass of all business delegates:</p>
<pre class="brush: java; title: ; notranslate">
public abstract class BaseFacade {
...
	/**
	 * Delegates a call to a stateless session bean on the server.
	 *
	 * @param &lt;T&gt; type business interface
	 * @param iterfaze business interface
	 * @param jndi binding on the server
	 * @return result of invocation
	 */
	public static &lt;T&gt; T delegate(Class&lt;T&gt; iterfaze, String jndi) {
		return Activator.getDefault().getServiceLocator().getStateless(iterfaze, jndi);
	}

	/** ... */
	public static void debug(String message) {...}
}
</pre>
<p>The <code>ServiceLocator.getStateless()</code> method is hiding the lookup of the remote EJB. Using the BaseFacade, the business delegate looks as following:</p>
<pre class="brush: java; title: ; notranslate">
public class MyBusinessServiceFacade extends BaseFacade implements MyBusinessService {

	public List&lt;OperationResultDto&gt; doSomeStuff(ParameterDto parameter) {
		debug(&quot;entering doSomeStuff(ParameterDto)&quot;);
		final List&lt;OperationResultDto&gt; result = delegate(MyBusinessService.class, MyBusinessService.IF_FQN)
				.doSomeStuff(parameter);
		debug(&quot;leaving doSomeStuff(ParameterDto)&quot;);
		return result;
	}

}
</pre>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">This setup results in a following architecture:</span></p>
<p style="text-align: center;">
<a  href="http://www.techjava.de/wp-content/uploads/architecture.png" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/architecture.png');" ><img class="size-full wp-image-713 aligncenter" src="http://www.techjava.de/wp-content/uploads/architecture.png" alt="Architecture" width="420" height="210" /></a></p>
<h2>Business Delegate Boilerplate</h2>
<p>The setup looks good in theory, but in fact it is pretty boring to program on the client side. You can reduce the effort of creating business delegates (in fact I use MDSD techniques and Xtext to generate it), but in every place a service is required,  the business delegate is instantiated directly. The approach works, but it just not nice, because you reference the implementation directly.</p>
<p>A common approach to avoid writing the code of direct instantiation is the usage of Dependency Injection frameworks. A very popular one is Google Guice, which is used in this article. The essential idea of Google Guice is to configure the binding between the dependency and its resolution and use Google Guice as a kind of factory to create instances and inject dependencies in it. For the creation of the binding, Guice offers a class <code>AbstractModule</code> to subclass from.</p>
<pre class="brush: java; title: ; notranslate">
public class ServiceFacadeModule extends AbstractModule {

	/**
	 * @see com.google.inject.AbstractModule#configure()
	 */
	@Override
	protected void configure() {
		bind(MyBusinessService.class).to(MyBusinessServiceFacade.class);
	}
}
...
public class InjectorHolder {
...
	private Injector injector;

	public static void configureInjector(AbstractModule module) {
		InjectorHolder.getInstance().setInjector(Guice.createInjector(module));
	}

	/**
	 * Creates an instance of a class.
	 *
	 * @param &lt;T&gt; type of the class
	 * @param clazz type to create
	 * @return a instance with injected dependencies
	 */
	public static &lt;T&gt; T get(Class&lt;T&gt; clazz) {
		return getInstance().getInjector().getInstance(clazz);
	}
...
}
</pre>
<p>In order to hide references to Guice classes in client code, the DI can be encapsulated inside of a <code>InjectorHolder</code>, which acts as factory for instances with service references:</p>
<pre class="brush: java; title: ; notranslate">
/**
 * Class with a reference.
 */
public class DataSource {

	/**
	 * Reference to the service.
	 */
	private MyBusinessService myBusinessService;

	@Inject
	public void setMyBusinessService(MyBusinessService myBusinessService) {
		this.myBusinessService = myBusinessService;
	}
}
/**
 * Client which requires the data source with injected references.
 */
public class MyView {

	/**
	 * Let Google Guice create the instance and inject dependencies.
	 */
	private DataSource source = InjectorHolder.get(DataSource.class);
}
</pre>
<p>Please note, that the data source is using setter-injection for the service implementations and the InjectorHolder as a factory to create an instance of data source with injected reference.</p>
<h3>Packaging Guice</h3>
<p>After this short introduction of Guice, it is time to package this 
<a  href="http://vannevarvision.wordpress.com/2007/03/08/making-external-libraries-available-as-an-eclipse-plug-in/" onclick="javascript:pageTracker._trackPageview('/external/vannevarvision.wordpress.com/2007/03/08/making-external-libraries-available-as-an-eclipse-plug-in/');" >3rd-party library into the Eclipse RCP client</a>. In fact it is all about putting the JARs (guice-2.0.jar, aopalliance-1.0.jar) into some folder inside of the client plug-in and modifying the MANIFEST.MF so that the JARs are on the bundle class-path and the packages are listed as &#8220;exported&#8221;.</p>
<h3>What about mock?</h3>
<p>After the client has the ability to use business delegates it can access the business functionality of the server. In fact this requires that the server is already implemented. In order to decouple the client from the server development, 
<a  href="http://en.wikipedia.org/wiki/Mock_object" onclick="javascript:pageTracker._trackPageview('/external/en.wikipedia.org/wiki/Mock_object');" >mocks</a> can be used. Mocks are popular in context of Unit tests, but can be used to simulate behavior of server implementation as well. Since mocks should not be delivered into production it is a good idea to put them into a separate mock plug-in, included into the special mock feature. The mock plug-in should export its packages. These should be imported by the main plug-in, instead of defining of a dependency on the mock plug-in directly. The mock feature is included in the product / top-level feature as an optional feature. This specific configuration allows the main plug-in to instantiate classes from the mock plug-in, if this is delivered, but doesn&#8217;t produce errors if the mock plug-in is not included into release.</p>
<p>Since the business delegate implementes the business interface, its mock should also do so:</p>
<pre class="brush: java; title: ; notranslate">
public class MyBusinessServiceMock implements MyBusinessService {

	public List&lt;OperationResultDto&gt; doSomeStuff(ParameterDto parameter) {
		debug(&quot;entering doSomeStuff(ParameterDto)&quot;);
		final List&lt;OperationResultDto&gt; result = new ArrayList&lt;OperationResultDto&gt;();
		result.add(new OperationResult(parameter.getValue()));
		debug(&quot;leaving doSomeStuff(ParameterDto)&quot;);
		return result;
	}
...
}
</pre>
<p>Since the mocks should also be injected by Guice, we define the binding module as well.</p>
<pre class="brush: java; title: ; notranslate">
public class ServiceMockModule extends AbstractModule {
	protected void configure() {
		bind(MyBusinessService.class).to(MyBusinessServiceMock.class);
	}
}
</pre>
<p>Finally, we got two implementations and two Guice&#8217;s AbstractModule implementation binding them. The last missing piece is the dynamic configuration which allows to switch between them easily. For this purpose we use the extension-point mechanism of Eclipse and define the following extension point (all documentation elements are removed for readability):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;schema targetNamespace=&quot;...&quot; xmlns=&quot;...&quot;&gt;
   &lt;element name=&quot;extension&quot;&gt;
      ...
      &lt;complexType&gt;
         &lt;sequence&gt;&lt;element ref=&quot;moduleConfiguration&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;unbounded&quot;/&gt;&lt;/sequence&gt;
         &lt;attribute name=&quot;point&quot; type=&quot;string&quot; use=&quot;required&quot;&gt;&lt;/attribute&gt;
         &lt;attribute name=&quot;id&quot; type=&quot;string&quot;&gt;&lt;/attribute&gt;
         &lt;attribute name=&quot;name&quot; type=&quot;string&quot;&gt;&lt;/attribute&gt;
      &lt;/complexType&gt;
   &lt;/element&gt;
   &lt;element name=&quot;moduleConfiguration&quot;&gt;
      &lt;complexType&gt;
         &lt;attribute name=&quot;moduleClassname&quot; type=&quot;string&quot; use=&quot;required&quot;&gt;
            &lt;annotation&gt;
               &lt;appInfo&gt;&lt;meta.attribute kind=&quot;java&quot; basedOn=&quot;com.google.inject.AbstractModule:&quot;/&gt;&lt;/appInfo&gt;
            &lt;/annotation&gt;
         &lt;/attribute&gt;
         &lt;attribute name=&quot;priority&quot; type=&quot;string&quot; use=&quot;required&quot;&gt;&lt;/attribute&gt;
      &lt;/complexType&gt;
   &lt;/element&gt;
&lt;/schema&gt;
</pre>
<p>Using this definition, the plug-in can extend the main plug-in, by providing <code>moduleConfigurations</code>, which is a class name of the class extending the Guice AbstractModule and the priority. Using the following utility class, the module configurations can be read:</p>
<pre class="brush: java; title: ; notranslate">
public class PluginUtility {

	public static TreeMap&lt;Integer, AbstractModule&gt; getModuleConfigurations() throws CoreException {
		final TreeMap&lt;Integer, AbstractModule&gt; moduleConfigurations = new TreeMap&lt;Integer, AbstractModule&gt;();
		IExtension[] moduleConfigurationExtensions = Platform.getExtensionRegistry().getExtensionPoint(&quot;...id...&quot;).getExtensions();
		for (IExtension moduleConfiguration : moduleConfigurationExtensions) {
			for (IConfigurationElement configElement : moduleConfiguration.getConfigurationElements()) {

				AbstractModule module = (AbstractModule) configElement.createExecutableExtension(&quot;moduleClassname&quot;);
				String priorityAsString = configElement.getAttribute(&quot;priority&quot;);
				int priority = 0;
				try {
					priority = Integer.parseInt(priorityAsString);
				} catch (NumberFormatException e) {
					throw new CoreException(...);
				}

				moduleConfigurations.put(Integer.valueOf(priority), module);
			}
		}
		return moduleConfigurations;
	}
}
</pre>
<p>Using this utility, the main plug-in can read in available AbstractModules available in runtime and configure Dependency Injection. Before the usage of InjectorHolder this should be configured. We use higher priority (bigger number) as a reason to select the AbstractModule.</p>
<pre class="brush: java; title: ; notranslate">
public class InjectorHolder {
...
	private Injector injector;

	public static InjectorHolder getInstance() {
		if (instance == null) {
			instance = new InjectroHolder();
			injector = Guice.createInjector(PluginUtility.getModuleConfigurations().lastEntry().getValue());
		}
		return instance;
	}
...
}
</pre>
<p>Finally, the two binding modules should use the extension-point. The plug-in containing the business delegates should define the module configuration with a &#8220;standard&#8221; priority:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;....ModuleConfiguration&quot; name=&quot;ModuleConfiguration&quot;&gt;
      &lt;moduleConfiguration
            moduleClassname=&quot;....ServiceFacadeModule&quot;
            priority=&quot;1&quot;&gt;
      &lt;/moduleConfiguration&gt;
   &lt;/extension&gt;
</pre>
<p>The mock plugin should define a higher priority, which would win against the business delegate, if included into release.</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;....ModuleConfiguration&quot; name=&quot;ModuleConfiguration&quot;&gt;
      &lt;moduleConfiguration
            moduleClassname=&quot;....ServiceMockModule&quot;
            priority=&quot;10&quot;&gt;
      &lt;/moduleConfiguration&gt;
   &lt;/extension&gt;
</pre>
<h3>Summary</h3>
<p>In this article, an implementation approach for business delegates and service locator patterns is shown. Usage of Google Guice Dependency Injection framework allows for a flexible resolution of dependency in client code. Since it doesn&#8217;t support multiple binding configurations, we introduce a self-defined extension point, which allows to register different DI-Configuration modules and assign different priorities to them. In addition, we use the ability of Eclipse to define and use optional feature, to foster runtime-based configuration. Using different &#8220;Run Configurations&#8221;, you can start the RCP client with different implementation of your business services. If the mock plug-in is included, its higher priority will win against the business delegates. Therefore the development of the client can be performed using mock objects instead of real business delegates without any additional configuration.</p>
<p>Have Fun&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2010/11/guicy-mocks/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Extending Xtext Build Participants</title>
		<link>http://www.techjava.de/topics/2010/06/extending-xtext-build-participants/</link>
		<comments>http://www.techjava.de/topics/2010/06/extending-xtext-build-participants/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 10:41:21 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[builder]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[oaw]]></category>
		<category><![CDATA[xpand]]></category>
		<category><![CDATA[xtend]]></category>
		<category><![CDATA[xtext]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=674</guid>
		<description><![CDATA[You&#8217;ve definitely heard about Xtext, the famous text modeling framework, community award winner . We are all looking forward to the new project management wonder: the release of Helios, upcoming on June the 23rd, which will include Xtext 1.0.0. In this article, I want do describe some aspects of integration of Xtext-based languages into IDE. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.techjava.de/wp-content/uploads/builder_hands.jpg" alt="" title="builder_hands" width="150" height="99" style="margin:10px; float: right;" /><br />
You&#8217;ve definitely heard about 
<a  href="http://www.eclipse.org/Xtext/" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/Xtext/');" >Xtext</a>, the famous text modeling framework, 
<a  href="http://www.eclipse.org/org/press-release/20100322_awardswinners.php" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/org/press-release/20100322_awardswinners.php');" >community award winner </a>. We are all looking forward to the new project management wonder: the 
<a  href="http://www.eclipse.org/helios/" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/helios/');" >release of Helios</a>, upcoming on June the 23rd, which will include Xtext 1.0.0. In this article, I want do describe some aspects of integration of Xtext-based languages into IDE.<span id="more-674"></span></p>
<h3>Introduction</h3>
<p>Creating your own domain-specific textual languages in Xtext is really easy, and the authors in 
<a  href="http://xtext.itemis.com/" onclick="javascript:pageTracker._trackPageview('/external/xtext.itemis.com/');" >Northern Germany</a> are doing a good job to make it even easier. Once you have a language, you want to process it and this means usually to transform your model into another representation. The facility responsible for this transformation is called generator and consists of a bunch of transformation templates (e.G. XPand) and some code executing them. On some event, the model is read in and the transformations are applied to produce code. Currently, there are two ways of triggering the transformation: you can put the calling infrastructure in a Modeling Workflow Engine file, which is a kind of batch script or you can write a build-participant, which react on the changes in the model. In this article I want to describe my experiences with the builder approach.</p>
<h3>Examining initial builder</h3>
<p>The base idea behind the builder approach is the fact, that Xtext provides an project builder, which watches for all Xtext resource changes (Xtext-based DSL models) and notifies the so-called XtextBuilderParticipants. These are registered using Eclipse extension point <code>org.eclipse.xtext.builder.participant</code> and implement the <code>IXtextBuilderParticipant</code> interface:</p>
<pre class="brush: java; title: ; notranslate">
...
public interface IXtextBuilderParticipant {
    void build(IBuildContext context, IProgressMonitor monitor) throws CoreException;
}

public interface IBuildContext {
    IProject getBuiltProject();
    List&lt;IResourceDescription.Delta&gt; getDeltas();
    ResourceSet getResourceSet();
    void needRebuild();
}
</pre>
<p>In order not to start completely from scratch, let us examine the builder provided in the Domain-Model-Example, delivered with Xtext. In the build method the example builder processes as follows:</p>
<ul>
<li>checks that the project is a Java project</li>
<li>finds the generation folder</li>
<li>creates an Output</li>
<li>creates an Outlet and registers it in the Output</li>
<li>registers a post-processor managing Java imports on the outlet</li>
<li>creates the Xpand execution context</li>
<li>registers the Java Beans version of the metamodel</li>
<li>processes the changes and analyses if the files have to be deleted or not prior re-generation</li>
<li>for all changed model elements re-generates</li>
</ul>
<p>Quite a lot of tasks, so there is a good reason, why 
<a  href="http://wiki.eclipse.org/Modeling_Workflow_Engine_%28MWE%29" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Modeling_Workflow_Engine_%28MWE%29');" >MWE</a> scripts are used for generation. </p>
<h3>Using Project natures</h3>
<p>The first improvement I created for the builder is the ability to distinguish DSLs. The problem of triggering <strong>all</strong> XtextBuildParticipants on the change of <strong>any</strong> Xtext-based resource is that the entire Workspace gets re-generated. In my scenario, we used three DSLs and a random change caused three builders to run, even if the change has been made in another project of workspace. In order to solve this problem I used the standard Eclipse way to distinguish projects: Project Natures. </p>
<p>The nature I created is used as a marker for the builder and is emtpy:</p>
<pre class="brush: java; title: ; notranslate">
public class UiNature implements IProjectNature {
	public static final String NATURE_ID = &quot;de.techjava.dsl.uiNature&quot;;
	private IProject project;

	public void configure() throws CoreException {
        }

	public void deconfigure() throws CoreException {
	}
	public IProject getProject() {
		return project;
	}
	public void setProject(IProject project) {
		this.project = project;
	}
}
</pre>
<p>Don&#8217;t forget to register it in the plugin.xml:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension point=&quot;org.eclipse.core.resources.natures&quot;
         id=&quot;de.techjava.dsl.uiNature&quot;
         name=&quot;User Interface DSL Project Nature&quot;&gt;
      &lt;runtime&gt;
         &lt;run class=&quot;de.techjava.dsl.userinterface.builder.UiNature&quot; /&gt;
      &lt;/runtime&gt;
   &lt;/extension&gt;
</pre>
<p>As the first line in my builder I check the presence of the nature in the current project and stop building if the nature is not present:</p>
<pre class="brush: java; title: ; notranslate">
if (!context.getBuiltProject().hasNature(UiNature.NATURE_ID)) {
	// skip projects without UI DSL nature
	return;
}
</pre>
<p>Now, what is missing is the ability to add and remove the nature to/from the project. I liked the way how Xpand/Xtend Natures are configured (using toggle action in configure menu of the project pop-up menu). What you need is a ToggleAction that can be switched on, if the nature is not present and switched off, if the nature is installed. </p>
<pre class="brush: java; title: ; notranslate">
public class ToggleNatureAction implements IObjectActionDelegate {
	private ISelection selection;
	@SuppressWarnings(&quot;unchecked&quot;)
	public void run(IAction action) {
		if (selection instanceof IStructuredSelection) {
			for (Iterator it = ((IStructuredSelection) selection).iterator(); it.hasNext();) {
				Object element = it.next();
				IProject project = null;
				if (element instanceof IProject) {
					project = (IProject) element;
				} else if (element instanceof IAdaptable) {
					project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
				}
				if (project != null) {
					toggleNature(project);
				}
			}
		}
	}

	public void selectionChanged(IAction action, ISelection selection) {
		this.selection = selection;
	}

	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
	}

	/**
	 * Toggles sample nature on a project
	 * @param project to have sample nature added or removed
	 */
	private void toggleNature(IProject project) {
	// implemetation of toggle nature ...
	}
}
</pre>
<p>In order to make an action to a toggle-action the 
<a  href="http://wiki.eclipse.org/index.php/Platform_Command_Framework" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/index.php/Platform_Command_Framework');" >Eclipse Command Framework</a>, 
<a  href="http://wiki.eclipse.org/Menu_Contributions" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Menu_Contributions');" >Object Contributions</a> and the 
<a  href="http://wiki.eclipse.org/Command_Core_Expressions" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Command_Core_Expressions');" >Command Core Expressions</a> are needed. The idea is to register two actions as object contributions on the IProject using the <code>org.eclipse.ui.popupMenus</code> extension point and define visibility of those to be complement to each other (if one is visible the other is not) based on the object state, which is the presence of a project nature. The actions used point to the same implementation class but have different labels. The menu path to pop-up menu <strong>Project &gt; Configure</strong> is <strong>org.eclipse.ui.projectConfigure/additions</strong>. The visibility is defined based on the objectState:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;extension point=&quot;org.eclipse.ui.popupMenus&quot;&gt;
      &lt;objectContribution adaptable=&quot;true&quot;
            id=&quot;de.techjava.dsl.userinterface.ui.addNature&quot;
            objectClass=&quot;org.eclipse.core.resources.IProject&quot;&gt;
         &lt;action
               class=&quot;de.techjava.dsl.userinterface.ui.action.ToggleNatureAction&quot;
               id=&quot;de.techjava.dsl.userinterface.ui.AddNatureAction&quot;
               label=&quot;Add User Interface DSL Nature&quot;
               menubarPath=&quot;org.eclipse.ui.projectConfigure/additions&quot;&gt;
         &lt;/action&gt;
         &lt;visibility&gt;
            &lt;not&gt;&lt;objectState name=&quot;nature&quot; value=&quot;de.techjava.dsl.uiNature&quot; /&gt;&lt;/not&gt;
         &lt;/visibility&gt;
      &lt;/objectContribution&gt;
      &lt;objectContribution adaptable=&quot;true&quot;
            id=&quot;de.techjava.dsl.userinterface.ui.removeNature&quot;
            objectClass=&quot;org.eclipse.core.resources.IProject&quot;&gt;
         &lt;action
               class=&quot;de.techjava.dsl.userinterface.ui.action.ToggleNatureAction&quot;
               id=&quot;de.techjava.dsl.userinterface.ui.AddNatureAction&quot;
               label=&quot;Remove User Interface DSL Nature&quot;
               menubarPath=&quot;org.eclipse.ui.projectConfigure/additions&quot;&gt;
         &lt;/action&gt;
         &lt;visibility&gt;
            &lt;objectState name=&quot;nature&quot; value=&quot;de.techjava.dsl.uiNature&quot; /&gt;
         &lt;/visibility&gt;
      &lt;/objectContribution&gt;
   &lt;/extension&gt;
</pre>
<p>Please note, that the nature is implemented and registered inside of the generator project and the toggle action is implemented in the UI project. Finally, the code of the toggleNature method, which is the standard code for the project nature installation and removal:</p>
<pre class="brush: java; title: ; notranslate">
...
	IProjectDescription description = project.getDescription();
	String[] natures = description.getNatureIds();

	// remove the nature
	for (int i = 0; i &lt; natures.length; ++i) {
		// if nature exists
		if (NATURE_ID.equals(natures[i])) {
			// Remove the nature
			String[] newNatures = new String[natures.length - 1];
			System.arraycopy(natures, 0, newNatures, 0, i);
			System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
			description.setNatureIds(newNatures);
			project.setDescription(description, null);
			return;
		}
	}

	// Add the nature
	String[] newNatures = new String[natures.length + 1];
	System.arraycopy(natures, 0, newNatures, 0, natures.length);
	newNatures[natures.length] = NATURE_ID;
	description.setNatureIds(newNatures);
	project.setDescription(description, null);
...
</pre>
<p>That&#8217;s it, run and right-click on the Project and then go to the Configure Menu (pretty low in the pop-up) and you will see the result:<br />
<img src="http://www.techjava.de/wp-content/uploads/both-features.png" alt="" title="both-features" width="507" height="145" style="margin:10px; float:left" /></p>
<h3>Parameterizing generator</h3>
<p>Domain-specific languages should cover only the real requirements and incorporate the specific decision made in the project. So far the theory, but in fact it is a trade-off and a compromise, what is a part of the language and what is too specific to be covered. The same holds for the generator: on the one hand you want the generator to solve exactly your problem, on the other hand you want to make it generic enough to cover a class of similar problems. </p>
<p>I faced the problem of using the generator for two teams in a big project, where the langage could be reused, but the generation infrastructure need to be slightly modified. For example, the information about the generation target folder, package prefix and the fact which artifact should be generated differred between the teams. In the same time the teams were able to agree on the same language. In order not to develop two generators, I decided to parameterize the generator and the templates. </p>
<p>The Xpand2/Xtend developers provided a way of parameterization of the templates using the so-called Global Variables, using the GLOBALVAR keyword. My favorite way of using it is to create a cached extension for reading the variable:</p>
<pre class="brush: bash; title: ; notranslate">
/*
 * Retrieves the boolean value of the global variable set from outside of the template
 */
cached Boolean generateService() :
    GLOBALVAR generateService == &quot;true&quot;
;
</pre>
<p>In order to set global variables from the build participant the XPand execution context constructor takes a <code>Map&lt;String, Variable&gt;</code> argument. The nice story about the global variables, that you can provide any objects as values. So the advantage over the usage of MWE workflow with property files read-in during processing is the big flexibility in providing the object-graphs or even statefull objects as global variable values. A good example of usage of global variable is provided in Domain-Example with Java Import Tool:</p>
<pre class="brush: java; highlight: [4,5]; title: ; notranslate">
JavaImportsTool importsTool = new JavaImportsTool();
...
ctx = new XpandExecutionContextImpl(output, null,
    Collections.singletonMap(JavaImportsTool.VAR_NAME,
    new Variable(JavaImportsTool.VAR_NAME,importsTool)),
    null, null);
...
</pre>
<p>In the same time it is important to be able to load simple properties from file in the generation project. For example you could implement your own ModelProperties container, which reads properties from the file located in the generation project. For example:</p>
<pre class="brush: java; title: ; notranslate">
public class ModelProperties extends Properties {
	/**
	 * Indicates that no timestamp is available
	 */
	private static final long NO_TIMESTAMP = -1;

	private long lastModified = NO_TIMESTAMP;
	private final IFile propertyFile;
	private final HashMap&lt;String, Variable&gt; globalVars;

	/**
	 * Creates a valid model properties instance
	 *
	 * @param aProject reference to the current project
	 * @param name of the property file
	 * @throws CoreException on errors
	 */
	public ModelProperties(final IProject aProject, String filename) throws CoreException {
		if (aProject == null) {
			ErrorHelper.throwCoreException(&quot;project must be not null&quot;);
		}
		if (filename == null) {
			ErrorHelper.throwCoreException(&quot;filename must be not null&quot;);
		}
		this.globalVars = new HashMap&lt;String, Variable&gt;();
		this.propertyFile = (IFile) aProject.findMember(filename);
	}

	public IFile getPropertyFile() {
		return propertyFile;
	}

	/**
	 * Returns the global variables.
	 * @return global variables.
	 */
	public Map&lt;String, Variable&gt; getGlobalVars() {
		updateProperties();
		return globalVars;
	}

	@Override
	public String getProperty(String key) {
		updateProperties();
		return super.getProperty(key);
	}

	/**
	 * Updates the properties and the global variables if the property file has
	 * been modified.
	 */
	public void updateProperties() {
		if (this.propertyFile != null &amp;&amp; lastModified != this.propertyFile.getModificationStamp()) {
			loadProperties();
			globalVars.clear();
			for (Map.Entry&lt;Object, Object&gt; entry : entrySet()) {
				final String propertyName = (String) entry.getKey();
				globalVars.put(propertyName, new Variable(propertyName, entry.getValue()));
			}
		}
	}

	/**
	 * Loads the properties from the model file
	 */
	private void loadProperties() {

		try {
			if (propertyFile != null &amp;&amp; propertyFile.exists()) {
				super.load(propertyFile.getContents());
				this.lastModified = propertyFile.getModificationStamp();
				handleSpecialProperties();
			}
		} catch (CoreException e) {
			// no model property file isn't a problem but clear the properties:
			super.clear();
			this.lastModified = NO_TIMESTAMP;
		} catch (IOException e) {
			super.clear();
			this.lastModified = NO_TIMESTAMP;
		}
	}

	protected void handleSpecialProperties() {

	}
}
</pre>
<p>Using this class you can simple initialize the XPandExecutionContext with properties read from the file system. So in build-Method of your Generator put something like:</p>
<pre class="brush: java; title: ; notranslate">
         ModelProperties structureProperties = new ModelProperties(context.getBuiltProject(), &quot;structure.properties&quot;);
         XpandExecutionContextImpl ctx = new XpandExecutionContextImpl(output, null, structureProperties null, null);
</pre>
<p>Now you can resolve the values from the property files directly from the Templates and Extensions using the built-in GLOBAL VAR feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2010/06/extending-xtext-build-participants/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Launching Eclipse RCP via Java Web Start</title>
		<link>http://www.techjava.de/topics/2010/02/launching-rcp-via-jws/</link>
		<comments>http://www.techjava.de/topics/2010/02/launching-rcp-via-jws/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 16:32:15 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Enterprise Systems]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Application id not found]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[delivery]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[Java Web Start]]></category>
		<category><![CDATA[JNLP]]></category>
		<category><![CDATA[JWS]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[rcp]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=582</guid>
		<description><![CDATA[The Eclipse RCP became a prominent platform for building client software. One of the delivery mechanisms supported by Eclipse RCP is Sun&#8217;s Java Web Start (JWS). Since Galileo Edition some changes has been introduced in the platform. This article provides some hints for creation of the RCP delivered by Java Web Start. Packaging In order [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.techjava.de/wp-content/uploads/eclipse-rcp.png" alt="" title="eclipse-rcp" width="237" height="237" style="float:right; margin:5px" />The Eclipse RCP became a prominent platform for building client software. One of the delivery mechanisms supported by Eclipse RCP is Sun&#8217;s Java Web Start (JWS). Since Galileo Edition some changes has been introduced in the platform. This article provides some hints for creation of the RCP delivered by Java Web Start.</p>
<h2>Packaging</h2>
<p>In order to package the RCP I suggest to use feature-based products as described in 
<a  href="http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/">a previous article</a>. Following it, you should have a top-level plug-in (also refered as product-defining plug-in) and top-level feature, which is called &#8220;wrap&#8221;-feature in the context of the Java Web Start. </p>
<h3>Exporting the product</h3>
<p>Before you start with Java Web Start (JWS), export the product and make sure it starts as a standalone application. In doing so, you have to ensure that your references to the plug-ins are correct. One of the way of doing it is to hit the Validate button in the top left of the product editor. <img src="http://www.techjava.de/wp-content/uploads/validate-product.png" alt="" title="validate-product" width="196" height="79" style="float:right; margin:5px;" /> If the validation is successful, try to export the product. The PDE builder will run and create a distribution. The errors of the compiler/builder/assembler, if any, are reported to files zipped to the <code>logs.zip</code> file in the distribution directory. <span id="more-582"></span> A prominent error is</p>
<pre class="brush: plain; light: true; title: ; notranslate">
Compliance level '1.3' is incompatible with source level '1.6'. A compliance level '1.6' or better is required.
</pre>
<p>Which actually means that the plug-in classes has not been compiled at all. In order to avoid this error make sure to set the following properties in the <code>build.properties</code> file of the corresponding plug-in:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
javacSource=1.3
javacTarget=1.3
</pre>
<h3>Exporting the wrap-feature</h3>
<p>After a successful export of the product, just export the top-level feature (the wrap-feature). Make sure to provide the signing information, since JWS requires all resources to be signed. If you are aiming to deliver for different platforms, make sure to define a target platform (<strong>Window > Preferences > Plug-in Development > Target Platform</strong>) which contains a Delta Pack. A Delta Pack is a set of plug-ins which can be downloaded separately on the 
<a  href="http://ww.eclipse.org/downloads/" onclick="javascript:pageTracker._trackPageview('/external/ww.eclipse.org/downloads/');" >Eclipse Homepage</a>. Also, don&#8217;t forget to switch over to the Java Web Start tab of the Feature Export Wizard, activate the checkbox &#8220;Create JNLP manifest for the JAR archives&#8221; and specify the site URL where the resulting JNLP will be located. Make sure all your features has the provider attribute set, since it is used as the &#8220;vendor&#8221; inside of the JNLP file, which is a mandatory attribute.</p>
<h3>Creating the main JNLP</h3>
<p>The PDE build will run and create a distribution in the specified directory. Along with the exported JARs in features and plug-ins, the packaging script will generate the JNLP descriptors for every feature. Still, the main JNLP file required for launching the application is missing and has to be provided separately. Here is, how it looks like:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;jnlp spec=&quot;1.0+&quot; codebase=&quot;http://localhost/app/&quot; href=&quot;app.jnlp&quot;&gt;
    &lt;information&gt;
        &lt;title&gt;application titel&lt;/title&gt;
        &lt;vendor&gt;provider&lt;/vendor&gt;
        &lt;offline-allowed/&gt;
    &lt;/information&gt;

    &lt;security&gt;
        &lt;all-permissions/&gt;
    &lt;/security&gt;

    &lt;application-desc main-class=&quot;org.eclipse.equinox.launcher.WebStartMain&quot;&gt;
	&lt;argument&gt;-product&lt;/argument&gt;
	&lt;argument&gt;de.techjava.app.webstart.productid&lt;/argument&gt;
	&lt;argument&gt;-application&lt;/argument&gt;
	&lt;argument&gt;de.techjava.app.webstart.appid&lt;/argument&gt;
    &lt;/application-desc&gt;

    &lt;resources&gt;
        &lt;j2se version=&quot;1.4+&quot; ax-heap-size=&quot;128m&quot; /&gt;
	&lt;jar href=&quot;plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar&quot;/&gt;
	&lt;extension name=&quot;wrap feature&quot; href=&quot;features/wrap_feature_1.0.0.jnlp&quot; /&gt;
	&lt;!-- OSGI setup --&gt;
        &lt;property name=&quot;osgi.instance.area&quot; value=&quot;@user.home/app&quot;/&gt;
        &lt;property name=&quot;osgi.configuration.area&quot; value=&quot;@user.home/app&quot;/&gt;
    &lt;/resources&gt;
&lt;/jnlp&gt;
</pre>
<p>Important is to specify both, the <strong>product id</strong> and the <strong>applciation id</strong>, otherwise you will see the &#8220;Application id not found&#8221; exception. Of course you can specify 
<a  href="http://help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html" onclick="javascript:pageTracker._trackPageview('/external/help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html');" >additional options</a> as command-line arguments of the launcher itself. I found it useful to be able to let the OSGi running and then connect to it and query for loaded bundles. You can do it by adding the following arguments:</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;argument&gt;-console&lt;/argument&gt;
	&lt;argument&gt;1234&lt;/argument&gt;
	&lt;argument&gt;-noExit&lt;/argument&gt;
</pre>
<p>This will allow to connect via telnet with running OSGi, even after the application finishes.<br />
This is basically it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2010/02/launching-rcp-via-jws/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Eclipse DemoCamp Hamburg &#124; November 2009</title>
		<link>http://www.techjava.de/topics/2009/11/eclipse-democamp-hamburg-november-2009/</link>
		<comments>http://www.techjava.de/topics/2009/11/eclipse-democamp-hamburg-november-2009/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 12:49:49 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Announce]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[DemoCamp]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[hotel east]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=534</guid>
		<description><![CDATA[An event of annual series of Eclipse Demo Camps is taking place in Hamburg again. The event was planned in November, but takes actually place in December. As usually Peter and Martinare responsible for the organization. To make it short: What: Eclipse DemoCamp November 2009 Where: Hotel East, Hamburg ( Simon-von-Utrecht-Str. 31, 20359 Hamburg, Germany) [...]]]></description>
			<content:encoded><![CDATA[<p>
<a  href="http://www.techjava.de/wp-content/uploads/EclipseDemoCampHamburg2007_78FD/EclipseDemoCamp.gif" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/EclipseDemoCampHamburg2007_78FD/EclipseDemoCamp.gif');" ><img style="border: 0pt none; margin: 10px; float:right;" src="http://www.techjava.de/wp-content/uploads/EclipseDemoCampHamburg2007_78FD/EclipseDemoCamp_thumb.gif" border="0" alt="EclipseDemoCamp" width="90" height="76" /></a> An event of 
<a  href="http://www.techjava.de/topics/2009/04/eclipse-democamp-2009-galileo-edition/">annual series</a> of Eclipse Demo Camps is taking place in Hamburg again. The event was planned in November, but takes actually place in December. As usually 
<a  href="http://www.peterfriese.de/" onclick="javascript:pageTracker._trackPageview('/external/www.peterfriese.de/');" >Peter</a> and 
<a  href="http://www.martinlippert.com/" onclick="javascript:pageTracker._trackPageview('/external/www.martinlippert.com/');" >Martin</a>are responsible for the organization. To make it short:</p>
<ul>
<li>What: Eclipse DemoCamp November 2009</li>
<li>Where: Hotel East, Hamburg (
<a  href="http://piurl.com/XhT" onclick="javascript:pageTracker._trackPageview('/external/piurl.com/XhT');" >Simon-von-Utrecht-Str. 31, 20359 Hamburg, Germany</a>)</li>
<li>When: December 4th 2009, 18:30-22:00 (official part)</li>
</ul>
<p>If you want to attend, make sure you find a minute to 
<a  href="http://wiki.eclipse.org/Eclipse_DemoCamps_November_2009/Hamburg" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Eclipse_DemoCamps_November_2009/Hamburg');" >write you name down in EclipseWiki.</a> I suppose these kind of events is well-known. If you never heard of that &#8211; look at the interesting topics and the attendee list of more than one hundred people. You will have the opportunity to listen to the talks, to speak with interesting people and get some news from Eclipse Commiters and Users. In the end you usually get some food and bevereges, to make the atmosphere a little more relaxed. If you never been there it is worth to visit&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/11/eclipse-democamp-hamburg-november-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EWiTa and ESE 2009</title>
		<link>http://www.techjava.de/topics/2009/11/ewita-and-ese-2009/</link>
		<comments>http://www.techjava.de/topics/2009/11/ewita-and-ese-2009/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 21:24:55 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Announce]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Enterprise Systems]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[business information]]></category>
		<category><![CDATA[Eclipse Summit Europe]]></category>
		<category><![CDATA[ESE2009]]></category>
		<category><![CDATA[ewita]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[summit]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=512</guid>
		<description><![CDATA[Even if some time has passed since the events EWiTa 2009 and Eclipse Summit Europe 2009, I would like to share my impressions, since I took part in both events&#8230; EWiTa 2009 EWiTa 2009 stands for Elmshorner Wirtschaftsinfromatiktag, that is German for &#8220;Elmshorn Business Information Systems Day&#8221;. The event has been organized by Frank Zimmermann, [...]]]></description>
			<content:encoded><![CDATA[<p>Even if some time has passed since the events EWiTa 2009 and Eclipse Summit Europe 2009, I would like to share my impressions, since I took part in both events&#8230;</p>
<h3>EWiTa 2009</h3>
<p><img style="margin: 5px; float: right;" src="http://farm3.static.flickr.com/2550/4037739235_3fc88b8416_m.jpg" alt="_MG_9975" width="160" height="240" />
<a  href="http://ewita.nordakademie.de/index.html" onclick="javascript:pageTracker._trackPageview('/external/ewita.nordakademie.de/index.html');" >EWiTa 2009</a> stands for Elmshorner Wirtschaftsinfromatiktag, that is German for &#8220;Elmshorn Business Information Systems Day&#8221;. The event has been organized by Frank Zimmermann, of 
<a  href="http://www.nordakademie.de/" onclick="javascript:pageTracker._trackPageview('/external/www.nordakademie.de/');" >Nordakademie</a> &#8211; a private university in Northern Germany. Even if the event is not an official sequel of the 
<a  href="http://mdsd08.techjava.de/" onclick="javascript:pageTracker._trackPageview('/external/mdsd08.techjava.de/');" >MDSD Today</a>, there were many similarities. The event had two tracks: the process modeling track and the MDSD track. After an excellent keynote from Mathias Weske about the importance of collaboration during the process of (business) modeling I stayed in the business track to listen to the Andrea Grass (
<a  href="http://www.oose.de/" onclick="javascript:pageTracker._trackPageview('/external/www.oose.de/');" >oose GmbH</a>) on the combination of UML and BPMN 2.0. To say the truth, I&#8217;m not a big fan of this approach, especially, because the conceptual mismatch of modeling of business behavior and technical behavior. After a coffee break I enjoyed an excellent talk of 
<a  href="http://www.heikobehrens.net/>Heiko Behrens</a> (<a href="http://www.itemis.com/" onclick="javascript:pageTracker._trackPageview('/external/www.heikobehrens.net/>Heiko Behrens</a> (<a href=');" >itemis</a>), reporting about the success story of xText in a big project of Deutsche Börse AG (German Stock Exchange).</p>
<p>After a small lunch, I was listening to two Arcando consultants reporting about their eTicketing project. The strange thing about this talk was that they just made some ads on a standard Microsoft product. After this, I enjoyed an interesting talk on business modeling based on CobIT process. Finally, I switched the track again to MDSD and listend to the an interesting usage of MDSD techniques for generation of DynPro and ABAP code. 
<a  href="http://flickriver.com/photos/sza/sets/72157622523990299/" onclick="javascript:pageTracker._trackPageview('/external/flickriver.com/photos/sza/sets/72157622523990299/');" ><img title="simon.zambrovski - View my 'EWiTa 2009' set on Flickriver" src="http://flickriver.com/badge/user/set-72157622523990299/recent/shuffle/medium-horiz/ffffff/333333/73775153@N00.jpg" border="0" alt="simon.zambrovski - View my 'EWiTa 2009' set on Flickriver" /></a></p>
<p>In general I enjoyed the event. I think the MDSD track was a little more technical, but the combination was good.</p>
<h3>Eclipse Summit Europe 2009</h3>
<p><img src="http://farm3.static.flickr.com/2679/4058140264_9e2eab48aa_m.jpg" width="240" height="160" alt="_MG_0117" style="margin: 5px; float: left;" />The Eclipse Summit Europe 2009 (ESE 2009) took place on October 27-29 in Ludwigsburg, Germany, it is the European complement to the EclipseCon in the US. In contrast to the spring event in Santa Clara, CA, the ESE is an autumn event in a beautiful baroque town near Stuttgart. The event lasted three days and is a must for Eclipse-related technology people. As usual, the venue was great, the keynotes excellent and the talks interesting. And of course it was the place to meet the committers, evangelists, see them in action, talk to them and discuss the future directions.</p>
<h4>Symposium Day</h4>
<p>The first day is an arrival day. People arrive during the day, some of them are already there. I was visiting the Modeling Track the whole day and had much fun with Ed Merks, Eike Stepper and Thomas Schindl in the morning. Later, in the Modeling Symposium, Eike showed the eDine RCP based on CDO, UBS envisioned the modeling tool pipeline and so on, and so on. About 10 people showed different technologies on and about modeling. Intersting, unstructured and relaxed. And of course, the first evening is the opportunity to speak with all the Eclipse VIPs and drink a cold beer.</p>
<h4>First Day</h4>
<p>The main conference day was Wednesday and it started with a great keynote on functional programming held by Don Syme, the father of F#. Suprisingly, the talk was about F#. For some of us, there was not enough functional beauty exposed in the talk, so I scheduled a private session with Don and he told 
<a  href="http://www.voelter.de/" onclick="javascript:pageTracker._trackPageview('/external/www.voelter.de/');" >Markus Voelter</a>, 
<a  href="http://www.heikobehrens.net/" onclick="javascript:pageTracker._trackPageview('/external/www.heikobehrens.net/');" >Heiko Behrens</a> and 
<a  href="http://simon.zambrovski.org/" onclick="javascript:pageTracker._trackPageview('/external/simon.zambrovski.org/');" >me</a> about some interesting F# features.<img src="http://farm3.static.flickr.com/2694/4057390437_56df43864f_m.jpg" width="160" height="240" alt="_MG_0090" style="margin: 5px; float: right;"/></p>
<p>I took part in the 
<a  href="http://www.eclipsecon.org/summiteurope2009/sessions?id=924" onclick="javascript:pageTracker._trackPageview('/external/www.eclipsecon.org/summiteurope2009/sessions');" >How about I/O</a> session on 
<a  href="https://wiki.sdn.sap.com/wiki/display/Java/JPicus" onclick="javascript:pageTracker._trackPageview('/external/wiki.sdn.sap.com/wiki/display/Java/JPicus');" >JPicus</a>. A very interesting tool for tracking I/O problems in Java programs developed by SAP. The 
<a  href="http://www.eclipsecon.org/summiteurope2009/sessions?id=861" onclick="javascript:pageTracker._trackPageview('/external/www.eclipsecon.org/summiteurope2009/sessions');" >Climb The Tower of Babel</a> was about the Eclipse translation project. Intersting is the runtime editor allowing you to translate you runnig application. After a delicios lunch, I enjoyed two modeling talks: Xtext and EMF Query. The itemis team introduced some really new features, which make Xtext in my oppinion to a unique technology. Just to mention few of them: white-space aware parsing, usage of scopes and qualified names, usage of index (construted by a builder) in your own language, separation of markers and annotations in the editor, integration of the generator on-save, declarative quick-fix in your DSL, strings with special meaning, references to java types, and much more&#8230; The EMF Query is a project developed by the SAP team, that leverages the index by a query language. The language is a SQL-like DSL for querying the EMF-based models. The infrastructure is very intersting and allows complex scenarios with multiple model providers &#8211; very technical, and I believe, very interesting project.</p>
<h4>Second Day</h4>
<p><img src="http://farm3.static.flickr.com/2747/4057438031_aa2a25e400_m.jpg" width="160" height="240" alt="_MG_0171" style="margin: 5px; float: right;" /><br />
After the keynote on the importance of software ecosystems and a deep economical analysis of Eclipse ecosystem, I switched off the track to be able to prepare 
<a  href="http://www.eclipsecon.org/summiteurope2009/sessions?id=911" onclick="javascript:pageTracker._trackPageview('/external/www.eclipsecon.org/summiteurope2009/sessions');" >my talk</a>. I was reporting about the IDE for TLA+ which I was building the last nine month at Microsoft Research, and which will be 
<a  href="http://www.tlaplus.net/posts/2009/08/coming-soon-tla-toolbox/" onclick="javascript:pageTracker._trackPageview('/external/www.tlaplus.net/posts/2009/08/coming-soon-tla-toolbox/');" >available soon</a>. The main emphasis of the talk, was not the demo of the IDE, but the exchange of experiences on building one. Especially, I focused on the possible pitfalls and conceptual mismatches of IDEs depending on the integrated language. The slides will be available soon. </p>
<p>At the end, I enjoyed the event very much. I even liked it more than EclipseCon. Modeling still seems to be the most interesting part of Eclipse ecosystem. Technologies like Xtext and CDO gain maturity, new technolgoes like EMF Query are being developed. It was nice to see the people again&#8230;  As usual, some pictures:<br />

<a  href="http://www.flickriver.com/photos/sza/sets/72157622569740211/" onclick="javascript:pageTracker._trackPageview('/external/www.flickriver.com/photos/sza/sets/72157622569740211/');" ><img src="http://www.flickriver.com/badge/user/set-72157622569740211/recent/shuffle/medium-tiny/ffffff/333333/73775153@N00.jpg" border="0" alt="simon.zambrovski - View my 'Eclipse Summit Europe 2009' set on Flickriver" title="simon.zambrovski - View my 'Eclipse Summit Europe 2009' set on Flickriver"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/11/ewita-and-ese-2009/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Eclipse CNF: Navigator Content Extensions</title>
		<link>http://www.techjava.de/topics/2009/08/eclipse-common-navigator-framework-2/</link>
		<comments>http://www.techjava.de/topics/2009/08/eclipse-common-navigator-framework-2/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 20:55:11 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[cnf]]></category>
		<category><![CDATA[common navigator framework]]></category>
		<category><![CDATA[navigator content extension]]></category>
		<category><![CDATA[NCE]]></category>
		<category><![CDATA[plug-in]]></category>
		<category><![CDATA[rcp]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=471</guid>
		<description><![CDATA[Abstract After providing the basic example of how the Eclipse Common Navigator Framework (CNF) can be used to display custom content, this article focuses on the main feature of the CNF &#8211; the contribution of content to the same navigator by several independent plug-ins. First of all, I will explain some minor changes introduced to [...]]]></description>
			<content:encoded><![CDATA[<h2>Abstract</h2>
<p><img class="alignnone size-thumbnail wp-image-501" style="float:right; margin:10px;" title="compass" src="http://www.techjava.de/wp-content/uploads/compass2-150x150.jpg" alt="compass" width="150" height="150" /> After 
<a  href="http://www.techjava.de/topics/2009/04/eclipse-common-navigator-framework/">providing the basic example</a> of how the Eclipse Common Navigator Framework (CNF) can be used to display custom content, this article focuses on the main feature of the CNF &#8211; the contribution of content to the same navigator by several independent plug-ins. First of all, I will explain some minor changes introduced to the CNF in the Gallileo Edition, then I will focus on the content itself and finally provide an overview of how the action contributions can be provided. In the end of the post, some ideas on control of dynamic content are explained.</p>
<h2>Gallileo Changes</h2>
<p>There are two noticeable changes in the CNF that have been added with 
<a  href="http://www.techjava.de/topics/2009/06/galileo-has-arrived/">Eclipse Galileo</a>. The return type of the method <span id="more-471"></span><code>CommonNavigator#getInitialInput()</code> has been changed to <code>Object</code> (which is important for the RCP usage of the CNF) and the call of the method <code>org.eclipse.ui.internal.ide.model.WorkbenchAdapterBuilder#registerAdapters()</code> has been replaced by the <code>org.eclipse.ui.ide.IDE.registerAdapters();</code> which should be executed in the <code>initialize</code> method of the <code>ApplicationWorkbenchAdvisor</code> of your RCP if you are using resources with the CNF.</p>
<pre class="brush: java; title: ; notranslate">
public class CommonNavigator ...
{
  /**
   * Used to provide the initial input for the {@link CommonViewer}.
   * By default getSite().getPage().getInput() is used.
   * Subclass this to return your desired input.
   * @return The initial input for the viewer.
   * Defaults to getSite().getPage().getInput()
   * @since 3.4
   */
  protected Object getInitialInput() {...}
}
</pre>
<h2>Content contribution</h2>
<p>The main advantage of the use of the CNF over a simple tree view is the ability to contribute content to the view from several plug-ins. Thus, the plug-in that contains the view does not depend on the contributing plug-ins. If you are not familiar with the CNF, please review the 
<a  href="http://www.techjava.de/topics/2009/04/eclipse-common-navigator-framework/">previous post</a>, since the example provided there will be extended. The data model used previously will be extended by an additional layer: along with parents and children, the pets are introduced. Let&#8217;s assume that pets are owned by children.</p>
<pre class="brush: java; title: ; notranslate">
/**
 * Represents a pet
 * @author Simon Zambrovski
 */
public class Pet
{
    private String name;
    private Child owner;

    public Pet(String name, Child owner)
    {
        super();
        this.name = name;
        this.owner = owner;
    }
    ...
    // getter and setter
}
</pre>
<p>First of all create a new plug-in project called <code>de.techjava.rcp.cnf.subcontent</code>, add a plug-in dependency to the <code>de.techjava.rcp.cnf</code> and to the <code>org.eclipse.ui.navigator</code>. Then add two extensions <code>org.eclipse.ui.navigator.navigatorContent</code> and <code>org.eclipse.ui.navigator.viewer</code>. The first extension defines the new Navigator Content Extension (NCE) and the second one is used to bind it to the existing viewer.</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.ui.navigator.navigatorContent&quot;&gt;
      &lt;navigatorContent
            activeByDefault=&quot;true&quot;
            contentProvider=&quot;de.techjava.rcp.cnf.subcontent.provider.CNFSubContentProvider&quot;
            id=&quot;de.techjava.rcp.cnf.subcontent.navigatorContent&quot;
            labelProvider=&quot;de.techjava.rcp.cnf.subcontent.provider.CNFSubLabelProvider&quot;
            name=&quot;Sub Content&quot;
            priority=&quot;normal&quot;
            providesSaveables=&quot;false&quot;&gt;
         &lt;enablement&gt;
            &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Child&quot; /&gt;
         &lt;/enablement&gt;
      &lt;/navigatorContent&gt;
   &lt;/extension&gt;
   &lt;extension
         point=&quot;org.eclipse.ui.handlers&quot;&gt;
      &lt;handler
            class=&quot;de.techjava.rcp.cnf.subcontent.handler.RenameHandler&quot;
            commandId=&quot;org.eclipse.ui.edit.rename&quot;&gt;
         &lt;activeWhen&gt;
            &lt;reference definitionId=&quot;de.techjava.rcp.cnf.subcontent.petSelected&quot; /&gt;
         &lt;/activeWhen&gt;
         &lt;enabledWhen&gt;
            &lt;reference definitionId=&quot;de.techjava.rcp.cnf.subcontent.petSelected&quot;/&gt;
         &lt;/enabledWhen&gt;
      &lt;/handler&gt;
   &lt;/extension&gt;
</pre>
<p>The Sub Content is defined following the same scheme as the content in the previous article of this series.  Its <code>contentProvider</code> and <code>labelProvider</code> attributes point to the corresponding classes. The label provider implementation is straight forward. The content provider has to be able to return a list of children, if the instance of the <code>Child</code>-class is selected in the Navigator. The <code>enablement</code> is defined in this way respectively. An important thing to understand at this point is that the CNF will <strong>join</strong> contributions of all NCEs triggered on the element selection. This means, that even if the NCE of the first plug-in does not provide any children for the <code>Child</code> element, there will be children contributed by the second plug-in&#8217;s content provider. Here is the example content provider, which returns the number of pets depending on the last digit in a child&#8217;s name:</p>
<pre class="brush: java; title: ; notranslate">
public class CNFSubContentProvider implements ITreeContentProvider
{
    ...
    public Object[] getChildren(Object parentElement)
    {
        if (parentElement instanceof Child
                &amp;&amp; !(parentElement instanceof Parent))
        {
            Child child = ((Child) parentElement);
            char lastDigit = child.getName().charAt(child.getName().length() - 1);
            if (Character.isDigit(lastDigit))
            {
                int petCount = Integer.parseInt(String.valueOf(lastDigit));
                Pet[] pets = new Pet[petCount];
                for (int i = 0; i &gt; petCount; i++)
                {
                    pets[i] = new Pet(child.getName() + &quot;'s pet &quot; + (i + 1), child);
                }
                return pets;
            }
            return EMPTY_ARRAY;
        } else
        {
            return EMPTY_ARRAY;
        }
    }
    ...
}
</pre>
<p>After this trivial configuration and the inclusion of the new plug-in into the example product, the resulting Navigator should show pets as sub-elements of the child-elements.<br />
<img class="alignnone size-full wp-image-484" title="CNF2" src="http://www.techjava.de/wp-content/uploads/CNF2.png" alt="CNF2" width="400" height="300" /></p>
<h2>Shared commands</h2>
<p>If the Navigator displays content from several plug-ins, the contributed commands should be handled carefully. The commands (contributed to the pop-up menu shown upon right-click on the corresponding item) should appear only on items they belong to. In order to achieve this, let us first look at the standard way of the command contribution. The CNF developer is strongly recommend to use the declarative contribution techniques instead of the Action Contribution Provider. For this purpose, the extension point <code>org.eclipse.ui.navigator.viewer</code> allows to contribute a <code>popupMenu</code> element as a child element of the <code>viewer</code>. The pop-up menu element defines the structure (in terms of separators) of the pop-up menu. There is a standard pop-up menu structure defined, which is default if a user-specific definition is ommited. In the example, the user-specific pop-up menu is defined:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.ui.navigator.viewer&quot;&gt;
      &lt;viewer
            viewerId=&quot;de.techjava.rcp.cnf.view&quot;&gt;
         &lt;popupMenu
               allowsPlatformContributions=&quot;true&quot;
               id=&quot;de.techjava.rcp.cnf.view.popup&quot;&gt;
            &lt;insertionPoint
                  name=&quot;group.new&quot;
                  separator=&quot;false&quot;&gt;
            &lt;/insertionPoint&gt;
            &lt;insertionPoint
                  name=&quot;group.open&quot;
                  separator=&quot;false&quot;&gt;
            &lt;/insertionPoint&gt;
            &lt;insertionPoint
                  name=&quot;group.edit&quot;
                  separator=&quot;true&quot;&gt;
            &lt;/insertionPoint&gt;
            ...
         &lt;/popupMenu&gt;
      &lt;/viewer&gt;
      ...
    &lt;/extension&gt;
</pre>
<p>Using the 
<a  href="http://wiki.eclipse.org/index.php/Platform_Command_Framework" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/index.php/Platform_Command_Framework');" >Eclipse Command Framework</a>, the commands can be contributed to the defined pop-up menu in the following way. Using the <code>org.eclipse.ui.menus</code> extension point one or several <code>menuContribution</code> elements can be defined. Each menu contribution defines a set of commands, controls, menus, tool bars or dynamic contributions (or any combination) which are added to a specific separator addressed in a special way (see Command Framework Documentation). In this example the set of commands is contributed:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.ui.menus&quot;&gt;
      &lt;menuContribution
            locationURI=&quot;popup:de.techjava.rcp.cnf.view.popup?after=group.edit&quot;&gt;
         &lt;command
               commandId=&quot;org.eclipse.ui.edit.delete&quot;
               id=&quot;cnf.popupmenu.delete&quot;
               label=&quot;Delete&quot;
               mnemonic=&quot;D&quot;
               style=&quot;push&quot;&gt;
         &lt;/command&gt;
         &lt;command
               commandId=&quot;org.eclipse.ui.edit.rename&quot;
               id=&quot;cnf.popupmenu.rename&quot;
               label=&quot;Rename&quot;
               mnemonic=&quot;R&quot;
               style=&quot;push&quot;&gt;
         &lt;/command&gt;
      &lt;/menuContribution&gt;
      ....
    &lt;/extension&gt;
</pre>
<p>Please note that the <code>commandId</code> must point to an existing command, which is either user-defined, or defined by the Eclipse platform. A <code>command</code> is an abstraction of a user command which is referenced from the User Interface on one hand and has assigned handlers (which execute the command) on the other hand. The representation of the command is shown in the UI only if a handler is assigned to it. The idea of using shared commands is to have multiple handlers for the same command, which are activated depending on the selected element.</p>
<p>In order to enable and disable handlers in a declarative way, the 
<a  href="http://wiki.eclipse.org/Command_Core_Expressions" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Command_Core_Expressions');" >Eclipse Core Expressions</a> are used. Core expressions can be written in the <code>enabledWhen</code> and <code>activeWhen</code> child elements of the handler definition. The core expressions can also be defined and referenced externally using the <code>org.eclipse.core.expressions.definitions</code> extension point. Here is an example definition of the handler assigned to the Rename command:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.ui.handlers&quot;&gt;
      &lt;handler
            class=&quot;de.techjava.rcp.cnf.handler.RenameHandler&quot;
            commandId=&quot;org.eclipse.ui.edit.rename&quot;&gt;
         &lt;activeWhen&gt;
            &lt;reference definitionId=&quot;de.techjava.rcp.cnf.elementSelected&quot; /&gt;
         &lt;/activeWhen&gt;
         &lt;enabledWhen&gt;
            &lt;reference definitionId=&quot;de.techjava.rcp.cnf.elementSelected&quot; /&gt;
         &lt;/enabledWhen&gt;
      &lt;/handler&gt;
   &lt;/extension&gt;
</pre>
<p>The handler is enabled and active if the expression <code>de.techjava.rcp.cnf.elementSelected</code> is triggered. The definition of the expression is as follows. It defines the <code>with</code>-scope on the current selection, <code>iterates</code> over the elements and applies the <code>instance of</code> operator on the elements using the OR-conjunction. In doing so, the expression will trigger if among the currently selected elements is at least one <code>Child</code> element.</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.core.expressions.definitions&quot;&gt;
      &lt;definition id=&quot;de.techjava.rcp.cnf.elementSelected&quot;&gt;
         &lt;with variable=&quot;selection&quot;&gt;
            &lt;iterate ifEmpty=&quot;false&quot; operator=&quot;or&quot;&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.data.Child&quot; /&gt;
            &lt;/iterate&gt;
         &lt;/with&gt;
      &lt;/definition&gt;
   &lt;/extension&gt;
</pre>
<p><img class="alignnone size-full wp-image-486" title="CNF2-rename-child" src="http://www.techjava.de/wp-content/uploads/CNF2-rename-child.png" alt="CNF2-rename-child" width="384" height="239" /><br />
In order to use the same action (the Rename item of the pop-up menu) in the Pet plug-in, the handler enabled on the Pet element has to be provided. The code is analogous to the code before:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;org.eclipse.ui.handlers&quot;&gt;
      &lt;handler
            class=&quot;de.techjava.rcp.cnf.subcontent.handler.RenameHandler&quot;
            commandId=&quot;org.eclipse.ui.edit.rename&quot;&gt;
         &lt;activeWhen&gt;
            &lt;reference
                  definitionId=&quot;de.techjava.rcp.cnf.subcontent.petSelected&quot;&gt;
            &lt;/reference&gt;
         &lt;/activeWhen&gt;
         &lt;enabledWhen&gt;
            &lt;reference definitionId=&quot;de.techjava.rcp.cnf.subcontent.petSelected&quot; /&gt;
         &lt;/enabledWhen&gt;
      &lt;/handler&gt;
   &lt;/extension&gt;
   &lt;extension
         point=&quot;org.eclipse.core.expressions.definitions&quot;&gt;
      &lt;definition
            id=&quot;de.techjava.rcp.cnf.subcontent.petSelected&quot;&gt;
         &lt;with variable=&quot;selection&quot;&gt;
            &lt;iterate ifEmpty=&quot;false&quot; operator=&quot;or&quot;&gt;
               &lt;instanceof value=&quot;de.techjava.rcp.cnf.subcontent.data.Pet&quot; /&gt;
            &lt;/iterate&gt;
         &lt;/with&gt;
      &lt;/definition&gt;
   &lt;/extension&gt;
</pre>
<p>This should enable the Rename action on the Pet elements, too.<br />
<img class="alignnone size-full wp-image-487" title="CNF2-rename-pet" src="http://www.techjava.de/wp-content/uploads/CNF2-rename-pet.png" alt="CNF2-rename-pet" width="384" height="239" /></p>
<h2>Dynamic content change</h2>
<p>Finally, the last topic, which is covered in this article is the control of which content is shown in the Common Navigator. The developer can define the initial behaviour by setting the <code>activeByDefault</code> attribute of the <code>NavigatorContent</code> element. The user can customize the visible NCEs in the special dialog:<br />
<img class="alignnone size-full wp-image-489" title="CNF2-available-customizations" src="http://www.techjava.de/wp-content/uploads/CNF2-available-customizations.png" alt="CNF2-available-customizations" width="407" height="339" /><br />
Of course there is a way to change the content shown in the Common Navigator at run-time. The following section describes how this can be done.</p>
<p>Responsible for loading the NCEs is the NavigatorContentService, which can be retrieved from the running Navigator instance. Using it is straight forward.</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * Sets the status of a NCE of the current viewer if any
     */
    public static void setToolboxNCEActive(final String extensionId, final boolean active)
    {
        CommonNavigator instance = findCommonNavigator(CNFNavigator.VIEW_ID);
        if (instance != null)
        {
            INavigatorContentService contentService = instance.getNavigatorContentService();
            boolean isActive = contentService.getActivationService().isNavigatorExtensionActive(extensionId);
            if (active &amp;&amp; !isActive)
            {
                contentService.getActivationService().activateExtensions(new String[] { extensionId }, false);
            } else if (!active &amp;&amp; isActive)
            {
                contentService.getActivationService().deactivateExtensions(new String[] { extensionId }, false);
            } else
            {
                // do nothing, just quit
                return;
            }
            contentService.getActivationService().persistExtensionActivations();
            contentService.update();
        }
    }
</pre>
<p>The method <code>findCommonNavigator(String viewId)</code> is responsible for delivering the instance of the CNF. For example it could query the view for visible viewers and compare them with the requested Id:</p>
<pre class="brush: java; title: ; notranslate">
    public static CommonNavigator findCommonNavigator(String navigatorViewId)
    {
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        if (page != null)
        {
            IViewPart view = page.findView(navigatorViewId);
            if (view != null &amp;&amp; view instanceof CommonNavigator)
                return ((CommonNavigator) view);
        }
        return null;
    }
</pre>
<p>After the NCE status is changed the viewer has to be updated. Please note, that retrieving the instance of the <code>INavigatorContentService</code> via the Factory (<code>NavigatorContentServiceFactory</code>) will not work for this scenario (see 
<a  href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284650" onclick="javascript:pageTracker._trackPageview('/external/bugs.eclipse.org/bugs/show_bug.cgi');" >Bug 284650</a>).</p>
<p>Making a step back and thinking about the usage of the method above, I realized that it can be reduced to the usage of core expressions instead of the simple boolean <code>activeByDefault</code> attribute. Maybe this enhancement could be contributed to the CNF at some point&#8230;</p>
<p>The source code to this post is available for 
<a  href="http://www.techjava.de/wp-content/uploads/rcp-cnf2.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/rcp-cnf2.zip');" >download</a>. It includes two plug-in projects (the CNF and the child content) which are packaged into a small RCP application. Just launch the product included in the CNF plug-in.</p>
<h3>References</h3>
<ul>
<li>
<a  href="http://wiki.eclipse.org/index.php/Common_Navigator_Framework" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/index.php/Common_Navigator_Framework');" >http://wiki.eclipse.org/index.php/Common_Navigator_Framework</a></li>
<li>
<a  href="http://wiki.eclipse.org/Command_Core_Expressions" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/Command_Core_Expressions');" >http://wiki.eclipse.org/Command_Core_Expressions</a></li>
<li>
<a  href="http://wiki.eclipse.org/index.php/Platform_Command_Framework" onclick="javascript:pageTracker._trackPageview('/external/wiki.eclipse.org/index.php/Platform_Command_Framework');" >http://wiki.eclipse.org/index.php/Platform_Command_Framework</a></li>
</ul>
<p>The compass image used in the post is taken from the 
<a  href="http://www.flickr.com/photos/bio_inc/484534267/" onclick="javascript:pageTracker._trackPageview('/external/www.flickr.com/photos/bio_inc/484534267/');" >FlickR gallery</a> of Jean Franco Castro.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/08/eclipse-common-navigator-framework-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Passing Data between Plug-ins</title>
		<link>http://www.techjava.de/topics/2009/07/passing-data-between-plug-ins/</link>
		<comments>http://www.techjava.de/topics/2009/07/passing-data-between-plug-ins/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 20:57:12 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[extension point]]></category>
		<category><![CDATA[pde]]></category>
		<category><![CDATA[plug-in]]></category>
		<category><![CDATA[rcp]]></category>
		<category><![CDATA[schema]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=436</guid>
		<description><![CDATA[Abstract The Eclipse Platform provides a very rich API for the development and configuration of plug-ins and RCPs. It does this in two ways: by providing the corresponding classes and interfaces or by using the extension point mechanism. During the development the question arises, how to develop own extension points and how those plug-in interfaces [...]]]></description>
			<content:encoded><![CDATA[<h2>Abstract</h2>
<p><img src="http://www.techjava.de/wp-content/uploads/imp_extplug_wiz.png" alt="Passing Data between Plug-ins" title="Passing Data between Plug-ins" width="75" height="66" style="margin:10px;float:right;" /><br />
The Eclipse Platform provides a very rich API for the development and configuration of plug-ins and RCPs. It does this in two ways: by providing the corresponding classes and interfaces or by using the extension point mechanism. During the development the question arises, how to develop own extension points and how those plug-in interfaces look like. This article summarizes some of my experiences with developing plug-ins extension points.</p>
<h2>Introduction</h2>
<p>The extensive use of extension points is the standard approach during the development of own plug-ins and Eclipse-based applications. Especially, in the 3.x branch, the Eclipse Developers introduced tons of new extension points, primarily for the user interface, moving towards the declarative definition of the UI. Even if the the topic of the definition of extension points is covered in several 
<a  href="http://www.amazon.de/Contributing-Eclipse-Principles-Patterns-Plug-Ins/dp/0321205758" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.de/Contributing-Eclipse-Principles-Patterns-Plug-Ins/dp/0321205758');" >books</a> and 
<a  href="http://www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html');" >articles</a>, it is a bit challenging to come up with a clean extension point design for a particular scenarios, especially for beginners. This has to do with the specific way, how the Eclipse platform handles extensions.</p>
<p>In order to have a concrete scenario, lets assume that a small RCP application consisting of two plug-ins is being developed. The application prints out the time every ten seconds. One plug-in is responsible for the functionality of the time generation (lets call it the Core plug-in) and another, for the presentation of the results of the first one (lets call it UI plug-in). The separation of code in UI and non-UI plug-ins is a common practice and the standard question is, how to to pass data between the two. In general we assume, that the UI plug-in depends on the Core plug-in.<br />
<span id="more-436"></span><br />
In the following the different alternatives are discussed.</p>
<h2>Call me synchronously</h2>
<p>One of the most simple and common cases is the situation, in which the UI plug-in has the control and needs to call a method on some instance of the Core plug-in. This happens particularly in cases, in which a command handler or an action implemented in the UI plug-in is invoked on behalf of user interaction and the functionality of the Core plug-in is called. The only thing to do is to add the classes to the exported by the Core plug-in. Since the UI plug-in depends on Core, the classes will become visible (in terms of OSGi) and can be imported and used directly. If the method is synchronous, the result can be received upon the completion of the method and displayed by the UI plug-in. In this case the plug-in boundary disappears.</p>
<h2>Call me asynchronously</h2>
<p>The things get more complicated, if the call is not synchronous, but is invoked inside of a <code>IWorkspaceRunnable</code> or a <code>Job</code>. This situation is common in enterprise scenarios, when the invoked functionality is a long running operation, like loading data from a database or accessing a resource over the network. The signatures of the methods for those operations do not provide a possibility to get the invocation result.</p>
<pre class="brush: java; title: ; notranslate">
public interface IWorkspaceRunnable {
    public void run(IProgressMonitor monitor) throws CoreException;
}
</pre>
<pre class="brush: java; title: ; notranslate">
public abstract class Job extends InternalJob implements IAdaptable {
    protected abstract IStatus run(IProgressMonitor monitor);
}
</pre>
<p>In fact the method invocation of asynchronous calls can be performed from any plug-in (so not only UI) and it does not play any role for the result. Thus, this case can be discussed together with the case, in which the Core plug-in broadcasts the data change.</p>
<h2>Don&#8217;t call us, we will call you</h2>
<p>Another case, which can be seen as a general extension of the asynchronous case is if the state changes, and consequently the UI change originates from the Core plug-in. This use case is possible if there are several UI plug-ins working with one Core plug-in, and the changes inside of the Core plug-in have to be propagated to the views, following the well-known Model-View-Controller Design Pattern. Then, a common approach is the implementation of the Listener-Broadcaster Design Pattern. The UI plug-ins (Views) should register themselves as listeners by the Core plug-ins and will be notified on changes of its (Model) state. In this case the extension point mechanism of Eclipse can be used as discussed in the following. It is also a good idea, to hide the code dealing with Eclipse Extension Registry and extensions, so a simple implementation of the broadcaster is provided, too.</p>
<h3>Definition of the extension point (Core plug-in side)</h3>
<p>The definition of extension point for the listener/broadcaster case involves four steps:</p>
<ul>
<li>Creation of the listener interface</li>
<li>Registration of the extension point</li>
<li>Creation of the extension point schema</li>
<li>Implementation of the broadcaster</li>
</ul>
<p>The so defined extension point can be used by plug-ins, which then provide implementations of the listener interface. The broadcaster, located in the Core plug-in is responsible for sending the data to them. Note, that providing the implementation of the listener via extension point <strong>is logically equivalent to the creation of a factory</strong> which is responsible for the production of listeners. The Core plug-in has the control of how this factory is used, how many listeners (from each extension) are created, and when these are notified.</p>
<h4>Creation of the listener interface</h4>
<p>The interface for the listener is usually very simple. It provides a method, which is called by the broadcaster, e.G:</p>
<pre class="brush: java; title: ; notranslate">
public interface ISimpleListener
{
    public void eventOccured();
}
</pre>
<p>Sometimes the method takes parameters, like <code>public void eventOccured(String message)</code> or <code>public void eventOccured(ISimpleEvent event)</code> and sometimes it returns a value. In general, the signature of the notification method is application-specific and will not be discussed further. Since the implementers of the listener does not have control over the way, how and when this method is used, it is advised to add two life-cycle methods to the interface <code>initialize()</code> and <code>terminate()</code>:</p>
<pre class="brush: java; title: ; notranslate">
package de.techjava.rcp.plugins.core.listener;

/**
 * A simple listener
 * @author Simon Zambrovski, TechJava Group
 */
public interface ISimpleListener
{
    /**
     * Initialization life-cycle method
     */
    public void initialize(Object source);

    /**
     * Signals the event occurrence
     * @param event
     */
    public void eventOccured(SimpleEvent event);

    /**
     * Termination life-cycle method
     */
    public void terminate();
}
</pre>
<p>The life-cycle of the listener is then defined as follows: first, its parameter-less constructor is called, then the <code>initialize</code> method is invoked, providing the ability to hook into some infrastructure inside of the implementing plug-in. After the initialization, the <code>eventOccured</code> method is called multiple times. Finally, the listener is informed about the fact that the source will not send any information by the invocation of the <code>terminate</code> method. The <code>source</code> parameter of the <code>ISimpleListener#initialize(Object)</code> method again is application specific and should be chosen that way, that the listener is able to determine the source of events. Alternatively, the method <code>ISimpleListener#eventOccured(SimpleEvent)</code> can carry this information on every invocation, either in the <code>SimpleEvent</code> object or as additional parameter.</p>
<h4>Registration of the extension point</h4>
<p>After the Java interface of the listener has been created, the extension point can be defined. The easiest way to this, is to use the Plug-In Manifest Editor &gt; Extension Points, but you can edit the <code>plugin.xml</code> directly. Basically, three values are required: <code>id</code>, <code>name</code> and <code>schema location</code>.<br />
<img class="alignnone" style="margin: 5px;" title="extension-point-wizard" src="http://www.techjava.de/wp-content/uploads/extension-point-wizard.png" alt="extension-point-wizard" width="435" height="311" /></p>
<p>The corresponding <code>plugin.xml</code> code looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;?eclipse version=&quot;3.5&quot;?&gt;
&lt;plugin&gt;
   &lt;extension-point
      id=&quot;de.techjava.rcp.plugins.core.listener&quot;
   	  name=&quot;Simple Core Listener&quot;
   	  schema=&quot;schema/org.techjava.rcp.plugins.core.listener.exsd&quot;/&gt;
&lt;/plugin&gt;
</pre>
<p>Since the dependent plug-ins should implement the <code>ISimpleListener</code> interface, the containing package  has to be exposed. This can be done either by adding the package to the list of exported packages using the Plug-In Manifest Editor &gt; Runtime &gt; Exported Packages or by simple editing of the <code>MANIFEST.MF</code> file and adding the following line to it:</p>
<pre class="brush: xml; title: ; notranslate">
Export-Package: de.techjava.rcp.plugins.core.listener
</pre>
<h4>Creation of the extension point schema</h4>
<p>The definition of the extension point is performed by creation of the XML-Schema document, describing the structure and the data of the extension point. The Eclipse IDE provides a convenient Extension Point Schema Editor for this task, implemented as multi-page editor with master-detail page for schema definition. The creation wizard already creates the extension element. What has to be done is this:</p>
<ul>
<li>Create <code>New Element</code></li>
<li>Provide an adequate <code>Name</code> for it (<code>listener</code> in our case)</li>
<li>Add an <code>Attribute</code> to this element</li>
<li>Provide an adequate <code>Name</code> for it (<code>class</code> in our case)</li>
<li>Change the <code>Use</code> to required</li>
<li>Change the <code>Type</code> to <code>java</code></li>
<li>Fill the <code>Implements</code> with the full-qualified name of the listener interface (<code>de.techjava.rcp.plugins.core.listener.ISimpleListener</code>)</li>
<li>Optionally, fill the description</li>
<li>Add a <code>Sequence</code> to the <code>extension</code></li>
<li>Add a reference to the <code>listener</code> to the <code>Sequence</code></li>
<li>Optionally, adjust the multiplicity of the <code>listener</code> element, to allow multiple listeners to be registered using one extension point</li>
</ul>
<p>In the Extension Point Schema Editor the corresponding changes should look like this: <img class="alignnone" style="margin: 5px;" title="extension-point-editor" src="http://www.techjava.de/wp-content/uploads/extension-point-editor1.png" alt="extension-point-editor" width="549" height="419" /></p>
<h4>Implementation of the broadcaster</h4>
<p>After the interface is created and the corresponding extension point is defined, a broadcaster can be implemented. Its purpose is to hide the code related to the use of the Extension Point Registry. For convenience, the broadcaster can implement the same interface as the listeners do (<code>ISimpleListener</code>).</p>
<pre class="brush: java; title: ; notranslate">
/**
 * Simple broadcaster implementing the listener interface
 * @author Simon Zambrovski, TechJava Group
 */
public class SimpleBroadcaster implements ISimpleListener
{

    private static final String POINT_ID = &quot;de.techjava.rcp.plugins.core.listener&quot;;
    private static final String CLASS_ATTRIBUTE = &quot;class&quot;;

    private List&lt;ISimpleListener&gt; listeners = null;

    /**
     * Construct the broadcaster and initializes the listeners registered
     * using {@link de.techjava.rcp.plugins.core.listener} extension
     * point
     */
    public SimpleBroadcaster(Object source)
    {
        // initialize on creation
        initialize(source);
    }

    public void eventOccured(SimpleEvent event)
    {
        // broadcast the events
        for (ISimpleListener listener : this.listeners)
        {
            if (listener != null)
            {
                listener.eventOccured(event);
            }
        }
    }

    public void initialize(Object source)
    {
        // retrieve the registered listeners
        this.listeners = getRegisteredListeners();

        // initialize
        for (ISimpleListener listener : this.listeners)
        {
            if (listener != null)
            {
                listener.initialize(source);
            }
        }
    }

    public void terminate()
    {
        // terminate
        for (ISimpleListener listener : this.listeners)
        {
            if (listener != null)
            {
                listener.terminate();
            }
        }
        this.listeners = null;
    }
...
}
</pre>
<p>The broadcaster holds the list of registered <code>ISimpleListener</code> instances. Its own implementation of the <code>ISimpleListener</code> is trivial and just delegates the calls to the elements of this list. The static method <code>SimpleBroadcaster#getRegisteredListeners()</code> is responsible for querying the registry for the registered extension and looks as follows:</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * Retrieves all registered listeners
     */
    public static List&lt;ISimpleListener&gt; getRegisteredListeners()
    {
        IConfigurationElement[] decls = Platform.getExtensionRegistry().getConfigurationElementsFor(POINT_ID);

        Vector&lt;ISimpleListener&gt; validExtensions = new Vector&lt;ISimpleListener&gt;();
        for (int i = 0; i &lt; decls.length; i++)
        {
            try
            {
                ISimpleListener extension = (ISimpleListener) decls[i].createExecutableExtension(CLASS_ATTRIBUTE);
                validExtensions.add(extension);
            } catch (CoreException e)
            {
                Activator.logError(&quot;Error instatiating the &quot; + POINT_ID + &quot; extension&quot;, e);
            }
        }
        return validExtensions;
    }
</pre>
<h4>Use of the broadcaster</h4>
<p>The use of the broadcaster from the Core plug-in is straight-forward. Here is an example of a job, which periodically sends message containing the time to the  listeners.</p>
<pre class="brush: java; title: ; notranslate">
/**
 * Broadcasts the current time
 * @author Simon Zambrovski
 * @version $Id$
 */
public class SimpleTimeBroadcastJob extends Job
{
    private SimpleDateFormat sdf = new SimpleDateFormat(&quot;yyyy-MM-dd hh:mm:ss&quot;);
    private SimpleBroadcaster broadcaster = null;

    public SimpleTimeBroadcastJob()
    {
        super(&quot;Time Broadcast Job&quot;);
    }

    protected IStatus run(IProgressMonitor monitor)
    {
        try
        {
            broadcaster = new SimpleBroadcaster(this);
            broadcaster.eventOccured(new SimpleEvent(&quot;Curent time in Core is &quot; + sdf.format(new Date())));
            broadcaster.terminate();
            return Status.OK_STATUS;
        } finally
        {
            // restart again in a 10 seconds
            schedule(10 * 1000);
        }
    }
}
</pre>
<p>Now, after the Core part is implemented, we focus on the implementation of the UI part, which receives the events.</p>
<h3>Use of extension point (UI plug-in side)</h3>
<p>The usage of the extension point is simpler than its definition and basically consists of the implementation of the listener interface and its registration. Here is a sample implementation writing to System.out:</p>
<pre class="brush: java; title: ; notranslate">
public class SimpleListener implements ISimpleListener
{
    private Object source;

    public SimpleListener()
    {
    }

    public void eventOccured(SimpleEvent event)
    {
        String message = &quot;Event from &quot; + source.toString() + &quot;: &quot; + event.getMessage();
        System.out.println(message);
    }

    public void initialize(Object source)
    {
        this.source = source;
        System.out.println(&quot;New &quot; + SimpleListener.class.getName() + &quot; listens to &quot; + source.toString());
    }

    public void terminate()
    {
        this.source = null;
        this.consoleStream = null;
        System.out.println(&quot;Listners destroyed&quot;);
    }
}
</pre>
<p>In order to tell the Eclipse Platform about the existence of this implementation, the extension point defined in the Core plug-in and has to be used in the UI plug-in.  For this purpose, the UI plug-in must list the Core plug-in in its <code>Dependencies</code> and define the use of the extension point in the <code>plugin.xml</code>:</p>
<pre class="brush: xml; title: ; notranslate">
   &lt;extension
         point=&quot;de.techjava.rcp.plugins.core.listener&quot;&gt;
      &lt;listener
            class=&quot;de.techjava.rcp.plugins.ui.SimpleListener&quot;&gt;
      &lt;/listener&gt;
   &lt;/extension&gt;
</pre>
<p>That&#8217;s it.</p>
<h2>Example</h2>
<p>The example source for this article is available 
<a  href="http://www.techjava.de/download/examples/rcp-plugins.zip" onclick="javascript:pageTracker._trackPageview('/downloads/download/examples/rcp-plugins.zip');" >here</a>. It is a little bit more elaborate and provides a simple application, which prints the time into the Eclipse Console. I used Eclipse Galileo (3.5.0) &#8211; just copy the two projects into your workspace and run the product.<br />
<img src="http://www.techjava.de/wp-content/uploads/time-rcp1.png" alt="time-rcp" title="time-rcp" width="585" height="265" class="alignnone size-full wp-image-449" style="margin:10px;"/></p>
<h2>References</h2>
<ul>
<li>
<a  href="http://www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html');" >Notes on the Eclipse Plug-in Architecture</a></li>
<li>
<a  href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1248225439&amp;sr=8-2" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=sr_1_2');" >Design Patterns: Elements of Reusable Object-Oriented Software</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/07/passing-data-between-plug-ins/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Packaging Eclipse-based RCP for the use in enterprise context</title>
		<link>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/</link>
		<comments>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 20:00:33 +0000</pubDate>
		<dc:creator>Simon Zambrovski</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Enterprise Systems]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[enterprise systems]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[product]]></category>
		<category><![CDATA[rcp]]></category>

		<guid isPermaLink="false">http://www.techjava.de/?p=394</guid>
		<description><![CDATA[Abstract Using Eclipse-based rich-clients as stand-alone applications is discussed in many books and articles. In the context of enterprise systems, the software development adopted several paradigms to improve the quality of the overall architecture. This short article describes some issues in packaging the application for using it in the context of enterprise systems. Architectural Assumptions [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin: 5px; float: right" title="Packaging" src="http://www.techjava.de/wp-content/uploads/packaging.jpg" alt="Packaging" width="120" height="120" /></p>
<h2>Abstract</h2>
<p>Using Eclipse-based rich-clients as stand-alone applications is discussed in many 
<a  href="http://www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612');" >books</a> and 
<a  href="http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html" onclick="javascript:pageTracker._trackPageview('/external/www.eclipse.org/articles/Article-RCP-1/tutorial1.html');" >articles</a>. In the context of enterprise systems, the software development adopted several paradigms to improve the quality of the overall architecture. This short article describes some issues in packaging the application for using it in the context of enterprise systems.</p>
<h2>Architectural Assumptions</h2>
<p>Designing enterprise architectures is a standard discipline for IT-consulting companies or freelancers involved in software development. Maybe one of the main characteristics of enterprise architectures is the framework-driven approach of software creation. Thus, the software has to comply certain rules and standards adopted inside the enterprise. In order to simplify such constrained development process, it is common to use an in-house software framework, which enforces the  compliance of the enterprise-internal standards and acts as glue between different technologies adopted as parts of the enterprise architecture.</p>
<p>Using such frameworks has major implications for the software development in general, and especially for the rich client development. The design issues are summarized in the next section.</p>
<h2>Usaging an Enterprise Framework</h2>
<p>The major goal of the enterprise in-house framework is to simplify the process of software systems development and to enforce standardization among the software systems. This usually includes the following aspects:</p>
<ul>
<li>Domain-specific component framework</li>
<li>Methods for master data management</li>
<li>Infrastructure services: authentication, authorization, communication, security, printing, reporting</li>
<li>Application skeletons and launchers</li>
</ul>
<p>The more unification and standardization is included inside the framework, the easier it is for a software developer to concentrate on the particular business task and the easier is the maintenance of the software system.</p>
<p>From the previous list, the most interesting part related to RCP packaging and deployment is the existence of the application skeletons and launchers. So, when launching an application, the framework libraries are loaded and executed first and pass the control to the application-specific modules. The advantage of this approach is that infrastructure services can be loaded first, which can be developed and shared among different applications.<br />
<span id="more-394"></span></p>
<h2>The required plug-ins</h2>
<p>Following the general idea of RCP packaging (see rules provided in the 
<a  href="http://www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612" onclick="javascript:pageTracker._trackPageview('/external/www.amazon.com/Eclipse-Rich-Client-Platform-Applications/dp/0321334612');" >RCP Book</a>) and assuming one target platform (in terms of one RCP product), <strong>one top-level plug-in and should be defined</strong>. In addition, we assume at least one <strong>in-house framework plug-in</strong> and at least <strong>one application-specific plug-in</strong>. Usually there will be more of each type, but it will not change the picture much. Important at this point is the fact, that the application-specific code depends on the in-house framework code. In order to simplify the identification of the plug-ins, an example project is introduced. Let’s assume the project is called <strong>FooBar</strong>. Then, the plug-ins are called:</p>
<ul>
<li><code>de.techjava.foobar</code>: This is the functional plug-in, which contains the application-specific code.</li>
<li><code>de.techjava.framework</code>: This is the framework plug-in, which contains framework component code.</li>
<li><code>de.techjava.foobar.product.standalone</code>: This is an application and product definition plug-in which contains the definition of the product and application-agnostic code for launching the application.</li>
</ul>
<h2>Managing plug-in dependencies</h2>
<p>A difficult issue for the RCP beginners is the management of dependencies between plug-ins. Especially, the transition from the development of a single plug-in to the configuration of features and products seem to be non-trivial. In order to solve this problem, there are simple rules to follow. You can violate these rules in sophisticated scenarios, but for the beginners it is a good idea to follow them.</p>
<ol>
<li><em>Create dependencies only if you need them</em>. Each plug-in should only list plug-ins (or even better packages) it really depends on. Make sure to check it with the “<strong>Find unused dependencies</strong>” action available on the right-click in the Dependencies Tab of the Plug-in Manifest Editor.</li>
<li><em>Use versioning information. </em>Plug-ins (or better bundles, or as 
<a  href="http://www.aniszczyk.org/" onclick="javascript:pageTracker._trackPageview('/external/www.aniszczyk.org/');" >Chris</a> call them Plundles) provide version information. And it is highly advisable to include them in the import statements of the plug-ins, which simplifies the migration later on…</li>
<li><em>Don’t forget anything</em>. Every Plug-in should appear in at least in one Plug-In section of the Feature definition. Every feature should be included by another feature, higher in the hierarchy.</li>
<li><em>Keep the hierarchy flat</em>. For simple scenarios, it is sufficient to have two levels of features (top-level feature, one per-product and the underlying features include their plug-ins).</li>
<li><em>Don’t re-export dependencies</em>. Every Feature for a group of plug-ins should also include plug-ins required by the members of the group. It does not hurt if a plug-in is included several times, but it does if it is not included at all. You can optimize here if you check which plug-ins are imported by the Eclipse RCP feature (which can be considered as stable), but it does not make assumptions about features developed by third parties.</li>
</ol>
<p>Following these rules it is simple to create features for the corresponding plug-ins. Several plug-ins which belong together and are handled as a fixed piece can be grouped into Features. Usaging Features is highly advisable, and sometimes simply required (e.G. by RCP in a Java Web Start target deployment strategy). So in addition to the previously mentioned plug-in projects, at least three feature projects are required:</p>
<ul>
<li><code>de.techjava.foobar.feature</code>: This is a functional feature, which includes the <code>de.techjava.foobar</code> plug-in and all plug-ins required by it, which do not appear in the Eclipse RCP feature</li>
<li><code>de.techjava.framework.feature</code>: This is a framework feature, which includes the <code>de.techjava.framework</code> plug-in and all plug-ins required by it, which do not appear in the Eclipse RCP feature</li>
<li><code>de.techjava.foobar.feature.standalone</code> This is the top level feature, which is used for the product configuration. <strong>It includes the two features above and the Eclipse RCP feature </strong>(and optional other features used, like e.G. org.eclipse.help). <strong>It also includes exactly one plug-in</strong>, which is not included anywhere else: <code>de.techjava.foobar.standalone.product</code></li>
</ul>
<h2>The product definition plug-in</h2>
<p>The definition of the product is spread among several files. First of all the plug-in.xml of the <code>de.techjava.foobar.standalone.product</code> plug-in makes uses of two extensions:</p>
<ul>
<li><code>org.eclipse.core.runtime.applications</code></li>
<li><code>org.eclipse.core.runtime.products</code></li>
</ul>
<p>The application extension point is used to point to the Java class implementing the interface <code>org.eclipse.equinox.app.IApplication</code>. Along with this implementation, other classes needed to start up the RCP (like Advisors, etc…) are placed into the source directory of the plug-in. The product extension point is used for the association of the application with a product id. The previously-defined top-level feature includes all required features and the product definition plug-in. Finally, the <code>.product</code> file is the place, where all things are bound together: product id, application id, launcher parameters, and the one top level feature: <code>de.techjava.foobar.feature.standalone</code>. Other customization of the RCP is possible from the <code>plugin-customization.ini</code>, which is placed together with the <code>.product</code> file into the plug-in root directory.</p>
<p><img class="alignnone size-full" style="margin:10px;" title="Product configuration" src="http://www.techjava.de/wp-content/uploads/product_feature_plugin1.png" alt="Product configuration" width="385" height="499" /><br />
As a result the following configuration should be achieved after the packaging is finished. The product references the product-id and the application, defined in the plugin.xml of the plug-in project it is contained in. The product configuration is feature-based and includes one top-level feature. The top-level feature includes all other features (functional, framework, Eclipse RCP, other optional) and the one plugin, in which the product file resides.</p>
<p>The simple example provided in this articles is available as sourcecode for download (
<a  href="http://www.techjava.de/download/examples/rcp-packaging.zip" onclick="javascript:pageTracker._trackPageview('/downloads/download/examples/rcp-packaging.zip');" >rcp-packaging.zip</a>).</p>
<h2>The framework hooks</h2>
<p>In the introduced scenario, the packaging is not specific to the in-house framework. It just includes the feature containing the framework plug-in. This approach works fine, if the framework is used in a white-box manner, which means that the framework provides ready-to-use components to be plugged-in to the application (like e.G. a component for the master data management). The other type of frameworks is the so-called black-box framework, which provides components that have to be configured and integrated into the application components. In this case, the framework components can not be plugged-in using some declarative extension points, but need to be called from the application code. In the latter case, the dependencies appear between the plug-in launching the application (<code>de.techjava.foobar.standalone.product</code>) and the framework plug-ins. This requires a modification in the previous setup and the violation of one of the rules posted above. The plug-in has to define the dependency to the framework plug-in, but the top-level feature does not include the required plug-in directly, but imports the whole framework feature.</p>
<p></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">Technorati-Tags: 
<a rel="tag"  href="http://technorati.com/tags/eclipse" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/eclipse');" >eclipse</a>,
<a rel="tag"  href="http://technorati.com/tags/java" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/java');" >java</a>,
<a rel="tag"  href="http://technorati.com/tags/rcp" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/rcp');" >rcp</a>,
<a rel="tag"  href="http://technorati.com/tags/packaging" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/packaging');" >packaging</a>,
<a rel="tag"  href="http://technorati.com/tags/plugin" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/plugin');" >plugin</a>,
<a rel="tag"  href="http://technorati.com/tags/feature" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/feature');" >feature</a>,
<a rel="tag"  href="http://technorati.com/tags/product" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/product');" >product</a>,
<a rel="tag"  href="http://technorati.com/tags/enterprise+systems" onclick="javascript:pageTracker._trackPageview('/external/technorati.com/tags/enterprise+systems');" >enterprise systems</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.techjava.de/topics/2009/07/packaging-eclipse-based-rcp-for-the-use-in-enterprise-context/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
