1 package org.apache.maven.reporting;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.artifact.repository.ArtifactRepository;
24 import org.apache.maven.doxia.sink.Sink;
25 import org.apache.maven.doxia.sink.SinkFactory;
26 import org.apache.maven.doxia.site.decoration.DecorationModel;
27 import org.apache.maven.doxia.site.decoration.Skin;
28 import org.apache.maven.doxia.siterenderer.Renderer;
29 import org.apache.maven.doxia.siterenderer.RendererException;
30 import org.apache.maven.doxia.siterenderer.RenderingContext;
31 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
32 import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
33 import org.apache.maven.doxia.tools.SiteTool;
34 import org.apache.maven.doxia.tools.SiteToolException;
35 import org.apache.maven.plugin.AbstractMojo;
36 import org.apache.maven.plugin.MojoExecutionException;
37 import org.apache.maven.plugins.annotations.Component;
38 import org.apache.maven.plugins.annotations.Parameter;
39 import org.apache.maven.project.MavenProject;
40 import org.apache.maven.shared.utils.WriterFactory;
41 import org.codehaus.plexus.util.ReaderFactory;
42
43 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
44
45 import java.io.File;
46 import java.io.FileOutputStream;
47 import java.io.IOException;
48 import java.io.OutputStreamWriter;
49 import java.io.Writer;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Locale;
53 import java.util.Map;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public abstract class AbstractMavenReport
72 extends AbstractMojo
73 implements MavenMultiPageReport
74 {
75
76
77
78
79
80 @Parameter( defaultValue = "${project.reporting.outputDirectory}", readonly = true, required = true )
81 protected File outputDirectory;
82
83
84
85
86 @Parameter( defaultValue = "${project}", readonly = true, required = true )
87 protected MavenProject project;
88
89
90
91
92 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}", readonly = true )
93 private String inputEncoding;
94
95
96
97
98 @Parameter( property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}", readonly = true )
99 private String outputEncoding;
100
101
102
103
104 @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
105 protected ArtifactRepository localRepository;
106
107
108
109
110 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
111 protected List<ArtifactRepository> remoteRepositories;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 @Parameter
128 protected Skin skin;
129
130
131
132
133
134
135
136
137
138 @Parameter( defaultValue = "default" )
139 protected String locale;
140
141
142
143
144 @Component
145 protected SiteTool siteTool;
146
147
148
149
150 @Component
151 protected Renderer siteRenderer;
152
153
154 private Sink sink;
155
156
157 private SinkFactory sinkFactory;
158
159
160 private File reportOutputDirectory;
161
162
163
164
165
166
167
168 @Override
169 public void execute()
170 throws MojoExecutionException
171 {
172 if ( !canGenerateReport() )
173 {
174 return;
175 }
176
177 File outputDirectory = new File( getOutputDirectory() );
178
179 String filename = getOutputName() + ".html";
180
181 Locale locale = getLocale();
182
183 try
184 {
185 SiteRenderingContext siteContext = createSiteRenderingContext( locale );
186
187
188 getSiteRenderer().copyResources( siteContext, outputDirectory );
189
190
191 RenderingContext docRenderingContext = new RenderingContext( outputDirectory, filename, null );
192
193 SiteRendererSink sink = new SiteRendererSink( docRenderingContext );
194
195 generate( sink, null, locale );
196
197 if ( !isExternalReport() )
198 {
199 outputDirectory.mkdirs();
200
201 try ( Writer writer =
202 new OutputStreamWriter( new FileOutputStream( new File( outputDirectory, filename ) ),
203 getOutputEncoding() ) )
204 {
205
206 getSiteRenderer().mergeDocumentIntoSite( writer, sink, siteContext );
207 }
208 }
209
210
211 getSiteRenderer().copyResources( siteContext, outputDirectory );
212 }
213 catch ( RendererException | IOException | MavenReportException e )
214 {
215 throw new MojoExecutionException(
216 "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e );
217 }
218 }
219
220 private SiteRenderingContext createSiteRenderingContext( Locale locale )
221 throws MavenReportException, IOException
222 {
223 DecorationModel decorationModel = new DecorationModel();
224 decorationModel.setSkin( getSkin() );
225
226 Map<String, Object> templateProperties = new HashMap<>();
227
228 templateProperties.put( "standalone", Boolean.TRUE );
229 templateProperties.put( "project", getProject() );
230 templateProperties.put( "inputEncoding", getInputEncoding() );
231 templateProperties.put( "outputEncoding", getOutputEncoding() );
232
233 for ( Map.Entry<Object, Object> entry : getProject().getProperties().entrySet() )
234 {
235 templateProperties.put( (String) entry.getKey(), entry.getValue() );
236 }
237
238 SiteRenderingContext context;
239 try
240 {
241 Artifact skinArtifact =
242 siteTool.getSkinArtifactFromRepository( localRepository, remoteRepositories, decorationModel );
243
244 getLog().info( buffer().a( "Rendering content with " ).strong( skinArtifact.getId()
245 + " skin" ).a( '.' ).toString() );
246
247 context = siteRenderer.createContextForSkin( skinArtifact, templateProperties, decorationModel,
248 project.getName(), locale );
249 }
250 catch ( SiteToolException e )
251 {
252 throw new MavenReportException( "Failed to retrieve skin artifact", e );
253 }
254 catch ( RendererException e )
255 {
256 throw new MavenReportException( "Failed to create context for skin", e );
257 }
258
259
260 context.setRootDirectory( project.getBasedir() );
261
262 return context;
263 }
264
265
266
267
268
269
270
271
272
273 @Deprecated
274 @Override
275 public void generate( Sink sink, Locale locale )
276 throws MavenReportException
277 {
278 generate( sink, null, locale );
279 }
280
281
282
283
284
285
286
287
288
289 @Override
290 public void generate( Sink sink, SinkFactory sinkFactory, Locale locale )
291 throws MavenReportException
292 {
293 if ( !canGenerateReport() )
294 {
295 getLog().info( "This report cannot be generated as part of the current build. "
296 + "The report name should be referenced in this line of output." );
297 return;
298 }
299
300 this.sink = sink;
301
302 this.sinkFactory = sinkFactory;
303
304 executeReport( locale );
305
306 closeReport();
307 }
308
309
310
311
312 @Override
313 public String getCategoryName()
314 {
315 return CATEGORY_PROJECT_REPORTS;
316 }
317
318 @Override
319 public File getReportOutputDirectory()
320 {
321 if ( reportOutputDirectory == null )
322 {
323 reportOutputDirectory = new File( getOutputDirectory() );
324 }
325
326 return reportOutputDirectory;
327 }
328
329 @Override
330 public void setReportOutputDirectory( File reportOutputDirectory )
331 {
332 this.reportOutputDirectory = reportOutputDirectory;
333 this.outputDirectory = reportOutputDirectory;
334 }
335
336 protected String getOutputDirectory()
337 {
338 return outputDirectory.getAbsolutePath();
339 }
340
341 protected MavenProject getProject()
342 {
343 return project;
344 }
345
346 protected Renderer getSiteRenderer()
347 {
348 return siteRenderer;
349 }
350
351
352
353
354
355
356 protected String getInputEncoding()
357 {
358 return ( inputEncoding == null ) ? ReaderFactory.FILE_ENCODING : inputEncoding;
359 }
360
361
362
363
364
365
366 protected String getOutputEncoding()
367 {
368 return ( outputEncoding == null ) ? WriterFactory.UTF_8 : outputEncoding;
369 }
370
371
372
373
374
375
376 protected Skin getSkin()
377 {
378 if ( skin == null )
379 {
380 Skin skin = new Skin();
381 skin.setGroupId( "org.apache.maven.skins" );
382 skin.setArtifactId( "maven-fluido-skin" );
383 skin.setVersion( "1.11.1" );
384 return skin;
385 }
386 else
387 {
388 return skin;
389 }
390 }
391
392
393
394
395
396
397 protected Locale getLocale()
398 {
399 return siteTool.getSiteLocales( locale ).get( 0 );
400 }
401
402
403
404
405 protected void closeReport()
406 {
407 getSink().close();
408 }
409
410
411
412
413 public Sink getSink()
414 {
415 return sink;
416 }
417
418
419
420
421 public SinkFactory getSinkFactory()
422 {
423 return sinkFactory;
424 }
425
426
427
428
429
430 @Override
431 public boolean isExternalReport()
432 {
433 return false;
434 }
435
436 @Override
437 public boolean canGenerateReport()
438 {
439 return true;
440 }
441
442
443
444
445
446
447
448 protected abstract void executeReport( Locale locale )
449 throws MavenReportException;
450 }