# Chapter 29. The Eclipse Plugin

The Eclipse plugin generates files that are used by the Eclipse IDE, thus making it possible to import the project into Eclipse (File - Import... - Existing Projects into Workspace). Both external dependencies (including associated source and javadoc files) and project dependencies are considered.

Since 1.0-milestone-4 WTP-generating code was refactored into a separate plugin called `eclipse-wtp`. So if you are interested in WTP integration then only apply the `eclipse-wtp` plugin. Otherwise applying `eclipse` plugin is enough. This change was requested by eclipse users who take advantage of `war` or `ear` plugin but they don't use eclipse WTP. Internally, `eclipse-wtp` also applies the `eclipse` plugin so you should not apply both of those plugins.

What exactly the Eclipse plugin generates depends on which other plugins are used:

Table 29.1. Eclipse plugin behavior

Plugin | Description
None | Generates minimal `.project` file.
Java | Adds Java configuration to `.project`. Generates `.classpath` and JDT settings file.
Groovy | Adds Groovy configuration to `.project` file.
Scala | Adds Scala support to `.project` file.
War | Adds web application support to `.project` file. Generates WTP settings files only if `eclipse-wtp` plugin was applied.
Ear | Adds ear application support to `.project` file. Generates WTP settings files only if `eclipse-wtp` plugin was applied.

One focus of the Eclipse plugin is to be open to customization. Therfore it provides a standardized set of hooks for adding and removing content from the generated files.

## 29.1. Usage

To use the Eclipse plugin, include this in your build script:

Example 29.1. Using the Eclipse plugin

`build.gradle`

    apply plugin: 'eclipse'

The Eclipse plugin adds a number of tasks to your projects. The main tasks that you will use are the `eclipse` and `cleanEclipse` tasks.

## 29.2. Tasks

The Eclipse plugin adds the tasks shown below to a project.

Table 29.2. Eclipse plugin - tasks

Task name | Depends on | Type | Description
`eclipse` | `eclipseProject`, `eclipseClasspath`, `eclipseJdt`, `eclipseWtpComponent`, `cleanEclipseWtpFacet` | `Task` | Generates all Eclipse configuration files
`cleanEclipse` | `cleanEclipseProject`, `cleanEclipseClasspath`, `cleanEclipseJdt`, `cleanEclipseWtpComponent`, `cleanEclipseWtpFacet` | `Delete` | Removes all Eclipse configuration files
`cleanEclipseProject` | `-` | `Delete` | Removes the `.project` file.
`cleanEclipseClasspath` | `-` | `Delete` | Removes the `.classpath` file.
`cleanEclipseJdt` | `-` | `Delete` | Removes the `.settings/org.eclipse.jdt.core.prefs` file.
`cleanEclipseWtpComponent` | `-` | `Delete` | Removes the `.settings/org.eclipse.wst.common.component` file.
`cleanEclipseWtpFacet` | `-` | `Delete` | Removes the `.settings/org.eclipse.wst.common.component` file.
`eclipseProject` | `-` | `GenerateEclipseProject` | Generates the `.project` file.
`eclipseClasspath` | `-` | `GenerateEclipseClasspath` | Generates the `.classpath` file.
`eclipseJdt` | `-` | `GenerateEclipseJdt` | Generates the `.settings/org.eclipse.jdt.core.prefs` file.
`eclipseWtpComponent` | `-` | `GenerateEclipseWtpComponent` | Generates the `.settings/org.eclipse.wst.common.component` file only if `eclipse-wtp` plugin was applied.
`eclipseWtpFacet` | `-` | `GenerateEclipseWtpFacet` | Generates the `.settings/org.eclipse.wst.common.project.facet.core.xml` file only if `eclipse-wtp` plugin was applied.

## 29.3. Configuration

Table 29.3. Configuration of the eclipse plugin

Model | Reference name | Description
`EclipseModel` | `eclipse` | Top level element that enables configuration of the eclipse plugin in a DSL-friendly fashion
`EclipseProject` | `eclipse.project` | Allows configuring project information
`EclipseClasspath` | `eclipse.classpath` | Allows configuring classpath information
`EclipseJdt` | `eclipse.jdt` | Allows configuring jdt information (source/target java compatibility)
`EclipseWtpComponent` | `eclipse.wtp.component` | Allows configuring wtp component information only if `eclipse-wtp` plugin was applied.
`EclipseWtpFacet` | `eclipse.wtp.facet` | Allows configuring wtp facet information only if `eclipse-wtp` plugin was applied.

