2.3.0

Overview:

Egap is an Eclipse plugin for the Guice dependency injection framework. The latest version is 2.3.0.

Online survey

It would be nice to give me a short feedback by answering this survey. No login/account is required and there are only 3 questions. Thank you for your help.

Compatibility & Error reports

Egap 2.3.0 requires Eclipse >= 4.5(Mars) running under a java runtime in version >= 1.8.

If you discover any errors, then use the ticket system from the sourceforge account: tickets.

Features:

The following features are sorted by (my personal) importance, so that the more important features come first.

  • Jump from an injection point to its binding
  • Create an @Inject field declaration from a snippet
  • Create a binding for an injection point
  • Convert an injection point to a Provider and vice versa
  • Convert a "new X()" statement to a "providerX.get()" statement
  • Create the factory interface for an @Assisted annotated constructor
  • Create the binding definition for a factory interface
  • Create a new Guice AbstractModule from an existing type
  • Install a Guice module in a parent module

Changes from version 2.2.6 to 2.3.0

  • Binding creation has been improved by using a dialog. You can create a linked binding or a provider method using this mechanism.
  • Improved feedback by showing an info box in several cases (e.g if a jump cannot be performed), so you better know why something does not work the way you expected it (Previously the message was shown in the status bar).
  • The 'Ctrl+Shift+v, g' shortcut has been overloaded to support the snippet creation and the 'newX to providerX.get()' feature.
  • As always: Removed a lot of bugs.

Update Site

http://jaculon.de/updatesite

The simplest way to install egap is by using this update site. In Eclipse go to "Help/Install new Software..." and enter the update site address.

Download:

You can download the latest egap version 2.3.0 from here. Here's the previous version 2.2.6.

Unzip the contents of the zip file in eclipses /dropin folder then restart Eclipse. Check that egap is displayed in the eclipse preferences:

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. This is an important step, as only egap enabled projects are added to the index and this index is used for the most of egap's operations (e.g the jump to the binding). 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

This is best explained in an example:

image

If we would like to see the binding for the injection point "jackThePianoPlayer" then we must put the cursor on the "jackThePianoPlayer" variable (on means: the cursor can be set before, in the middle or at the end of the variable, it doesn't matter) and hit Ctrl+Shift+v, g. This should take us to the binding as defined in a guice module:

image

The jump will also work if you use constructor injection, but you must ensure that the parameter names (in the constructor) are equal to the field names. The following example is analyzable by egap as the parameter name 'jackThePianoPlayer' is equal to the field name.

image

Setter injection is not supported.

Egap recognizes both @Inject annotations: The javax.inject.Inject(JSR-330) annotation and the com.google.inject.Inject(Guice) annotation.

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

In General: Hitting Ctrl+Shift+V g multiple times will cycle you through all available bindings and finally take you back from where you started.

If egap could not find a binding then it will tell you by showing a popup window:

image

Sometimes egap will tell you:

image

or:

image

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 for seed.

image

Create a binding for an injection point

With this quick fix you can create a linked binding or a provider method for an injection point.

Example 1: Creating a linked binding

If we put the cursor on the "iPianoPlayer" field and trigger the quickfix "Create a binding for 'iPianoPlayer'":

image

then the following dialog will be shown:

image

I think(and hope) that the dialog is self-explanatory for anyone familiar with the guice binding api.

The top area displays if there were any existing bindings found. If there are existing bindings then an arrow button is displayed, which will take you to the binding if you press it. Pressing the button multiple times will cycle you through all existing bindings and finally takes you back from where you started.

image

Ok, now let's continue from our example by choosing an implementation type (JazzPianoPlayer) and the guice module (BarModule) where the generated binding should be inserted into. Both items are mandatory. The implementation type can be selected from the drop down box named 'to'. If there is only one implementation available it will be automatically selected. You can also choose the scope here by using the drop down box labeled as 'in Scopes'.

image

Finally we must push the 'Create' button. Then the selected guice module is openend and the cursor is located on the new binding. Bindings are inserted as last statement in the configure method.

image

If you hit 'Create' then the dialog will also show you any missing items(if there are any):

image

Example 2: Creating a provider method

The creation of a provider method is very similar to the creation of a linked binding except that there's another option "Use MembersInjector" displayed and that you can choose the same type for the implementation as for the bound type.

Let's start with a provider method for a customized drink:

image

Hit 'Create':

image

This is what the provider method would look like if the "Use MembersInjector" checkbox was selected:

image

If you would like another modifier than private for the generated method then you can adapt this in the egap preferences.

Create an @Inject field declaration

With this quick fix you can create a new @Inject annotated field from a snippet.

As usual this is most simply explained by an example:

If we put the cursor on the "Drink" snippet and trigger the quickfix "Create @Inject field drink":

image

then a new field 'drink' annotated with @Inject is added to the class. Further the typed name's first letter is converted to lowercase (e.g 'Drink' is renamed to 'drink') and a dialog will inform you about the added field:

image

The quickfix and the command is enabled, if the snippet is a valid java type identifier (e.g it starts with an uppercase letter).

Ok, now let's try another scenario to show you what happens if a Drink already exists. Type 'Drink' again (also note that the existing drink is named martini):

image

and this time hit the shortcut Ctrl+Shift+v, g:

create_drink_04

Egap has recognized that a field of Type 'Drink' already exists and displayed a popup message to inform you about that. Also note that the snippet 'Drink' has been renamed to 'martini' and the cursor has been set to the end of martini. Strange feature? Maybe, but i often find it useful if i'm coding somewhere and need a dependency. This way egap will tell me if there's already a dependency of this type and will also perform the renaming for me.

If you would like another modifier than private for the generated field then you can adapt this in the egap preferences.

You can also use the shortcut Ctrl+Shift+v g for this transformation.

Provider conversion

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

The quickfix is enabled if the cursor is located on the identifier of a field declaration and the field declaration is annotated with @Inject.

Example:

image

will be transformed to:

image

The conversion replaces all references to the field declaration by provider.get() statements.

You can also transform from a Provider to the previous type by invoking "Convert to IPianoPlayer<Bar>":

image

Et voila:

image

Convert a "new X()" statement 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

If you would like another modifier than private for the generated field then you can adapt this in the egap preferences.

You can also use the shortcut Ctrl+Shift+V g for this transformation.

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

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 for a factory interface. The binding statement is added as last statement in the 'configure' method of the chosen 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 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 linked binding in a nearby Guice module

This quickfix has been replaced by the create binding quickfix (in version 2.3.0).

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).
Modifier
Here you can set the modifier which is used if egap creates a new field or method.

Limitations

Throwing Providers are currently not supported.

Egap under the hood

On startup egap will scan your workspace for direct descendants of AbstractModules and PrivateModules. Please note that egap will only scan the projects which own the egap nature (Here is explained how to add the egap nature to a project). Then an analyzer checks every method of the guice module for bindings, provider methods and install statements. These statements are then added to the guice index, which can then be queried e.g by the jump command.

Limitation: The analyzer only understands chained call expressions

Currently the egap plugin is limited in the way that only chained method calls are recognized as bindings.

Example:

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

image

The following binding is not recognizable by egap, as it uses an intermediary binding builder, which the egap analyzer 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

License:

Egap is licensed under the Apache License 2.0.

Credits

Egap uses code from Google's Guice and Guava library.

Egap uses the beautiful icons from Yusuke Kamiyamane and from fam fam. Design comes from Free CSS Templates

Egap uses the JProfiler.

Imprint

Tim Majunke | 36215 Bad Hersfeld | Michael Schnabrich Str. 18 | email