View Javadoc

1   package org.apache.maven.plugins.site;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.doxia.sink.Sink;
23  import org.apache.maven.doxia.sink.SinkFactory;
24  import org.apache.maven.doxia.sink.render.RenderingContext;
25  import org.apache.maven.doxia.siterenderer.DocumentRenderer;
26  import org.apache.maven.doxia.siterenderer.Renderer;
27  import org.apache.maven.doxia.siterenderer.RendererException;
28  import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
29  import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
30  import org.apache.maven.doxia.tools.MojoLogWrapper;
31  import org.apache.maven.plugin.logging.Log;
32  import org.apache.maven.reporting.MavenReport;
33  import org.apache.maven.reporting.MavenReportException;
34  import org.codehaus.plexus.util.IOUtil;
35  import org.codehaus.plexus.util.WriterFactory;
36  
37  import java.io.FileNotFoundException;
38  import java.io.IOException;
39  import java.io.OutputStream;
40  import java.io.Writer;
41  import java.io.File;
42  import java.lang.reflect.InvocationTargetException;
43  import java.lang.reflect.Method;
44  import java.util.ArrayList;
45  import java.util.Locale;
46  import java.util.List;
47  
48  /**
49   * Renders a Maven report.
50   *
51   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
52   */
53  public class ReportDocumentRenderer
54      implements DocumentRenderer
55  {
56      private MavenReport report;
57  
58      private RenderingContext renderingContext;
59  
60      private Log log;
61  
62      public ReportDocumentRenderer( MavenReport report, RenderingContext renderingContext, Log log )
63      {
64          this.report = report;
65  
66          this.renderingContext = renderingContext;
67  
68          this.log = log;
69      }
70  
71      private static class MySink
72          extends SiteRendererSink
73      {
74          private File outputDir;
75  
76          private String outputName;
77  
78          public MySink( File outputDir, String outputName, RenderingContext ctx )
79          {
80              super( ctx );
81              this.outputName = outputName;
82              this.outputDir = outputDir;
83          }
84  
85          public String getOutputName()
86          {
87              return outputName;
88          }
89  
90          public File getOutputDir()
91          {
92              return outputDir;
93          }
94  
95      }
96  
97      private static class MySinkFactory
98          implements SinkFactory
99      {
100         private RenderingContext context;
101 
102         private List<MySink> sinks = new ArrayList<MySink>();
103 
104         public MySinkFactory( RenderingContext ctx )
105         {
106             this.context = ctx;
107         }
108 
109         public Sink createSink( File outputDir, String outputName )
110         {
111             MySink sink = new MySink( outputDir, outputName, context );
112             sinks.add( sink );
113             return sink;
114         }
115 
116         public Sink createSink( File arg0, String arg1, String arg2 )
117             throws IOException
118         {
119             // Not used
120             return null;
121         }
122 
123         public Sink createSink( OutputStream arg0 )
124             throws IOException
125         {
126             // Not used
127             return null;
128         }
129 
130         public Sink createSink( OutputStream arg0, String arg1 )
131             throws IOException
132         {
133             // Not used
134             return null;
135         }
136 
137         public List<MySink> sinks()
138         {
139             return sinks;
140         }
141     }
142 
143     public void renderDocument( Writer writer, Renderer renderer, SiteRenderingContext siteRenderingContext )
144         throws RendererException, FileNotFoundException
145     {
146         Locale locale = siteRenderingContext.getLocale();
147         String localReportName = report.getName( locale );
148         log.info( "Generating \"" + localReportName + "\" report." );
149 
150         MySinkFactory sf = new MySinkFactory( renderingContext );
151 
152         SiteRendererSink sink = new SiteRendererSink( renderingContext );
153         sink.enableLogging( new MojoLogWrapper( log ) );
154 
155         try
156         {
157             if ( !generateMultiPage( locale, sf, sink ) )
158             {
159                 try
160                 {
161                     report.generate( sink, locale );
162                 }
163                 catch ( NoSuchMethodError e )
164                 {
165                     throw new RendererException( "No method on " + report.getClass(), e );
166                 }
167             }
168         }
169         catch ( MavenReportException e )
170         {
171             throw new RendererException( "Error rendering Maven report: " + e.getMessage(), e );
172         }
173         finally
174         {
175             sink.close();
176         }
177 
178         if ( !report.isExternalReport() )
179         {
180             try
181             {
182                 List<MySink> sinks = sf.sinks();
183 
184                 log.debug( "Multipage report: " + sinks.size() + " subreports" );
185 
186                 for ( MySink mySink : sinks )
187                 {
188                     mySink.enableLogging( new MojoLogWrapper( log ) );
189 
190                     log.debug( "  Rendering " + mySink.getOutputName() );
191 
192                     File outputFile = new File( mySink.getOutputDir(), mySink.getOutputName() );
193 
194                     Writer out = null;
195                     try
196                     {
197                         out = WriterFactory.newWriter( outputFile, siteRenderingContext.getOutputEncoding() );
198                         renderer.generateDocument( out, mySink, siteRenderingContext );
199                     }
200                     finally
201                     {
202                         mySink.close();
203                         IOUtil.close( out );
204                     }
205                 }
206             }
207             catch ( IOException e )
208             {
209                 throw new RendererException( "Cannot create writer", e );
210             }
211 
212             renderer.generateDocument( writer, sink, siteRenderingContext );
213         }
214     }
215 
216     private boolean generateMultiPage( Locale locale, SinkFactory sf, Sink sink )
217         throws MavenReportException
218     {
219         try
220         {
221             // MavenMultiPageReport is not in Maven Core, then the class is different in site plugin and in each report
222             // plugin: only reflection can let us invoke its method
223             Method generate =
224                 report.getClass().getMethod( "generate", Sink.class, SinkFactory.class, Locale.class );
225 
226             generate.invoke( report, sink, sf, locale );
227 
228             return true;
229         }
230         catch ( SecurityException se )
231         {
232             return false;
233         }
234         catch ( NoSuchMethodException nsme )
235         {
236             return false;
237         }
238         catch ( IllegalArgumentException iae )
239         {
240             throw new MavenReportException( "error while invoking generate", iae );
241         }
242         catch ( IllegalAccessException iae )
243         {
244             throw new MavenReportException( "error while invoking generate", iae );
245         }
246         catch ( InvocationTargetException ite )
247         {
248             throw new MavenReportException( "error while invoking generate", ite );
249         }
250     }
251 
252     public String getOutputName()
253     {
254         return renderingContext.getOutputName();
255     }
256 
257     public RenderingContext getRenderingContext()
258     {
259         return renderingContext;
260     }
261 
262     public boolean isOverwrite()
263     {
264         // TODO: would be nice to query the report to see if it is modified
265         return true;
266     }
267 
268     /**
269      * @return true if the current report is external, false otherwise
270      */
271     public boolean isExternalReport()
272     {
273         return report.isExternalReport();
274     }
275 }