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 }