第三十八章. Eclipse 插件

Chapter 38. The Eclipse Plugin

Eclipse 插件生成 Eclipse IDE 所使用的文件,从而让项目能够导入 Eclipse(File - Import... - Existing Projects into Workspace)。它同时考虑到了外部依赖(包括关联的源代码和 javadoc 文件)及项目依赖。
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.

从 1.0-milestone-4 开始,WTP-generating 代码被重构为一个名为 eclipse-wtp 的单独插件。因此,如果你对 WTP 集成感兴趣,那么可以只应用 eclipse-wtp 插件。否则应用 eclipse 插件就够了。这一变化是 Eclipse 用户请求的,他们想利用 warear 插件,但又不想使用 Eclipse WTP。在内部, eclipse-wtp 也应用了 eclipse 插件,所以你不需要同时应用这两个插件。
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 don't need to apply both of those plugins.

Eclipse 插件生成的内容具体取决于使用的其他插件:
What exactly the Eclipse plugin generates depends on which other plugins are used:

表 38.1. Eclipse 插件行为 - Table 38.1. Eclipse plugin behavior

插件
Plugin
描述
Description
None 生成最小的 .project 文件。
Generates minimal .project file.
Java 添加 Java 配置到 .project。生成 .classpath 和 JDT 设置文件。
Adds Java configuration to .project. Generates .classpath and JDT settings file.
Groovy 添加 Groovy 配置到 .project文件。
Adds Groovy configuration to .project file.
Scala 添加 Scala 支持到 .project.classpath 文件。
Adds Scala support to .project and .classpath files.
War 添加 web 应用程序支持到 .project 文件。仅在应用了 eclipse-wtp 插件时生成 WTP 设置文件。
Adds web application support to .project file. Generates WTP settings files only if eclipse-wtp plugin was applied.
Ear 添加 ear 应用程序支持到 .project 文件。仅在应用了 eclipse-wtp 插件时生成 WTP 设置文件。
Adds ear application support to .project file. Generates WTP settings files only if eclipse-wtp plugin was applied.

Eclipse 插件可以自定义,并提供了一套标准化的钩子,用于添加和删除生成的文件中的内容。
The Eclipse plugin is open to customization and provides a standardized set of hooks for adding and removing content from the generated files.

38.1. 用法

38.1. Usage

要使用 Eclipse 插件,请在构建脚本中包含以下语句:
To use the Eclipse plugin, include this in your build script:

示例 38.1. 使用 Eclipse 插件 - Example 38.1. Using the Eclipse plugin

build.gradle

apply plugin: 'eclipse'

Eclipse插件向你的项目添加了许多任务。你将使用的主要任务是 eclipsecleanEclipse 任务。
The Eclipse plugin adds a number of tasks to your projects. The main tasks that you will use are the eclipse and cleanEclipse tasks.

38.2. 任务

38.2. Tasks

Eclipse 插件向一个项目添加了如下所示的任务。
The Eclipse plugin adds the tasks shown below to a project.

表 38.2. Eclipse 插件——任务 - Table 38.2. Eclipse plugin - tasks

任务名称
Task name
依赖于
Depends on
类型
Type
描述
Description
eclipse eclipseProject, eclipseClasspath, eclipseJdt, eclipseWtpComponent, cleanEclipseWtpFacet Task 生成所有的 Eclipse 配置文件
Generates all Eclipse configuration files
cleanEclipse cleanEclipseProject, cleanEclipseClasspath, cleanEclipseJdt, cleanEclipseWtpComponent, cleanEclipseWtpFacet Delete 删除所有的 Eclipse 配置文件
Removes all Eclipse configuration files
cleanEclipseProject - Delete 删除 .project 文件。
Removes the .project file.
cleanEclipseClasspath - Delete 删除 .classpath 文件。
Removes the .classpath file.
cleanEclipseJdt - Delete 删除 .settings/org.eclipse.jdt.core.prefs 文件。
Removes the .settings/org.eclipse.jdt.core.prefs file.
cleanEclipseWtpComponent - Delete 删除 .settings/org.eclipse.wst.common.component 文件。
Removes the .settings/org.eclipse.wst.common.component file.
cleanEclipseWtpFacet - Delete 删除 .settings/org.eclipse.wst.common.component 文件。
Removes the .settings/org.eclipse.wst.common.component file.
eclipseProject - GenerateEclipseProject 生成 .project 文件。
Generates the .project file.
eclipseClasspath - GenerateEclipseClasspath 生成 .classpath 文件。
Generates the .classpath file.
eclipseJdt - GenerateEclipseJdt 生成 .settings/org.eclipse.jdt.core.prefs 文件。
Generates the .settings/org.eclipse.jdt.core.prefs file.
eclipseWtpComponent - GenerateEclipseWtpComponent 只有当 eclipse-wtp 插件被应用的时候,生成 .settings/org.eclipse.wst.common.component 文件。
Generates the .settings/org.eclipse.wst.common.component file only if eclipse-wtp plugin was applied.
eclipseWtpFacet - GenerateEclipseWtpFacet 只有当 eclipse-wtp 插件应用的时候,生成 .settings/org.eclipse.wst.common.project.facet.core.xml 文件。
Generates the .settings/org.eclipse.wst.common.project.facet.core.xml file only if eclipse-wtp plugin was applied.

38.3. 配置

38.3. Configuration

表 38.3. Eclipse 插件的配置 - Table 38.3. Configuration of the Eclipse plugin

