You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by hb...@apache.org on 2018/02/05 22:42:48 UTC
svn commit: r1823259 -
/maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt
Author: hboutemy
Date: Mon Feb 5 22:42:48 2018
New Revision: 1823259
URL: http://svn.apache.org/viewvc?rev=1823259&view=rev
Log:
Filled in guide-java-report-plugin-development.apt #11
https://github.com/apache/maven-site/pull/11
Submitted by: Bertrand Martin https://github.com/bertysentry
Modified:
maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt
Modified: maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt
URL: http://svn.apache.org/viewvc/maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt?rev=1823259&r1=1823258&r2=1823259&view=diff
==============================================================================
--- maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt (original)
+++ maven/site/trunk/content/apt/guides/plugin/guide-java-report-plugin-development.apt Mon Feb 5 22:42:48 2018
@@ -2,8 +2,9 @@
Guide to Developing Java Report Plugins
------
Hervé Boutemy
+ Bertrand Martin
------
- 2017-11-16
+ 2018-01-21
------
~~ Licensed to the Apache Software Foundation (ASF) under one
@@ -28,14 +29,488 @@
Introduction
- This guide is intended to assist users in developing Java reporting plugins for
- Maven that will contribute to sites generated by {{{/plugins/maven-site-plugin/}<<<maven-site-plugin>>>}}
+ This guide is intended to assist users in developing reporting plugins for
+ Maven in Java that will contribute to sites generated by {{{/plugins/maven-site-plugin/}<<<maven-site-plugin>>>}}
or site pdf documents generated by {{{/plugins/maven-pdf-plugin/}<<<maven-pdf-site>>>}}.
- Any Mojo becomes a <report> Mojo when it implements {{{/shared/maven-reporting-api/}Maven Reporting API}}. Then a plugin
- may have some reporting goals and some build (non-reporting) goals.
+ First and foremost, a <report plugin> is a <Maven plugin> and it is strongly advised to first read the
+ {{{./guide-java-plugin-development.html}Guide to Developing Java Plugins}} to properly understand
+ its core mechanisms.
- Work In Progress (external reports, Doxia Sink API vs generated markup in <<<target/generated-site/>>>)...
+ A plugin is actually not a <report plugin> in itself. But one (or several) of its goals or <Mojos> may be
+ specialized to be invoked by {{{/plugins/maven-site-plugin/}<<<maven-site-plugin>>>}}, typically during the
+ <<<site>>> build life cycle.
+
+ A Maven plugin can therefore implement <regular> goals and <report> goals. The below details how to write a <Mojo>
+ that will get invoked as a <report> by {{{/plugins/maven-site-plugin/}<<<maven-site-plugin>>>}}.
+
+* How It Works
+
+ [[1]]
+ A regular Maven project usually invokes a <reporting goal> of a plugin by declaring such plugin in the
+ {{{/plugins/maven-site-plugin/examples/configuring-reports.html}<<<<reporting\>>>>}} section of its <<<pom.xml>>> as in the example below:
+
++---
+<project>
+ ...
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>com.mycompany.maven</groupId>
+ <artifactId>simple-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </reporting>
+ ...
++---
+
+ [[2]]
+ When {{{/plugins/maven-site-plugin/}<<<maven-site-plugin>>>}} is invoked (for example with the <<<mvn site>>> command),
+ the specified plugins are loaded and the <executeReport()> method of each class that extends
+ {{{/shared/maven-reporting-impl/apidocs/org/apache/maven/reporting/AbstractMavenReport.html}<AbstractMavenReport>}}
+ is executed.
+
+ [[3]]
+ The <executeReport()> method generates a document through Maven's {{{/doxia/doxia/doxia-sink-api/}Doxia Sink API}}.
+ This document is comprised of basic elements like title, headings, text, links, tables, etc.
+ This is where you will put the logic of your report, assembling elements, based on the content of the Maven project.
+
+ [[4]]
+ These document elements are passed to Doxia to generate an HTML document, which itself gets wrapped into a {{{/skins}Maven Skin}},
+ as specified in the projects {{{/guides/mini/guide-site.html}<<<./src/site/site.xml>>>}}.
+
+ [[5]]
+ The result produces an HTML file in the <<<./target/site>>> directory of your project.
+
+ []
+
+ {{{/doxia/doxia-sitetools/doxia-site-renderer/}More details about Doxia Site Renderer}}
+
+* Basic Requirements of a Report <Mojo>
+
+ Each goal or <Mojo> is implemented with a separate Java class. For a <Mojo> to become a <report Mojo>, it needs
+ to extend the {{{/shared/maven-reporting-impl/apidocs/org/apache/maven/reporting/AbstractMavenReport.html}<org.apache.maven.reporting.AbstractMavenReport>}}
+ class (instead of <org.apache.maven.plugin.AbstractMojo> for a regular <Mojo>).
+
+ The class will also need to implement the following methods:
+
+ * <<<public String getOutputName()>>>: returns the name of page that will be produced
+
+ * <<<public String getName(Locale locale)>>>: returns the display name of the report
+
+ * <<<public String getDescription(Locale locale)>>>: returns the description of the report
+
+ * <<<protected void executeReport(Locale locale) throws MavenReportException>>>: produces the actual report
+
+ []
+
+ To build a Maven plugin that includes <report Mojos>, the <<<pom.xml>>> of your project will need declare the project
+ as a regular plugin, and include specific dependencies required by the report <Mojos>:
+
+ * {{{https://mvnrepository.com/artifact/org.apache.maven.reporting/maven-reporting-impl}<<<org.apache.maven.reporting:maven-reporting-impl:3.0.0>>>}}
+
+ * {{{https://mvnrepository.com/artifact/org.apache.maven.reporting/maven-reporting-api}<<<org.apache.maven.reporting:maven-reporting-api:3.0>>>}}
+
+ []
+
+* A (Very) Simple Report
+
+ Let's write a very simple <report Mojo> in a very simple Maven plugin:
+
+ * Plugin's name: <<Simple Plugin>>
+
+ * Plugin's artifact coordinates: <<<com.mycompany.maven:simple-maven-plugin:1.0-SNAPSHOT>>>
+
+ * One goal: <<simple>>
+
+ * One result: <<<simple-report.html>>>
+
+ []
+
+ Our Maven plugin project has 2 files only:
+
+ * <<<./pom.xml>>>
+
+ * <<<./src/main/java/com/mycompany/maven/SimpleReport.java>>>
+
+ []
+
+ The below examples can be copied and pasted as a template.
+
+** ./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>
+ </properties>
+
+ <dependencies>
+ <!-- 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>
+ </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</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",
+ aggregator = false,
+ executionStrategy = "always",
+ defaultPhase = LifecyclePhase.SITE,
+ requiresDependencyResolution = ResolutionScope.RUNTIME,
+ requiresDirectInvocation = false,
+ requiresOnline = false,
+ 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_();
+
+ }
+
+}
++---
+
+** Building the Simple Plugin
+
+ Building the plugin is done by executing the below command in the root directory of the plugin project:
+
++---
+$ mvn clean install
++---
+
+ This command will:
+
+ * erase the content of the <<<./target>>> directory
+
+ * compile your code
+
+ * produces the plugin JAR artifact (<<<./target/simple-maven-plugin-1.0-SNAPSHOT.jar>>>)
+
+ * copy the artifact to your local repository so that it can be "consumed" by other projects (which
+ is the purpose of a plugin, right?).
+
+ []
+
+ To make sure everything went well and is properly declared, you can now execute the below command
+ in any other Maven project directory:
+
++---
+$ 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] ------------------------------------------------------------------------
++---
+
+** Invoking the Simple Plugin
+
+ To invoke the <report Mojo> of our plugin in another Maven project, we just need to declare the plugin in the
+ {{{/plugins/maven-site-plugin/examples/configuring-reports.html}<<<<reporting\>>>>}} section of its <<<pom.xml>>> as in the example below:
+
++---
+<project>
+...
+<reporting>
+ <plugins>
+ <plugin>
+ <groupId>com.mycompany.maven</groupId>
+ <artifactId>simple-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+</reporting>
+...
++---
+
+ Note: When no specific report is specified, all of the <Mojos> in the plugin, that are declared as "reporting" will be executed.
+ {{{/plugins/maven-site-plugin/examples/configuring-reports.html}More information about configuring reports}}.
+
+
+* More Information
+
+** The Doxia Sink API
+
+ In your <executeReport()> method, you will leverage the {{{/doxia/doxia/doxia-sink-api/}Doxia Sink API}}
+ to add elements to the report document.
+
+ You will use the {{{https://maven.apache.org/doxia/doxia/doxia-sink-api/apidocs/org/apache/maven/doxia/sink/Sink.html}<Sink>}} object associated to the report:
+
++---
+Sink sink = getSink();
++---
+
+ This object allows you to append new elements to the report document (initially empty). Unlike some DOM manipulation APIs,
+ you cannot insert elements in already existing elements, or remove elements.
+
+ The elements that you append to the document will look familiar if you have basic knowledge of HTML. Most of the elements
+ have opening and closing tags, like <sink.body()> (opening) and <sink.body_()> (closing).
+
+ * <sink.head()> and <sink.head_()>
+
+ * <sink.paragraph()> and <sink.paragraph_()>
+
+ * <sink.section1()> and <sink.section1_()>
+
+ * <sink.bold()> and <sink.bold_()>
+
+ * etc.
+
+ []
+
+ <<Do not forget to close elements!>>
+
+ At the very least, a document should include the following:
+
+ * Head and title (<sink.head()> and <sink.title()>)
+
+ * Body (<sink.body()>)
+
+ * Section 1 with title (<sink.section1()> and <sink.sectionTitle1()>)
+
+ []
+
+ The {{{/doxia/doxia/doxia-sink-api/apidocs/org/apache/maven/doxia/sink/Sink.html}<Sink>}} object
+ allows you to add raw text with the <rawText()> method. More precisely, it allows you to add raw HTML code into the
+ document for full flexibility. However, you should limit the usage of this method as you may add elements that are not supported
+ by non-HTML renderers (like {{{/plugins/maven-pdf-plugin/}<<<maven-pdf-site>>>}}).
+
+ The Doxia Sink API allows you to specify {{{/doxia/doxia/doxia-sink-api/apidocs/org/apache/maven/doxia/sink/SinkEventAttributes.html}<SinkEventAttributes>}}
+ to each element, i.e. HTML properties, notably the class and the ID of an object, which allows for easy customization
+ with an appropriate CSS (either provided by the specified Maven Skin, or by the project itself).
+
+** Creating more than one document
+
+ You may need to create not just one HTML file, but several of them (like Javadoc produces one HTML file for
+ each Java class). To do so, you will need to get a new <Sink> for each HTML file you need to produce.
+ This is achieved by using the
+ {{{/doxia/doxia/doxia-sink-api/apidocs/org/apache/maven/doxia/sink/SinkFactory.html}<SinkFactory>}} object
+ that you can easily obtain with the
+ {{{/shared/maven-reporting-impl/apidocs/org/apache/maven/reporting/AbstractMavenReport.html#getSinkFactory()}<getSinkFactory()>}}
+ method of your
+ {{{/shared/maven-reporting-impl/apidocs/org/apache/maven/reporting/AbstractMavenReport.html}<AbstractMavenReport>}} instance,
+ as in the example below.
+
++---
+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");
+ ...
++---
+
+ The above example will create a <<<other-report.html>>> HTML file along with <<<simple-report.html>>>.
+
+ Note: Despite the fact that you will be creating additional HTML files, the Velocity variable <<<$currentFileName>>>
+ passed to the <<<site.vm>>> script of the Maven Skin will keep the name of the original report (i.e. the result of
+ your <getOutputName()> method). {{{/doxia/doxia-sitetools/doxia-site-renderer/}More information about the Velocity
+ variables}}.
* Resources