View Javadoc

1   /*
2    * Copyright 2007-2013 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.exceptions;
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.List;
24  import java.util.Locale;
25  import java.util.Map;
26  import java.util.ResourceBundle;
27  
28  import org.apache.commons.lang.LocaleUtils;
29  import org.apache.commons.lang.StringUtils;
30  import org.apache.maven.artifact.Artifact;
31  import org.apache.maven.artifact.factory.ArtifactFactory;
32  import org.apache.maven.artifact.repository.ArtifactRepository;
33  import org.apache.maven.artifact.resolver.ArtifactResolver;
34  import org.apache.maven.doxia.sink.render.RenderingContext;
35  import org.apache.maven.doxia.site.decoration.Body;
36  import org.apache.maven.doxia.site.decoration.DecorationModel;
37  import org.apache.maven.doxia.siterenderer.Renderer;
38  import org.apache.maven.doxia.siterenderer.RendererException;
39  import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
40  import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
41  import org.apache.maven.plugin.MojoExecutionException;
42  import org.apache.maven.plugin.logging.Log;
43  import org.apache.maven.project.MavenProject;
44  import org.apache.maven.reporting.AbstractMavenReport;
45  import org.apache.maven.reporting.MavenReportException;
46  
47  import de.smartics.maven.util.LoggingUtils;
48  import de.smartics.maven.util.PathUtils;
49  import de.smartics.maven.util.report.ReportUtils;
50  
51  /**
52   * Generates a report on elements found in the source tree.
53   *
54   * @requiresProject
55   * @requiresDependencyResolution
56   */
57  public abstract class AbstractElementReport extends AbstractMavenReport
58  {
59    // ********************************* Fields *********************************
60  
61    // --- constants ------------------------------------------------------------
62  
63    // --- members --------------------------------------------------------------
64  
65    // ... plugin infrastructure ................................................
66  
67    /**
68     * The Maven project.
69     *
70     * @parameter expression="${project}"
71     * @required
72     * @readonly
73     */
74    protected MavenProject project;
75  
76    /**
77     * The plugin's dependencies to build the classpath for tools to be called.
78     *
79     * @parameter expression="${plugin.artifacts}"
80     * @required
81     * @readonly
82     */
83    protected List<Artifact> pluginArtifacts;
84  
85    /**
86     * The Doxia site renderer.
87     *
88     * @component
89     * @required
90     * @readonly
91     */
92    protected Renderer siteRenderer;
93  
94    /**
95     * Local Repository.
96     *
97     * @parameter expression="${localRepository}"
98     * @required
99     * @readonly
100    */
101   protected ArtifactRepository localRepository;
102 
103   /**
104    * The resolver for resolving artifacts.
105    *
106    * @component
107    * @required
108    * @readonly
109    */
110   protected ArtifactResolver resolver;
111 
112   /**
113    * The factory to create dependent artifacts.
114    *
115    * @component
116    * @required
117    * @readonly
118    */
119   protected ArtifactFactory factory;
120 
121   // ... references to artifacts of other plugins .............................
122 
123   /**
124    * Specifies the path to the directory the <code>maven-javadoc-report</code>
125    * generates the Javadoc HTML files. This allows the report generated by this
126    * plugin to reference Javadoc pages.
127    *
128    * @parameter expression="${report.javadocDir}"
129    *            default-value="${project.reporting.outputDirectory}/apidocs"
130    */
131   protected File javadocDir;
132 
133   // ... own configuration parameters .........................................
134 
135   // ... basics
136 
137   /**
138    * Specifies the directory where the report will written to. This information
139    * is only used if the report is not part of the site generation process.
140    *
141    * @parameter expression="${project.reporting.outputDirectory}"
142    * @readonly
143    */
144   protected File outputDirectory;
145 
146   /**
147    * Specifies the log level used for this plugin.
148    * <p>
149    * Allowed values are <code>SEVERE</code>, <code>WARNING</code>,
150    * <code>INFO</code> and <code>FINEST</code>.
151    * </p>
152    *
153    * @parameter expression="${exceptioncodes.logLevel}"
154    */
155   protected String logLevel;
156 
157   /**
158    * The locale to use regardless of the report. This should be set to the
159    * locale the Javadoc comment is written in. If not set, the Maven provided
160    * locale is used.
161    *
162    * @parameter expression="${exceptioncodes.locale}"
163    */
164   protected String locale;
165 
166   // ****************************** Initializer *******************************
167 
168   // ****************************** Constructors ******************************
169 
170   // ****************************** Inner Classes *****************************
171 
172   // ********************************* Methods ********************************
173 
174   // --- init -----------------------------------------------------------------
175 
176   // --- get&set --------------------------------------------------------------
177 
178   // ... plugin metadata ......................................................
179 
180   /**
181    * {@inheritDoc}
182    *
183    * @see org.apache.maven.reporting.AbstractMavenReport#getDescription(java.util.Locale)
184    */
185   public String getDescription(final Locale locale)
186   {
187     return getBundle(locale).getString("report.description");
188   }
189 
190   /**
191    * {@inheritDoc}
192    *
193    * @see org.apache.maven.reporting.AbstractMavenReport#getName(java.util.Locale)
194    */
195   public String getName(final Locale locale)
196   {
197     return getBundle(locale).getString("report.name");
198   }
199 
200   // ... plugin infrastructure ................................................
201 
202   /**
203    * Returns the maven project.
204    *
205    * @return the maven project.
206    */
207   public MavenProject getProject()
208   {
209     return project;
210   }
211 
212   /**
213    * Sets the maven project.
214    *
215    * @param project the maven project.
216    */
217   public void setProject(final MavenProject project)
218   {
219     this.project = project;
220   }
221 
222   /**
223    * {@inheritDoc}
224    *
225    * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
226    */
227   protected String getOutputDirectory()
228   {
229     return outputDirectory.getAbsolutePath();
230   }
231 
232   /**
233    * {@inheritDoc}
234    *
235    * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
236    */
237   protected Renderer getSiteRenderer()
238   {
239     return siteRenderer;
240   }
241 
242   // --- business -------------------------------------------------------------
243 
244   /**
245    * Runs the report generation.
246    *
247    * @throws MojoExecutionException on any problem encountered.
248    */
249   public void execute() throws MojoExecutionException
250   {
251     final Log log = getLog();
252     if (!canGenerateReport())
253     {
254       if (log.isInfoEnabled())
255       {
256         log.info("Nothing to generate a properties report. Skipping...");
257       }
258       return;
259     }
260 
261     LoggingUtils.configureLogger(log, logLevel);
262 
263     provideSink();
264   }
265 
266   /**
267    * Ensures that a writeable sink is provided.
268    * <p>
269    * Stolen from the changes plugin.
270    * </p>
271    *
272    * @throws MojoExecutionException if the sink cannot be created.
273    */
274   protected void provideSink() throws MojoExecutionException
275   {
276     final Locale reportLocale = determineLocale();
277     try
278     {
279       final SiteRenderingContext siteContext =
280           createSiteRenderingContext(reportLocale);
281 
282       final RenderingContext context =
283           new RenderingContext(outputDirectory, getOutputName() + ".html");
284 
285       final SiteRendererSink sink = new SiteRendererSink(context);
286       generate(sink, null, reportLocale);
287 
288       outputDirectory.mkdirs();
289 
290       final Writer writer =
291           new FileWriter(new File(outputDirectory, getOutputName() + ".html"));
292 
293       // The writer will be closed by the renderer
294       // http://maven.apache.org/doxia/doxia-sitetools/doxia-site-renderer/xref/index.html
295       siteRenderer.generateDocument(writer, sink, siteContext);
296 
297       siteRenderer.copyResources(siteContext, new File(project.getBasedir(),
298           "src/site/resources"), outputDirectory);
299 
300     }
301     catch (final RendererException e)
302     {
303       throw new MojoExecutionException("An error has occurred in "
304                                        + getName(reportLocale)
305                                        + " report generation.", e);
306     }
307     catch (final IOException e)
308     {
309       throw new MojoExecutionException("An error has occurred in "
310                                        + getName(reportLocale)
311                                        + " report generation.", e);
312     }
313     catch (final MavenReportException e)
314     {
315       throw new MojoExecutionException("An error has occurred in "
316                                        + getName(reportLocale)
317                                        + " report generation.", e);
318     }
319   }
320 
321   private SiteRenderingContext createSiteRenderingContext(
322       final Locale reportLocale) throws IOException, MojoExecutionException
323   {
324     final DecorationModel model = new DecorationModel();
325     model.setBody(new Body());
326     final Map<String, String> attributes = new HashMap<String, String>();
327     attributes.put("outputEncoding", "UTF-8");
328     final SiteRenderingContext siteContext =
329         siteRenderer.createContextForSkin(ReportUtils.getSkinArtifactFile(
330             project, localRepository, resolver, factory), attributes, model,
331             getName(reportLocale), reportLocale);
332     return siteContext;
333   }
334 
335   /**
336    * Determines the locale to use. The plugin allows the user to override the
337    * locale provided by Maven.
338    *
339    * @return the locale to use for this report.
340    */
341   private Locale determineLocale()
342   {
343     return StringUtils.isNotBlank(this.locale) ? LocaleUtils
344         .toLocale(this.locale) : Locale.getDefault();
345   }
346 
347   /**
348    * Returns the resource bundle for the given locale.
349    *
350    * @param locale the locale for which the resource bundle is requested.
351    * @return the bundle for the given locale.
352    */
353   protected ResourceBundle getBundle(final Locale locale)
354   {
355     return ResourceBundle.getBundle(getBundleName(), locale,
356         AbstractElementReport.class.getClassLoader()); // NOPMD
357   }
358 
359   /**
360    * Returns the name of the bundle to load to label report information.
361    *
362    * @return the name of the bundle to load to label report information.
363    * @see #getBundle(Locale)
364    */
365   protected abstract String getBundleName();
366 
367   @Override
368   @SuppressWarnings("unchecked")
369   public boolean canGenerateReport()
370   {
371     final String packaging = project.getPackaging();
372     return !("pom".equals(packaging) || !PathUtils.exists(project
373         .getCompileSourceRoots()));
374   }
375 
376   // --- object basics --------------------------------------------------------
377 
378 }