## 29.4. Customizing the generated files

The eclipse plugin provides the same hooks and behavior for customizing the generated files.

The tasks recognize existing Eclipse files, and merge them with the generated content.

### 29.4.1. Merging

Sections of existing Eclipse files that are also the target of generated content will be amended or overwritten, depending on the particular section. The remaining sections will be left as-is.

#### 29.4.1.1. Disabling merging with a complete overwrite

To completely overwrite existing Eclipse files, execute a clean task together with its corresponding generation task, for example `gradle cleanEclipse eclipse` (in that order). If you want to make this the default behavior, add `tasks.eclipse.dependsOn(cleanEclipse)` to your build script. This makes it unnecessary to execute the clean task explicitly.

Complete overwrite works equally well for individual files, for example by executing `gradle cleanEclipseClasspath eclipseClasspath`.

### 29.4.2. Hooking into the generation lifecycle

The Eclipse plugin provides domain classes modeling the sections of the Eclipse files that are generated by Gradle. The generation lifecycle is as follows:

1. If there is an existing file, its whole XML content is parsed and stored in memory; otherwise, a default file is used in its place
2. The domain objects are populated with the relevant content of the existing file
3. The `beforeMerged` hook is executed
4. The domain objects are populated with content from Gradle's build model, which may require merging with content from the existing file
5. The `whenMerged` hook is executed
6. All sections modeled by the domain objects are removed from the in-memory XML representation
7. The domain objects inject their content into the in-memory XML representation
8. The `withXml` hook is executed
9. The in-memory XML representation is written to disk

The following table lists the domain object used for each of the Eclipse model types:

Table 29.4. Advanced configuration hooks

Model | `beforeMerged { arg -> }` argument type | `whenMerged { arg -> }` argument type | `withXml { arg -> }` argument type
`EclipseProject` | `Project` | `Project` | `XmlProvider`
`EclipseClasspath` | `Classpath` | `Classpath` | `XmlProvider`
`EclipseJdt` | `Jdt` | `Jdt` |
`EclipseWtpComponent` | `WtpComponent` | `WtpComponent` | `XmlProvider`
`EclipseWtpFacet` | `WtpFacet` | `WtpFacet` | `XmlProvider`

#### 29.4.2.1. Partial overwrite of existing content

A complete overwrite causes all existing content to be discarded, thereby losing any changes made directly in the IDE. The `beforeMerged` hook makes it possible to overwrite just certain parts of the existing content. The following example removes all existing dependencies from the `Classpath` domain object:

Example 29.2. Partial Overwrite for Classpath

`build.gradle`

    eclipse.classpath.file {
        beforeMerged { classpath ->
            classpath.entries.removeAll { entry -> entry.kind == 'lib' || entry.kind == 'var' }
        }
    }

The resulting `.classpath` file will only contain Gradle-generated dependency entries, but not any other dependency entries that may have been present in the original file. (In the case of dependency entries, this is also the default behavior.) Other sections of the `.classpath` file will be either left as-is or merged. The same could be done for the natures in the `.project` file:

Example 29.3. Partial Overwrite for Project

`build.gradle`

    eclipse.project.file.beforeMerged { project ->
        project.natures.clear()
    }

#### 29.4.2.2. Modifying the fully populated domain objects

The `whenMerged` hook allows to manipulate the fully populated domain objects. Often this is the preferred way to customize Eclipse files. Here is how you would export all the dependencies of an Eclipse project:

Example 29.4. Export Dependencies

`build.gradle`

    eclipse.classpath.file {
        whenMerged { classpath ->
            classpath.entries.findAll { entry -> entry.kind == 'lib' }*.exported = false
        }
    }

#### 29.4.2.3. Modifying the XML representation

The `withXml`hook allows to manipulate the in-memory XML representation just before the file gets written to disk. Although Groovy's XML support makes up for a lot, this approach is less convenient than manipulating the domain objects. In return, you get total control over the generated file, including sections not modeled by the domain objects.

Example 29.5. Customizing the XML

`build.gradle`

    apply plugin: 'eclipse-wtp'

    eclipse.wtp.facet.file.withXml { provider ->
        provider.asNode().fixed.find { it.@facet == 'jst.java' }.@facet = 'jst2.java'
    }