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