blob: f4066d8b7a347cfea1cd2698fd46a3041d41df03 [file] [log] [blame]
package org.apache.maven.plugins.site.render;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import org.apache.maven.doxia.siterenderer.DocumentRenderer;
import org.apache.maven.doxia.siterenderer.DoxiaDocumentRenderer;
import org.apache.maven.doxia.siterenderer.RendererException;
import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
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.MavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.reporting.exec.MavenReportExecution;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* Generates the site for a single project.
* <p>
* Note that links between module sites in a multi module build will <b>not</b> work, since local build directory
* structure doesn't match deployed site.
* </p>
*
* @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
*
*/
@Mojo( name = "site", requiresDependencyResolution = ResolutionScope.TEST, requiresReports = true )
public class SiteMojo
extends AbstractSiteRenderingMojo
{
/**
* Directory where the project sites and report distributions will be generated (as html/css/...).
*/
@Parameter( property = "siteOutputDirectory", defaultValue = "${project.reporting.outputDirectory}" )
protected File outputDirectory;
/**
* Convenience parameter that allows you to disable report generation.
*/
@Parameter( property = "generateReports", defaultValue = "true" )
private boolean generateReports;
/**
* Generate a sitemap. The result will be a "sitemap.html" file at the site root.
*
* @since 2.1
*/
@Parameter( property = "generateSitemap", defaultValue = "false" )
private boolean generateSitemap;
/**
* Whether to validate xml input documents. If set to true, <strong>all</strong> input documents in xml format (in
* particular xdoc and fml) will be validated and any error will lead to a build failure.
*
* @since 2.1.1
*/
@Parameter( property = "validate", defaultValue = "false" )
private boolean validate;
/**
* {@inheritDoc}
*/
public void execute()
throws MojoExecutionException, MojoFailureException
{
if ( skip )
{
getLog().info( "maven.site.skip = true: Skipping site generation" );
return;
}
if ( getLog().isDebugEnabled() )
{
getLog().debug( "executing Site Mojo" );
}
checkInputEncoding();
List<MavenReportExecution> reports;
if ( generateReports )
{
reports = getReports();
}
else
{
reports = Collections.emptyList();
}
try
{
List<Locale> localesList = getLocales();
// Default is first in the list
Locale defaultLocale = localesList.get( 0 );
Locale.setDefault( defaultLocale );
for ( Locale locale : localesList )
{
if ( locale == defaultLocale )
{
getLog().info( buffer().strong( "Rendering site with default locale " + locale.getDisplayName()
+ " (" + locale + ")" ).toString() );
}
else
{
getLog().info( "" );
getLog().info( buffer().strong( "Rendering localized site for " + locale.getDisplayName() + " ("
+ locale + ")" ).toString() );
}
renderLocale( locale, reports );
}
}
catch ( RendererException e )
{
if ( e.getCause() instanceof MavenReportException )
{
// issue caused by report, not really by Doxia Site Renderer
throw new MojoExecutionException( e.getMessage(), e.getCause() );
}
throw new MojoExecutionException( e.getMessage(), e );
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error during site generation", e );
}
}
private void renderLocale( Locale locale, List<MavenReportExecution> reports )
throws IOException, RendererException, MojoFailureException, MojoExecutionException
{
SiteRenderingContext context = createSiteRenderingContext( locale );
// MSITE-723 add generated site directory, in case some content has been put in pre-site phase
context.addSiteDirectory( generatedSiteDirectory );
context.setInputEncoding( getInputEncoding() );
context.setOutputEncoding( getOutputEncoding() );
context.setValidate( validate );
if ( validate )
{
getLog().info( "Validation is switched on, xml input documents will be validated!" );
}
File outputDir = getOutputDirectory( locale );
Map<String, DocumentRenderer> documents = locateDocuments( context, reports, locale );
// copy resources
siteRenderer.copyResources( context, outputDir );
// 1. render Doxia documents first
List<DocumentRenderer> reportDocuments = renderDoxiaDocuments( documents, context, outputDir, false );
// 2. then reports
// prepare external reports
for ( MavenReportExecution mavenReportExecution : reports )
{
MavenReport report = mavenReportExecution.getMavenReport();
report.setReportOutputDirectory( outputDir );
}
siteRenderer.render( reportDocuments, context, outputDir );
if ( generateSitemap )
{
getLog().info( "Generating Sitemap." );
new SiteMap( getOutputEncoding(), i18n ).generate( context.getDecoration(), generatedSiteDirectory,
locale );
}
// 3. Generated docs must be (re-)done afterwards as they are often generated by reports
context.getSiteDirectories().clear();
context.addSiteDirectory( generatedSiteDirectory );
Map<String, DocumentRenderer> generatedDocuments =
siteRenderer.locateDocumentFiles( context, false /* not editable */ );
renderDoxiaDocuments( generatedDocuments, context, outputDir, true );
// copy generated resources also
siteRenderer.copyResources( context, outputDir );
}
/**
* Render Doxia documents from the list given, but not reports.
*
* @param documents a collection of documents containing both Doxia source files and reports
* @return the sublist of documents that are not Doxia source files
*/
private List<DocumentRenderer> renderDoxiaDocuments( Map<String, DocumentRenderer> documents,
SiteRenderingContext context, File outputDir,
boolean generated )
throws RendererException, IOException
{
Map<String, DocumentRenderer> doxiaDocuments = new TreeMap<>();
List<DocumentRenderer> nonDoxiaDocuments = new ArrayList<>();
Map<String, Integer> counts = new TreeMap<>();
for ( Map.Entry<String, DocumentRenderer> entry : documents.entrySet() )
{
DocumentRenderer doc = entry.getValue();
if ( doc instanceof DoxiaDocumentRenderer )
{
doxiaDocuments.put( entry.getKey(), doc );
DoxiaDocumentRenderer doxia = (DoxiaDocumentRenderer) doc;
// count documents per parserId
String parserId = doxia.getRenderingContext().getParserId();
Integer count = counts.get( parserId );
if ( count == null )
{
count = 1;
}
else
{
count++;
}
counts.put( parserId, count );
}
else
{
nonDoxiaDocuments.add( doc );
}
}
if ( doxiaDocuments.size() > 0 )
{
MessageBuilder mb = buffer();
mb.a( "Rendering " );
mb.strong( doxiaDocuments.size() + ( generated ? " generated" : "" ) + " Doxia document"
+ ( doxiaDocuments.size() > 1 ? "s" : "" ) );
mb.a( ": " );
boolean first = true;
for ( Map.Entry<String, Integer> entry : counts.entrySet() )
{
if ( first )
{
first = false;
}
else
{
mb.a( ", " );
}
mb.strong( entry.getValue() + " " + entry.getKey() );
}
getLog().info( mb.toString() );
siteRenderer.render( doxiaDocuments.values(), context, outputDir );
}
return nonDoxiaDocuments;
}
private File getOutputDirectory( Locale locale )
{
File file;
if ( locale.getLanguage().equals( Locale.getDefault().getLanguage() ) )
{
file = outputDirectory;
}
else
{
file = new File( outputDirectory, locale.getLanguage() );
}
// Safety
if ( !file.exists() )
{
file.mkdirs();
}
return file;
}
public MavenProject getProject()
{
return project;
}
public MavenSession getSession()
{
return mavenSession;
}
}