View Javadoc
1   package org.apache.maven.plugins.site.render;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Locale;
28  import java.util.Map;
29  import java.util.TreeMap;
30  
31  import org.apache.maven.doxia.siterenderer.DocumentRenderer;
32  import org.apache.maven.doxia.siterenderer.DoxiaDocumentRenderer;
33  import org.apache.maven.doxia.siterenderer.RendererException;
34  import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
35  import org.apache.maven.execution.MavenSession;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugin.MojoFailureException;
38  import org.apache.maven.plugins.annotations.Mojo;
39  import org.apache.maven.plugins.annotations.Parameter;
40  import org.apache.maven.plugins.annotations.ResolutionScope;
41  import org.apache.maven.project.MavenProject;
42  import org.apache.maven.reporting.MavenReport;
43  import org.apache.maven.reporting.exec.MavenReportExecution;
44  
45  /**
46   * Generates the site for a single project.
47   * <p>
48   * Note that links between module sites in a multi module build will <b>not</b> work, since local build directory
49   * structure doesn't match deployed site.
50   * </p>
51   *
52   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
53   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
54   * @version $Id: SiteMojo.html 1000583 2016-11-06 19:42:52Z hboutemy $
55   */
56  @Mojo( name = "site", requiresDependencyResolution = ResolutionScope.TEST, requiresReports = true )
57  public class SiteMojo
58      extends AbstractSiteRenderingMojo
59  {
60      /**
61       * Directory where the project sites and report distributions will be generated.
62       */
63      @Parameter( property = "siteOutputDirectory", defaultValue = "${project.reporting.outputDirectory}" )
64      protected File outputDirectory;
65  
66      /**
67       * Convenience parameter that allows you to disable report generation.
68       */
69      @Parameter( property = "generateReports", defaultValue = "true" )
70      private boolean generateReports;
71  
72      /**
73       * Generate a sitemap. The result will be a "sitemap.html" file at the site root.
74       *
75       * @since 2.1
76       */
77      @Parameter( property = "generateSitemap", defaultValue = "false" )
78      private boolean generateSitemap;
79  
80      /**
81       * Whether to validate xml input documents. If set to true, <strong>all</strong> input documents in xml format (in
82       * particular xdoc and fml) will be validated and any error will lead to a build failure.
83       *
84       * @since 2.1.1
85       */
86      @Parameter( property = "validate", defaultValue = "false" )
87      private boolean validate;
88  
89      /**
90       * {@inheritDoc} Generate the project site
91       * <p/>
92       * throws MojoExecutionException if any
93       *
94       * @see org.apache.maven.plugin.Mojo#execute()
95       */
96      public void execute()
97          throws MojoExecutionException, MojoFailureException
98      {
99          if ( skip )
100         {
101             getLog().info( "maven.site.skip = true: Skipping site generation" );
102             return;
103         }
104 
105         if ( getLog().isDebugEnabled() )
106         {
107             getLog().debug( "executing Site Mojo" );
108         }
109 
110         checkInputEncoding();
111 
112         List<MavenReportExecution> reports;
113         if ( generateReports )
114         {
115             reports = getReports();
116         }
117         else
118         {
119             reports = Collections.emptyList();
120         }
121 
122         try
123         {
124             List<Locale> localesList = getLocales();
125 
126             // Default is first in the list
127             Locale defaultLocale = localesList.get( 0 );
128             Locale.setDefault( defaultLocale );
129 
130             for ( Locale locale : localesList )
131             {
132                 renderLocale( locale, reports );
133             }
134         }
135         catch ( RendererException e )
136         {
137             throw new MojoExecutionException( e.getMessage(), e );
138         }
139         catch ( IOException e )
140         {
141             throw new MojoExecutionException( "Error during site generation", e );
142         }
143     }
144 
145     private void renderLocale( Locale locale, List<MavenReportExecution> reports )
146         throws IOException, RendererException, MojoFailureException, MojoExecutionException
147     {
148         SiteRenderingContext context = createSiteRenderingContext( locale );
149         // MSITE-723 add generated site directory, in case some content has been put in pre-site phase
150         context.addSiteDirectory( generatedSiteDirectory );
151 
152         context.setInputEncoding( getInputEncoding() );
153         context.setOutputEncoding( getOutputEncoding() );
154         context.setValidate( validate );
155         if ( validate )
156         {
157             getLog().info( "Validation is switched on, xml input documents will be validated!" );
158         }
159 
160         File outputDir = getOutputDirectory( locale );
161 
162         Map<String, DocumentRenderer> documents = locateDocuments( context, reports, locale );
163 
164         // copy resources
165         siteRenderer.copyResources( context, outputDir );
166 
167         // 1. render Doxia documents first
168         List<DocumentRenderer> reportDocuments = renderDoxiaDocuments( documents, context, outputDir, false );
169 
170         // 2. then reports
171         // prepare external reports
172         for ( MavenReportExecution mavenReportExecution : reports )
173         {
174             MavenReport report = mavenReportExecution.getMavenReport();
175             report.setReportOutputDirectory( outputDir );
176         }
177 
178         siteRenderer.render( reportDocuments, context, outputDir );
179 
180         if ( generateSitemap )
181         {
182             getLog().info( "Generating Sitemap." );
183 
184             new SiteMap( getOutputEncoding(), i18n ).generate( context.getDecoration(), generatedSiteDirectory,
185                                                                locale );
186         }
187 
188         // 3. Generated docs must be (re-)done afterwards as they are often generated by reports
189         context.getSiteDirectories().clear();
190         context.addSiteDirectory( generatedSiteDirectory );
191 
192         Map<String, DocumentRenderer> generatedDocuments = siteRenderer.locateDocumentFiles( context );
193 
194         renderDoxiaDocuments( generatedDocuments, context, outputDir, true );
195 
196         // copy generated resources also
197         siteRenderer.copyResources( context, outputDir );
198     }
199 
200     /**
201      * Render Doxia documents from the list given, but not reports.
202      * 
203      * @param documents a collection of documents containing both Doxia source files and reports
204      * @return the sublist of documents that are not Doxia source files
205      */
206     private List<DocumentRenderer> renderDoxiaDocuments( Map<String, DocumentRenderer> documents,
207                                                          SiteRenderingContext context, File outputDir,
208                                                          boolean generated )
209                                                              throws RendererException, IOException
210     {
211         Map<String, DocumentRenderer> doxiaDocuments = new TreeMap<String, DocumentRenderer>();
212         List<DocumentRenderer> nonDoxiaDocuments = new ArrayList<DocumentRenderer>();
213 
214         Map<String, Integer> counts = new TreeMap<String, Integer>();
215 
216         for ( Map.Entry<String, DocumentRenderer> entry : documents.entrySet() )
217         {
218             DocumentRenderer doc = entry.getValue();
219 
220             if ( doc instanceof DoxiaDocumentRenderer )
221             {
222                 doxiaDocuments.put( entry.getKey(), doc );
223 
224                 DoxiaDocumentRenderer doxia = (DoxiaDocumentRenderer) doc;
225 
226                 // count documents per parserId
227                 String parserId = doxia.getRenderingContext().getParserId();
228                 Integer count = counts.get( parserId );
229                 if ( count == null )
230                 {
231                     count = 1;
232                 }
233                 else
234                 {
235                     count++;
236                 }
237                 counts.put( parserId, count );
238             }
239             else
240             {
241                 nonDoxiaDocuments.add( doc );
242             }
243         }
244 
245         if ( doxiaDocuments.size() > 0 )
246         {
247             StringBuilder sb = new StringBuilder( 15 * counts.size() );
248             for ( Map.Entry<String, Integer> entry : counts.entrySet() )
249             {
250                 if ( sb.length() > 0 )
251                 {
252                     sb.append( ", " );
253                 }
254                 sb.append( entry.getValue() );
255                 sb.append( ' ' );
256                 sb.append( entry.getKey() );
257             }
258 
259             getLog().info( "Rendering " + doxiaDocuments.size() + ( generated ? " generated" : "" ) + " Doxia document"
260                 + ( doxiaDocuments.size() > 1 ? "s" : "" ) + ": " + sb.toString() );
261 
262             siteRenderer.render( doxiaDocuments.values(), context, outputDir );
263         }
264 
265         return nonDoxiaDocuments;
266     }
267 
268     private File getOutputDirectory( Locale locale )
269     {
270         File file;
271         if ( locale.getLanguage().equals( Locale.getDefault().getLanguage() ) )
272         {
273             file = outputDirectory;
274         }
275         else
276         {
277             file = new File( outputDirectory, locale.getLanguage() );
278         }
279 
280         // Safety
281         if ( !file.exists() )
282         {
283             file.mkdirs();
284         }
285 
286         return file;
287     }
288 
289     public MavenProject getProject()
290     {
291         return project;
292     }
293 
294     public MavenSession getSession()
295     {
296         return mavenSession;
297     }
298 }