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