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.plugin.MojoExecutionException;
47 import org.apache.maven.plugin.MojoFailureException;
48 import org.apache.maven.reporting.MavenReport;
49
50
51
52
53
54
55
56
57 public abstract class AbstractSiteRenderingMojo
58 extends AbstractSiteMojo
59 {
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 private Map<String, String> moduleExcludes;
79
80
81
82
83
84
85 private DecorationModelInheritanceAssembler assembler;
86
87
88
89
90
91
92
93
94 private List<ArtifactRepository> repositories;
95
96
97
98
99
100
101
102 private File templateDirectory;
103
104
105
106
107
108
109
110 private String template;
111
112
113
114
115
116
117
118
119 private File templateFile;
120
121
122
123
124
125
126 private Map<String, Object> attributes;
127
128
129
130
131
132
133 protected Renderer siteRenderer;
134
135
136
137
138
139
140 protected List<MavenReport> reports;
141
142
143
144
145
146
147
148 private File xdocDirectory;
149
150
151
152
153
154
155
156
157
158 protected File generatedSiteDirectory;
159
160
161
162
163
164
165
166
167
168
169
170
171 private boolean relativizeDecorationLinks;
172
173
174
175
176
177
178
179
180 private boolean generateProjectInfo;
181
182 protected List<MavenReport> filterReports( List<MavenReport> reports )
183 {
184 List<MavenReport> filteredReports = new ArrayList<MavenReport>( reports.size() );
185 for ( MavenReport report : reports )
186 {
187 if ( report.canGenerateReport() )
188 {
189 filteredReports.add( report );
190 }
191 }
192 return filteredReports;
193 }
194
195 protected SiteRenderingContext createSiteRenderingContext( Locale locale )
196 throws MojoExecutionException, IOException, MojoFailureException
197 {
198 if ( attributes == null )
199 {
200 attributes = new HashMap<String, Object>();
201 }
202
203 if ( attributes.get( "project" ) == null )
204 {
205 attributes.put( "project", project );
206 }
207
208 if ( attributes.get( "inputEncoding" ) == null )
209 {
210 attributes.put( "inputEncoding", getInputEncoding() );
211 }
212
213 if ( attributes.get( "outputEncoding" ) == null )
214 {
215 attributes.put( "outputEncoding", getOutputEncoding() );
216 }
217
218
219 for ( Map.Entry<Object, Object> entry : project.getProperties().entrySet() )
220 {
221 attributes.put( (String) entry.getKey(), entry.getValue() );
222 }
223
224 DecorationModel decorationModel;
225 try
226 {
227 decorationModel = siteTool.getDecorationModel( project, reactorProjects, localRepository, repositories,
228 siteTool.getRelativePath( siteDirectory.getAbsolutePath(),
229 project.getBasedir().getAbsolutePath() ),
230 locale, getInputEncoding(), getOutputEncoding() );
231 }
232 catch ( SiteToolException e )
233 {
234 throw new MojoExecutionException( "SiteToolException: " + e.getMessage(), e );
235 }
236
237 if ( relativizeDecorationLinks )
238 {
239 final String url = project.getUrl();
240
241 if ( url == null )
242 {
243 getLog().warn( "No project URL defined - decoration links will not be relativized!" );
244 }
245 else
246 {
247 getLog().info( "Relativizing decoration links with respect to project URL: " + url );
248 assembler.resolvePaths( decorationModel, url );
249 }
250 }
251
252 if ( template != null )
253 {
254 if ( templateFile != null )
255 {
256 getLog().warn( "'template' configuration is ignored when 'templateFile' is set" );
257 }
258 else
259 {
260 templateFile = new File( templateDirectory, template );
261 }
262 }
263
264 File skinFile;
265 try
266 {
267 Artifact skinArtifact =
268 siteTool.getSkinArtifactFromRepository( localRepository, repositories, decorationModel );
269 getLog().info( "Rendering site with " + skinArtifact.getId() + " skin." );
270
271 skinFile = skinArtifact.getFile();
272 }
273 catch ( SiteToolException e )
274 {
275 throw new MojoExecutionException( "SiteToolException: " + e.getMessage(), e );
276 }
277 SiteRenderingContext context;
278 if ( templateFile != null )
279 {
280 if ( !templateFile.exists() )
281 {
282 throw new MojoFailureException( "Template file '" + templateFile + "' does not exist" );
283 }
284 context = siteRenderer.createContextForTemplate( templateFile, skinFile, attributes, decorationModel,
285 project.getName(), locale );
286 }
287 else
288 {
289 context = siteRenderer.createContextForSkin( skinFile, attributes, decorationModel, project.getName(),
290 locale );
291 }
292
293
294 if ( !locale.getLanguage().equals( Locale.getDefault().getLanguage() ) )
295 {
296 context.addSiteDirectory( new File( siteDirectory, locale.getLanguage() ) );
297 context.addModuleDirectory( new File( xdocDirectory, locale.getLanguage() ), "xdoc" );
298 context.addModuleDirectory( new File( xdocDirectory, locale.getLanguage() ), "fml" );
299 }
300 else
301 {
302 context.addSiteDirectory( siteDirectory );
303 context.addModuleDirectory( xdocDirectory, "xdoc" );
304 context.addModuleDirectory( xdocDirectory, "fml" );
305 }
306
307 if ( moduleExcludes != null )
308 {
309 context.setModuleExcludes( moduleExcludes );
310 }
311
312 return context;
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 protected Map<String, MavenReport> locateReports( List<MavenReport> reports,
329 Map<String, DocumentRenderer> documents, Locale locale )
330 {
331 Map<String, MavenReport> reportsByOutputName = new LinkedHashMap<String, MavenReport>();
332 for ( Iterator<MavenReport> i = reports.iterator(); i.hasNext(); )
333 {
334 MavenReport report = i.next();
335
336 String outputName = report.getOutputName() + ".html";
337
338
339 reportsByOutputName.put( report.getOutputName(), report );
340
341 if ( documents.containsKey( outputName ) )
342 {
343 String displayLanguage = locale.getDisplayLanguage( Locale.ENGLISH );
344
345 getLog().info( "Skipped \"" + report.getName( locale ) + "\" report, file \"" + outputName
346 + "\" already exists for the " + displayLanguage + " version." );
347 i.remove();
348 }
349 else
350 {
351 RenderingContext renderingContext = new RenderingContext( siteDirectory, outputName );
352 ReportDocumentRenderer renderer = new ReportDocumentRenderer( report, renderingContext, getLog() );
353 documents.put( outputName, renderer );
354 }
355 }
356 return reportsByOutputName;
357 }
358
359
360
361
362
363
364
365
366 protected Map<String, List<MavenReport>> categoriseReports( Collection<MavenReport> reports )
367 {
368 Map<String, List<MavenReport>> categories = new LinkedHashMap<String, List<MavenReport>>();
369 for ( MavenReport report : reports )
370 {
371 List<MavenReport> categoryReports = categories.get( report.getCategoryName() );
372 if ( categoryReports == null )
373 {
374 categoryReports = new ArrayList<MavenReport>();
375 categories.put( report.getCategoryName(), categoryReports );
376 }
377 categoryReports.add( report );
378 }
379 return categories;
380 }
381
382 protected Map<String, DocumentRenderer> locateDocuments( SiteRenderingContext context, List<MavenReport> reports,
383 Locale locale )
384 throws IOException, RendererException
385 {
386 Map<String, DocumentRenderer> documents = siteRenderer.locateDocumentFiles( context );
387
388 Map<String, MavenReport> reportsByOutputName = locateReports( reports, documents, locale );
389
390
391 Map<String, List<MavenReport>> categories = categoriseReports( reportsByOutputName.values() );
392
393 siteTool.populateReportsMenu( context.getDecoration(), locale, categories );
394 populateReportItems( context.getDecoration(), locale, reportsByOutputName );
395
396 if ( categories.containsKey( MavenReport.CATEGORY_PROJECT_INFORMATION ) && generateProjectInfo )
397 {
398 List<MavenReport> categoryReports = categories.get( MavenReport.CATEGORY_PROJECT_INFORMATION );
399
400 RenderingContext renderingContext = new RenderingContext( siteDirectory, "project-info.html" );
401 String title = i18n.getString( "site-plugin", locale, "report.information.title" );
402 String desc1 = i18n.getString( "site-plugin", locale, "report.information.description1" );
403 String desc2 = i18n.getString( "site-plugin", locale, "report.information.description2" );
404 DocumentRenderer renderer = new CategorySummaryDocumentRenderer( renderingContext, title, desc1, desc2,
405 i18n, categoryReports, getLog() );
406
407 if ( !documents.containsKey( renderer.getOutputName() ) )
408 {
409 documents.put( renderer.getOutputName(), renderer );
410 }
411 else
412 {
413 getLog().info( "Category summary '" + renderer.getOutputName() + "' skipped; already exists" );
414 }
415 }
416
417 if ( categories.containsKey( MavenReport.CATEGORY_PROJECT_REPORTS ) )
418 {
419 List<MavenReport> categoryReports = categories.get( MavenReport.CATEGORY_PROJECT_REPORTS );
420 RenderingContext renderingContext = new RenderingContext( siteDirectory, "project-reports.html" );
421 String title = i18n.getString( "site-plugin", locale, "report.project.title" );
422 String desc1 = i18n.getString( "site-plugin", locale, "report.project.description1" );
423 String desc2 = i18n.getString( "site-plugin", locale, "report.project.description2" );
424 DocumentRenderer renderer = new CategorySummaryDocumentRenderer( renderingContext, title, desc1, desc2,
425 i18n, categoryReports, getLog() );
426
427 if ( !documents.containsKey( renderer.getOutputName() ) )
428 {
429 documents.put( renderer.getOutputName(), renderer );
430 }
431 else
432 {
433 getLog().info( "Category summary '" + renderer.getOutputName() + "' skipped; already exists" );
434 }
435 }
436 return documents;
437 }
438
439 protected void populateReportItems( DecorationModel decorationModel, Locale locale,
440 Map<String, MavenReport> reportsByOutputName )
441 {
442 for ( Menu menu : decorationModel.getMenus() )
443 {
444 populateItemRefs( menu.getItems(), locale, reportsByOutputName );
445 }
446 }
447
448 private void populateItemRefs( List<MenuItem> items, Locale locale, Map<String, MavenReport> reportsByOutputName )
449 {
450 for ( Iterator<MenuItem> i = items.iterator(); i.hasNext(); )
451 {
452 MenuItem item = i.next();
453
454 if ( item.getRef() != null )
455 {
456 MavenReport report = reportsByOutputName.get( item.getRef() );
457
458 if ( report != null )
459 {
460 if ( item.getName() == null )
461 {
462 item.setName( report.getName( locale ) );
463 }
464
465 if ( item.getHref() == null || item.getHref().length() == 0 )
466 {
467 item.setHref( report.getOutputName() + ".html" );
468 }
469 }
470 else
471 {
472 getLog().warn( "Unrecognised reference: '" + item.getRef() + "'" );
473 i.remove();
474 }
475 }
476
477 populateItemRefs( item.getItems(), locale, reportsByOutputName );
478 }
479 }
480 }