/*
* Copyright (C) 2011 4th Line GmbH, Switzerland
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fourthline.lemma.maven;
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.MavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.seamless.util.io.IO;
import org.seamless.xhtml.XHTML;
import org.seamless.xhtml.XHTMLElement;
import org.fourthline.lemma.pipeline.javadoc.XHTMLTemplateJavadocPipeline;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
/**
* @author Christian Bauer
* @goal site-manual
* @phase site
* @requiresDependencyResolution test
*/
public class LemmaReport extends LemmaMojo implements MavenReport {
/* ##################################################################################################### */
protected final AbstractMavenReport delegate;
public LemmaReport() {
this.delegate = new AbstractMavenReport() {
@Override
protected Renderer getSiteRenderer() {
return null;
}
@Override
protected String getOutputDirectory() {
return null;
}
@Override
protected MavenProject getProject() {
return LemmaReport.this.getProject();
}
@Override
protected void executeReport(Locale locale) throws MavenReportException {
LemmaReport.this.executeReport(locale);
}
@Override
protected void closeReport() {
LemmaReport.this.closeReport();
super.closeReport();
}
public String getOutputName() {
return LemmaReport.this.getOutputName();
}
public String getName(Locale locale) {
return LemmaReport.this.getName(locale);
}
public String getDescription(Locale locale) {
return LemmaReport.this.getDescription(locale);
}
};
}
public void generate(org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException {
delegate.generate(sink, locale);
}
public String getCategoryName() {
return delegate.getCategoryName();
}
public void setReportOutputDirectory(File file) {
delegate.setReportOutputDirectory(file);
}
public File getReportOutputDirectory() {
return delegate.getReportOutputDirectory();
}
public boolean isExternalReport() {
return delegate.isExternalReport();
}
public boolean canGenerateReport() {
return delegate.canGenerateReport();
}
/* ##################################################################################################### */
// Abused by Maven site plugin, a / denotes a directory path (they even convert from / to \\!)
// Thanks guys... it's so much easier now!
public String getOutputName() {
String path = IO.makeRelativePath(outputPath, project.getReporting().getOutputDirectory());
// Yes, the damn stupid code that attaches ".html" to everything (good luck overriding that) does
// so by chopping off everything after the FIRST DOT and not the LAST DOT (which is how sane
// people usually detect a file suffix). So we make dashes out of dots...
// The offending code is hidden here - don't even try to replace it, you'll suffer:
//
// org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext
//
//outputFilename = outputFilename.replaceAll("\\.", "-");
return path + "/" + outputFilename;
}
public String getName(Locale locale) {
return "Lemma Manual";
}
public String getDescription(Locale locale) {
return "A user manual generated from unit test source code.";
}
protected void executeReport(Locale locale) throws MavenReportException {
try {
// We might want to load stuff from the test classpath
extendPluginClasspath((List<String>)project.getTestClasspathElements());
File templateFile = new File(manualSourceDirectory, templateFilename);
if (!templateFile.exists()) {
throw new Exception("Configured 'templateFile' not found: " + templateFile);
}
// Default to test source directory if no source directories are configured
if (sourceDirectories.isEmpty()) {
File testSourceDirectory = new File(project.getBuild().getTestSourceDirectory());
sourceDirectories.add(testSourceDirectory);
getLog().info(">>> Generating documentation using test source directory: " + testSourceDirectory);
} else {
getLog().info(">>> Generating documentation using multiple source directories:");
for (File sourceDirectory : sourceDirectories) {
getLog().info(sourceDirectory.toString());
}
}
XHTMLTemplateJavadocPipeline pipeline = createPipeline(sourceDirectories, packageNames, project);
XHTML result = pipeline.execute(templateFile);
Sink sink = delegate.getSink();
sink.head();
sink.title();
sink.text(result.getRoot(pipeline.getXPath()).getHead().getHeadTitle().getContent());
sink.title_();
sink.head_();
sink.body();
XHTML bodyDom = pipeline.getParser().createDocument();
bodyDom.createRoot(pipeline.getXPath(), XHTML.ELEMENT.div);
for (XHTMLElement child : result.getRoot(pipeline.getXPath()).getBody().getChildren()) {
bodyDom.getRoot(pipeline.getXPath()).appendChild(child, true);
}
sink.rawText(pipeline.getParser().print(bodyDom, 4, false));
sink.body_();
sink.flush();
sink.close();
} catch (Exception ex) {
throw new MavenReportException("Error occurred: " + ex.getMessage(), ex);
}
}
protected void closeReport() {
try {
String path = IO.makeRelativePath(outputPath, project.getReporting().getOutputDirectory());
copyManualResources(new File(project.getReporting().getOutputDirectory(), path));
copyDocFiles(new File(project.getReporting().getOutputDirectory(), path));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}