View Javadoc

1   package org.apache.rat.mp;
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 java.io.File;
23  import java.io.FileWriter;
24  import java.io.IOException;
25  import java.io.PrintWriter;
26  import java.io.StringWriter;
27  import java.io.Writer;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.Locale;
31  import java.util.Map;
32  import java.util.ResourceBundle;
33  
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.factory.ArtifactFactory;
36  import org.apache.maven.artifact.repository.ArtifactRepository;
37  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
38  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
39  import org.apache.maven.artifact.resolver.ArtifactResolver;
40  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
41  import org.apache.maven.artifact.versioning.VersionRange;
42  import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext;
43  import org.apache.maven.doxia.site.decoration.Body;
44  import org.apache.maven.doxia.site.decoration.DecorationModel;
45  import org.apache.maven.doxia.site.decoration.Skin;
46  import org.apache.maven.doxia.siterenderer.Renderer;
47  import org.apache.maven.doxia.siterenderer.RendererException;
48  import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
49  import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
50  import org.apache.maven.plugin.MojoExecutionException;
51  import org.apache.maven.plugin.MojoFailureException;
52  import org.apache.maven.reporting.MavenReport;
53  import org.apache.maven.reporting.MavenReportException;
54  import org.apache.rat.Defaults;
55  import org.apache.maven.doxia.sink.Sink;
56  
57  
58  /**
59   * Generates a report with RAT's output.
60   * 
61   * @goal rat
62   * @requiresDependencyResolution test
63   */
64  public class RatReportMojo extends AbstractRatMojo implements MavenReport
65  {
66      /**
67       * Specifies the directory where the report will be generated
68       * 
69       * @parameter default-value="${project.reporting.outputDirectory}"
70       * @required
71       */
72      private File outputDirectory;
73  
74      /**
75       * @component
76       */
77      private Renderer siteRenderer;
78  
79      /**
80       * @component
81       */
82      private ArtifactFactory factory;
83  
84      /**
85       * @component
86       */
87      private ArtifactResolver resolver;
88  
89      /**
90       * @parameter default-value="${localRepository}"
91       * @required
92       * @readonly
93       */
94      private ArtifactRepository localRepository;
95  
96      /**
97       * Returns the skins artifact file.
98       * 
99       * @throws MojoFailureException
100      *             An error in the plugin configuration was detected.
101      * @throws MojoExecutionException
102      *             An error occurred while searching for the artifact file.
103      * @return Artifact file
104      */
105     private File getSkinArtifactFile() throws MojoFailureException, MojoExecutionException
106     {
107         Skin skin = Skin.getDefaultSkin();
108 
109         String version = skin.getVersion();
110         Artifact artifact;
111         try
112         {
113             if ( version == null )
114             {
115                 version = Artifact.RELEASE_VERSION;
116             }
117             VersionRange versionSpec = VersionRange.createFromVersionSpec( version );
118             artifact =
119                 factory.createDependencyArtifact( skin.getGroupId(), skin.getArtifactId(), versionSpec, "jar", null,
120                                                   null );
121 
122             resolver.resolve( artifact, getProject().getRemoteArtifactRepositories(), localRepository );
123         }
124         catch ( InvalidVersionSpecificationException e )
125         {
126             throw new MojoFailureException( "The skin version '" + version + "' is not valid: " + e.getMessage() );
127         }
128         catch ( ArtifactResolutionException e )
129         {
130             throw new MojoExecutionException( "Unable to find skin", e );
131         }
132         catch ( ArtifactNotFoundException e )
133         {
134             throw new MojoFailureException( "The skin does not exist: " + e.getMessage() );
135         }
136 
137         return artifact.getFile();
138     }
139 
140     /**
141      * Creates the report as a string. Currently, this string will be embedded verbatimly into the report document.
142      * 
143      * @throws MojoFailureException
144      *             An error in the plugin configuration was detected.
145      * @throws MojoExecutionException
146      *             An error occurred while creating the report.
147      * @return Report contents
148      */
149     private String createReport() throws MojoExecutionException, MojoFailureException
150     {
151         StringWriter sw = new StringWriter();
152         PrintWriter pw = null;
153         try
154         {
155             pw = new PrintWriter( sw );
156             createReport( new PrintWriter( sw ), Defaults.getDefaultStyleSheet() );
157             final String result = sw.toString();
158             pw.close();
159             pw = null;
160             sw.close();
161             sw = null;
162             return result;
163         }
164         catch ( IOException e )
165         {
166             throw new MojoExecutionException( e.getMessage(), e );
167         }
168         finally
169         {
170             if ( pw != null )
171             {
172                 try
173                 {
174                     pw.close();
175                 }
176                 catch ( Throwable t )
177                 {
178                     // Ignore me
179                 }
180             }
181             if ( sw != null )
182             {
183                 try
184                 {
185                     sw.close();
186                 }
187                 catch ( Throwable t )
188                 {
189                     // Ignore me
190                 }
191             }
192         }
193     }
194 
195     /**
196      * Called from Maven to invoke the plugin.
197      * 
198      * @throws MojoFailureException
199      *             An error in the plugin configuration was detected.
200      * @throws MojoExecutionException
201      *             An error occurred while creating the report.
202      */
203     public void execute() throws MojoExecutionException, MojoFailureException
204     {
205         DecorationModel model = new DecorationModel();
206         model.setBody( new Body() );
207         Map attributes = new HashMap();
208         attributes.put( "outputEncoding", "UTF-8" );
209         Locale locale = Locale.getDefault();
210         try
211         {
212             SiteRenderingContext siteContext =
213                 siteRenderer.createContextForSkin( getSkinArtifactFile(), attributes, model, getName( locale ),
214                                                    locale );
215             RenderingContext context = new RenderingContext( outputDirectory, getOutputName() + ".html" );
216 
217             SiteRendererSink sink = new SiteRendererSink( context );
218             generate( sink, locale );
219 
220             outputDirectory.mkdirs();
221 
222             Writer writer = new FileWriter( new File( outputDirectory, getOutputName() + ".html" ) );
223 
224             siteRenderer.generateDocument( writer, sink, siteContext );
225 
226             siteRenderer.copyResources( siteContext, new File( getProject().getBasedir(), "src/site/resources" ),
227                                         outputDirectory );
228         }
229         catch ( IOException e )
230         {
231             throw new MojoExecutionException( e.getMessage(), e );
232         }
233         catch ( MavenReportException e )
234         {
235             throw new MojoExecutionException( e.getMessage(), e );
236         }
237         catch ( RendererException e )
238         {
239             throw new MojoExecutionException( e.getMessage(), e );
240         }
241     }
242 
243     /**
244      * Returns, whether the report may be generated.
245      * 
246      * @return Always true.
247      */
248     public boolean canGenerateReport()
249     {
250         return true;
251     }
252 
253     /**
254      * Searches for a RAT artifact in the dependency list and returns its version.
255      * 
256      * @return Version number, if found, or null.
257      */
258     private String getRatVersion()
259     {
260         for ( Iterator iter = getProject().getDependencyArtifacts().iterator(); iter.hasNext(); )
261         {
262             Artifact a = (Artifact) iter.next();
263             if ( "rat-lib".equals( a.getArtifactId() ) )
264             {
265                 return a.getVersion();
266             }
267         }
268         return null;
269     }
270 
271     /**
272      * Writes the report to the Doxia sink.
273      * 
274      * @param sink
275      *            The doxia sink, kind of a SAX handler.
276      * @param locale
277      *            The locale to use for writing the report.
278      * @throws MavenReportException
279      *             Writing the report failed.
280      */
281     public void generate( Sink sink, Locale locale ) throws MavenReportException
282     {
283         ResourceBundle bundle = getBundle( locale );
284         final String title = bundle.getString( "report.rat.title" );
285         sink.head();
286         sink.title();
287         sink.text( title );
288         sink.title_();
289         sink.head_();
290 
291         sink.body();
292 
293         sink.section1();
294         sink.sectionTitle1();
295         sink.text( title );
296         sink.sectionTitle1_();
297 
298         sink.paragraph();
299         sink.text( bundle.getString( "report.rat.link" ) + " " );
300         sink.link( bundle.getString( "report.rat.url" ) );
301         sink.text( bundle.getString( "report.rat.fullName" ) );
302         sink.link_();
303         final String ratVersion = getRatVersion();
304         if ( ratVersion != null )
305         {
306             sink.text( " " + ratVersion );
307         }
308         sink.text( "." );
309         sink.paragraph_();
310 
311         sink.paragraph();
312         sink.verbatim( true );
313         try
314         {
315             sink.text( createReport() );
316         }
317         catch ( MojoExecutionException e )
318         {
319             throw new MavenReportException( e.getMessage(), e );
320         }
321         catch ( MojoFailureException e )
322         {
323             throw new MavenReportException( e.getMessage(), e );
324         }
325         sink.verbatim_();
326         sink.paragraph_();
327         sink.section1_();	
328         sink.body_();
329     }
330 
331     /**
332      * Returns the reports category name.
333      * 
334      * @return {@link MavenReport#CATEGORY_PROJECT_REPORTS}
335      */
336     public String getCategoryName()
337     {
338         return MavenReport.CATEGORY_PROJECT_REPORTS;
339     }
340 
341     /**
342      * Returns the reports bundle
343      * 
344      * @param locale
345      *            Requested locale of the bundle
346      * @return The bundle, which is used to read localized strings.
347      */
348     private ResourceBundle getBundle( Locale locale )
349     {
350         return ResourceBundle.getBundle( "org/apache/rat/mp/rat-report", locale, getClass().getClassLoader() );
351     }
352 
353     /**
354      * Returns the reports description.
355      * 
356      * @param locale
357      *            Requested locale of the bundle
358      * @return Report description, as given by the key "report.rat.description" in the bundle.
359      */
360     public String getDescription( Locale locale )
361     {
362         return getBundle( locale ).getString( "report.rat.description" );
363     }
364 
365     /**
366      * Returns the reports name.
367      * 
368      * @param locale
369      *            Requested locale of the bundle
370      * @return Report name, as given by the key "report.rat.name" in the bundle.
371      */
372     public String getName( Locale locale )
373     {
374         return getBundle( locale ).getString( "report.rat.name" );
375     }
376 
377     /**
378      * Returns the reports file name.
379      * 
380      * @return "rat-report"
381      */
382     public String getOutputName()
383     {
384         return "rat-report";
385     }
386 
387     /**
388      * Returns the reports output directory.
389      * 
390      * @return Value of the "outputDirectory" parameter.
391      */
392     public File getReportOutputDirectory()
393     {
394         return outputDirectory;
395     }
396 
397     /**
398      * Returns, whether this is an external report.
399      * 
400      * @return Always false.
401      */
402     public boolean isExternalReport()
403     {
404         return false;
405     }
406 
407     /**
408      * Sets the reports output directory.
409      * 
410      * @param pOutputDirectory
411      *            Reports target directory.
412      */
413     public void setReportOutputDirectory( File pOutputDirectory )
414     {
415         outputDirectory = pOutputDirectory;
416     }
417 }