View Javadoc

1   package org.apache.maven.reporting;
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.site.decoration.DecorationModel;
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.plugin.AbstractMojo;
31  import org.apache.maven.plugin.MojoExecutionException;
32  import org.apache.maven.project.MavenProject;
33  import org.codehaus.plexus.util.IOUtil;
34  
35  import java.io.File;
36  import java.io.FileOutputStream;
37  import java.io.IOException;
38  import java.io.OutputStreamWriter;
39  import java.io.Writer;
40  import java.util.Locale;
41  
42  /**
43   * The basis for a Maven report which can be generated both as part of a site generation or
44   * as a direct standalone invocation.
45   * Both invocations are delegated to <a href=""><code>abstract executeReport( Locale )</code></a>:
46   * <ul> 
47   * <li>Mojo's execute() method (see maven-plugin-api)</li>
48   * <li>MavenMultiPageReport's generate( Sink, SinkFactory, Locale ) (see maven-reporting-api)</li>
49   * </ul>
50   *
51   * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
52   * @version $Id: AbstractMavenReport.java 1164275 2011-09-01 21:11:46Z hboutemy $
53   * @since 2.0
54   * @see #execute() Mojo.execute() (from maven-plugin-api) 
55   * @see #generate(Sink, SinkFactory, Locale) MavenMultiPageReport.generate( Sink, SinkFactory, Locale ) (from maven-reporting-api)
56   * @see #executeReport(Locale) abstract executeReport( Locale )
57   */
58  public abstract class AbstractMavenReport
59      extends AbstractMojo
60      implements MavenMultiPageReport
61  {
62      /** The current sink to use */
63      private Sink sink;
64  
65      /** The sink factory to use */
66      private SinkFactory sinkFactory;
67  
68      /** The current report output directory to use */
69      private File reportOutputDirectory;
70  
71      /**
72       * This method is called when the report generation is invoked directly as a standalone Mojo.
73       *
74       * @throws MojoExecutionException if an error occurs when generating the report
75       * @see org.apache.maven.plugins.site.ReportDocumentRender
76       * @see org.apache.maven.plugin.Mojo#execute()
77       */
78      public void execute()
79          throws MojoExecutionException
80      {
81          if ( !canGenerateReport() )
82          {
83              return;
84          }
85  
86          Writer writer = null;
87          try
88          {
89              File outputDirectory = new File( getOutputDirectory() );
90  
91              String filename = getOutputName() + ".html";
92  
93              Locale locale = Locale.getDefault();
94  
95              SiteRenderingContext siteContext = new SiteRenderingContext();
96              siteContext.setDecoration( new DecorationModel() );
97              siteContext.setTemplateName( "org/apache/maven/doxia/siterenderer/resources/default-site.vm" );
98              siteContext.setLocale( locale );
99  
100             RenderingContext context = new RenderingContext( outputDirectory, filename );
101 
102             SiteRendererSink sink = new SiteRendererSink( context );
103 
104             generate( sink, null, locale );
105 
106             if ( !isExternalReport() ) // MSHARED-204: only render Doxia sink if not an external report
107             {
108                 outputDirectory.mkdirs();
109 
110                 writer =
111                     new OutputStreamWriter( new FileOutputStream( new File( outputDirectory, filename ) ), "UTF-8" );
112 
113                 getSiteRenderer().generateDocument( writer, sink, siteContext );
114 
115                 //getSiteRenderer().copyResources( siteContext, new File( project.getBasedir(), "src/site/resources" ),
116                 //                            outputDirectory );
117             }
118         }
119         catch ( RendererException e )
120         {
121             throw new MojoExecutionException(
122                 "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e );
123         }
124         catch ( IOException e )
125         {
126             throw new MojoExecutionException(
127                 "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e );
128         }
129         catch ( MavenReportException e )
130         {
131             throw new MojoExecutionException(
132                 "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e );
133         }
134         finally
135         {
136             IOUtil.close( writer );
137         }
138     }
139 
140     /**
141      * Generate a report.
142      *
143      * @param aSink the sink to use for the generation.
144      * @param aLocale the wanted locale to generate the report, could be null.
145      * @throws MavenReportException if any
146      * @deprecated use {@link #generate(Sink, SinkFactory, Locale)} instead.
147      */
148     public void generate( org.codehaus.doxia.sink.Sink aSink, Locale aLocale )
149         throws MavenReportException
150     {
151         generate( aSink, null, aLocale );
152     }
153 
154     /**
155      * Generate a report.
156      *
157      * @param aSink
158      * @param aLocale
159      * @throws MavenReportException
160      * @see org.apache.maven.reporting.MavenReport#generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)
161      * @deprecated use {@link #generate(Sink, SinkFactory, Locale)} instead.
162      */
163     public void generate( Sink aSink, Locale aLocale )
164         throws MavenReportException
165     {
166         generate( aSink, null, aLocale );
167     }
168 
169     /**
170      * This method is called when the report generation is invoked by maven-site-plugin.
171      *
172      * @param aSink
173      * @param aSinkFactory
174      * @param aLocale
175      * @throws MavenReportException
176      */
177     public void generate( Sink aSink, SinkFactory aSinkFactory, Locale aLocale )
178         throws MavenReportException
179     {
180         if ( aSink == null )
181         {
182             throw new MavenReportException( "You must specify a sink." );
183         }
184 
185         if ( !canGenerateReport() )
186         {
187             getLog().info( "This report cannot be generated as part of the current build. "
188                            + "The report name should be referenced in this line of output." );
189             return;
190         }
191 
192         this.sink = aSink;
193 
194         this.sinkFactory = aSinkFactory;
195 
196         executeReport( aLocale );
197 
198         closeReport();
199     }
200 
201     /**
202      * {@inheritDoc}
203      * @return CATEGORY_PROJECT_REPORTS
204      */
205     public String getCategoryName()
206     {
207         return CATEGORY_PROJECT_REPORTS;
208     }
209 
210     /** {@inheritDoc} */
211     public File getReportOutputDirectory()
212     {
213         if ( reportOutputDirectory == null )
214         {
215             reportOutputDirectory = new File( getOutputDirectory() );
216         }
217 
218         return reportOutputDirectory;
219     }
220 
221     /** {@inheritDoc} */
222     public void setReportOutputDirectory( File reportOutputDirectory )
223     {
224         this.reportOutputDirectory = reportOutputDirectory;
225     }
226 
227     /**
228      * Actions when closing the report.
229      */
230     protected void closeReport()
231     {
232         getSink().close();
233     }
234 
235     /**
236      * @return the sink used
237      */
238     public Sink getSink()
239     {
240         return sink;
241     }
242 
243     /**
244      * @return the sink factory used
245      */
246     public SinkFactory getSinkFactory()
247     {
248         return sinkFactory;
249     }
250 
251     /**
252      * @see org.apache.maven.reporting.MavenReport#isExternalReport()
253      * @return <tt>false</tt> by default.
254      */
255     public boolean isExternalReport()
256     {
257         return false;
258     }
259 
260     /** {@inheritDoc} */
261     public boolean canGenerateReport()
262     {
263         return true;
264     }
265 
266     /**
267      * @return the site renderer used.
268      */
269     protected abstract Renderer getSiteRenderer();
270 
271     /**
272      * The output directory when the mojo is run directly from the command line. Implementors should use this method to
273      * return the value of a mojo parameter that the user may use to customize the output directory.
274      * <br/>
275      * <strong>Note:</strong>
276      * When the mojo is run as part of a site generation, Maven will set the effective output directory via
277      * {@link org.apache.maven.reporting.MavenReport#setReportOutputDirectory(java.io.File)}. In this case, the return
278      * value of this method is irrelevant. Therefore, developers should always call {@link #getReportOutputDirectory()}
279      * to get the effective output directory for the report. The later method will eventually fallback to this method
280      * if the mojo is not run as part of a site generation.
281      *
282      * @return The path to the output directory as specified in the plugin configuration for this report.
283      */
284     protected abstract String getOutputDirectory();
285 
286     /**
287      * @return the Maven project instance.
288      */
289     protected abstract MavenProject getProject();
290 
291     /**
292      * Execute the generation of the report.
293      *
294      * @param locale the wanted locale to return the report's description, could be null.
295      * @throws MavenReportException if any
296      */
297     protected abstract void executeReport( Locale locale )
298         throws MavenReportException;
299 }