Coverage Report - org.apache.maven.report.projectinfo.dependencies.renderer.DependencyManagementRenderer
 
Classes in this File Line Coverage Branch Coverage Complexity
DependencyManagementRenderer
73%
66/90
53%
14/26
4.2
DependencyManagementRenderer$1
5%
1/19
0%
0/14
4.2
 
 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.metadata.ArtifactMetadataRetrievalException;
 32  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 33  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 34  
 import org.apache.maven.artifact.versioning.ArtifactVersion;
 35  
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 36  
 import org.apache.maven.artifact.versioning.VersionRange;
 37  
 import org.apache.maven.doxia.sink.Sink;
 38  
 import org.apache.maven.model.Dependency;
 39  
 import org.apache.maven.model.License;
 40  
 import org.apache.maven.plugin.logging.Log;
 41  
 import org.apache.maven.project.MavenProject;
 42  
 import org.apache.maven.project.MavenProjectBuilder;
 43  
 import org.apache.maven.project.ProjectBuildingException;
 44  
 import org.apache.maven.report.projectinfo.AbstractProjectInfoRenderer;
 45  
 import org.apache.maven.report.projectinfo.ProjectInfoReportUtils;
 46  
 import org.apache.maven.report.projectinfo.dependencies.ManagementDependencies;
 47  
 import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
 48  
 import org.codehaus.plexus.i18n.I18N;
 49  
 import org.codehaus.plexus.util.StringUtils;
 50  
 
 51  
 /**
 52  
  * @author Nick Stolwijk
 53  
  * @version $Id: DependencyManagementRenderer.java 1397965 2012-10-13 22:51:30Z hboutemy $
 54  
  * @since 2.1
 55  
  */
 56  
 public class DependencyManagementRenderer
 57  
     extends AbstractProjectInfoRenderer
 58  
 {
 59  
     private final ManagementDependencies dependencies;
 60  
 
 61  
     private final Log log;
 62  
 
 63  
     private final ArtifactMetadataSource artifactMetadataSource;
 64  
 
 65  
     private final ArtifactFactory artifactFactory;
 66  
 
 67  
     private final MavenProjectBuilder mavenProjectBuilder;
 68  
 
 69  
     private final List<ArtifactRepository> remoteRepositories;
 70  
 
 71  
     private final ArtifactRepository localRepository;
 72  
 
 73  
     private final RepositoryUtils repoUtils;
 74  
 
 75  
     /**
 76  
      * Default constructor
 77  
      *
 78  
      * @param sink
 79  
      * @param locale
 80  
      * @param i18n
 81  
      * @param log
 82  
      * @param artifactFactory
 83  
      * @param dependencies
 84  
      * @param mavenProjectBuilder
 85  
      * @param remoteRepositories
 86  
      * @param localRepository
 87  
      * @param repoUtils
 88  
      */
 89  
     public DependencyManagementRenderer( Sink sink, Locale locale, I18N i18n, Log log,
 90  
                                          ManagementDependencies dependencies,
 91  
                                          ArtifactMetadataSource artifactMetadataSource,
 92  
                                          ArtifactFactory artifactFactory, MavenProjectBuilder mavenProjectBuilder,
 93  
                                          List<ArtifactRepository> remoteRepositories,
 94  
                                          ArtifactRepository localRepository, RepositoryUtils repoUtils )
 95  
     {
 96  2
         super( sink, i18n, locale );
 97  
 
 98  2
         this.log = log;
 99  2
         this.dependencies = dependencies;
 100  2
         this.artifactMetadataSource = artifactMetadataSource;
 101  2
         this.artifactFactory = artifactFactory;
 102  2
         this.mavenProjectBuilder = mavenProjectBuilder;
 103  2
         this.remoteRepositories = remoteRepositories;
 104  2
         this.localRepository = localRepository;
 105  2
         this.repoUtils = repoUtils;
 106  2
     }
 107  
 
 108  
     // ----------------------------------------------------------------------
 109  
     // Public methods
 110  
     // ----------------------------------------------------------------------
 111  
 
 112  
     @Override
 113  
     protected String getI18Nsection()
 114  
     {
 115  18
         return "dependencyManagement";
 116  
     }
 117  
 
 118  
     @Override
 119  
     public void renderBody()
 120  
     {
 121  
         // Dependencies report
 122  
 
 123  2
         if ( !dependencies.hasDependencies() )
 124  
         {
 125  0
             startSection( getTitle() );
 126  
 
 127  0
             paragraph( getI18nString( "nolist" ) );
 128  
 
 129  0
             endSection();
 130  
 
 131  0
             return;
 132  
         }
 133  
 
 134  
         // === Section: Project Dependencies.
 135  2
         renderSectionProjectDependencies();
 136  2
     }
 137  
 
 138  
     // ----------------------------------------------------------------------
 139  
     // Private methods
 140  
     // ----------------------------------------------------------------------
 141  
 
 142  
     private void renderSectionProjectDependencies()
 143  
     {
 144  2
         startSection( getTitle() );
 145  
 
 146  
         // collect dependencies by scope
 147  2
         Map<String, List<Dependency>> dependenciesByScope = dependencies.getManagementDependenciesByScope();
 148  
 
 149  2
         renderDependenciesForAllScopes( dependenciesByScope );
 150  
 
 151  2
         endSection();
 152  2
     }
 153  
 
 154  
     private void renderDependenciesForAllScopes( Map<String, List<Dependency>> dependenciesByScope )
 155  
     {
 156  2
         renderDependenciesForScope( Artifact.SCOPE_COMPILE, dependenciesByScope.get( Artifact.SCOPE_COMPILE ) );
 157  2
         renderDependenciesForScope( Artifact.SCOPE_RUNTIME, dependenciesByScope.get( Artifact.SCOPE_RUNTIME ) );
 158  2
         renderDependenciesForScope( Artifact.SCOPE_TEST, dependenciesByScope.get( Artifact.SCOPE_TEST ) );
 159  2
         renderDependenciesForScope( Artifact.SCOPE_PROVIDED, dependenciesByScope.get( Artifact.SCOPE_PROVIDED ) );
 160  2
         renderDependenciesForScope( Artifact.SCOPE_SYSTEM, dependenciesByScope.get( Artifact.SCOPE_SYSTEM ) );
 161  2
     }
 162  
 
 163  
     private String[] getDependencyTableHeader( boolean hasClassifier )
 164  
     {
 165  2
         String groupId = getI18nString( "column.groupId" );
 166  2
         String artifactId = getI18nString( "column.artifactId" );
 167  2
         String version = getI18nString( "column.version" );
 168  2
         String classifier = getI18nString( "column.classifier" );
 169  2
         String type = getI18nString( "column.type" );
 170  2
         String license = getI18nString( "column.license" );
 171  
 
 172  2
         if ( hasClassifier )
 173  
         {
 174  0
             return new String[] { groupId, artifactId, version, classifier, type, license };
 175  
         }
 176  
 
 177  2
         return new String[] { groupId, artifactId, version, type, license };
 178  
     }
 179  
 
 180  
     private void renderDependenciesForScope( String scope, List<Dependency> artifacts )
 181  
     {
 182  10
         if ( artifacts != null )
 183  
         {
 184  
             // can't use straight artifact comparison because we want optional last
 185  2
             Collections.sort( artifacts, getDependencyComparator() );
 186  
 
 187  2
             startSection( scope );
 188  
 
 189  2
             paragraph( getI18nString( "intro." + scope ) );
 190  2
             startTable();
 191  
 
 192  2
             boolean hasClassifier = false;
 193  2
             for ( Dependency dependency : artifacts )
 194  
             {
 195  2
                 if ( StringUtils.isNotEmpty( dependency.getClassifier() ) )
 196  
                 {
 197  0
                     hasClassifier = true;
 198  0
                     break;
 199  
                 }
 200  
             }
 201  
 
 202  2
             String[] tableHeader = getDependencyTableHeader( hasClassifier );
 203  2
             tableHeader( tableHeader );
 204  
 
 205  2
             for ( Dependency dependency : artifacts )
 206  
             {
 207  2
                 tableRow( getDependencyRow( dependency, hasClassifier ) );
 208  
             }
 209  2
             endTable();
 210  
 
 211  2
             endSection();
 212  
         }
 213  10
     }
 214  
 
 215  
     @SuppressWarnings( "unchecked" )
 216  
     private String[] getDependencyRow( Dependency dependency, boolean hasClassifier )
 217  
     {
 218  2
         Artifact artifact =
 219  
             artifactFactory.createProjectArtifact( dependency.getGroupId(), dependency.getArtifactId(),
 220  
                                                    dependency.getVersion() );
 221  
 
 222  2
         StringBuilder licensesBuffer = new StringBuilder();
 223  2
         String url = null;
 224  
         try
 225  
         {
 226  2
             VersionRange range = VersionRange.createFromVersionSpec( dependency.getVersion() );
 227  
 
 228  2
             if ( range.getRecommendedVersion() == null )
 229  
             {
 230  
                 // MPIR-216: no direct version but version range: need to choose one precise version
 231  0
                 log.debug( "Resolving range for DependencyManagement on " + artifact.getId() );
 232  
 
 233  0
                 List<ArtifactVersion> versions =
 234  
                     artifactMetadataSource.retrieveAvailableVersions( artifact, localRepository, remoteRepositories );
 235  
     
 236  
                 // only use versions from range
 237  0
                 for ( Iterator<ArtifactVersion> iter = versions.iterator(); iter.hasNext(); )
 238  
                 {
 239  0
                     if ( ! range.containsVersion( iter.next() ) )
 240  
                     {
 241  0
                         iter.remove();
 242  
                     }
 243  
                 }
 244  
 
 245  
                 // select latest, assuming pom information will be the most accurate
 246  0
                 if ( versions.size() > 0 )
 247  
                 {
 248  0
                     Collections.sort( versions );
 249  
                     
 250  0
                     artifact.setVersion( versions.get( versions.size() - 1 ).toString() );
 251  0
                     log.debug( "DependencyManagement resolved: " + artifact.getId() );
 252  
                 }
 253  
             }
 254  
 
 255  2
             url =
 256  
                 ProjectInfoReportUtils.getArtifactUrl( artifactFactory, artifact, mavenProjectBuilder,
 257  
                                                        remoteRepositories, localRepository );
 258  
 
 259  2
             MavenProject artifactProject = repoUtils.getMavenProjectFromRepository( artifact );
 260  
 
 261  2
             List<License> licenses = artifactProject.getLicenses();
 262  2
             for ( License license : licenses )
 263  
             {
 264  2
                 String licenseCell = ProjectInfoReportUtils.getArtifactIdCell( license.getName(), license.getUrl() );
 265  2
                 if ( licensesBuffer.length() > 0 )
 266  
                 {
 267  0
                     licensesBuffer.append( ", " );
 268  
                 }
 269  2
                 licensesBuffer.append( licenseCell );
 270  2
             }
 271  
         }
 272  0
         catch ( InvalidVersionSpecificationException e )
 273  
         {
 274  0
             log.warn( "Unable to parse version for " + artifact.getId(), e );
 275  
         }
 276  0
         catch ( ArtifactMetadataRetrievalException e )
 277  
         {
 278  0
             log.warn( "Unable to retrieve versions for " + artifact.getId() + " from repository.", e );
 279  
         }
 280  0
         catch ( ProjectBuildingException e )
 281  
         {
 282  0
             log.warn( "Unable to create Maven project for " + artifact.getId() + " from repository.", e );
 283  2
         }
 284  
 
 285  2
         String artifactIdCell = ProjectInfoReportUtils.getArtifactIdCell( artifact.getArtifactId(), url );
 286  
 
 287  2
         if ( hasClassifier )
 288  
         {
 289  0
             return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
 290  
                 dependency.getClassifier(), dependency.getType(), licensesBuffer.toString() };
 291  
         }
 292  
 
 293  2
         return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
 294  
             dependency.getType(), licensesBuffer.toString() };
 295  
     }
 296  
 
 297  
     private Comparator<Dependency> getDependencyComparator()
 298  
     {
 299  2
         return new Comparator<Dependency>()
 300  
         {
 301  2
             public int compare( Dependency a1, Dependency a2 )
 302  
             {
 303  0
                 int result = a1.getGroupId().compareTo( a2.getGroupId() );
 304  0
                 if ( result != 0 )
 305  
                 {
 306  0
                     return result;
 307  
                 }
 308  
 
 309  0
                 result = a1.getArtifactId().compareTo( a2.getArtifactId() );
 310  0
                 if ( result != 0 )
 311  
                 {
 312  0
                     return result;
 313  
                 }
 314  
 
 315  0
                 result = a1.getType().compareTo( a2.getType() );
 316  0
                 if ( result != 0 )
 317  
                 {
 318  0
                     return result;
 319  
                 }
 320  
 
 321  0
                 if ( a1.getClassifier() == null )
 322  
                 {
 323  0
                     if ( a2.getClassifier() != null )
 324  
                     {
 325  0
                         return 1;
 326  
                     }
 327  
                 }
 328  
                 else
 329  
                 {
 330  0
                     if ( a2.getClassifier() != null )
 331  
                     {
 332  0
                         result = a1.getClassifier().compareTo( a2.getClassifier() );
 333  
                     }
 334  
                     else
 335  
                     {
 336  0
                         return -1;
 337  
                     }
 338  
                 }
 339  
 
 340  0
                 if ( result != 0 )
 341  
                 {
 342  0
                     return result;
 343  
                 }
 344  
 
 345  
                 // We don't consider the version range in the comparison, just the resolved version
 346  0
                 return a1.getVersion().compareTo( a2.getVersion() );
 347  
             }
 348  
         };
 349  
     }
 350  
 }