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