Abstract:

Egap is an Eclipse plugin for the Guice dependency injection framework. I hope you like it!
Please note that some operations from Egap (e.g Provider conversions) create or change code. So make sure you have a backup by using a versioning system and check the changes made by Egap. I do not take any responsibility for defects.

Features:

  • Jump from an injection point to its binding definition
  • Convert an injection point to a Provider and vice versa
  • Create a provider method for an injection point
  • Convert a "new X" expression to a "providerX.get()" statement (new in version 2.2.6)
  • Create the factory interface for an @Assisted annotated constructor
  • Create the binding definition for a factory interface
  • Create a linked binding in a nearby Guice module
  • Install a Guice module in a parent module
  • Create a new Guice AbstractModule from an existing type

Changes from version 1.0.125 to 2.2.6

  • Added support for JSR-330, which means you can also use the javax.inject.Inject annotation.
  • Added support for generic injection points
  • Added support for builtin bindings
  • Removed feature to create a Junit 5 testcase. The more unit plugin can do this already better.
  • Removed a lot of bugs.

License:

Egap is licensed under the Apache License 2.0.

Update Site:

http://jaculon.de/updatesite

Download:

You can download the latest Egap version from here.

Copy the jar file in eclipses dropin folder. Restart Eclipse. Check that Egap is displayed in the Eclipse Preferences Dialog:

image

First step: Add the Egap nature to your projects

The first thing you have to do is to enable Egap on java projects that use Guice. To do so you can use the context menu on the java project you wish to add and select "Add Egap Nature":

image

After you have added the nature, Egap will scan the project for guice statements (for details see here). This might last a little and is displayed in the eclipse progress view.

You can also remove the nature by calling "Remove Egap Nature" on a java project.

Jump from an injection point to its binding definition

This is best explained in an example:

image

If we would like to see the binding definition for the injection point "jackThePianoPlayer" then we must put the the cursor on the "jackThePianoPlayer" variable (as in the screenshot above) and hit Ctrl+Shift+V g. This should take us to the binding definition as defined in a guice module:

image

Hitting Ctrl+Shift+V g again will take you to the next binding definition. If you already are at the last binding definition then Egap takes you back to the injection point.

In General: Hitting Ctrl+Shift+V g multiple times will cycle you through all available binding definitions and finally take you back from where you started. If Egap could not find a binding definition then it will tell you in the status bar (e.g No binding definition found for injection point 'jackThePianoPlayer').

You can also jump from the variable declaration of a provider method to its binding definition.

Example:

Put the cursor on the parameter 'seed' and hit Ctrl+Shift+V g.

image

You will be taken to the binding definition for seed.

image

Provider conversion

The provider conversion enables the conversion of an injection from a Provider type to a "non Provider" type and vice versa.

Example:

image

is converted to:

image

from Provider to previous type:

image

Create a provider method for an injection point

With this quick fix you can create a new provider method in a package-module or parent-package-module.

Example:

image

generates the following provider method:

image

Convert a "new X" expression to a "providerX.get()" statement

Example:

Put the cursor on the new keyword and hit ctrl+1:

image

Then apply the transformation by clicking on the "Transform to restaurantProvider.get()" proposal. The result is that the "new Restaurant()" expression has been converted to a "providerRestaurant.get()" expression and a new field declaration has been added to the class:

image

Create a factory interface for an @Assisted constructor

This quick fix lets us create the factory interface for an @Assisted constructor.

The quick fix is displayed if the cursor is located on the type declaration and

  • a constructor with at least one @Assisted annotation exists and
  • the factory interface does not yet exist in the package

Please not that currently only Guice 2.0 binding definitions are supported.

Example:

image

In this case the quick fix enables us to create a factory interface 'RealPaymentFactory'. The name of the factory interface is automatically calculated by appending 'Factory' to the type name (let's call it the source type). The factory interface is created in the same package as the source type:

image

The next step would be to create a binding for the factory interface. This is where the next quick fix can help you.

Create a binding for a factory interface

This quick fix enables us to create the binding definition for a factory interface. The binding statement is added as last statement in the 'configure' method of the choosen Guice module.

The quick fix is displayed if the cursor is located on the type declaration and

  • a constructor with at least one @Assisted annotation exists and
  • the factory interface exists and
  • a Guice module exists in the same package or the parent-package as the source type. There are as many quick fixes displayed as there are Guice modules.

Example:

image

Triggering the quickfix creates the following statement in the EgapSandboxModule:

egap_binding_to_real_payment_factory

Create a linked binding in a nearby Guice module

The quick fix enables you to create a linked binding definition in a package-module or parent-package-module. It is enabled if the cursor is located on a type declaration. A quickfix is displayed for every interface that the type implements.

Example:

Select the type declaration(FipsThePianoPlayer in the example) and hit ctrl+1:

image

As FipsThePianoPlayer implements two interfaces there are also two quickfixes displayed. Triggering the highlighted quickfix generates the following binding definition in the IPianoPlayerModule:

image

Create a Guice module from an existing type

This quick fix let's us create a Guice module from an existing type. The derived Guice module is named as the the type with the 'Module' postfix appended to it. It is created in the same package as the 'Payment' interface.

The quick fix is displayed if

  • the cursor is located on a type declaration and
  • the derived Guice module does not already exist in the package of the source type

Example:

Ok, now let's create a guice module from the 'Payment' interface. Hitting Ctrl+1 on Payment displays the quick fix:

image

After triggering the quickfix the PaymentModule is created.

image

Install a guice module in a parent module

This quick fix is handy if you have created a new module and you want to install it in a parent module.

Example:

image

After triggering the quick fix the 'PaymentModule' is installed in the 'EgapSandboxModule':

screenshot EgapSandboxModule

Create a JUnit 5 testcase from an existing class with dependencies injected as Mockito mocks. New in version 1.0.125.

Has been removed in version 2.2.6 as the more unit plugin (link) provides a similar yet more sophisticated functionality.

Preferences

The Egap preferences are located on the Egap node in the preferences dialog:

egap_preferences

Debug mode
If the debug mode is enabled then more debug messages are generated. You can view the messages in the eclipse error log (Window/Show View/Error Log).

The Egap parser

In the following section i will explain some internals to you.

Parsing guice statements

Only direct descendants of AbstractModules and PrivateModules are currently supported. The parser checks every method of the guice module for binding definitions, provider methods and install statements.

The parser only understands chained call expressions

Currently the Egap plugin is limited in the way that only chained method calls are recognized as binding definitions.

Example:

The following binding definition is recognizable by Egap, as it is implemented as chained call expressions:

image

The following binding definition is not recognizable by Egap, as it uses an intermediary binding builder, which the Egap parser does not support:

image

The implication is that you won't be able to jump to this binding definition.

Glossary

Parent module
A parent module is a Guice module, which is located in the parent package of another module (The child module).

Example:

image

Impressum

Tim Majunke | 53115 Bonn | Kreuzbergweg 16 | email