模型
Model
引用名称
Reference name
描述
Description
EclipseModel eclipse 顶级元素,支持以 DSL 友好的方式配置 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 允许配置 jdt 信息(source/target java 兼容性)
Allows configuring jdt information (source/target java compatibility)
EclipseWtpComponent eclipse.wtp.component 仅当 eclipse-wtp 插件被应用时,允许配置 wtp 组件信息。
Allows configuring wtp component information only if eclipse-wtp plugin was applied.
EclipseWtpFacet eclipse.wtp.facet 仅当 eclipse-wtp 插件被应用时,允许配置 wtp 方面的信息。
Allows configuring wtp facet information only if eclipse-wtp plugin was applied.

38.4. 自定义生成的文件

38.4. Customizing the generated files

Eclipse 插件能够让你自定义生成的元数据文件。该插件提供了一个 DSL,用于配置把项目的 Eclipse 视图模型化的模型对象。然后,这些模型对象与现有的 Eclipse XML 元数据合并,最终生成新的元数据。模型对象提供较低级别的钩子,用于处理表示与模型配置合并前后的文件内容的域对象。它们还提供了一个非常低级别的钩子,用于在持久化之前直接使用原始 XML 进行调整,以进行 Eclipse 插件不建模的微调和配置。
The Eclipse plugin allows you to customize the generated metadata files. The plugin provides a DSL for configuring model objects that model the Eclipse view of the project. These model objects are then merged with the existing Eclipse XML metadata to ultimately generate new metadata. The model objects provide lower level hooks for working with domain objects representing the file content before and after merging with the model configuration. They also provide a very low level hook for working directly with the raw XML for adjustment before it is persisted, for fine tuning and configuration that the Eclipse plugin does not model.

38.4.1. 合并

38.4.1. Merging

已存在的 Eclipse 文件的部分,也是生成的目标内容,将会被修改或覆盖,具体取决于特定的部分。其余部分将保持原样。
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.

38.4.1.1. 使用完全覆盖禁用合并

38.4.1.1. Disabling merging with a complete overwrite

要完全覆盖现有 Eclipse 文件,请执行 clean 任务及其相应的生成任务,例如 gradle cleanEclipse eclipse(按此顺序)。如果要让它成为默认行为,请添加 tasks.eclipse.dependsOn(cleanEclipse) 到构建脚本中。这样我们就不用显式执行清理任务了。
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.

完全覆盖同样可以用于个人文件,例如通过执行 gradle cleanEclipseClasspath eclipseClasspath
Complete overwrite works equally well for individual files, for example by executing gradle cleanEclipseClasspath eclipseClasspath.

38.4.2. Hooking 到生成的生命周期中

38.4.2. Hooking into the generation lifecycle

Eclipse 插件提供了一些对象,对由 Gradle 生成的 Eclipse 文件部分进行建模。生成的生命周期如下:
The Eclipse plugin provides objects modeling the sections of the Eclipse files that are generated by Gradle. The generation lifecycle is as follows:

  1. 读取文件;如果它不存在,则使用由 Gradle 提供的默认版本
  2. beforeMerged的钩子会使用一个表示现有文件的域对象执行
  3. 从 Gradle 构建推断出来或在 eclipse DSL 中显示定义的配置会与现有的内容合并在一起
  4. whenMerged的钩子会使用一个表示持久化的域对象执行
  5. withXml的钩子会使用一个表示将被持久化的XML的 raw 执行
  6. 最终的 XML 被持久化

下表列出了用于每个 Eclipse 模型类型的域对象:
The following table lists the domain object used for each of the Eclipse model types:

表 38.4. 高级配置钩子 - Table 38.4. Advanced configuration hooks

模型
Model
beforeMerged { arg -> } 参数类型
beforeMerged { arg -> } argument type
whenMerged { arg -> } 参数类型
whenMerged { arg -> } argument type
withXml { arg -> } 参数类型
withXml { arg -> } argument type
EclipseProject Project Project XmlProvider
EclipseClasspath Classpath Classpath XmlProvider
EclipseJdt Jdt Jdt
EclipseWtpComponent WtpComponent WtpComponent XmlProvider
EclipseWtpFacet WtpFacet WtpFacet XmlProvider

38.4.2.1. 部分覆盖现有内容

38.4.2.1. Partial overwrite of existing content

完全覆盖会导致现有的所有内容被丢弃,从而丢失在 IDE 中直接做的任何更改。作为另一种选择,beforeMerged 钩子使得可以只覆盖现有内容的某些部分。以下示例从 Classpath 域对象中删除现有的所有依赖:
A complete overwrite causes all existing content to be discarded, thereby losing any changes made directly in the IDE. Alternatively, 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:

示例 38.2. Classpath 的部分覆盖 - Example 38.2. Partial Overwrite for Classpath

build.gradle

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


所产生的 .classpath 文件将仅包含 Gradle-generated 的依赖项,但不包含可能存在于原始文件中的任何其他依赖。(对于依赖项条目,这也是默认行为。).classpath文件的其余部分将保持原样或合并。对 .project 文件的自然处理了是一样:

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:

示例 38.3. Project 的部分覆盖 - Example 38.3. Partial Overwrite for Project

build.gradle

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


38.4.2.2. 修改完全填充的域对象

38.4.2.2. Modifying the fully populated domain objects

whenMerged 钩子允许操作完全填充的域对象。通常,这是自定义 Eclipse 文件的首选方法。下面的例子展示了如何导出一个 Eclipse 项目的所有依赖:
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:

示例 38.4. 导出依赖 - Example 38.4. Export Dependencies

build.gradle

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


38.4.2.3. 修改 XML 的表示形式

38.4.2.3. Modifying the XML representation

withXml钩子允许在文件写入磁盘之前操作内存中的 XML 表示形式。尽管 Groovy 的 XML 支持对其帮助很大,但这种方法比起操作域对象依然很不方便。作为回报,你可以对生成的文件进行完全的控制,包括未由域对象建模的部分。
The withXmlhook 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.

示例 38.5. 自定义 XML - Example 38.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'
}