Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Maven User
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<h1>Introduction</h1> <p>Writing a report plugin is very similar to writing any other Mojo Plugin (see e.g. "Better Builds with Maven", Chapter 5 for an introduction into that). The most significant difference is that you do extend the <code>AbstractMavenReport</code> class rather than the <code>AbstractMojo</code> class.</p> <h1>AbstractMavenReport</h1> <p>You need to implement your Mojo as AbstractMavenReport, then you can simply add it to the <plugin> section within the <reporting><plugins> section of your POM and your report will be generated and linked into the Maven site automagically:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> /* * ... * @author me * @goal my-report * @phase site */ public class MyReportMojo extends AbstractMavenReport { /** * Directory where reports will go. * * @parameter expression="${project.reporting.outputDirectory}" * @required * @readonly */ private String outputDirectory; /** * @parameter default-value="${project}" * @required * @readonly */ private MavenProject project; /** * @component * @required * @readonly */ private SiteRenderer siteRenderer; </pre></td></tr></table> <p><br class="atl-forced-newline" /></p> <p>and so on. <code>@phase site</code> binds your plugin to the site lifecycle of the build. You need to implement or override the following methods:</p> <ul> <li><code>public void executeReport(Locale defaultLocale) throws MavenReportException</code> - This method is called during site phase to actually produce your report.</li> <li>Other methods: <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> protected MavenProject getProject() { return project; } protected String getOutputDirectory() { return outputDirectory; } protected Renderer getSiteRenderer() { return siteRenderer; } public String getDescription( Locale locale ) { return getBundle( locale ).getString( "report.myreport.description" ); } public String getName( Locale locale ) { return getBundle( locale ).getString( "report.myreport.name" ); } public String getOutputName() { return "my-report"; } private ResourceBundle getBundle( Locale locale ) { return ResourceBundle.getBundle( "my-report", locale, this.getClass().getClassLoader() ); } </pre></td></tr></table> <br class="atl-forced-newline" /> <br class="atl-forced-newline" /> For the use of getBundle() you need to provide a resource bundle in <code>src/main/resources/my-report.properties</code> that contains the necessary keys for your plugin, e.g. <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> report.dashboard.name=Dashboard Report report.dashboard.description=Dashboard Report of the Project. report.dashboard.header=Dashboard Report ... </pre></td></tr></table> <br class="atl-forced-newline" /> <br class="atl-forced-newline" /> <strong>Note</strong> If you want to create the report without using Doxia, e.g. via XSL transformation from some XML file, then simply add the following method to your Mojo:</li> </ul> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> public boolean isExternalReport() { return true; } </pre></td></tr></table> <p><br class="atl-forced-newline" /></p> <p>Keep in mind that in that case Maven will not be able to include the navigation into your report so you have to leave it out or include it yourself.</p> <h2>Dependencies</h2> <p>You will need the following dependencies to build your report plugin:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <dependency> <groupId>org.apache.maven.reporting</groupId> <artifactId>maven-reporting-api</artifactId> <version>2.0.8</version> </dependency> <dependency> <groupId>org.apache.maven.reporting</groupId> <artifactId>maven-reporting-impl</artifactId> <version>2.0.4.3</version> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> <version>2.0.1</version> </dependency> </pre></td></tr></table> <h1>AbstractMavenReportRenderer</h1> <p>For a relatively straightforward report, you can take advantage of AbstractMavenReportRenderer. </p> <p>This class will handle the basic negotiations with the Doxia sink, setting up the head, title, and body. You implement a renderBody method to fill in the middle. it provides utilities for sections and tables.</p> <h1>Doxia Sink</h1> <p>You also need to use the Doxia Sink API to have complete decoration (ie. menus). That is quite straightforward. You simply import <code>org.apache.maven.doxia.sink.Sink</code> and get an instance by simply calling the class method <code>getSink()</code> (you don't even have to implement it). Then you can do things like that:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> sink.tableCell(); sink.text( "some text" ); sink.tableCell_(); </pre></td></tr></table> <p><br class="atl-forced-newline" /></p> <p>to get <code><td>some text</td></code>.</p> <p>Here is another complete example:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> Sink sink = getSink(); sink.head(); sink.title(); sink.text("FIDL graph report"); sink.title_(); sink.head_(); sink.body(); sink.section1(); sink.sectionTitle1(); sink.text("FIDL automata index"); sink.sectionTitle1_(); sink.lineBreak(); sink.lineBreak(); sink .text("List of behavioral elements with link to graphical representation of FIDL automata."); sink.lineBreak(); makeLinks(sink); sink.section1_(); sink.body_(); sink.flush(); sink.close(); </pre></td></tr></table> <p><br class="atl-forced-newline" /></p> <p>As one can easily see, the Sink API reproduces the major structural elements of HTML (and most other text markup languages). Start tag is denoted by <code>xxxx()</code> method and end of tag by <code>xxxx_()</code> method. You can do pretty much anything you could do with (x)HTML as there is even a <code>rawText()</code> method that outputs exactly what you give it.<br /> Note that the <code>text()</code> method takes care of escaping characters.</p> <p><strong>Caveat:</strong> the sectionning is <em>strict</em> which means that section level 2 must be nested in section 1 etc.</p> <p><strong>Note:</strong> To find out more about the possible markup (that is the available methods) you need to read the sources at <a href="http://svn.apache.org/repos/asf/maven/doxia/doxia/trunk/doxia-sink-api/src/main/java/org/apache/maven/doxia/sink/Sink.java">http://svn.apache.org/repos/asf/maven/doxia/doxia/trunk/doxia-sink-api/src/main/java/org/apache/maven/doxia/sink/Sink.java</a>since there is no documentation on <a href="http://maven.apache.org/doxia/doxia-sink-api/index.html">http://maven.apache.org/doxia/doxia-sink-api/index.html</a> at the moment.</p> <h1>More than one report from one plugin</h1> <p>If you want to have more than one goal in your plugin to generate several reports, simply add another Mojo with its own <code>@goal something</code> tag. From the POM, you can control which goal is executed within the <code><reportSet></code> section as follows:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <reportSets> <reportSet> <configuration/> <reports> <report>goal1</report> <report>goal2</report> </reports> </reportSet> </reportSets> </pre></td></tr></table> <p><br class="atl-forced-newline" /></p> <h1>Examples</h1> <h2>Maven Changes Plugin</h2> <p>One of the best possibilities to understand how reporting works at this level is to have a look into the sources of the Maven Changes Plugin at <a href="https://svn.apache.org/repos/asf/maven/plugins/trunk/maven-changes-plugin/">https://svn.apache.org/repos/asf/maven/plugins/trunk/maven-changes-plugin/</a>(or the current TAG inhttps://svn.apache.org/repos/asf/maven/plugins/tag, if you prefer that). The sources aren't hard to read and it takes little time to understand the mechanism.</p> <h2>GraphGeneratorMojo by Arnaud Bailly</h2> <p>Taken from <a href="http://www.nabble.com/-M2--Is-there-a-guide-how-to-write-Report-Plugins--tf2458030.html#a6850949">http://www.nabble.com/-M2--Is-there-a-guide-how-to-write-Report-Plugins--tf2458030.html#a6850949</a></p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-parameters="borderStyle=solid|title=GraphGeneratorMojo.java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6Ym9yZGVyU3R5bGU9c29saWR8dGl0bGU9R3JhcGhHZW5lcmF0b3JNb2pvLmphdmF9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> /** * */ package fr.lifl.fidl.maven; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Locale; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.siterenderer.Renderer; import org.apache.maven.project.MavenProject; import org.apache.maven.reporting.AbstractMavenReport; import org.apache.maven.reporting.MavenReportException; import fr.lifl.fidl.FIDL; import fr.lifl.fidl.idl3.impl.RootScope; import fr.lifl.fidl.idl3.parser.ParseException; import fr.lifl.parsing.LoggingParserListener; /** * A maven 2.0 plugin for generating images of the automata in a FIDL * descriptor. This plugin is used in the <code>site</code> phase to generate * HTML pages describing the specifications of each automaton in a given set of * files. * * * @author nono * @goal fidl-graph * @phase site */ public class GraphGeneratorMojo extends AbstractMavenReport { /** * The directory containing source code to parse. * * @parameter expression="${basedir}/src/main/fidl" * @required */ private File sourceDir; /** * The list of source files to parse, relative to source directory. * * @parameter * @required */ private List sources; /** * The list of directories to include for import resolution. * * @parameter */ private List includes; /** * The output directory. * * @parameter expression="${project.build.directory}/generated-sources/fidl" * @required */ private File outputDirectory; /** * Format of graphical output. Defaults to png. * * @parameter expression="png" */ private String format = "png"; /** * Generate automaton xml descriptor ? * @parameter expression="false" */ private boolean auto = false; /** * <i>Maven Internal</i>: The Doxia Site Renderer. * * @component */ private Renderer siteRenderer; /** * <i>Maven Internal</i>: The Project descriptor. * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * @return Returns the auto. */ public boolean isAuto() { return auto; } /** * @param auto * The auto to set. */ public void setAuto(boolean auto) { this.auto = auto; } /** * @return Returns the format. */ public String getFormat() { return format; } /** * @param format * The format to set. */ public void setFormat(String format) { this.format = format; } /* * (non-Javadoc) * * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory() */ protected String getOutputDirectory() { return outputDirectory.getAbsolutePath(); } /** * @return Returns the siteRenderer. */ public Renderer getSiteRenderer() { return siteRenderer; } protected MavenProject getProject() { return project; } protected void executeReport(Locale arg0) throws MavenReportException { /* configure parser */ FIDL fidl = new FIDL(); fidl.setIncludes(getIncludes()); fidl.setRoot(new RootScope()); LogWrapper wr = new LogWrapper(getLog()); fidl.addParserListener(new LoggingParserListener(wr)); /* create output */ if (!outputDirectory.exists()) outputDirectory.mkdirs(); /* loop over source files */ for (Iterator it = getSources().iterator(); it.hasNext();) { /* get source file and check it */ String src = (String) it.next(); File f = new File(getSourceDir(), src); if (!f.exists()) { getLog().warn("Source file " + f.getPath() + " does not exist"); continue; } /* input into generator */ FileInputStream fis; try { fis = new FileInputStream(f); getLog().info("Generating documentation from FIDL source " + f); fidl.parse(fis, src); } catch (IOException e) { throw new MavenReportException("Error in opening file stream for " + f, e); } catch (ParseException e) { throw new MavenReportException("Error in generating documentation for " + f, e); } } Sink sink = getSink(); /* generate graphs pages */ GraphGenerator ggen = new GraphGenerator(); ggen.setOutputDir(outputDirectory); ggen.setRoot(fidl.getRoot()); ggen.setLog(getLog()); ggen.setFormat(format); ggen.setAuto(auto); ggen.generate(); /* generate HTML pages */ FIDLHTMLGenerator html = new FIDLHTMLGenerator(); html.setOutputDir(outputDirectory); html.setRoot(fidl.getRoot()); html.setFormat(format); html.setLog(getLog()); try { html.generate(sink); } catch (IOException e) { throw new MavenReportException("Error in generating html report", e); } } public String getOutputName() { return "fidl/index"; } public String getName(Locale arg0) { return "FIDL Graph report"; } public String getDescription(Locale arg0) { return "Generate graph and HTML summary for FIDL specification"; } /** * @return Returns the includes. */ public List getIncludes() { return includes; } /** * @param includes * The includes to set. */ public void setIncludes(List includes) { this.includes = includes; } /** * @return Returns the sourceDir. */ public File getSourceDir() { return sourceDir; } /** * @param sourceDir * The sourceDir to set. */ public void setSourceDir(File sourceDir) { this.sourceDir = sourceDir; } /** * @return Returns the sources. */ public List getSources() { return sources; } /** * @param sources * The sources to set. */ public void setSources(List sources) { this.sources = sources; } /** * @param outputDirectory * The outputDirectory to set. */ public void setOutputDirectory(File outputDirectory) { this.outputDirectory = outputDirectory; } /** * @param siteRenderer * The siteRenderer to set. */ public void setSiteRenderer(Renderer siteRenderer) { this.siteRenderer = siteRenderer; } /** * For testing purpose only. * @param project The project to set. */ public void setProject(MavenProject project) { this.project = project; } } </pre></td></tr></table> <p><br class="atl-forced-newline" /></p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced