JApiCmpReport.java
package japicmp.maven;
import japicmp.config.Options;
import japicmp.output.html.HtmlOutput;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
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.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.RemoteRepository;
import java.io.File;
import java.util.*;
@Mojo(name = "cmp-report", defaultPhase = LifecyclePhase.SITE)
public class JApiCmpReport extends AbstractMavenReport {
@Parameter
Version oldVersion;
@Parameter
List<DependencyDescriptor> oldVersions;
@Parameter
Version newVersion;
@Parameter
List<DependencyDescriptor> newVersions;
@Parameter
ConfigParameters parameter = new ConfigParameters();
@Parameter
List<Dependency> dependencies;
@Parameter
List<Dependency> oldClassPathDependencies;
@Parameter
List<Dependency> newClassPathDependencies;
@Parameter(property = "japicmp.skip", defaultValue = "false")
boolean skip;
@Parameter(property = "japicmp.skipDiffReport")
boolean skipDiffReport;
@Parameter(property = "japicmp.skipHtmlReport")
boolean skipHtmlReport;
@Parameter(property = "japicmp.skipMarkdownReport")
boolean skipMarkdownReport;
@Parameter(property = "japicmp.skipXmlReport")
boolean skipXmlReport;
@Parameter(required = true, property = "project.build.directory")
File projectBuildDir;
@Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true)
List<RemoteRepository> remoteProjectRepositories;
@Parameter(defaultValue = "(,${project.version})", readonly = true)
String versionRangeWithProjectVersion;
@Parameter(defaultValue = "${mojoExecution}", readonly = true)
MojoExecution mojoExecution;
@Component
RepositorySystem repoSystem;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
RepositorySystemSession repoSession;
@Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true)
List<RemoteRepository> remoteRepos;
@Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true)
List<ArtifactRepository> artifactRepositories;
MavenParameters mavenParameters;
PluginParameters pluginParameters;
JApiCmpProcessor processor;
/**
* Default constructor.
*/
public JApiCmpReport() {
/* Intentionally left blank. */
}
/**
* Generate the report depending on the specified locale.
*
* @param locale the wanted locale to return the report's description, could be <code>null</code>.
* @throws MavenReportException if an error occurs
*/
@Override
protected void executeReport(final Locale locale) throws MavenReportException {
mavenParameters = new MavenParameters(this.artifactRepositories, this.project,
this.mojoExecution, this.versionRangeWithProjectVersion,
this.repoSystem, this.repoSession,
this.remoteProjectRepositories);
pluginParameters = new PluginParameters(this.skip,
this.newVersion, this.oldVersion, this.parameter,
this.dependencies, this.projectBuildDir,
this.outputDirectory, true, this.oldVersions,
this.newVersions, this.oldClassPathDependencies,
this.newClassPathDependencies,
new SkipReport(
this.skipDiffReport,
this.skipHtmlReport,
this.skipMarkdownReport,
this.skipXmlReport),
new BreakBuild());
try {
processor = new JApiCmpProcessor(pluginParameters, mavenParameters, getLog());
final Optional<HtmlOutput> htmlOutputOptional = processor.execute();
if (htmlOutputOptional.isPresent()) {
final HtmlOutput htmlOutput = htmlOutputOptional.get();
String htmlString = htmlOutput.getHtml();
htmlString = replaceHtmlTags(htmlString);
writeToSink(htmlString);
}
} catch (Exception e) {
final String msg = "Failed to generate report: " + e.getMessage();
final Sink sink = getSink();
sink.text(msg);
sink.close();
throw new MavenReportException(msg, e);
}
}
private void writeToSink(final String htmlString) {
final Sink sink = getSink();
try {
final String htmlTitle = getHtmlTitle();
if (htmlTitle != null) {
sink.head();
sink.title();
sink.text(pluginParameters.parameter().getHtmlTitle());
sink.title_();
sink.head_();
}
sink.rawText(htmlString);
} finally {
sink.close();
}
}
private static String replaceHtmlTags(final String html) {
String newHtml = html.replaceAll("</?html>", "");
newHtml = newHtml.replaceAll("</?body>", "");
newHtml = newHtml.replaceAll("</?head>", "");
newHtml = newHtml.replaceAll("<title>[^<]*</title>", "");
newHtml = newHtml.replaceAll("<META[^>]*>", "");
return newHtml;
}
private String getHtmlTitle() {
String ret = null;
if (this.parameter.getHtmlTitle() != null) {
ret = pluginParameters.parameter().getHtmlTitle();
}
return ret;
}
/**
* Return the base name used to create report's output file(s).
*
* @return the report's output file(s) base name
*/
@Override
public String getOutputName() {
String ret = "japicmp";
if (this.parameter.getReportLinkName() != null) {
ret = this.parameter.getReportLinkName().replace(' ', '_');
}
return ret;
}
/**
* Return the localized report name.
*
* @param locale the wanted locale to return the report's description, could be <code>null</code>.
* @return the name of the report
*/
@Override
public String getName(final Locale locale) {
String ret = "japicmp";
if (this.parameter.getReportLinkName() != null) {
ret = this.parameter.getReportLinkName();
}
return ret;
}
/**
* Return the localized report description.
*
* @param locale the wanted locale to return the report's description, could be <code>null</code>.
* @return the description of this report
*/
@Override
public String getDescription(final Locale locale) {
String ret = "failed report";
try {
final Options options = processor.getOptions();
if (options != null) {
ret = options.getDifferenceDescription();
}
} catch (MojoFailureException e) {
ret = "failed report: " + e.getMessage();
}
return ret;
}
/**
* Verify some conditions before generate the report. Returns {@code false} if {@code skip} is {@code true}, or if
* {@code skipPomModules} is {@code true} and the project type is {@code pom}. Otherwise, returns {@code true}.
*
* @return {@code true} if report should be generated; otherwise, {@code false}
*/
@Override
public boolean canGenerateReport() {
final boolean skippingPom = this.parameter.getSkipPomModules() && "pom".equalsIgnoreCase(
this.project.getArtifact().getType());
return !this.skip && !skippingPom;
}
}