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 }