View Javadoc

1   package org.apache.maven.plugin.docck;
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.model.ReportPlugin;
23  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
24  import org.apache.maven.plugin.descriptor.MojoDescriptor;
25  import org.apache.maven.plugin.descriptor.Parameter;
26  import org.apache.maven.plugin.descriptor.PluginDescriptor;
27  import org.apache.maven.plugin.docck.reports.DocumentationReporter;
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.tools.plugin.extractor.ExtractionException;
30  import org.apache.maven.tools.plugin.scanner.MojoScanner;
31  import org.codehaus.plexus.util.IOUtil;
32  import org.codehaus.plexus.util.ReaderFactory;
33  
34  import java.io.File;
35  import java.io.IOException;
36  import java.io.Reader;
37  import java.util.ArrayList;
38  import java.util.Iterator;
39  import java.util.List;
40  
41  /**
42   * Checks a plugin's documentation for the standard minimums.
43   *
44   * @author jdcasey
45   * @goal check
46   * @aggregator
47   * @phase validate
48   */
49  public class CheckPluginDocumentationMojo
50      extends AbstractCheckDocumentationMojo
51  {
52  
53      /**
54       * Plexus component that searches for Mojos.
55       *
56       * @component
57       */
58      protected MojoScanner mojoScanner;
59  
60      // TODO: really a description of length 1 isn't all that helpful...
61      private static final int MIN_DESCRIPTION_LENGTH = 1;
62  
63      protected void checkPackagingSpecificDocumentation( MavenProject project, DocumentationReporter reporter )
64      {
65          PluginDescriptor descriptor = new PluginDescriptor();
66  
67          try
68          {
69              mojoScanner.populatePluginDescriptor( project, descriptor );
70          }
71          catch ( InvalidPluginDescriptorException e )
72          {
73              reporter.error( "Failed to parse mojo descriptors.\nError: " + e.getMessage() );
74              descriptor = null;
75          }
76          catch ( ExtractionException e )
77          {
78              reporter.error( "Failed to parse mojo descriptors.\nError: " + e.getMessage() );
79              descriptor = null;
80          }
81  
82          if ( descriptor != null )
83          {
84              List mojos = descriptor.getMojos();
85  
86              // ensure that all mojo classes are documented
87              if ( mojos != null && !mojos.isEmpty() )
88              {
89                  for ( Iterator it = mojos.iterator(); it.hasNext(); )
90                  {
91                      MojoDescriptor mojo = (MojoDescriptor) it.next();
92  
93                      String mojoDescription = mojo.getDescription();
94  
95                      if ( mojoDescription == null || mojoDescription.trim().length() < MIN_DESCRIPTION_LENGTH )
96                      {
97                          reporter.error( "Mojo: \'" + mojo.getGoal() + "\' is missing a description." );
98                      }
99  
100                     List params = mojo.getParameters();
101 
102                     // ensure that all parameters are documented
103                     if ( params != null && !params.isEmpty() )
104                     {
105                         for ( Iterator paramIterator = params.iterator(); paramIterator.hasNext(); )
106                         {
107                             Parameter param = (Parameter) paramIterator.next();
108 
109                             if ( param.getRequirement() == null && param.isEditable() )
110                             {
111                                 String paramDescription = param.getDescription();
112 
113                                 if ( paramDescription == null
114                                     || paramDescription.trim().length() < MIN_DESCRIPTION_LENGTH )
115                                 {
116                                     reporter.error( "Parameter: \'" + param.getName() + "\' in mojo: \'"
117                                         + mojo.getGoal() + "\' is missing a description." );
118                                 }
119                             }
120                         }
121                     }
122                 }
123             }
124         }
125 
126         checkConfiguredReportPlugins( project, reporter );
127 
128         checkProjectSite( project, reporter );
129     }
130 
131     protected boolean approveProjectPackaging( String packaging )
132     {
133         return "maven-plugin".equals( packaging );
134     }
135 
136     private void checkProjectSite( MavenProject project, DocumentationReporter reporter )
137     {
138         File projectSiteDirectory = new File( project.getBasedir(), siteDirectory );
139 
140         // check for site.xml
141         File siteXml = new File( projectSiteDirectory, "site.xml" );
142 
143         if ( !siteXml.exists() )
144         {
145             reporter.error( "site.xml is missing." );
146         }
147         else
148         {
149             Reader streamReader = null;
150             try
151             {
152                 streamReader = ReaderFactory.newXmlReader( siteXml );
153 
154                 String siteHtml = IOUtil.toString( streamReader );
155 
156                 if ( siteHtml.indexOf( "href=\"index.html\"" ) < 0 )
157                 {
158                     reporter.error( "site.xml is missing the link to: index.html \"Introduction\"." );
159                 }
160 
161                 if ( siteHtml.indexOf( "href=\"usage.html\"" ) < 0 )
162                 {
163                     reporter.error( "site.xml is missing the link to: usage.html \"Usage\"." );
164                 }
165 
166                 if ( siteHtml.indexOf( "href=\"plugin-info.html\"" ) < 0 )
167                 {
168                     reporter.error( "site.xml is missing the link to: plugin-info.html \"Goals\"." );
169                 }
170 
171                 if ( siteHtml.indexOf( "href=\"faq.html\"" ) < 0 )
172                 {
173                     reporter.error( "site.xml is missing the link to: faq.html \"FAQ\"." );
174                 }
175             }
176             catch ( IOException e )
177             {
178                 reporter.error( "Unable to read site.xml file: \'" + siteXml.getAbsolutePath()
179                     + "\'.\nError: " + e.getMessage() );
180             }
181             finally
182             {
183                 IOUtil.close( streamReader );
184             }
185         }
186 
187         // check for index.(apt|html|xml)[.vm]
188         if ( !findFiles( projectSiteDirectory, "index" ) )
189         {
190             reporter.error( "There is no \'index\' file in your site directory (in apt|html|xml[.vm] format)." );
191         }
192 
193         // check for usage.(apt|html|xml)[.vm]
194         if ( !findFiles( projectSiteDirectory, "usage" ) )
195         {
196             reporter.error( "There is no \'usage\' file in your site directory (in apt|html|xml[.vm] format)." );
197         }
198 
199         // check for **/examples/**.(apt|html|xml)[.vm] or **/example*.(apt|html|xml)[.vm] 
200         if ( !findFiles( projectSiteDirectory, "**/examples/*" )
201              && !findFiles( projectSiteDirectory, "**/example*" ) )
202         {
203             reporter.error( "There are no example files in your site directory (in apt|html|xml[.vm] format)."
204                 + " They should either be called \'example*.(apt|html|xml)[.vm]\'"
205                 + " or they should be located in the \'examples\' directory." );
206         }
207 
208         if ( !findFiles( projectSiteDirectory, "faq" ) )
209         {
210             reporter.error( "There is no \'faq\' file in your site directory (in apt|fml|html|xml[.vm] format)." );
211         }
212     }
213 
214     /**
215      * Checks the project configured plugins if the required report plugins are present.
216      *
217      * @param project  MavenProject to check
218      * @param reporter listener
219      * @todo maybe this should be checked default for all project?
220      */
221     private void checkConfiguredReportPlugins( MavenProject project, DocumentationReporter reporter )
222     {
223         List expectedPlugins = getRequiredPlugins();
224 
225         List reportPlugins = project.getReportPlugins();
226         if ( reportPlugins != null && reportPlugins.size() > 0 )
227         {
228             for ( Iterator plugins = reportPlugins.iterator(); plugins.hasNext(); )
229             {
230                 ReportPlugin plugin = (ReportPlugin) plugins.next();
231 
232                 expectedPlugins.remove( plugin.getArtifactId() );
233             }
234         }
235         else
236         {
237             reporter.error( "pom.xml has no report plugins configured." );
238         }
239 
240         for ( Iterator plugins = expectedPlugins.iterator(); plugins.hasNext(); )
241         {
242             reporter.error( "pom.xml is missing the report plugin: " + plugins.next().toString() + "." );
243         }
244     }
245 
246     /**
247      * Returns a List of Strings of required report plugins.
248      *
249      * @return List of report plugin artifactIds
250      */
251     private List getRequiredPlugins()
252     {
253         List list = new ArrayList();
254 
255         list.add( "maven-javadoc-plugin" );
256         list.add( "maven-jxr-plugin" );
257 
258         return list;
259     }
260 }