View Javadoc

1   package org.apache.maven.report.projectinfo.dependencies.renderer;
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.util.Collections;
23  import java.util.Comparator;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.Map;
28  
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.artifact.factory.ArtifactFactory;
31  import org.apache.maven.artifact.repository.ArtifactRepository;
32  import org.apache.maven.doxia.sink.Sink;
33  import org.apache.maven.model.Dependency;
34  import org.apache.maven.model.License;
35  import org.apache.maven.plugin.logging.Log;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.project.MavenProjectBuilder;
38  import org.apache.maven.project.ProjectBuildingException;
39  import org.apache.maven.report.projectinfo.AbstractProjectInfoRenderer;
40  import org.apache.maven.report.projectinfo.ProjectInfoReportUtils;
41  import org.apache.maven.report.projectinfo.dependencies.ManagementDependencies;
42  import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
43  import org.codehaus.plexus.i18n.I18N;
44  import org.codehaus.plexus.util.StringUtils;
45  
46  /**
47   * @author Nick Stolwijk
48   * @version $Id: DependencyManagementRenderer.java 1038048 2010-11-23 10:52:14Z vsiveton $
49   * @since 2.1
50   */
51  public class DependencyManagementRenderer
52      extends AbstractProjectInfoRenderer
53  {
54      private final ManagementDependencies dependencies;
55  
56      private final Log log;
57  
58      private final ArtifactFactory artifactFactory;
59  
60      private final MavenProjectBuilder mavenProjectBuilder;
61  
62      private final List<ArtifactRepository> remoteRepositories;
63  
64      private final ArtifactRepository localRepository;
65  
66      private final RepositoryUtils repoUtils;
67  
68      /**
69       * Default constructor
70       *
71       * @param sink
72       * @param locale
73       * @param i18n
74       * @param log
75       * @param artifactFactory
76       * @param dependencies
77       * @param mavenProjectBuilder
78       * @param remoteRepositories
79       * @param localRepository
80       * @param repoUtils
81       */
82      public DependencyManagementRenderer( Sink sink, Locale locale, I18N i18n, Log log,
83                                           ManagementDependencies dependencies, ArtifactFactory artifactFactory,
84                                           MavenProjectBuilder mavenProjectBuilder,
85                                           List<ArtifactRepository> remoteRepositories,
86                                           ArtifactRepository localRepository, RepositoryUtils repoUtils )
87      {
88          super( sink, i18n, locale );
89  
90          this.log = log;
91          this.dependencies = dependencies;
92          this.artifactFactory = artifactFactory;
93          this.mavenProjectBuilder = mavenProjectBuilder;
94          this.remoteRepositories = remoteRepositories;
95          this.localRepository = localRepository;
96          this.repoUtils = repoUtils;
97      }
98  
99      // ----------------------------------------------------------------------
100     // Public methods
101     // ----------------------------------------------------------------------
102 
103     @Override
104     protected String getI18Nsection()
105     {
106         return "dependencyManagement";
107     }
108 
109     @Override
110     public void renderBody()
111     {
112         // Dependencies report
113 
114         if ( !dependencies.hasDependencies() )
115         {
116             startSection( getTitle() );
117 
118             paragraph( getI18nString( "nolist" ) );
119 
120             endSection();
121 
122             return;
123         }
124 
125         // === Section: Project Dependencies.
126         renderSectionProjectDependencies();
127     }
128 
129     // ----------------------------------------------------------------------
130     // Private methods
131     // ----------------------------------------------------------------------
132 
133     private void renderSectionProjectDependencies()
134     {
135         startSection( getTitle() );
136 
137         // collect dependencies by scope
138         Map<String, List<Dependency>> dependenciesByScope = dependencies.getManagementDependenciesByScope();
139 
140         renderDependenciesForAllScopes( dependenciesByScope );
141 
142         endSection();
143     }
144 
145     private void renderDependenciesForAllScopes( Map<String, List<Dependency>> dependenciesByScope )
146     {
147         renderDependenciesForScope( Artifact.SCOPE_COMPILE, dependenciesByScope.get( Artifact.SCOPE_COMPILE ) );
148         renderDependenciesForScope( Artifact.SCOPE_RUNTIME, dependenciesByScope.get( Artifact.SCOPE_RUNTIME ) );
149         renderDependenciesForScope( Artifact.SCOPE_TEST, dependenciesByScope.get( Artifact.SCOPE_TEST ) );
150         renderDependenciesForScope( Artifact.SCOPE_PROVIDED, dependenciesByScope.get( Artifact.SCOPE_PROVIDED ) );
151         renderDependenciesForScope( Artifact.SCOPE_SYSTEM, dependenciesByScope.get( Artifact.SCOPE_SYSTEM ) );
152     }
153 
154     private String[] getDependencyTableHeader( boolean hasClassifier )
155     {
156         String groupId = getI18nString( "column.groupId" );
157         String artifactId = getI18nString( "column.artifactId" );
158         String version = getI18nString( "column.version" );
159         String classifier = getI18nString( "column.classifier" );
160         String type = getI18nString( "column.type" );
161         String license = getI18nString( "column.license" );
162 
163         if ( hasClassifier )
164         {
165             return new String[] { groupId, artifactId, version, classifier, type, license };
166         }
167 
168         return new String[] { groupId, artifactId, version, type, license };
169     }
170 
171     private void renderDependenciesForScope( String scope, List<Dependency> artifacts )
172     {
173         if ( artifacts != null )
174         {
175             // can't use straight artifact comparison because we want optional last
176             Collections.sort( artifacts, getDependencyComparator() );
177 
178             startSection( scope );
179 
180             paragraph( getI18nString( "intro." + scope ) );
181             startTable();
182 
183             boolean hasClassifier = false;
184             for ( Dependency dependency : artifacts )
185             {
186                 if ( StringUtils.isNotEmpty( dependency.getClassifier() ) )
187                 {
188                     hasClassifier = true;
189                     break;
190                 }
191             }
192 
193             String[] tableHeader = getDependencyTableHeader( hasClassifier );
194             tableHeader( tableHeader );
195 
196             for ( Dependency dependency : artifacts )
197             {
198                 tableRow( getDependencyRow( dependency, hasClassifier ) );
199             }
200             endTable();
201 
202             endSection();
203         }
204     }
205 
206     private String[] getDependencyRow( Dependency dependency, boolean hasClassifier )
207     {
208         Artifact artifact = artifactFactory.createParentArtifact( dependency.getGroupId(), dependency.getArtifactId(),
209                                                                   dependency.getVersion() );
210         String url =
211             ProjectInfoReportUtils.getArtifactUrl( artifactFactory, artifact, mavenProjectBuilder, remoteRepositories,
212                                                    localRepository );
213         String artifactIdCell = ProjectInfoReportUtils.getArtifactIdCell( artifact.getArtifactId(), url );
214 
215         MavenProject artifactProject;
216         StringBuffer sb = new StringBuffer();
217         try
218         {
219             artifactProject = repoUtils.getMavenProjectFromRepository( artifact );
220             @SuppressWarnings( "unchecked" )
221             List<License> licenses = artifactProject.getLicenses();
222             for ( Iterator<License> iterator = licenses.iterator(); iterator.hasNext(); )
223             {
224                 License license = iterator.next();
225                 String artifactIdCell2 = ProjectInfoReportUtils.getArtifactIdCell( license.getName(), license.getUrl() );
226                 sb.append( artifactIdCell2 );
227             }
228         }
229         catch ( ProjectBuildingException e )
230         {
231             log.warn( "Unable to create Maven project from repository.", e );
232         }
233 
234         if ( hasClassifier )
235         {
236             return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
237                 dependency.getClassifier(), dependency.getType(), sb.toString() };
238         }
239 
240         return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
241             dependency.getType(), sb.toString() };
242     }
243 
244     private Comparator<Dependency> getDependencyComparator()
245     {
246         return new Comparator<Dependency>()
247         {
248             public int compare( Dependency a1, Dependency a2 )
249             {
250                 int result = a1.getGroupId().compareTo( a2.getGroupId() );
251                 if ( result == 0 )
252                 {
253                     result = a1.getArtifactId().compareTo( a2.getArtifactId() );
254                     if ( result == 0 )
255                     {
256                         result = a1.getType().compareTo( a2.getType() );
257                         if ( result == 0 )
258                         {
259                             if ( a1.getClassifier() == null )
260                             {
261                                 if ( a2.getClassifier() != null )
262                                 {
263                                     result = 1;
264                                 }
265                             }
266                             else
267                             {
268                                 if ( a2.getClassifier() != null )
269                                 {
270                                     result = a1.getClassifier().compareTo( a2.getClassifier() );
271                                 }
272                                 else
273                                 {
274                                     result = -1;
275                                 }
276                             }
277                             if ( result == 0 )
278                             {
279                                 // We don't consider the version range in the comparison, just the resolved version
280                                 result = a1.getVersion().compareTo( a2.getVersion() );
281                             }
282                         }
283                     }
284                 }
285 
286                 return result;
287             }
288         };
289     }
290 }