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.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.io.Writer;
26 import java.io.File;
27
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30
31 import java.util.ArrayList;
32 import java.util.Locale;
33 import java.util.List;
34
35 import org.apache.maven.doxia.sink.Sink;
36 import org.apache.maven.doxia.sink.SinkFactory;
37 import org.apache.maven.doxia.sink.render.RenderingContext;
38 import org.apache.maven.doxia.siterenderer.DocumentRenderer;
39 import org.apache.maven.doxia.siterenderer.Renderer;
40 import org.apache.maven.doxia.siterenderer.RendererException;
41 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
42 import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
43 import org.apache.maven.doxia.tools.MojoLogWrapper;
44 import org.apache.maven.plugin.logging.Log;
45 import org.apache.maven.reporting.MavenReport;
46 import org.apache.maven.reporting.MavenReportException;
47
48 import org.codehaus.plexus.util.IOUtil;
49 import org.codehaus.plexus.util.WriterFactory;
50
51
52
53
54
55
56 public class ReportDocumentRenderer
57 implements DocumentRenderer
58 {
59 private final MavenReport report;
60
61 private final RenderingContext renderingContext;
62
63 private final String pluginInfo;
64
65 private final Log log;
66
67 public ReportDocumentRenderer( MavenReport report, RenderingContext renderingContext, Log log )
68 {
69 this.report = report;
70
71 pluginInfo = getPluginInfo( report );
72
73 this.renderingContext = renderingContext;
74
75 this.log = log;
76 }
77
78
79
80
81
82
83
84
85 private String getPluginInfo( MavenReport report )
86 {
87 Package pkg = report.getClass().getPackage();
88
89 if ( pkg != null )
90 {
91 String title = pkg.getSpecificationTitle();
92 String version = pkg.getSpecificationVersion();
93
94 if ( title == null )
95 {
96 return version;
97 }
98 else if ( version == null )
99 {
100 return title;
101 }
102 else
103 {
104 return title + ' ' + version;
105 }
106 }
107
108 return null;
109 }
110
111 private static class MySink
112 extends SiteRendererSink
113 {
114 private File outputDir;
115
116 private String outputName;
117
118 public MySink( File outputDir, String outputName, RenderingContext ctx )
119 {
120 super( ctx );
121 this.outputName = outputName;
122 this.outputDir = outputDir;
123 }
124
125 public String getOutputName()
126 {
127 return outputName;
128 }
129
130 public File getOutputDir()
131 {
132 return outputDir;
133 }
134
135 }
136
137 private static class MySinkFactory
138 implements SinkFactory
139 {
140 private RenderingContext context;
141
142 private List<MySink> sinks = new ArrayList<MySink>();
143
144 public MySinkFactory( RenderingContext ctx )
145 {
146 this.context = ctx;
147 }
148
149 public Sink createSink( File outputDir, String outputName )
150 {
151 MySink sink = new MySink( outputDir, outputName, context );
152 sinks.add( sink );
153 return sink;
154 }
155
156 public Sink createSink( File arg0, String arg1, String arg2 )
157 throws IOException
158 {
159
160 return null;
161 }
162
163 public Sink createSink( OutputStream arg0 )
164 throws IOException
165 {
166
167 return null;
168 }
169
170 public Sink createSink( OutputStream arg0, String arg1 )
171 throws IOException
172 {
173
174 return null;
175 }
176
177 public List<MySink> sinks()
178 {
179 return sinks;
180 }
181 }
182
183 public void renderDocument( Writer writer, Renderer renderer, SiteRenderingContext siteRenderingContext )
184 throws RendererException, FileNotFoundException
185 {
186 Locale locale = siteRenderingContext.getLocale();
187 String localReportName = report.getName( locale );
188
189 log.info( "Generating \"" + localReportName + "\" report"
190 + ( pluginInfo == null ? "." : ( " --- " + pluginInfo ) ) );
191
192 MySinkFactory sf = new MySinkFactory( renderingContext );
193
194 SiteRendererSink sink = new SiteRendererSink( renderingContext );
195 sink.enableLogging( new MojoLogWrapper( log ) );
196
197 try
198 {
199
200 if ( !generateMultiPage( locale, sf, sink ) )
201 {
202
203 try
204 {
205 report.generate( sink, locale );
206 }
207 catch ( NoSuchMethodError e )
208 {
209 throw new RendererException( "No method on " + report.getClass(), e );
210 }
211 }
212 }
213 catch ( MavenReportException e )
214 {
215 throw new RendererException( "Error rendering Maven report: " + e.getMessage(), e );
216 }
217 finally
218 {
219 sink.close();
220 }
221
222 if ( !report.isExternalReport() )
223 {
224 try
225 {
226 List<MySink> sinks = sf.sinks();
227
228 log.debug( "Multipage report: " + sinks.size() + " subreports" );
229
230 for ( MySink mySink : sinks )
231 {
232 mySink.enableLogging( new MojoLogWrapper( log ) );
233
234 log.debug( " Rendering " + mySink.getOutputName() );
235
236 File outputFile = new File( mySink.getOutputDir(), mySink.getOutputName() );
237
238 Writer out = null;
239 try
240 {
241 out = WriterFactory.newWriter( outputFile, siteRenderingContext.getOutputEncoding() );
242 renderer.generateDocument( out, mySink, siteRenderingContext );
243 }
244 finally
245 {
246 mySink.close();
247 IOUtil.close( out );
248 }
249 }
250 }
251 catch ( IOException e )
252 {
253 throw new RendererException( "Cannot create writer", e );
254 }
255
256 renderer.generateDocument( writer, sink, siteRenderingContext );
257 }
258 }
259
260
261
262
263
264
265 private boolean generateMultiPage( Locale locale, SinkFactory sf, Sink sink )
266 throws MavenReportException
267 {
268 try
269 {
270
271
272 Method generate =
273 report.getClass().getMethod( "generate", Sink.class, SinkFactory.class, Locale.class );
274
275 generate.invoke( report, sink, sf, locale );
276
277 return true;
278 }
279 catch ( SecurityException se )
280 {
281 return false;
282 }
283 catch ( NoSuchMethodException nsme )
284 {
285 return false;
286 }
287 catch ( IllegalArgumentException iae )
288 {
289 throw new MavenReportException( "error while invoking generate", iae );
290 }
291 catch ( IllegalAccessException iae )
292 {
293 throw new MavenReportException( "error while invoking generate", iae );
294 }
295 catch ( InvocationTargetException ite )
296 {
297 throw new MavenReportException( "error while invoking generate", ite );
298 }
299 }
300
301 public String getOutputName()
302 {
303 return renderingContext.getOutputName();
304 }
305
306 public RenderingContext getRenderingContext()
307 {
308 return renderingContext;
309 }
310
311 public boolean isOverwrite()
312 {
313
314 return true;
315 }
316
317
318
319
320 public boolean isExternalReport()
321 {
322 return report.isExternalReport();
323 }
324 }