View Javadoc
1   package org.apache.maven.report.projectinfo;
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.artifact.Artifact;
23  import org.apache.maven.artifact.versioning.VersionRange;
24  import org.apache.maven.doxia.sink.Sink;
25  import org.apache.maven.model.Plugin;
26  import org.apache.maven.model.PluginManagement;
27  import org.apache.maven.plugin.logging.Log;
28  import org.apache.maven.plugins.annotations.Mojo;
29  import org.apache.maven.plugins.annotations.Parameter;
30  import org.apache.maven.plugins.annotations.ResolutionScope;
31  import org.apache.maven.project.DefaultProjectBuildingRequest;
32  import org.apache.maven.project.MavenProject;
33  import org.apache.maven.project.ProjectBuilder;
34  import org.apache.maven.project.ProjectBuildingException;
35  import org.apache.maven.project.ProjectBuildingRequest;
36  import org.apache.maven.repository.RepositorySystem;
37  import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
38  import org.codehaus.plexus.i18n.I18N;
39  import org.codehaus.plexus.util.StringUtils;
40  
41  import java.util.Collections;
42  import java.util.Comparator;
43  import java.util.List;
44  import java.util.Locale;
45  
46  /**
47   * Generates the Project Plugin Management report.
48   *
49   * @author Nick Stolwijk
50   * @since 2.1
51   */
52  @Mojo( name = "plugin-management", requiresDependencyResolution = ResolutionScope.TEST )
53  public class PluginManagementReport
54      extends AbstractProjectInfoReport
55  {
56      
57      /**
58       * Specify the excluded plugins. This can be a list of artifacts in the format
59       * groupId[:artifactId[:type[:version]]]. <br>
60       * Plugins matching any exclude will not be present in the report.
61       * 
62       * @since 3.0.1
63       */
64      @Parameter
65      private List<String> pluginManagementExcludes = null;
66      
67      // ----------------------------------------------------------------------
68      // Public methods
69      // ----------------------------------------------------------------------
70  
71      @Override
72      public void executeReport( Locale locale )
73      {
74          PluginManagementRenderer r =
75              new PluginManagementRenderer( getLog(), getSink(), locale, getI18N( locale ),
76                                            project.getPluginManagement().getPlugins(), project, projectBuilder,
77                                            repositorySystem, getSession().getProjectBuildingRequest(),
78                                            pluginManagementExcludes );
79          r.render();
80      }
81  
82      /** {@inheritDoc} */
83      public String getOutputName()
84      {
85          return "plugin-management";
86      }
87  
88      @Override
89      protected String getI18Nsection()
90      {
91          return "plugin-management";
92      }
93  
94      @Override
95      public boolean canGenerateReport()
96      {
97            boolean result = super.canGenerateReport();
98            if ( result && skipEmptyReport )
99            {
100               result = getProject().getPluginManagement() != null
101                       && !isEmpty( project.getPluginManagement().getPlugins() );
102           }
103 
104           return result;
105     }
106 
107     // ----------------------------------------------------------------------
108     // Private
109     // ----------------------------------------------------------------------
110 
111     /**
112      * Internal renderer class
113      *
114      * @author Nick Stolwijk
115      */
116     protected static class PluginManagementRenderer
117         extends AbstractProjectInfoRenderer
118     {
119 
120         private final Log log;
121 
122         private final List<Plugin> pluginManagement;
123 
124         private final MavenProject project;
125 
126         private final ProjectBuilder projectBuilder;
127 
128         private final RepositorySystem repositorySystem;
129 
130         private final ProjectBuildingRequest buildingRequest;
131         
132         private final PatternExcludesArtifactFilter patternExcludesArtifactFilter;
133 
134         /**
135          * @param log {@link #log}
136          * @param sink {@link Sink}
137          * @param locale {@link Locale}
138          * @param i18n {@link I18N}
139          * @param plugins {@link Plugin}
140          * @param project {@link MavenProject}
141          * @param projectBuilder {@link ProjectBuilder}
142          * @param repositorySystem {@link RepositorySystem}
143          * @param buildingRequest {@link ProjectBuildingRequest}
144          * @param excludes the list of plugins to be excluded from the report
145          */
146         public PluginManagementRenderer( Log log, Sink sink, Locale locale, I18N i18n, List<Plugin> plugins,
147                                          MavenProject project, ProjectBuilder projectBuilder,
148                                          RepositorySystem repositorySystem, ProjectBuildingRequest buildingRequest,
149                                          List<String> excludes )
150         {
151             super( sink, i18n, locale );
152 
153             this.log = log;
154 
155             this.pluginManagement = plugins;
156 
157             this.project = project;
158 
159             this.projectBuilder = projectBuilder;
160 
161             this.repositorySystem = repositorySystem;
162 
163             this.buildingRequest = buildingRequest;
164 
165             this.patternExcludesArtifactFilter = new PatternExcludesArtifactFilter( excludes );
166         }
167 
168         @Override
169         protected String getI18Nsection()
170         {
171             return "plugin-management";
172         }
173 
174         @Override
175         public void renderBody()
176         {
177             PluginManagement projectPluginManagement = project.getPluginManagement();
178 
179             if ( projectPluginManagement == null || projectPluginManagement.getPlugins() == null
180                 || projectPluginManagement.getPlugins().isEmpty() )
181             {
182                 startSection( getTitle() );
183 
184                 paragraph( getI18nString( "nolist" ) );
185 
186                 endSection();
187 
188                 return;
189             }
190 
191             // === Section: Project PluginManagement.
192             renderSectionPluginManagement();
193         }
194 
195         private void renderSectionPluginManagement()
196         {
197             String[] tableHeader = getPluginTableHeader();
198 
199             startSection( getTitle() );
200 
201             // can't use straight artifact comparison because we want optional last
202             Collections.sort( pluginManagement, getPluginComparator() );
203 
204             startTable();
205             tableHeader( tableHeader );
206 
207             ProjectBuildingRequest buildRequest = new DefaultProjectBuildingRequest( buildingRequest );
208             buildRequest.setRemoteRepositories( project.getPluginArtifactRepositories() );
209             
210             for ( Plugin plugin : pluginManagement )
211             {
212                 VersionRange versionRange;
213                 if ( StringUtils.isEmpty( plugin.getVersion() ) )
214                 {
215                     versionRange = VersionRange.createFromVersion( Artifact.RELEASE_VERSION );
216                 }
217                 else
218                 {
219                     versionRange = VersionRange.createFromVersion( plugin.getVersion() );
220                 }
221 
222                 Artifact pluginArtifact = repositorySystem.createProjectArtifact( plugin.getGroupId(), plugin
223                     .getArtifactId(), versionRange.toString() );
224 
225                 if ( patternExcludesArtifactFilter.include( pluginArtifact ) )
226                 {
227                     try
228                     {
229                         MavenProject pluginProject =
230                             projectBuilder.build( pluginArtifact, buildingRequest ).getProject();
231 
232                         tableRow( getPluginRow( pluginProject.getGroupId(), pluginProject.getArtifactId(),
233                                                 pluginProject.getVersion(), pluginProject.getUrl() ) );
234                     }
235                     catch ( ProjectBuildingException e )
236                     {
237                         log.info( "Could not build project for: " + plugin.getArtifactId() + ":" + e.getMessage(), e );
238                         tableRow( getPluginRow( plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion(),
239                                                 null ) );
240                     }
241                 }
242                 else
243                 {
244                     log.debug( "Excluding plugin " + pluginArtifact.getId() + " from report" );
245                 }
246             }
247             endTable();
248 
249             endSection();
250         }
251 
252         // ----------------------------------------------------------------------
253         // Private methods
254         // ----------------------------------------------------------------------
255 
256         private String[] getPluginTableHeader()
257         {
258             // reused key...
259             String groupId = getI18nString( "dependency-management", "column.groupId" );
260             String artifactId = getI18nString( "dependency-management", "column.artifactId" );
261             String version = getI18nString( "dependency-management", "column.version" );
262             return new String[] { groupId, artifactId, version };
263         }
264 
265         private String[] getPluginRow( String groupId, String artifactId, String version, String link )
266         {
267             artifactId = ProjectInfoReportUtils.getArtifactIdCell( artifactId, link );
268             return new String[] { groupId, artifactId, version };
269         }
270 
271         private Comparator<Plugin> getPluginComparator()
272         {
273             return new Comparator<Plugin>()
274             {
275                 /** {@inheritDoc} */
276                 public int compare( Plugin a1, Plugin a2 )
277                 {
278                     int result = a1.getGroupId().compareTo( a2.getGroupId() );
279                     if ( result == 0 )
280                     {
281                         result = a1.getArtifactId().compareTo( a2.getArtifactId() );
282                     }
283                     return result;
284                 }
285             };
286         }
287 
288     }
289 }