View Javadoc

1   /*
2    * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.plugin.buildmetadata;
17  
18  import java.io.File;
19  import java.io.FileWriter;
20  import java.io.IOException;
21  import java.io.Writer;
22  import java.util.HashMap;
23  import java.util.Locale;
24  import java.util.Map;
25  import java.util.ResourceBundle;
26  
27  import org.apache.commons.lang.LocaleUtils;
28  import org.apache.maven.artifact.factory.ArtifactFactory;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.resolver.ArtifactResolver;
31  import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext;
32  import org.apache.maven.doxia.site.decoration.Body;
33  import org.apache.maven.doxia.site.decoration.DecorationModel;
34  import org.apache.maven.doxia.siterenderer.Renderer;
35  import org.apache.maven.doxia.siterenderer.RendererException;
36  import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
37  import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
38  import org.apache.maven.plugin.MojoExecutionException;
39  import org.apache.maven.plugin.logging.Log;
40  import org.apache.maven.project.MavenProject;
41  import org.apache.maven.reporting.AbstractMavenReport;
42  import org.apache.maven.reporting.MavenReportException;
43  import org.codehaus.plexus.util.StringUtils;
44  
45  import de.smartics.maven.util.LoggingUtils;
46  import de.smartics.maven.util.report.ReportUtils;
47  
48  /**
49   * The abstract base implementation for reports.
50   *
51   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
52   * @version $Revision:591 $
53   */
54  public abstract class AbstractReportMojo extends AbstractMavenReport
55  {
56    // ********************************* Fields *********************************
57  
58    // --- constants ------------------------------------------------------------
59  
60    // --- members --------------------------------------------------------------
61  
62    // ... plugin infrastructure ................................................
63  
64    /**
65     * The Maven project.
66     *
67     * @parameter expression="${project}"
68     * @required
69     * @readonly
70     * @since 1.0
71     */
72    protected MavenProject project;
73  
74    /**
75     * The Doxia site renderer.
76     *
77     * @component
78     * @required
79     * @readonly
80     * @since 1.0
81     */
82    protected Renderer siteRenderer;
83  
84    /**
85     * Local Repository.
86     *
87     * @parameter expression="${localRepository}"
88     * @required
89     * @readonly
90     * @since 1.0
91     */
92    protected ArtifactRepository localRepository;
93  
94    /**
95     * The resolver for resolving artifacts.
96     *
97     * @component
98     * @required
99     * @readonly
100    * @since 1.0
101    */
102   protected ArtifactResolver resolver;
103 
104   /**
105    * The factory to create dependent artifacts.
106    *
107    * @component
108    * @required
109    * @readonly
110    * @since 1.0
111    */
112   protected ArtifactFactory factory;
113 
114   // ... report configuration parameters ......................................
115 
116   /**
117    * Specifies the directory where the report will written to. This information
118    * is only used if the report is not part of the site generation process.
119    *
120    * @parameter expression="${project.reporting.outputDirectory}"
121    * @readonly
122    * @since 1.0
123    */
124   protected File outputDirectory;
125 
126   /**
127    * Specifies the log level <code>buildmetadata.logLevel</code> used for this
128    * plugin.
129    * <p>
130    * Allowed values are <code>SEVERE</code>, <code>WARNING</code>,
131    * <code>INFO</code> and <code>FINEST</code>.
132    * </p>
133    *
134    * @parameter expression="${buildmetadata.logLevel}"
135    * @since 1.0
136    */
137   protected String logLevel;
138 
139   /**
140    * The locale to use regardless of the report. This should be set to the
141    * locale the Javadoc comment is written in. If not set, the Maven provided
142    * locale is used.
143    *
144    * @parameter expression="${buildmetadata.locale}"
145    * @since 1.0
146    */
147   protected String locale;
148 
149   /**
150    * A simple flag to skip the generation of the reports. If set on the command
151    * line use <code>-Dbuildmetadata.skip</code>.
152    *
153    * @parameter expression="${buildmetadata.skip}" default-value="false"
154    * @since 1.0
155    */
156   protected boolean skip;
157 
158   // ****************************** Initializer *******************************
159 
160   // ****************************** Constructors ******************************
161 
162   // ****************************** Inner Classes *****************************
163 
164   // ********************************* Methods ********************************
165 
166   // --- init -----------------------------------------------------------------
167 
168   // --- get&set --------------------------------------------------------------
169 
170   // ... plugin infrastructure ................................................
171 
172   /**
173    * {@inheritDoc}
174    *
175    * @see org.apache.maven.reporting.AbstractMavenReport#getProject()
176    */
177   @Override
178   protected final MavenProject getProject()
179   {
180     return project;
181   }
182 
183   /**
184    * {@inheritDoc}
185    *
186    * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
187    */
188   @Override
189   protected final Renderer getSiteRenderer()
190   {
191     return siteRenderer;
192   }
193 
194   // ... report configuration parameters ......................................
195 
196   // ... basics
197 
198   /**
199    * {@inheritDoc}
200    *
201    * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
202    */
203   @Override
204   protected final String getOutputDirectory()
205   {
206     return outputDirectory.getAbsolutePath();
207   }
208 
209   // --- business -------------------------------------------------------------
210 
211   // CHECKSTYLE:OFF
212   /**
213    * Runs the report generation.
214    *
215    * @throws MojoExecutionException on any problem encountered.
216    */
217   public void execute() throws MojoExecutionException // CHECKSTYLE:ON
218   {
219     final Log log = getLog();
220     if (!canGenerateReport())
221     {
222       if (log.isInfoEnabled())
223       {
224         log.info("Report '" + getName(Locale.getDefault())
225                  + "' skipped due to offline mode.");
226       }
227       return;
228     }
229 
230     LoggingUtils.configureLogger(log, logLevel);
231 
232     provideSink();
233   }
234 
235   // CHECKSTYLE:OFF
236   /**
237    * {@inheritDoc}
238    *
239    * @see org.apache.maven.reporting.AbstractMavenReport#canGenerateReport()
240    */
241   @Override
242   public boolean canGenerateReport() // CHECKSTYLE:ON
243   {
244     return super.canGenerateReport() && !skip;
245   }
246 
247   // CHECKSTYLE:OFF
248   /**
249    * {@inheritDoc}
250    * <p>
251    * Configures the plugin logger.
252    * </p>
253    *
254    * @see org.apache.maven.reporting.AbstractMavenReport#executeReport(java.util.Locale)
255    */
256   @Override
257   protected void executeReport(final Locale locale) throws MavenReportException // CHECKSTYLE:ON
258   {
259     final Log log = getLog();
260     LoggingUtils.configureLogger(log, logLevel);
261   }
262 
263   /**
264    * Ensures that a writeable sink is provided.
265    * <p>
266    * Stolen from the changes plugin.
267    * </p>
268    *
269    * @throws MojoExecutionException if the sink cannot be created.
270    */
271   protected final void provideSink() throws MojoExecutionException
272   {
273     final Locale reportLocale = determineLocale();
274 
275     try
276     {
277       final DecorationModel model = new DecorationModel();
278       model.setBody(new Body());
279       final Map<String, String> attributes = new HashMap<String, String>();
280       attributes.put("outputEncoding", "UTF-8"); // TODO correct???
281       final SiteRenderingContext siteContext =
282           siteRenderer.createContextForSkin(ReportUtils.getSkinArtifactFile(
283               project, localRepository, resolver, factory), attributes, model,
284               getName(reportLocale), reportLocale);
285 
286       final RenderingContext context =
287           new RenderingContext(outputDirectory, getOutputName() + ".html");
288 
289       final SiteRendererSink sink = new SiteRendererSink(context);
290       generate(sink, reportLocale);
291 
292       provideDir();
293 
294       // The writer will be closed by the renderer
295       // http://maven.apache.org/doxia/doxia-sitetools/doxia-site-renderer/xref/index.html
296       final Writer writer =
297           new FileWriter(new File(outputDirectory, getOutputName() + ".html"));
298       siteRenderer.generateDocument(writer, sink, siteContext);
299 
300       siteRenderer.copyResources(siteContext, new File(project.getBasedir(),
301           "src/site/resources"), outputDirectory);
302     }
303     catch (final RendererException e)
304     {
305       throw new MojoExecutionException(createErrorMessage(reportLocale), e);
306     }
307     catch (final IOException e)
308     {
309       throw new MojoExecutionException(createErrorMessage(reportLocale), e);
310     }
311     catch (final MavenReportException e)
312     {
313       throw new MojoExecutionException(createErrorMessage(reportLocale), e);
314     }
315   }
316 
317   private void provideDir() throws IOException
318   {
319     if (!outputDirectory.exists())
320     {
321       if (!outputDirectory.mkdirs()) // NOPMD
322       {
323         throw new IOException("Cannot generate directories '"
324                               + outputDirectory.getPath() + "'");
325       }
326     }
327   }
328 
329   /**
330    * Creates an error message signaling a problem with the report generation.
331    *
332    * @param reportLocale the locale to select the report name.
333    * @return the error message for failed report generation.
334    */
335   private String createErrorMessage(final Locale reportLocale)
336   {
337     return "An error has occurred in " + getName(reportLocale)
338            + " report generation.";
339   }
340 
341   /**
342    * Determines the locale to use. The plugin allows the user to override the
343    * locale provided by Maven.
344    *
345    * @return the locale to use for this report.
346    */
347   private Locale determineLocale()
348   {
349     return StringUtils.isNotBlank(this.locale) ? LocaleUtils
350         .toLocale(this.locale) : Locale.getDefault();
351   }
352 
353   /**
354    * Returns the resource bundle for the given locale.
355    *
356    * @param locale the locale for which the resource bundle is requested.
357    * @return the bundle for the given locale.
358    */
359   protected final ResourceBundle getBundle(final Locale locale)
360   {
361     return ResourceBundle.getBundle(
362         "de.smartics.maven.buildmetadata.BuildReport", locale);
363   }
364 
365   // --- object basics --------------------------------------------------------
366 
367 }