1 package org.apache.maven.plugins.site;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.artifact.repository.ArtifactRepository;
36 import org.apache.maven.doxia.sink.render.RenderingContext;
37 import org.apache.maven.doxia.site.decoration.DecorationModel;
38 import org.apache.maven.doxia.site.decoration.Menu;
39 import org.apache.maven.doxia.site.decoration.MenuItem;
40 import org.apache.maven.doxia.site.decoration.inheritance.DecorationModelInheritanceAssembler;
41 import org.apache.maven.doxia.siterenderer.DocumentRenderer;
42 import org.apache.maven.doxia.siterenderer.Renderer;
43 import org.apache.maven.doxia.siterenderer.RendererException;
44 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
45 import org.apache.maven.doxia.tools.SiteToolException;
46 import org.apache.maven.execution.MavenSession;
47 import org.apache.maven.plugin.MojoExecutionException;
48 import org.apache.maven.plugin.MojoFailureException;
49 import org.apache.maven.reporting.MavenReport;
50 import org.apache.maven.reporting.exec.MavenReportExecution;
51 import org.apache.maven.reporting.exec.MavenReportExecutor;
52 import org.apache.maven.reporting.exec.MavenReportExecutorRequest;
53 import org.apache.maven.reporting.exec.ReportPlugin;
54 import org.codehaus.plexus.PlexusConstants;
55 import org.codehaus.plexus.PlexusContainer;
56 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
57 import org.codehaus.plexus.context.Context;
58 import org.codehaus.plexus.context.ContextException;
59 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
60
61
62
63
64
65
66
67 public abstract class AbstractSiteRenderingMojo
68 extends AbstractSiteMojo implements Contextualizable
69 {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 private Map<String, String> moduleExcludes;
89
90
91
92
93
94
95 private DecorationModelInheritanceAssembler assembler;
96
97
98
99
100
101
102
103
104 private List<ArtifactRepository> repositories;
105
106
107
108
109
110
111
112 private File templateDirectory;
113
114
115
116
117
118
119
120 private String template;
121
122
123
124
125
126
127
128
129 private File templateFile;
130
131
132
133
134
135
136
137 private Map<String, Object> attributes;
138
139
140
141
142
143
144 protected Renderer siteRenderer;
145
146
147
148
149
150
151
152
153 protected List<MavenReport> reports;
154
155
156
157
158
159
160
161 private File xdocDirectory;
162
163
164
165
166
167
168
169
170
171 protected File generatedSiteDirectory;
172
173
174
175
176
177
178
179
180 protected MavenSession mavenSession;
181
182
183
184
185
186
187
188
189
190
191
192
193
194 private ReportPlugin[] reportPlugins;
195
196 private PlexusContainer container;
197
198
199
200
201
202
203
204
205
206
207
208
209 private boolean relativizeDecorationLinks;
210
211
212
213
214
215
216
217
218 private boolean generateProjectInfo;
219
220
221 public void contextualize( Context context )
222 throws ContextException
223 {
224 container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
225 }
226
227 protected List<MavenReportExecution> getReports()
228 throws MojoExecutionException
229 {
230 if ( isMaven3OrMore() )
231 {
232 MavenReportExecutorRequest mavenReportExecutorRequest = new MavenReportExecutorRequest();
233 mavenReportExecutorRequest.setLocalRepository( localRepository );
234 mavenReportExecutorRequest.setMavenSession( mavenSession );
235 mavenReportExecutorRequest.setProject( project );
236 mavenReportExecutorRequest.setReportPlugins( reportPlugins );
237
238 MavenReportExecutor mavenReportExecutor;
239 try
240 {
241 mavenReportExecutor = (MavenReportExecutor) container.lookup( MavenReportExecutor.class.getName() );
242 }
243 catch ( ComponentLookupException e )
244 {
245 throw new MojoExecutionException( "could not get MavenReportExecutor component", e );
246 }
247 return mavenReportExecutor.buildMavenReports( mavenReportExecutorRequest );
248 }
249
250 List<MavenReportExecution> reportExecutions = new ArrayList<MavenReportExecution>( reports.size() );
251 for ( MavenReport report : reports )
252 {
253 if ( report.canGenerateReport() )
254 {
255 reportExecutions.add( new MavenReportExecution( report ) );
256 }
257 }
258 return reportExecutions;
259 }
260
261 protected SiteRenderingContext createSiteRenderingContext( Locale locale )
262 throws MojoExecutionException, IOException, MojoFailureException
263 {
264 if ( attributes == null )
265 {
266 attributes = new HashMap<String, Object>();
267 }
268
269 if ( attributes.get( "project" ) == null )
270 {
271 attributes.put( "project", project );
272 }
273
274 if ( attributes.get( "inputEncoding" ) == null )
275 {
276 attributes.put( "inputEncoding", getInputEncoding() );
277 }
278
279 if ( attributes.get( "outputEncoding" ) == null )
280 {
281 attributes.put( "outputEncoding", getOutputEncoding() );
282 }
283
284
285 for ( Map.Entry<Object, Object> entry : project.getProperties().entrySet() )
286 {
287 attributes.put( (String) entry.getKey(), entry.getValue() );
288 }
289
290 DecorationModel decorationModel;
291 try
292 {
293 decorationModel = siteTool.getDecorationModel( project, reactorProjects, localRepository, repositories,
294 siteTool.getRelativePath( siteDirectory.getAbsolutePath(),
295 project.getBasedir().getAbsolutePath() ),
296 locale, getInputEncoding(), getOutputEncoding() );
297 }
298 catch ( SiteToolException e )
299 {
300 throw new MojoExecutionException( "SiteToolException: " + e.getMessage(), e );
301 }
302
303 if ( relativizeDecorationLinks )
304 {
305 final String url = project.getUrl();
306
307 if ( url == null )
308 {
309 getLog().warn( "No project URL defined - decoration links will not be relativized!" );
310 }
311 else
312 {
313 getLog().info( "Relativizing decoration links with respect to project URL: " + url );
314 assembler.resolvePaths( decorationModel, url );
315 }
316 }
317
318 if ( template != null )
319 {
320 if ( templateFile != null )
321 {
322 getLog().warn( "'template' configuration is ignored when 'templateFile' is set" );
323 }
324 else
325 {
326 templateFile = new File( templateDirectory, template );
327 }
328 }
329
330 File skinFile;
331 try
332 {
333 Artifact skinArtifact =
334 siteTool.getSkinArtifactFromRepository( localRepository, repositories, decorationModel );
335 getLog().info( "Rendering site with " + skinArtifact.getId() + " skin." );
336
337 skinFile = skinArtifact.getFile();
338 }
339 catch ( SiteToolException e )
340 {
341 throw new MojoExecutionException( "SiteToolException: " + e.getMessage(), e );
342 }
343 SiteRenderingContext context;
344 if ( templateFile != null )
345 {
346 if ( !templateFile.exists() )
347 {
348 throw new MojoFailureException( "Template file '" + templateFile + "' does not exist" );
349 }
350 context = siteRenderer.createContextForTemplate( templateFile, skinFile, attributes, decorationModel,
351 project.getName(), locale );
352 }
353 else
354 {
355 context = siteRenderer.createContextForSkin( skinFile, attributes, decorationModel, project.getName(),
356 locale );
357 }
358
359
360 if ( !locale.getLanguage().equals( Locale.getDefault().getLanguage() ) )
361 {
362 context.addSiteDirectory( new File( siteDirectory, locale.getLanguage() ) );
363 context.addModuleDirectory( new File( xdocDirectory, locale.getLanguage() ), "xdoc" );
364 context.addModuleDirectory( new File( xdocDirectory, locale.getLanguage() ), "fml" );
365 }
366 else
367 {
368 context.addSiteDirectory( siteDirectory );
369 context.addModuleDirectory( xdocDirectory, "xdoc" );
370 context.addModuleDirectory( xdocDirectory, "fml" );
371 }
372
373 if ( moduleExcludes != null )
374 {
375 context.setModuleExcludes( moduleExcludes );
376 }
377
378 return context;
379 }
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 protected Map<String, MavenReport> locateReports( List<MavenReportExecution> reports,
395 Map<String, DocumentRenderer> documents, Locale locale )
396 {
397
398 List<MavenReportExecution> filtered = new ArrayList<MavenReportExecution>( reports );
399
400 Map<String, MavenReport> reportsByOutputName = new LinkedHashMap<String, MavenReport>();
401 for ( MavenReportExecution mavenReportExecution : filtered )
402 {
403 MavenReport report = mavenReportExecution.getMavenReport();
404
405 String outputName = report.getOutputName() + ".html";
406
407
408 reportsByOutputName.put( report.getOutputName(), report );
409
410 if ( documents.containsKey( outputName ) )
411 {
412 String displayLanguage = locale.getDisplayLanguage( Locale.ENGLISH );
413
414 getLog().info( "Skipped \"" + report.getName( locale ) + "\" report, file \"" + outputName
415 + "\" already exists for the " + displayLanguage + " version." );
416 reports.remove( mavenReportExecution );
417 }
418 else
419 {
420 RenderingContext renderingContext = new RenderingContext( siteDirectory, outputName );
421 DocumentRenderer renderer = new ReportDocumentRenderer( mavenReportExecution, renderingContext, getLog() );
422 documents.put( outputName, renderer );
423 }
424 }
425 return reportsByOutputName;
426 }
427
428
429
430
431
432
433
434
435 protected Map<String, List<MavenReport>> categoriseReports( Collection<MavenReport> reports )
436 {
437 Map<String, List<MavenReport>> categories = new LinkedHashMap<String, List<MavenReport>>();
438 for ( MavenReport report : reports )
439 {
440 List<MavenReport> categoryReports = categories.get( report.getCategoryName() );
441 if ( categoryReports == null )
442 {
443 categoryReports = new ArrayList<MavenReport>();
444 categories.put( report.getCategoryName(), categoryReports );
445 }
446 categoryReports.add( report );
447 }
448 return categories;
449 }
450
451 protected Map<String, DocumentRenderer> locateDocuments( SiteRenderingContext context, List<MavenReportExecution> reports,
452 Locale locale )
453 throws IOException, RendererException
454 {
455 Map<String, DocumentRenderer> documents = siteRenderer.locateDocumentFiles( context );
456
457 Map<String, MavenReport> reportsByOutputName = locateReports( reports, documents, locale );
458
459
460 Map<String, List<MavenReport>> categories = categoriseReports( reportsByOutputName.values() );
461
462 siteTool.populateReportsMenu( context.getDecoration(), locale, categories );
463 populateReportItems( context.getDecoration(), locale, reportsByOutputName );
464
465 if ( categories.containsKey( MavenReport.CATEGORY_PROJECT_INFORMATION ) && generateProjectInfo )
466 {
467 List<MavenReport> categoryReports = categories.get( MavenReport.CATEGORY_PROJECT_INFORMATION );
468
469 RenderingContext renderingContext = new RenderingContext( siteDirectory, "project-info.html" );
470 String title = i18n.getString( "site-plugin", locale, "report.information.title" );
471 String desc1 = i18n.getString( "site-plugin", locale, "report.information.description1" );
472 String desc2 = i18n.getString( "site-plugin", locale, "report.information.description2" );
473 DocumentRenderer renderer = new CategorySummaryDocumentRenderer( renderingContext, title, desc1, desc2,
474 i18n, categoryReports, getLog() );
475
476 if ( !documents.containsKey( renderer.getOutputName() ) )
477 {
478 documents.put( renderer.getOutputName(), renderer );
479 }
480 else
481 {
482 getLog().info( "Category summary '" + renderer.getOutputName() + "' skipped; already exists" );
483 }
484 }
485
486 if ( categories.containsKey( MavenReport.CATEGORY_PROJECT_REPORTS ) )
487 {
488 List<MavenReport> categoryReports = categories.get( MavenReport.CATEGORY_PROJECT_REPORTS );
489 RenderingContext renderingContext = new RenderingContext( siteDirectory, "project-reports.html" );
490 String title = i18n.getString( "site-plugin", locale, "report.project.title" );
491 String desc1 = i18n.getString( "site-plugin", locale, "report.project.description1" );
492 String desc2 = i18n.getString( "site-plugin", locale, "report.project.description2" );
493 DocumentRenderer renderer = new CategorySummaryDocumentRenderer( renderingContext, title, desc1, desc2,
494 i18n, categoryReports, getLog() );
495
496 if ( !documents.containsKey( renderer.getOutputName() ) )
497 {
498 documents.put( renderer.getOutputName(), renderer );
499 }
500 else
501 {
502 getLog().info( "Category summary '" + renderer.getOutputName() + "' skipped; already exists" );
503 }
504 }
505 return documents;
506 }
507
508 protected void populateReportItems( DecorationModel decorationModel, Locale locale,
509 Map<String, MavenReport> reportsByOutputName )
510 {
511 for ( Menu menu : decorationModel.getMenus() )
512 {
513 populateItemRefs( menu.getItems(), locale, reportsByOutputName );
514 }
515 }
516
517 private void populateItemRefs( List<MenuItem> items, Locale locale, Map<String, MavenReport> reportsByOutputName )
518 {
519 for ( Iterator<MenuItem> i = items.iterator(); i.hasNext(); )
520 {
521 MenuItem item = i.next();
522
523 if ( item.getRef() != null )
524 {
525 MavenReport report = reportsByOutputName.get( item.getRef() );
526
527 if ( report != null )
528 {
529 if ( item.getName() == null )
530 {
531 item.setName( report.getName( locale ) );
532 }
533
534 if ( item.getHref() == null || item.getHref().length() == 0 )
535 {
536 item.setHref( report.getOutputName() + ".html" );
537 }
538 }
539 else
540 {
541 getLog().warn( "Unrecognised reference: '" + item.getRef() + "'" );
542 i.remove();
543 }
544 }
545
546 populateItemRefs( item.getItems(), locale, reportsByOutputName );
547 }
548 }
549 }