介绍
本指南旨在帮助用户在 Java 中为 Maven 开发报告插件,这些插件将有助于生成的maven-site-plugin
站点或生成的站点 PDF 文档maven-pdf-site
。
首先,报告插件是一个Maven 插件,强烈建议先阅读Java 插件开发指南以正确理解其核心机制。
插件本身实际上并不是报表插件。但是它的一个(或几个)目标或Mojo可能被专门用于调用maven-site-plugin
,通常在site
构建生命周期中。
因此,Maven 插件可以实现常规目标和报告目标。下面详细介绍了如何编写一个Mojo ,它将被.maven-site-plugin
这个怎么运作
- 常规 Maven 项目通常通过在其部分中声明此类插件来调用插件的报告目标,如下例所示:
<reporting>
pom.xml
<project> ... <reporting> <plugins> <plugin> <groupId>com.mycompany.maven</groupId> <artifactId>simple-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> </plugin> </plugins> </reporting> ...
- 当
maven-site-plugin
被调用时(例如使用mvn site
命令),指定的插件被加载并且generate()
每个 Mojo 类的方法MavenReport
被执行。 - 该
generate()
方法通过 Maven 的Doxia Sink API生成一个文档。本文档由标题、标题、文本、链接、表格等基本元素组成。这是您将根据 Maven 项目的内容放置报表逻辑、组装元素的地方。 - 这些文档元素被传递给 Doxia 以生成 HTML 文档,该文档本身被包装到Maven Skin中,如项目中指定的那样
./src/site/site.xml
。 - 结果会在
./target/site
您的项目目录中生成一个 HTML 文件。
报表Mojo的基本要求
每个目标或Mojo都使用单独的 Java 类实现。一个Mojo要成为一个报表 Mojo,它需要实现org.apache.maven.reporting.MavenReport
(除了org.apache.maven.plugin.Mojo
)。
实现接口Mojo
和MavenReport
接口的一种简单方法是扩展由org.apache.maven.reporting.AbstractMavenReport
提供的类maven-reporting-impl
(而不是org.apache.maven.plugin.AbstractMojo
常规Mojo)。
该类将需要实现以下方法:
public String getOutputName()
:返回将要生成的页面的名称public String getName(Locale locale)
:返回报告的显示名称public String getDescription(Locale locale)
:返回报告的描述protected void executeReport(Locale locale) throws MavenReportException
:生成实际报告
要构建包含报告 Mojos的 Maven 插件,pom.xml
您的项目需要将项目声明为常规插件,并包含报告Mojos所需的特定依赖项:
一份(非常)简单的报告
让我们在一个非常简单的 Maven 插件中编写一个非常简单的报告 Mojo :
- 插件名称:简单插件
- 插件的神器坐标:
com.mycompany.maven:simple-maven-plugin:1.0-SNAPSHOT
- 目标一:简单
- 结果之一:
simple-report.html
我们的 Maven 插件项目只有 2 个文件:
./pom.xml
./src/main/java/com/mycompany/maven/SimpleReport.java
以下示例可以作为模板复制和粘贴。
./pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.maven</groupId> <artifactId>simple-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>Simple Plugin</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <doxiaVersion>1.10</doxiaVersion> <doxiaSitetoolsVersion>1.10</doxiaSitetoolsVersion> </properties> <dependencies> <!-- Doxia API and Doxia Sitetools --> <dependency> <groupId>org.apache.maven.doxia</groupId> <artifactId>doxia-sink-api</artifactId> <version>${doxiaVersion}</version> </dependency> <dependency> <groupId>org.apache.maven.doxia</groupId> <artifactId>doxia-site-renderer</artifactId> <version>${doxiaSitetoolsVersion}</version> </dependency> <!-- reporting API --> <dependency> <groupId>org.apache.maven.reporting</groupId> <artifactId>maven-reporting-impl</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.apache.maven.reporting</groupId> <artifactId>maven-reporting-api</artifactId> <version>3.0</version> </dependency> <!-- plugin API and plugin-tools --> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.5.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-utils</artifactId> <version>3.2.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.5.1</version> <configuration> <goalPrefix>simple</goalPrefix> </configuration> <executions> <execution> <id>default-descriptor</id> <phase>process-classes</phase> </execution> <execution> <id>generated-helpmojo</id> <goals> <goal>helpmojo</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
./src/main/java/com/mycompany/maven/SimpleReport.java
package com.mycompany.maven; import java.util.Locale; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.apache.maven.reporting.AbstractMavenReport; import org.apache.maven.reporting.MavenReportException; /** * Builds an simple report page as an example. * * <p> * This example show how easy it is to build your own reporting plugin * (or, for that matter, your own reporting Mojo) * */ @Mojo( name = "simple", defaultPhase = LifecyclePhase.SITE, requiresDependencyResolution = ResolutionScope.RUNTIME, requiresProject = true, threadSafe = true ) public class SimpleReport extends AbstractMavenReport { public String getOutputName() { // This report will generate simple-report.html when invoked in a project with `mvn site` return "simple-report"; } public String getName(Locale locale) { // Name of the report when listed in the project-reports.html page of a project return "Simple Report"; } public String getDescription(Locale locale) { // Description of the report when listed in the project-reports.html page of a project return "This simple report is a very simple report that does nothing but " + "shows off Maven's wonderful reporting capabilities."; } /** * Practical reference to the Maven project */ @Parameter(defaultValue = "${project}", readonly = true) private MavenProject project; @Override protected void executeReport(Locale locale) throws MavenReportException { // Get the logger Log logger = getLog(); // Some info logger.info("Generating " + getOutputName() + ".html" + " for " + project.getName() + " " + project.getVersion()); // Get the Maven Doxia Sink, which will be used to generate the // various elements of the document Sink mainSink = getSink(); if (mainSink == null) { throw new MavenReportException("Could not get the Doxia sink"); } // Page title mainSink.head(); mainSink.title(); mainSink.text("Simple Report for " + project.getName() + " " + project.getVersion()); mainSink.title_(); mainSink.head_(); mainSink.body(); // Heading 1 mainSink.section1(); mainSink.sectionTitle1(); mainSink.text("Simple Report for " + project.getName() + " " + project.getVersion()); mainSink.sectionTitle1_(); // Content mainSink.paragraph(); mainSink.text("This page provides simple information, like its location: "); mainSink.text(project.getBasedir().getAbsolutePath()); mainSink.paragraph_(); // Close mainSink.section1_(); mainSink.body_(); } }
构建简单的插件
通过在插件项目的根目录中执行以下命令来构建插件:
$ mvn install
该命令将:
- 编译你的代码
- 生成插件 JAR 工件 (
./target/simple-maven-plugin-1.0-SNAPSHOT.jar
) - 将工件复制到您的本地存储库,以便其他项目可以“使用”它(这是插件的目的,对吗?)。
为了确保一切顺利并正确声明,您现在可以在任何其他 Maven 项目目录中执行以下命令:
$ mvn com.mycompany.maven:simple-maven-plugin:1.0-SNAPSHOT:help [INFO] --- simple-maven-plugin:1.0-SNAPSHOT:help (default-cli) @ hardware-connectors --- [INFO] Simple Plugin 1.0-SNAPSHOT This plugin has 2 goals: simple:help Display help information on simple-maven-plugin. Call mvn simple:help -Ddetail=true -Dgoal=<goal-name> to display parameter details. simple:simple Builds an simple report page as an example. This example show how easy it is to build your own reporting plugin (or, for that matter, your own reporting Mojo) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
调用简单插件
要在另一个 Maven 项目中调用我们插件的报告 Mojo,我们只需要在其<reporting>
部分中声明插件,pom.xml
如下例所示:
<project> ... <reporting> <plugins> <plugin> <groupId>com.mycompany.maven</groupId> <artifactId>simple-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> </plugin> </plugins> </reporting> ... </项目>
注意:当没有指定特定的报告时,插件中所有声明为“报告”的Mojo都将被执行。有关配置报告的更多信息。
更多信息
Doxia Sink API
在您的executeReport()
方法中,您将利用Doxia Sink API向报告文档添加元素。
您将使用与Sink
报告关联的对象:
Sink sink = getSink();
此对象允许您将新元素附加到报表文档(最初为空)。与某些 DOM 操作 API 不同,您不能在现有元素中插入元素或删除元素。
如果您具有 HTML 的基本知识,您附加到文档的元素看起来很熟悉。大多数元素都有开始和结束标记,例如sink.body()
(开始)和sink.body_()
(结束)。
sink.head()
和sink.head_()
sink.paragraph()
和sink.paragraph_()
sink.section1()
和sink.section1_()
sink.bold()
和sink.bold_()
- 等等。
不要忘记关闭元素!
至少,一份文件应包括以下内容:
- 标题和标题(
sink.head()
和sink.title()
) - 身体 (
sink.body()
) - 第 1 节的标题 (
sink.section1()
和sink.sectionTitle1()
)
该Sink
对象允许您使用rawText()方法添加原始文本。更准确地说,它允许您将原始 HTML 代码添加到文档中以获得完全的灵活性。但是,您应该限制此方法的使用,因为您可能会添加非 HTML 渲染器不支持的元素(如maven-pdf-site
)。
Doxia Sink API 允许您为每个元素指定SinkEventAttributes,即 HTML 属性,特别是对象的类和 ID,这允许使用适当的 CSS(由指定的 Maven 皮肤或项目本身提供)轻松自定义)。
创建多个文档
您可能需要创建的不仅仅是一个 HTML 文件,而是其中的几个(如 Javadoc 为每个 Java 类生成一个 HTML 文件)。为此,您需要为需要生成的每个 HTML 文件获取一个新的接收器。这是通过使用您可以通过您的实例的方法SinkFactory
轻松获得的对象来实现的,如下例所示。getSinkFactory()
AbstractMavenReport
public class SimpleReport extends AbstractMavenReport { ... /** * Where the HTML pages of the report will be created. */ @Parameter( defaultValue = "${project.reporting.outputDirectory}", property = "outputDirectory", required = true ) private File outputDirectory; ... @Override protected void executeReport(Locale locale) throws MavenReportException { ... // Create a new sink String pageFilename = "other-report.html"; Sink otherSink; try { otherSink = getSinkFactory().createSink(outputDirectory, pageFilename); } catch (IOException e) { throw new MavenReportException("Could not create sink for " + pageFilename + " in " + outputDirectory.getAbsolutePath(), e); } // Create the "other" report otherSink.head(); otherSink.title(); otherSink.text("The Other Report"); ...
上面的示例将创建一个other-report.html
HTML 文件以及simple-report.html
.
注意:尽管您将创建额外的 HTML 文件,但$currentFileName
传递给site.vm
Maven 皮肤脚本的 Velocity 变量将保留原始报告的名称(即您的getOutputName()方法的结果)。有关速度变量的更多信息。
资源
- 开发 Java 插件指南:起点,因为报告插件是插件...
- Maven Reporting API:当 Mojo 为站点提供报告时实现的报告 API。
- Maven 报告实现:报告 API 和插件 API 的基本实现。
- Doxia Sink API:生成内容的 API。