Coverage Report - org.apache.maven.report.projectinfo.dependencies.renderer.DependenciesRenderer
 
Classes in this File Line Coverage Branch Coverage Complexity
DependenciesRenderer
46 %
272/596
32 %
59/186
4,279
DependenciesRenderer$1
100 %
6/6
50 %
1/2
4,279
DependenciesRenderer$2
12 %
1/8
0 %
0/8
4,279
DependenciesRenderer$FileDecimalFormat
25 %
4/16
0 %
0/4
4,279
DependenciesRenderer$TotalCell
0 %
0/57
0 %
0/32
4,279
 
 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.io.File;
 23  
 import java.io.IOException;
 24  
 import java.net.URL;
 25  
 import java.security.NoSuchAlgorithmException;
 26  
 import java.security.SecureRandom;
 27  
 import java.text.DecimalFormat;
 28  
 import java.text.DecimalFormatSymbols;
 29  
 import java.text.FieldPosition;
 30  
 import java.util.ArrayList;
 31  
 import java.util.Collections;
 32  
 import java.util.Comparator;
 33  
 import java.util.HashMap;
 34  
 import java.util.HashSet;
 35  
 import java.util.Iterator;
 36  
 import java.util.List;
 37  
 import java.util.Locale;
 38  
 import java.util.Map;
 39  
 import java.util.Set;
 40  
 import java.util.SortedSet;
 41  
 import java.util.TreeSet;
 42  
 
 43  
 import org.apache.maven.artifact.Artifact;
 44  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 45  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 46  
 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
 47  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 48  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 49  
 import org.apache.maven.doxia.parser.Parser;
 50  
 import org.apache.maven.doxia.sink.Sink;
 51  
 import org.apache.maven.doxia.util.HtmlTools;
 52  
 import org.apache.maven.model.License;
 53  
 import org.apache.maven.plugin.logging.Log;
 54  
 import org.apache.maven.project.MavenProject;
 55  
 import org.apache.maven.project.MavenProjectBuilder;
 56  
 import org.apache.maven.project.ProjectBuildingException;
 57  
 import org.apache.maven.report.projectinfo.ProjectInfoReportUtils;
 58  
 import org.apache.maven.report.projectinfo.dependencies.Dependencies;
 59  
 import org.apache.maven.report.projectinfo.dependencies.DependenciesReportConfiguration;
 60  
 import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
 61  
 import org.apache.maven.reporting.AbstractMavenReportRenderer;
 62  
 import org.apache.maven.settings.Settings;
 63  
 import org.apache.maven.shared.dependency.tree.DependencyNode;
 64  
 import org.apache.maven.shared.jar.JarData;
 65  
 import org.codehaus.plexus.i18n.I18N;
 66  
 import org.codehaus.plexus.util.StringUtils;
 67  
 
 68  
 /**
 69  
  * Renderer the dependencies report.
 70  
  *
 71  
  * @version $Id: DependenciesRenderer.java 748483 2009-02-27 10:56:55Z vsiveton $
 72  
  * @since 2.1
 73  
  */
 74  
 public class DependenciesRenderer
 75  
     extends AbstractMavenReportRenderer
 76  
 {
 77  
     /** URL for the 'icon_info_sml.gif' image */
 78  
     private static final String IMG_INFO_URL = "./images/icon_info_sml.gif";
 79  
 
 80  
     /** URL for the 'close.gif' image */
 81  
     private static final String IMG_CLOSE_URL = "./images/close.gif";
 82  
 
 83  
     /** Random used to generate a UID */
 84  
     private static final SecureRandom RANDOM;
 85  
 
 86  
     /** Used to format decimal values in the "Dependency File Details" table */
 87  1
     protected static final DecimalFormat DEFAULT_DECIMAL_FORMAT = new DecimalFormat( "#,##0" );
 88  
 
 89  1
     private static final Set JAR_SUBTYPE = new HashSet();
 90  
 
 91  
     /**
 92  
      * An HTML script tag with the Javascript used by the dependencies report.
 93  
      */
 94  
     private static final String JAVASCRIPT;
 95  
 
 96  
     private final DependencyNode dependencyTreeNode;
 97  
 
 98  
     private final Dependencies dependencies;
 99  
 
 100  
     private final DependenciesReportConfiguration configuration;
 101  
 
 102  
     private final Locale locale;
 103  
 
 104  
     private final I18N i18n;
 105  
 
 106  
     private final Log log;
 107  
 
 108  
     private final Settings settings;
 109  
 
 110  
     private final RepositoryUtils repoUtils;
 111  
 
 112  
     /** Used to format file length values */
 113  
     private final DecimalFormat fileLengthDecimalFormat;
 114  
 
 115  
     /**
 116  
      * @since 2.1.1
 117  
      */
 118  
     private int section;
 119  
 
 120  
     /**
 121  
      * Will be filled with license name / set of projects.
 122  
      */
 123  1
     private Map licenseMap = new HashMap()
 124  
     {
 125  
         /** {@inheritDoc} */
 126  1
         public Object put( Object key, Object value )
 127  
         {
 128  
             // handle multiple values as a set to avoid duplicates
 129  2
             SortedSet valueList = (SortedSet) get( key );
 130  2
             if ( valueList == null )
 131  
             {
 132  2
                 valueList = new TreeSet();
 133  
             }
 134  2
             valueList.add( value );
 135  2
             return super.put( key, valueList );
 136  
         }
 137  
     };
 138  
 
 139  
     private final ArtifactFactory artifactFactory;
 140  
 
 141  
     private final MavenProjectBuilder mavenProjectBuilder;
 142  
 
 143  
     private final List remoteRepositories;
 144  
 
 145  
     private final ArtifactRepository localRepository;
 146  
 
 147  
     static
 148  
     {
 149  1
         JAR_SUBTYPE.add( "jar" );
 150  1
         JAR_SUBTYPE.add( "war" );
 151  1
         JAR_SUBTYPE.add( "ear" );
 152  1
         JAR_SUBTYPE.add( "sar" );
 153  1
         JAR_SUBTYPE.add( "rar" );
 154  1
         JAR_SUBTYPE.add( "par" );
 155  1
         JAR_SUBTYPE.add( "ejb" );
 156  
 
 157  
         try
 158  
         {
 159  1
             RANDOM = SecureRandom.getInstance( "SHA1PRNG" );
 160  
         }
 161  0
         catch ( NoSuchAlgorithmException e )
 162  
         {
 163  0
             throw new RuntimeException( e );
 164  1
         }
 165  
 
 166  1
         StringBuffer sb = new StringBuffer();
 167  1
         sb.append( "<script language=\"javascript\" type=\"text/javascript\">" ).append( "\n" );
 168  1
         sb.append( "      function toggleDependencyDetail( divId, imgId )" ).append( "\n" );
 169  1
         sb.append( "      {" ).append( "\n" );
 170  1
         sb.append( "        var div = document.getElementById( divId );" ).append( "\n" );
 171  1
         sb.append( "        var img = document.getElementById( imgId );" ).append( "\n" );
 172  1
         sb.append( "        if( div.style.display == '' )" ).append( "\n" );
 173  1
         sb.append( "        {" ).append( "\n" );
 174  1
         sb.append( "          div.style.display = 'none';" ).append( "\n" );
 175  1
         sb.append( "          img.src='" + IMG_INFO_URL + "';" ).append( "\n" );
 176  1
         sb.append( "        }" ).append( "\n" );
 177  1
         sb.append( "        else" ).append( "\n" );
 178  1
         sb.append( "        {" ).append( "\n" );
 179  1
         sb.append( "          div.style.display = '';" ).append( "\n" );
 180  1
         sb.append( "          img.src='" + IMG_CLOSE_URL + "';" ).append( "\n" );
 181  1
         sb.append( "        }" ).append( "\n" );
 182  1
         sb.append( "      }" ).append( "\n" );
 183  1
         sb.append( "</script>" ).append( "\n" );
 184  1
         JAVASCRIPT = sb.toString();
 185  1
     }
 186  
 
 187  
     /**
 188  
      * Default constructor.
 189  
      *
 190  
      * @param sink
 191  
      * @param locale
 192  
      * @param i18n
 193  
      * @param log
 194  
      * @param settings
 195  
      * @param dependencies
 196  
      * @param dependencyTreeNode
 197  
      * @param config
 198  
      * @param repoUtils
 199  
      * @param artifactFactory
 200  
      * @param mavenProjectBuilder
 201  
      * @param remoteRepositories
 202  
      * @param localRepository
 203  
      */
 204  
     public DependenciesRenderer( Sink sink, Locale locale, I18N i18n, Log log, Settings settings,
 205  
                                  Dependencies dependencies, DependencyNode dependencyTreeNode,
 206  
                                  DependenciesReportConfiguration config, RepositoryUtils repoUtils,
 207  
                                  ArtifactFactory artifactFactory, MavenProjectBuilder mavenProjectBuilder,
 208  
                                  List remoteRepositories, ArtifactRepository localRepository )
 209  
     {
 210  1
         super( sink );
 211  
 
 212  1
         this.locale = locale;
 213  1
         this.i18n = i18n;
 214  1
         this.log = log;
 215  1
         this.settings = settings;
 216  1
         this.dependencies = dependencies;
 217  1
         this.dependencyTreeNode = dependencyTreeNode;
 218  1
         this.repoUtils = repoUtils;
 219  1
         this.configuration = config;
 220  1
         this.artifactFactory = artifactFactory;
 221  1
         this.mavenProjectBuilder = mavenProjectBuilder;
 222  1
         this.remoteRepositories = remoteRepositories;
 223  1
         this.localRepository = localRepository;
 224  
 
 225  
         // Using the right set of symbols depending of the locale
 226  1
         DEFAULT_DECIMAL_FORMAT.setDecimalFormatSymbols( new DecimalFormatSymbols( locale ) );
 227  
 
 228  1
         this.fileLengthDecimalFormat = new FileDecimalFormat( i18n, locale );
 229  1
         this.fileLengthDecimalFormat.setDecimalFormatSymbols( new DecimalFormatSymbols( locale ) );
 230  1
     }
 231  
 
 232  
     // ----------------------------------------------------------------------
 233  
     // Public methods
 234  
     // ----------------------------------------------------------------------
 235  
 
 236  
     /** {@inheritDoc} */
 237  
     public String getTitle()
 238  
     {
 239  2
         return getReportString( "report.dependencies.title" );
 240  
     }
 241  
 
 242  
     /** {@inheritDoc} */
 243  
     public void renderBody()
 244  
     {
 245  
         // Dependencies report
 246  
 
 247  1
         if ( !dependencies.hasDependencies() )
 248  
         {
 249  0
             startSection( getTitle() );
 250  
 
 251  
             // TODO: should the report just be excluded?
 252  0
             paragraph( getReportString( "report.dependencies.nolist" ) );
 253  
 
 254  0
             endSection();
 255  
 
 256  0
             return;
 257  
         }
 258  
 
 259  
         // === Section: Project Dependencies.
 260  1
         renderSectionProjectDependencies();
 261  
 
 262  
         // === Section: Project Transitive Dependencies.
 263  1
         renderSectionProjectTransitiveDependencies();
 264  
 
 265  
         // === Section: Project Dependency Graph.
 266  1
         renderSectionProjectDependencyGraph();
 267  
 
 268  
         // === Section: Licenses
 269  1
         renderSectionDependencyLicenseListing();
 270  
 
 271  1
         if ( configuration.getDependencyDetailsEnabled() )
 272  
         {
 273  
             // === Section: Dependency File Details.
 274  0
             renderSectionDependencyFileDetails();
 275  
         }
 276  
 
 277  1
         if ( configuration.getDependencyLocationsEnabled() )
 278  
         {
 279  
             // === Section: Dependency Repository Locations.
 280  0
             renderSectionDependencyRepositoryLocations();
 281  
         }
 282  1
     }
 283  
 
 284  
     // ----------------------------------------------------------------------
 285  
     // Protected methods
 286  
     // ----------------------------------------------------------------------
 287  
 
 288  
     /** {@inheritDoc} */
 289  
     // workaround for MPIR-140
 290  
     // TODO Remove me when maven-reporting-impl:2.1-SNAPSHOT is out
 291  
     protected void startSection( String name )
 292  
     {
 293  6
         section = section + 1;
 294  
 
 295  6
         super.sink.anchor( HtmlTools.encodeId( name ) );
 296  6
         super.sink.anchor_();
 297  
 
 298  6
         switch ( section )
 299  
         {
 300  
             case 1:
 301  4
                 sink.section1();
 302  4
                 sink.sectionTitle1();
 303  4
                 break;
 304  
             case 2:
 305  2
                 sink.section2();
 306  2
                 sink.sectionTitle2();
 307  2
                 break;
 308  
             case 3:
 309  0
                 sink.section3();
 310  0
                 sink.sectionTitle3();
 311  0
                 break;
 312  
             case 4:
 313  0
                 sink.section4();
 314  0
                 sink.sectionTitle4();
 315  0
                 break;
 316  
             case 5:
 317  0
                 sink.section5();
 318  0
                 sink.sectionTitle5();
 319  0
                 break;
 320  
 
 321  
             default:
 322  
                 // TODO: warning - just don't start a section
 323  
                 break;
 324  
         }
 325  
 
 326  6
         text( name );
 327  
 
 328  6
         switch ( section )
 329  
         {
 330  
             case 1:
 331  4
                 sink.sectionTitle1_();
 332  4
                 break;
 333  
             case 2:
 334  2
                 sink.sectionTitle2_();
 335  2
                 break;
 336  
             case 3:
 337  0
                 sink.sectionTitle3_();
 338  0
                 break;
 339  
             case 4:
 340  0
                 sink.sectionTitle4_();
 341  0
                 break;
 342  
             case 5:
 343  0
                 sink.sectionTitle5_();
 344  0
                 break;
 345  
 
 346  
             default:
 347  
                 // TODO: warning - just don't start a section
 348  
                 break;
 349  
         }
 350  6
     }
 351  
 
 352  
     /** {@inheritDoc} */
 353  
     // workaround for MPIR-140
 354  
     // TODO Remove me when maven-reporting-impl:2.1-SNAPSHOT is out
 355  
     protected void endSection()
 356  
     {
 357  6
         switch ( section )
 358  
         {
 359  
             case 1:
 360  4
                 sink.section1_();
 361  4
                 break;
 362  
             case 2:
 363  2
                 sink.section2_();
 364  2
                 break;
 365  
             case 3:
 366  0
                 sink.section3_();
 367  0
                 break;
 368  
             case 4:
 369  0
                 sink.section4_();
 370  0
                 break;
 371  
             case 5:
 372  0
                 sink.section5_();
 373  0
                 break;
 374  
 
 375  
             default:
 376  
                 // TODO: warning - just don't start a section
 377  
                 break;
 378  
         }
 379  
 
 380  6
         section = section - 1;
 381  
 
 382  6
         if ( section < 0 )
 383  
         {
 384  0
             throw new IllegalStateException( "Too many closing sections" );
 385  
         }
 386  6
     }
 387  
 
 388  
     // ----------------------------------------------------------------------
 389  
     // Private methods
 390  
     // ----------------------------------------------------------------------
 391  
 
 392  
     /**
 393  
      * @param withClassifier <code>true</code> to include the classifier column, <code>false</code> otherwise.
 394  
      * @param withOptional <code>true</code> to include the optional column, <code>false</code> otherwise.
 395  
      * @return the dependency table header with/without classifier/optional column
 396  
      * @see #renderArtifactRow(Artifact, boolean, boolean)
 397  
      */
 398  
     private String[] getDependencyTableHeader( boolean withClassifier, boolean withOptional )
 399  
     {
 400  1
         String groupId = getReportString( "report.dependencies.column.groupId" );
 401  1
         String artifactId = getReportString( "report.dependencies.column.artifactId" );
 402  1
         String version = getReportString( "report.dependencies.column.version" );
 403  1
         String classifier = getReportString( "report.dependencies.column.classifier" );
 404  1
         String type = getReportString( "report.dependencies.column.type" );
 405  1
         String optional = getReportString( "report.dependencies.column.optional" );
 406  
 
 407  1
         if ( withClassifier )
 408  
         {
 409  0
             if ( withOptional )
 410  
             {
 411  0
                 return new String[] { groupId, artifactId, version, classifier, type, optional };
 412  
             }
 413  
 
 414  0
             return new String[] { groupId, artifactId, version, classifier, type };
 415  
         }
 416  
 
 417  1
         if ( withOptional )
 418  
         {
 419  0
             return new String[] { groupId, artifactId, version, type, optional };
 420  
         }
 421  
 
 422  1
         return new String[] { groupId, artifactId, version, type };
 423  
     }
 424  
 
 425  
     private void renderSectionProjectDependencies()
 426  
     {
 427  1
         startSection( getTitle() );
 428  
 
 429  
         // collect dependencies by scope
 430  1
         Map dependenciesByScope = dependencies.getDependenciesByScope( false );
 431  
 
 432  1
         renderDependenciesForAllScopes( dependenciesByScope );
 433  
 
 434  1
         endSection();
 435  1
     }
 436  
 
 437  
     /**
 438  
      * @param dependenciesByScope map with supported scopes as key and a list of <code>Artifact</code> as values.
 439  
      * @see Artifact#SCOPE_COMPILE
 440  
      * @see Artifact#SCOPE_PROVIDED
 441  
      * @see Artifact#SCOPE_RUNTIME
 442  
      * @see Artifact#SCOPE_SYSTEM
 443  
      * @see Artifact#SCOPE_TEST
 444  
      */
 445  
     private void renderDependenciesForAllScopes( Map dependenciesByScope )
 446  
     {
 447  1
         renderDependenciesForScope( Artifact.SCOPE_COMPILE, (List) dependenciesByScope.get( Artifact.SCOPE_COMPILE ) );
 448  1
         renderDependenciesForScope( Artifact.SCOPE_RUNTIME, (List) dependenciesByScope.get( Artifact.SCOPE_RUNTIME ) );
 449  1
         renderDependenciesForScope( Artifact.SCOPE_TEST, (List) dependenciesByScope.get( Artifact.SCOPE_TEST ) );
 450  1
         renderDependenciesForScope( Artifact.SCOPE_PROVIDED,
 451  
                                     (List) dependenciesByScope.get( Artifact.SCOPE_PROVIDED ) );
 452  1
         renderDependenciesForScope( Artifact.SCOPE_SYSTEM, (List) dependenciesByScope.get( Artifact.SCOPE_SYSTEM ) );
 453  1
     }
 454  
 
 455  
     private void renderSectionProjectTransitiveDependencies()
 456  
     {
 457  1
         Map dependenciesByScope = dependencies.getDependenciesByScope( true );
 458  
 
 459  1
         startSection( getReportString( "report.transitivedependencies.title" ) );
 460  
 
 461  1
         if ( dependenciesByScope.values().isEmpty() )
 462  
         {
 463  1
             paragraph( getReportString( "report.transitivedependencies.nolist" ) );
 464  
         }
 465  
         else
 466  
         {
 467  0
             paragraph( getReportString( "report.transitivedependencies.intro" ) );
 468  
 
 469  0
             renderDependenciesForAllScopes( dependenciesByScope );
 470  
         }
 471  
 
 472  1
         endSection();
 473  1
     }
 474  
 
 475  
     private void renderSectionProjectDependencyGraph()
 476  
     {
 477  1
         startSection( getReportString( "report.dependencies.graph.title" ) );
 478  
 
 479  
         // === SubSection: Dependency Tree
 480  1
         renderSectionDependencyTree();
 481  
 
 482  1
         endSection();
 483  1
     }
 484  
 
 485  
     private void renderSectionDependencyTree()
 486  
     {
 487  1
         sink.rawText( JAVASCRIPT );
 488  
 
 489  
         // for Dependencies Graph Tree
 490  1
         startSection( getReportString( "report.dependencies.graph.tree.title" ) );
 491  
 
 492  1
         sink.list();
 493  1
         printDependencyListing( dependencyTreeNode );
 494  1
         sink.list_();
 495  
 
 496  1
         endSection();
 497  1
     }
 498  
 
 499  
     private void renderSectionDependencyFileDetails()
 500  
     {
 501  0
         startSection( getReportString( "report.dependencies.file.details.title" ) );
 502  
 
 503  0
         List alldeps = dependencies.getAllDependencies();
 504  0
         Collections.sort( alldeps, getArtifactComparator() );
 505  
 
 506  
         // i18n
 507  0
         String filename = getReportString( "report.dependencies.file.details.column.file" );
 508  0
         String size = getReportString( "report.dependencies.file.details.column.size" );
 509  0
         String entries = getReportString( "report.dependencies.file.details.column.entries" );
 510  0
         String classes = getReportString( "report.dependencies.file.details.column.classes" );
 511  0
         String packages = getReportString( "report.dependencies.file.details.column.packages" );
 512  0
         String jdkrev = getReportString( "report.dependencies.file.details.column.jdkrev" );
 513  0
         String debug = getReportString( "report.dependencies.file.details.column.debug" );
 514  0
         String sealed = getReportString( "report.dependencies.file.details.column.sealed" );
 515  
 
 516  0
         int[] justification =
 517  
             new int[] { Parser.JUSTIFY_LEFT, Parser.JUSTIFY_RIGHT, Parser.JUSTIFY_RIGHT, Parser.JUSTIFY_RIGHT,
 518  
                 Parser.JUSTIFY_RIGHT, Parser.JUSTIFY_CENTER, Parser.JUSTIFY_CENTER, Parser.JUSTIFY_CENTER };
 519  
 
 520  0
         startTable();
 521  
 
 522  0
         sink.tableRows( justification, true );
 523  
 
 524  0
         TotalCell totaldeps = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 525  0
         TotalCell totaldepsize = new TotalCell( fileLengthDecimalFormat );
 526  0
         TotalCell totalentries = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 527  0
         TotalCell totalclasses = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 528  0
         TotalCell totalpackages = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 529  0
         double highestjdk = 0.0;
 530  0
         TotalCell totaldebug = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 531  0
         TotalCell totalsealed = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 532  
 
 533  0
         boolean hasSealed = hasSealed( alldeps );
 534  
 
 535  
         // Table header
 536  
         String[] tableHeader;
 537  0
         if ( hasSealed )
 538  
         {
 539  0
             tableHeader = new String[] { filename, size, entries, classes, packages, jdkrev, debug, sealed };
 540  
         }
 541  
         else
 542  
         {
 543  0
             tableHeader = new String[] { filename, size, entries, classes, packages, jdkrev, debug };
 544  
         }
 545  0
         tableHeader( tableHeader );
 546  
 
 547  
         // Table rows
 548  0
         for ( Iterator it = alldeps.iterator(); it.hasNext(); )
 549  
         {
 550  0
             Artifact artifact = (Artifact) it.next();
 551  
 
 552  0
             if ( artifact.getFile() == null )
 553  
             {
 554  0
                 log.error( "Artifact: " + artifact.getId() + " has no file." );
 555  0
                 continue;
 556  
             }
 557  
 
 558  0
             File artifactFile = artifact.getFile();
 559  
 
 560  0
             totaldeps.incrementTotal( artifact.getScope() );
 561  0
             totaldepsize.addTotal( artifactFile.length(), artifact.getScope() );
 562  
 
 563  0
             if ( JAR_SUBTYPE.contains( artifact.getType().toLowerCase() ) )
 564  
             {
 565  
                 try
 566  
                 {
 567  0
                     JarData jarDetails = dependencies.getJarDependencyDetails( artifact );
 568  
 
 569  0
                     String debugstr = "release";
 570  0
                     if ( jarDetails.isDebugPresent() )
 571  
                     {
 572  0
                         debugstr = "debug";
 573  0
                         totaldebug.incrementTotal( artifact.getScope() );
 574  
                     }
 575  
 
 576  0
                     totalentries.addTotal( jarDetails.getNumEntries(), artifact.getScope() );
 577  0
                     totalclasses.addTotal( jarDetails.getNumClasses(), artifact.getScope() );
 578  0
                     totalpackages.addTotal( jarDetails.getNumPackages(), artifact.getScope() );
 579  
 
 580  
                     try
 581  
                     {
 582  0
                         if ( jarDetails.getJdkRevision() != null )
 583  
                         {
 584  0
                             highestjdk = Math.max( highestjdk, Double.parseDouble( jarDetails.getJdkRevision() ) );
 585  
                         }
 586  
                     }
 587  0
                     catch ( NumberFormatException e )
 588  
                     {
 589  
                         // ignore
 590  0
                     }
 591  
 
 592  0
                     String sealedstr = "";
 593  0
                     if ( jarDetails.isSealed() )
 594  
                     {
 595  0
                         sealedstr = "sealed";
 596  0
                         totalsealed.incrementTotal( artifact.getScope() );
 597  
                     }
 598  
 
 599  0
                     tableRow( hasSealed, new String[] { artifactFile.getName(),
 600  
                         fileLengthDecimalFormat.format( artifactFile.length() ),
 601  
                         DEFAULT_DECIMAL_FORMAT.format( jarDetails.getNumEntries() ),
 602  
                         DEFAULT_DECIMAL_FORMAT.format( jarDetails.getNumClasses() ),
 603  
                         DEFAULT_DECIMAL_FORMAT.format( jarDetails.getNumPackages() ), jarDetails.getJdkRevision(),
 604  
                         debugstr, sealedstr } );
 605  
                 }
 606  0
                 catch ( IOException e )
 607  
                 {
 608  0
                     createExceptionInfoTableRow( artifact, artifactFile, e, hasSealed );
 609  0
                 }
 610  
             }
 611  
             else
 612  
             {
 613  0
                 tableRow( hasSealed, new String[] { artifactFile.getName(),
 614  
                     fileLengthDecimalFormat.format( artifactFile.length() ), "", "", "", "", "", "" } );
 615  
             }
 616  0
         }
 617  
 
 618  
         // Total raws
 619  0
         tableHeader[0] = getReportString( "report.dependencies.file.details.total" );
 620  0
         tableHeader( tableHeader );
 621  
 
 622  0
         justification[0] = Parser.JUSTIFY_RIGHT;
 623  0
         justification[6] = Parser.JUSTIFY_RIGHT;
 624  
 
 625  0
         for ( int i = -1; i < TotalCell.SCOPES_COUNT; i++ )
 626  
         {
 627  0
             if ( totaldeps.getTotal( i ) > 0 )
 628  
             {
 629  0
                 tableRow( hasSealed, new String[] { totaldeps.getTotalString( i ), totaldepsize.getTotalString( i ),
 630  
                     totalentries.getTotalString( i ), totalclasses.getTotalString( i ),
 631  
                     totalpackages.getTotalString( i ), ( i < 0 ) ? String.valueOf( highestjdk ) : "",
 632  
                     totaldebug.getTotalString( i ), totalsealed.getTotalString( i ) } );
 633  
             }
 634  
         }
 635  
 
 636  0
         sink.tableRows_();
 637  
 
 638  0
         endTable();
 639  0
         endSection();
 640  0
     }
 641  
 
 642  
     private void tableRow( boolean fullRow, String[] content )
 643  
     {
 644  1
         sink.tableRow();
 645  
 
 646  1
         int count = fullRow ? content.length : ( content.length - 1 );
 647  
 
 648  5
         for ( int i = 0; i < count; i++ )
 649  
         {
 650  4
             tableCell( content[i] );
 651  
         }
 652  
 
 653  1
         sink.tableRow_();
 654  1
     }
 655  
 
 656  
     private void createExceptionInfoTableRow( Artifact artifact, File artifactFile, Exception e, boolean hasSealed )
 657  
     {
 658  0
         tableRow( hasSealed, new String[] { artifact.getId(), artifactFile.getAbsolutePath(), e.getMessage(), "", "",
 659  
             "", "", "" } );
 660  0
     }
 661  
 
 662  
     private void populateRepositoryMap( Map repos, List rowRepos )
 663  
     {
 664  0
         Iterator it = rowRepos.iterator();
 665  0
         while ( it.hasNext() )
 666  
         {
 667  0
             ArtifactRepository repo = (ArtifactRepository) it.next();
 668  
 
 669  0
             repos.put( repo.getId(), repo );
 670  0
         }
 671  0
     }
 672  
 
 673  
     private void blacklistRepositoryMap( Map repos, List repoUrlBlackListed )
 674  
     {
 675  0
         for ( Iterator it = repos.keySet().iterator(); it.hasNext(); )
 676  
         {
 677  0
             String key = (String) it.next();
 678  0
             ArtifactRepository repo = (ArtifactRepository) repos.get( key );
 679  
 
 680  
             // ping repo
 681  0
             if ( !repo.isBlacklisted() )
 682  
             {
 683  0
                 if ( !repoUrlBlackListed.contains( repo.getUrl() ) )
 684  
                 {
 685  
                     try
 686  
                     {
 687  0
                         URL repoUrl = new URL( repo.getUrl() );
 688  0
                         if ( ProjectInfoReportUtils.getInputStream( repoUrl, settings ) == null )
 689  
                         {
 690  0
                             log.warn( "The repository url '" + repoUrl + "' has no stream - Repository '"
 691  
                                 + repo.getId() + "' will be blacklisted." );
 692  0
                             repo.setBlacklisted( true );
 693  0
                             repoUrlBlackListed.add( repo.getUrl() );
 694  
                         }
 695  
                     }
 696  0
                     catch ( IOException e )
 697  
                     {
 698  0
                         log.warn( "The repository url '" + repo.getUrl() + "' is invalid - Repository '" + repo.getId()
 699  
                             + "' will be blacklisted." );
 700  0
                         repo.setBlacklisted( true );
 701  0
                         repoUrlBlackListed.add( repo.getUrl() );
 702  0
                     }
 703  
                 }
 704  
                 else
 705  
                 {
 706  0
                     repo.setBlacklisted( true );
 707  
                 }
 708  
             }
 709  
             else
 710  
             {
 711  0
                 repoUrlBlackListed.add( repo.getUrl() );
 712  
             }
 713  0
         }
 714  0
     }
 715  
 
 716  
     private void renderSectionDependencyRepositoryLocations()
 717  
     {
 718  0
         startSection( getReportString( "report.dependencies.repo.locations.title" ) );
 719  
 
 720  
         // Collect Alphabetical Dependencies
 721  0
         List alldeps = dependencies.getAllDependencies();
 722  0
         Collections.sort( alldeps, getArtifactComparator() );
 723  
 
 724  
         // Collect Repositories
 725  0
         Map repoMap = new HashMap();
 726  
 
 727  0
         populateRepositoryMap( repoMap, repoUtils.getRemoteArtifactRepositories() );
 728  0
         for ( Iterator it = alldeps.iterator(); it.hasNext(); )
 729  
         {
 730  0
             Artifact artifact = (Artifact) it.next();
 731  
             try
 732  
             {
 733  0
                 MavenProject artifactProject = repoUtils.getMavenProjectFromRepository( artifact );
 734  0
                 populateRepositoryMap( repoMap, artifactProject.getRemoteArtifactRepositories() );
 735  
             }
 736  0
             catch ( ProjectBuildingException e )
 737  
             {
 738  0
                 log.warn( "Unable to create Maven project from repository.", e );
 739  0
             }
 740  0
         }
 741  
 
 742  0
         List repoUrlBlackListed = new ArrayList();
 743  0
         blacklistRepositoryMap( repoMap, repoUrlBlackListed );
 744  
 
 745  
         // Render Repository List
 746  
 
 747  0
         printRepositories( repoMap, repoUrlBlackListed );
 748  
 
 749  
         // Render Artifacts locations
 750  
 
 751  0
         printArtifactsLocations( repoMap, alldeps );
 752  
 
 753  0
         endSection();
 754  0
     }
 755  
 
 756  
     private void renderSectionDependencyLicenseListing()
 757  
     {
 758  1
         startSection( getReportString( "report.dependencies.graph.tables.licenses" ) );
 759  1
         printGroupedLicenses();
 760  1
         endSection();
 761  1
     }
 762  
 
 763  
     private void renderDependenciesForScope( String scope, List artifacts )
 764  
     {
 765  5
         if ( artifacts != null )
 766  
         {
 767  1
             boolean withClassifier = hasClassifier( artifacts );
 768  1
             boolean withOptional = hasOptional( artifacts );
 769  1
             String[] tableHeader = getDependencyTableHeader( withClassifier, withOptional );
 770  
 
 771  
             // can't use straight artifact comparison because we want optional last
 772  1
             Collections.sort( artifacts, getArtifactComparator() );
 773  
 
 774  1
             startSection( scope );
 775  
 
 776  1
             paragraph( getReportString( "report.dependencies.intro." + scope ) );
 777  
 
 778  1
             startTable();
 779  1
             tableHeader( tableHeader );
 780  1
             for ( Iterator iterator = artifacts.iterator(); iterator.hasNext(); )
 781  
             {
 782  1
                 Artifact artifact = (Artifact) iterator.next();
 783  
 
 784  1
                 renderArtifactRow( artifact, withClassifier, withOptional );
 785  1
             }
 786  1
             endTable();
 787  
 
 788  1
             endSection();
 789  
         }
 790  5
     }
 791  
 
 792  
     private Comparator getArtifactComparator()
 793  
     {
 794  1
         return new Comparator()
 795  
         {
 796  1
             public int compare( Object o1, Object o2 )
 797  
             {
 798  0
                 Artifact a1 = (Artifact) o1;
 799  0
                 Artifact a2 = (Artifact) o2;
 800  
 
 801  
                 // put optional last
 802  0
                 if ( a1.isOptional() && !a2.isOptional() )
 803  
                 {
 804  0
                     return +1;
 805  
                 }
 806  0
                 else if ( !a1.isOptional() && a2.isOptional() )
 807  
                 {
 808  0
                     return -1;
 809  
                 }
 810  
                 else
 811  
                 {
 812  0
                     return a1.compareTo( a2 );
 813  
                 }
 814  
             }
 815  
         };
 816  
     }
 817  
 
 818  
     /**
 819  
      * @param artifact not null
 820  
      * @param withClassifier <code>true</code> to include the classifier column, <code>false</code> otherwise.
 821  
      * @param withOptional <code>true</code> to include the optional column, <code>false</code> otherwise.
 822  
      * @see #getDependencyTableHeader(boolean, boolean)
 823  
      */
 824  
     private void renderArtifactRow( Artifact artifact, boolean withClassifier, boolean withOptional )
 825  
     {
 826  1
         String isOptional =
 827  
             artifact.isOptional() ? getReportString( "report.dependencies.column.isOptional" )
 828  
                             : getReportString( "report.dependencies.column.isNotOptional" );
 829  
 
 830  1
         String url =
 831  
             ProjectInfoReportUtils.getArtifactUrl( artifactFactory, artifact, mavenProjectBuilder, remoteRepositories,
 832  
                                                    localRepository );
 833  1
         String artifactIdCell = ProjectInfoReportUtils.getArtifactIdCell( artifact.getArtifactId(), url );
 834  
 
 835  
         String content[];
 836  1
         if ( withClassifier )
 837  
         {
 838  0
             content =
 839  
                 new String[] { artifact.getGroupId(), artifactIdCell, artifact.getVersion(), artifact.getClassifier(),
 840  
                     artifact.getType(), isOptional };
 841  
         }
 842  
         else
 843  
         {
 844  1
             content =
 845  
                 new String[] { artifact.getGroupId(), artifactIdCell, artifact.getVersion(), artifact.getType(),
 846  
                     isOptional };
 847  
         }
 848  
 
 849  1
         tableRow( withOptional, content );
 850  1
     }
 851  
 
 852  
     private void printDependencyListing( DependencyNode node )
 853  
     {
 854  2
         Artifact artifact = node.getArtifact();
 855  2
         String id = artifact.getId();
 856  2
         String dependencyDetailId = getUUID();
 857  2
         String imgId = getUUID();
 858  
 
 859  2
         sink.listItem();
 860  
 
 861  2
         sink.paragraph();
 862  2
         sink.text( id + ( StringUtils.isNotEmpty( artifact.getScope() ) ? " (" + artifact.getScope() + ") " : " " ) );
 863  2
         sink.rawText( "<img id=\"" + imgId + "\" src=\"" + IMG_INFO_URL
 864  
             + "\" alt=\"Information\" onclick=\"toggleDependencyDetail( '" + dependencyDetailId + "', '" + imgId
 865  
             + "' );\" style=\"cursor: pointer;vertical-align:text-bottom;\"></img>" );
 866  2
         sink.paragraph_();
 867  
 
 868  2
         printDescriptionsAndURLs( node, dependencyDetailId );
 869  
 
 870  2
         if ( !node.getChildren().isEmpty() )
 871  
         {
 872  1
             boolean toBeIncluded = false;
 873  1
             List subList = new ArrayList();
 874  1
             for ( Iterator deps = node.getChildren().iterator(); deps.hasNext(); )
 875  
             {
 876  1
                 DependencyNode dep = (DependencyNode) deps.next();
 877  
 
 878  1
                 if ( !dependencies.getAllDependencies().contains( dep.getArtifact() ) )
 879  
                 {
 880  0
                     continue;
 881  
                 }
 882  
 
 883  1
                 subList.add( dep );
 884  1
                 toBeIncluded = true;
 885  1
             }
 886  
 
 887  1
             if ( toBeIncluded )
 888  
             {
 889  1
                 sink.list();
 890  1
                 for ( Iterator deps = subList.iterator(); deps.hasNext(); )
 891  
                 {
 892  1
                     DependencyNode dep = (DependencyNode) deps.next();
 893  
 
 894  1
                     printDependencyListing( dep );
 895  1
                 }
 896  1
                 sink.list_();
 897  
             }
 898  
         }
 899  
 
 900  2
         sink.listItem_();
 901  2
     }
 902  
 
 903  
     private void printDescriptionsAndURLs( DependencyNode node, String uid )
 904  
     {
 905  2
         Artifact artifact = node.getArtifact();
 906  2
         String id = artifact.getId();
 907  2
         String unknownLicenseMessage = getReportString( "report.dependencies.graph.tables.unknown" );
 908  
 
 909  2
         sink.rawText( "<div id=\"" + uid + "\" style=\"display:none\">" );
 910  
 
 911  2
         sink.table();
 912  
 
 913  2
         if ( !Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
 914  
         {
 915  
             try
 916  
             {
 917  2
                 MavenProject artifactProject = repoUtils.getMavenProjectFromRepository( artifact );
 918  2
                 String artifactDescription = artifactProject.getDescription();
 919  2
                 String artifactUrl = artifactProject.getUrl();
 920  2
                 String artifactName = artifactProject.getName();
 921  2
                 List licenses = artifactProject.getLicenses();
 922  
 
 923  2
                 sink.tableRow();
 924  2
                 sink.tableHeaderCell();
 925  2
                 sink.text( artifactName );
 926  2
                 sink.tableHeaderCell_();
 927  2
                 sink.tableRow_();
 928  
 
 929  2
                 sink.tableRow();
 930  2
                 sink.tableCell();
 931  
 
 932  2
                 sink.paragraph();
 933  2
                 sink.bold();
 934  2
                 sink.text( getReportString( "report.dependencies.column.description" ) + ": " );
 935  2
                 sink.bold_();
 936  2
                 if ( StringUtils.isNotEmpty( artifactDescription ) )
 937  
                 {
 938  1
                     sink.text( artifactDescription );
 939  
                 }
 940  
                 else
 941  
                 {
 942  1
                     sink.text( getReportString( "report.index.nodescription" ) );
 943  
                 }
 944  2
                 sink.paragraph_();
 945  
 
 946  2
                 if ( StringUtils.isNotEmpty( artifactUrl ) )
 947  
                 {
 948  1
                     sink.paragraph();
 949  1
                     sink.bold();
 950  1
                     sink.text( getReportString( "report.dependencies.column.url" ) + ": " );
 951  1
                     sink.bold_();
 952  1
                     if ( ProjectInfoReportUtils.isArtifactUrlValid( artifactUrl ) )
 953  
                     {
 954  1
                         sink.link( artifactUrl );
 955  1
                         sink.text( artifactUrl );
 956  1
                         sink.link_();
 957  
                     }
 958  
                     else
 959  
                     {
 960  0
                         sink.text( artifactUrl );
 961  
                     }
 962  1
                     sink.paragraph_();
 963  
                 }
 964  
 
 965  2
                 sink.paragraph();
 966  2
                 sink.bold();
 967  2
                 sink.text( getReportString( "report.license.title" ) + ": " );
 968  2
                 sink.bold_();
 969  2
                 if ( !licenses.isEmpty() )
 970  
                 {
 971  1
                     for ( Iterator iter = licenses.iterator(); iter.hasNext(); )
 972  
                     {
 973  1
                         License element = (License) iter.next();
 974  1
                         String licenseName = element.getName();
 975  1
                         String licenseUrl = element.getUrl();
 976  
 
 977  1
                         if ( licenseUrl != null )
 978  
                         {
 979  1
                             sink.link( licenseUrl );
 980  
                         }
 981  1
                         sink.text( licenseName );
 982  
 
 983  1
                         if ( licenseUrl != null )
 984  
                         {
 985  1
                             sink.link_();
 986  
                         }
 987  
 
 988  1
                         licenseMap.put( licenseName, artifactName );
 989  1
                     }
 990  
                 }
 991  
                 else
 992  
                 {
 993  1
                     sink.text( getReportString( "report.license.nolicense" ) );
 994  
 
 995  1
                     licenseMap.put( unknownLicenseMessage, artifactName );
 996  
                 }
 997  2
                 sink.paragraph_();
 998  
             }
 999  0
             catch ( ProjectBuildingException e )
 1000  
             {
 1001  0
                 log.error( "ProjectBuildingException error : ", e );
 1002  2
             }
 1003  
         }
 1004  
         else
 1005  
         {
 1006  0
             sink.tableRow();
 1007  0
             sink.tableHeaderCell();
 1008  0
             sink.text( id );
 1009  0
             sink.tableHeaderCell_();
 1010  0
             sink.tableRow_();
 1011  
 
 1012  0
             sink.tableRow();
 1013  0
             sink.tableCell();
 1014  
 
 1015  0
             sink.paragraph();
 1016  0
             sink.bold();
 1017  0
             sink.text( getReportString( "report.dependencies.column.description" ) + ": " );
 1018  0
             sink.bold_();
 1019  0
             sink.text( getReportString( "report.index.nodescription" ) );
 1020  0
             sink.paragraph_();
 1021  
 
 1022  0
             if ( artifact.getFile() != null )
 1023  
             {
 1024  0
                 sink.paragraph();
 1025  0
                 sink.bold();
 1026  0
                 sink.text( getReportString( "report.dependencies.column.url" ) + ": " );
 1027  0
                 sink.bold_();
 1028  0
                 sink.text( artifact.getFile().getAbsolutePath() );
 1029  0
                 sink.paragraph_();
 1030  
             }
 1031  
         }
 1032  
 
 1033  2
         sink.tableCell_();
 1034  2
         sink.tableRow_();
 1035  
 
 1036  2
         sink.table_();
 1037  
 
 1038  2
         sink.rawText( "</div>" );
 1039  2
     }
 1040  
 
 1041  
     private void printGroupedLicenses()
 1042  
     {
 1043  1
         for ( Iterator iter = licenseMap.keySet().iterator(); iter.hasNext(); )
 1044  
         {
 1045  2
             String licenseName = (String) iter.next();
 1046  2
             sink.paragraph();
 1047  2
             sink.bold();
 1048  2
             if ( StringUtils.isEmpty( licenseName ) )
 1049  
             {
 1050  0
                 sink.text( i18n.getString( "project-info-report", locale, "report.dependencies.unamed" ) );
 1051  
             }
 1052  
             else
 1053  
             {
 1054  2
                 sink.text( licenseName );
 1055  
             }
 1056  2
             sink.text( ": " );
 1057  2
             sink.bold_();
 1058  
 
 1059  2
             SortedSet projects = (SortedSet) licenseMap.get( licenseName );
 1060  
 
 1061  2
             for ( Iterator iterator = projects.iterator(); iterator.hasNext(); )
 1062  
             {
 1063  2
                 String projectName = (String) iterator.next();
 1064  2
                 sink.text( projectName );
 1065  2
                 if ( iterator.hasNext() )
 1066  
                 {
 1067  0
                     sink.text( ", " );
 1068  
                 }
 1069  2
             }
 1070  
 
 1071  2
             sink.paragraph_();
 1072  2
         }
 1073  1
     }
 1074  
 
 1075  
     private void printRepositories( Map repoMap, List repoUrlBlackListed )
 1076  
     {
 1077  
         // i18n
 1078  0
         String repoid = getReportString( "report.dependencies.repo.locations.column.repoid" );
 1079  0
         String url = getReportString( "report.dependencies.repo.locations.column.url" );
 1080  0
         String release = getReportString( "report.dependencies.repo.locations.column.release" );
 1081  0
         String snapshot = getReportString( "report.dependencies.repo.locations.column.snapshot" );
 1082  0
         String blacklisted = getReportString( "report.dependencies.repo.locations.column.blacklisted" );
 1083  0
         String releaseEnabled = getReportString( "report.dependencies.repo.locations.cell.release.enabled" );
 1084  0
         String releaseDisabled = getReportString( "report.dependencies.repo.locations.cell.release.disabled" );
 1085  0
         String snapshotEnabled = getReportString( "report.dependencies.repo.locations.cell.snapshot.enabled" );
 1086  0
         String snapshotDisabled = getReportString( "report.dependencies.repo.locations.cell.snapshot.disabled" );
 1087  0
         String blacklistedEnabled = getReportString( "report.dependencies.repo.locations.cell.blacklisted.enabled" );
 1088  0
         String blacklistedDisabled = getReportString( "report.dependencies.repo.locations.cell.blacklisted.disabled" );
 1089  
 
 1090  0
         startTable();
 1091  
 
 1092  
         // Table header
 1093  
 
 1094  
         String[] tableHeader;
 1095  
         int[] justificationRepo;
 1096  0
         if ( repoUrlBlackListed.isEmpty() )
 1097  
         {
 1098  0
             tableHeader = new String[] { repoid, url, release, snapshot };
 1099  0
             justificationRepo =
 1100  
                 new int[] { Parser.JUSTIFY_LEFT, Parser.JUSTIFY_LEFT, Parser.JUSTIFY_CENTER, Parser.JUSTIFY_CENTER };
 1101  
         }
 1102  
         else
 1103  
         {
 1104  0
             tableHeader = new String[] { repoid, url, release, snapshot, blacklisted };
 1105  0
             justificationRepo =
 1106  
                 new int[] { Parser.JUSTIFY_LEFT, Parser.JUSTIFY_LEFT, Parser.JUSTIFY_CENTER, Parser.JUSTIFY_CENTER,
 1107  
                     Parser.JUSTIFY_CENTER };
 1108  
         }
 1109  
 
 1110  0
         sink.tableRows( justificationRepo, true );
 1111  
 
 1112  0
         tableHeader( tableHeader );
 1113  
 
 1114  
         // Table rows
 1115  
 
 1116  0
         for ( Iterator it = repoMap.keySet().iterator(); it.hasNext(); )
 1117  
         {
 1118  0
             String key = (String) it.next();
 1119  0
             ArtifactRepository repo = (ArtifactRepository) repoMap.get( key );
 1120  
 
 1121  0
             sink.tableRow();
 1122  0
             tableCell( repo.getId() );
 1123  
 
 1124  0
             sink.tableCell();
 1125  0
             if ( repo.isBlacklisted() )
 1126  
             {
 1127  0
                 sink.text( repo.getUrl() );
 1128  
             }
 1129  
             else
 1130  
             {
 1131  0
                 sink.link( repo.getUrl() );
 1132  0
                 sink.text( repo.getUrl() );
 1133  0
                 sink.link_();
 1134  
             }
 1135  0
             sink.tableCell_();
 1136  
 
 1137  0
             ArtifactRepositoryPolicy releasePolicy = repo.getReleases();
 1138  0
             tableCell( releasePolicy.isEnabled() ? releaseEnabled : releaseDisabled );
 1139  
 
 1140  0
             ArtifactRepositoryPolicy snapshotPolicy = repo.getSnapshots();
 1141  0
             tableCell( snapshotPolicy.isEnabled() ? snapshotEnabled : snapshotDisabled );
 1142  
 
 1143  0
             if ( !repoUrlBlackListed.isEmpty() )
 1144  
             {
 1145  0
                 tableCell( repo.isBlacklisted() ? blacklistedEnabled : blacklistedDisabled );
 1146  
             }
 1147  0
             sink.tableRow_();
 1148  0
         }
 1149  
 
 1150  0
         sink.tableRows_();
 1151  
 
 1152  0
         endTable();
 1153  0
     }
 1154  
 
 1155  
     private void printArtifactsLocations( Map repoMap, List alldeps )
 1156  
     {
 1157  
         // i18n
 1158  0
         String artifact = getReportString( "report.dependencies.repo.locations.column.artifact" );
 1159  
 
 1160  0
         sink.paragraph();
 1161  0
         sink.text( getReportString( "report.dependencies.repo.locations.artifact.breakdown" ) );
 1162  0
         sink.paragraph_();
 1163  
 
 1164  0
         List repoIdList = new ArrayList();
 1165  
         // removed blacklisted repo
 1166  0
         for ( Iterator it = repoMap.keySet().iterator(); it.hasNext(); )
 1167  
         {
 1168  0
             String repokey = (String) it.next();
 1169  0
             ArtifactRepository repo = (ArtifactRepository) repoMap.get( repokey );
 1170  0
             if ( !repo.isBlacklisted() )
 1171  
             {
 1172  0
                 repoIdList.add( repokey );
 1173  
             }
 1174  0
         }
 1175  
 
 1176  0
         String[] tableHeader = new String[repoIdList.size() + 1];
 1177  0
         int[] justificationRepo = new int[repoIdList.size() + 1];
 1178  
 
 1179  0
         tableHeader[0] = artifact;
 1180  0
         justificationRepo[0] = Parser.JUSTIFY_LEFT;
 1181  
 
 1182  0
         int idnum = 1;
 1183  0
         for ( Iterator it = repoIdList.iterator(); it.hasNext(); )
 1184  
         {
 1185  0
             String id = (String) it.next();
 1186  0
             tableHeader[idnum] = id;
 1187  0
             justificationRepo[idnum] = Parser.JUSTIFY_CENTER;
 1188  0
             idnum++;
 1189  0
         }
 1190  
 
 1191  0
         Map totalByRepo = new HashMap();
 1192  0
         TotalCell totaldeps = new TotalCell( DEFAULT_DECIMAL_FORMAT );
 1193  
 
 1194  0
         startTable();
 1195  
 
 1196  0
         sink.tableRows( justificationRepo, true );
 1197  
 
 1198  0
         tableHeader( tableHeader );
 1199  
 
 1200  0
         for ( Iterator it = alldeps.iterator(); it.hasNext(); )
 1201  
         {
 1202  0
             Artifact dependency = (Artifact) it.next();
 1203  
 
 1204  0
             totaldeps.incrementTotal( dependency.getScope() );
 1205  
 
 1206  0
             sink.tableRow();
 1207  
 
 1208  0
             if ( !Artifact.SCOPE_SYSTEM.equals( dependency.getScope() ) )
 1209  
             {
 1210  
 
 1211  0
                 tableCell( dependency.getId() );
 1212  
 
 1213  0
                 for ( Iterator itrepo = repoIdList.iterator(); itrepo.hasNext(); )
 1214  
                 {
 1215  0
                     String repokey = (String) itrepo.next();
 1216  0
                     ArtifactRepository repo = (ArtifactRepository) repoMap.get( repokey );
 1217  
 
 1218  0
                     String depUrl = repoUtils.getDependencyUrlFromRepository( dependency, repo );
 1219  
 
 1220  0
                     Integer old = (Integer) totalByRepo.get( repokey );
 1221  0
                     if ( old == null )
 1222  
                     {
 1223  0
                         totalByRepo.put( repokey, new Integer( 0 ) );
 1224  0
                         old = new Integer( 0 );
 1225  
                     }
 1226  
 
 1227  0
                     boolean dependencyExists = false;
 1228  
                     // check snapshots in snapshots repository only and releases in release repositories...
 1229  0
                     if ( ( dependency.isSnapshot() && repo.getSnapshots().isEnabled() )
 1230  
                         || ( !dependency.isSnapshot() && repo.getReleases().isEnabled() ) )
 1231  
                     {
 1232  0
                         dependencyExists = repoUtils.dependencyExistsInRepo( repo, dependency );
 1233  
                     }
 1234  
 
 1235  0
                     if ( dependencyExists )
 1236  
                     {
 1237  0
                         sink.tableCell();
 1238  0
                         if ( StringUtils.isNotEmpty( depUrl ) )
 1239  
                         {
 1240  0
                             sink.link( depUrl );
 1241  
                         }
 1242  
                         else
 1243  
                         {
 1244  0
                             sink.text( depUrl );
 1245  
                         }
 1246  
 
 1247  0
                         sink.figure();
 1248  0
                         sink.figureCaption();
 1249  0
                         sink.text( "Found at " + repo.getUrl() );
 1250  0
                         sink.figureCaption_();
 1251  0
                         sink.figureGraphics( "images/icon_success_sml.gif" );
 1252  0
                         sink.figure_();
 1253  
 
 1254  0
                         sink.link_();
 1255  0
                         sink.tableCell_();
 1256  
 
 1257  0
                         totalByRepo.put( repokey, new Integer( old.intValue() + 1 ) );
 1258  
                     }
 1259  
                     else
 1260  
                     {
 1261  0
                         tableCell( "-" );
 1262  
                     }
 1263  0
                 }
 1264  
             }
 1265  
             else
 1266  
             {
 1267  0
                 tableCell( dependency.getId() );
 1268  
 
 1269  0
                 for ( Iterator itrepo = repoIdList.iterator(); itrepo.hasNext(); )
 1270  
                 {
 1271  0
                     itrepo.next();
 1272  
 
 1273  0
                     tableCell( "-" );
 1274  
                 }
 1275  
             }
 1276  
 
 1277  0
             sink.tableRow_();
 1278  0
         }
 1279  
 
 1280  
         // Total row
 1281  
 
 1282  
         // reused key
 1283  0
         tableHeader[0] = getReportString( "report.dependencies.file.details.total" );
 1284  0
         tableHeader( tableHeader );
 1285  0
         String[] totalRow = new String[repoIdList.size() + 1];
 1286  0
         totalRow[0] = totaldeps.toString();
 1287  0
         idnum = 1;
 1288  0
         for ( Iterator itrepo = repoIdList.iterator(); itrepo.hasNext(); )
 1289  
         {
 1290  0
             String repokey = (String) itrepo.next();
 1291  
 
 1292  0
             Integer dependencies = (Integer) totalByRepo.get( repokey );
 1293  0
             totalRow[idnum++] = dependencies != null ? dependencies.toString() : "0";
 1294  0
         }
 1295  
 
 1296  0
         tableRow( totalRow );
 1297  
 
 1298  0
         sink.tableRows_();
 1299  
 
 1300  0
         endTable();
 1301  0
     }
 1302  
 
 1303  
     private String getReportString( String key )
 1304  
     {
 1305  24
         return i18n.getString( "project-info-report", locale, key );
 1306  
     }
 1307  
 
 1308  
     /**
 1309  
      * @param artifacts not null
 1310  
      * @return <code>true</code> if one artifact in the list has a classifier, <code>false</code> otherwise.
 1311  
      */
 1312  
     private boolean hasClassifier( List artifacts )
 1313  
     {
 1314  1
         for ( Iterator iterator = artifacts.iterator(); iterator.hasNext(); )
 1315  
         {
 1316  1
             Artifact artifact = (Artifact) iterator.next();
 1317  
 
 1318  1
             if ( StringUtils.isNotEmpty( artifact.getClassifier() ) )
 1319  
             {
 1320  0
                 return true;
 1321  
             }
 1322  1
         }
 1323  
 
 1324  1
         return false;
 1325  
     }
 1326  
 
 1327  
     /**
 1328  
      * @param artifacts not null
 1329  
      * @return <code>true</code> if one artifact in the list is optional, <code>false</code> otherwise.
 1330  
      */
 1331  
     private boolean hasOptional( List artifacts )
 1332  
     {
 1333  1
         for ( Iterator iterator = artifacts.iterator(); iterator.hasNext(); )
 1334  
         {
 1335  1
             Artifact artifact = (Artifact) iterator.next();
 1336  
 
 1337  1
             if ( artifact.isOptional() )
 1338  
             {
 1339  0
                 return true;
 1340  
             }
 1341  1
         }
 1342  
 
 1343  1
         return false;
 1344  
     }
 1345  
 
 1346  
     /**
 1347  
      * @param artifacts not null
 1348  
      * @return <code>true</code> if one artifact in the list is sealed, <code>false</code> otherwise.
 1349  
      */
 1350  
     private boolean hasSealed( List artifacts )
 1351  
     {
 1352  0
         for ( Iterator it = artifacts.iterator(); it.hasNext(); )
 1353  
         {
 1354  0
             Artifact artifact = (Artifact) it.next();
 1355  
 
 1356  
             // TODO site:run Why do we need to resolve this...
 1357  0
             if ( artifact.getFile() == null && !Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
 1358  
             {
 1359  
                 try
 1360  
                 {
 1361  0
                     repoUtils.resolve( artifact );
 1362  
                 }
 1363  0
                 catch ( ArtifactResolutionException e )
 1364  
                 {
 1365  0
                     log.error( "Artifact: " + artifact.getId() + " has no file.", e );
 1366  0
                     continue;
 1367  
                 }
 1368  0
                 catch ( ArtifactNotFoundException e )
 1369  
                 {
 1370  0
                     if ( ( dependencies.getProject().getGroupId().equals( artifact.getGroupId() ) )
 1371  
                         && ( dependencies.getProject().getArtifactId().equals( artifact.getArtifactId() ) )
 1372  
                         && ( dependencies.getProject().getVersion().equals( artifact.getVersion() ) ) )
 1373  
                     {
 1374  0
                         log.warn( "The artifact of this project has never been deployed." );
 1375  
                     }
 1376  
                     else
 1377  
                     {
 1378  0
                         log.error( "Artifact: " + artifact.getId() + " has no file.", e );
 1379  
                     }
 1380  
 
 1381  0
                     continue;
 1382  0
                 }
 1383  
             }
 1384  
 
 1385  0
             if ( JAR_SUBTYPE.contains( artifact.getType().toLowerCase() ) )
 1386  
             {
 1387  
                 try
 1388  
                 {
 1389  0
                     JarData jarDetails = dependencies.getJarDependencyDetails( artifact );
 1390  0
                     if ( jarDetails.isSealed() )
 1391  
                     {
 1392  0
                         return true;
 1393  
                     }
 1394  
                 }
 1395  0
                 catch ( IOException e )
 1396  
                 {
 1397  0
                     log.error( "IOException: " + e.getMessage(), e );
 1398  0
                 }
 1399  
             }
 1400  0
         }
 1401  0
         return false;
 1402  
     }
 1403  
 
 1404  
     /**
 1405  
      * @return a valid HTML ID respecting
 1406  
      * <a href="http://www.w3.org/TR/xhtml1/#C_8">XHTML 1.0 section C.8. Fragment Identifiers</a>
 1407  
      */
 1408  
     private static String getUUID()
 1409  
     {
 1410  4
         return "_" + Math.abs( RANDOM.nextInt() );
 1411  
     }
 1412  
 
 1413  
     /**
 1414  
      * Formats file length with the associated <a href="http://en.wikipedia.org/wiki/SI_prefix#Computing">SI</a>
 1415  
      * unit (GB, MB, kB) and using the pattern <code>########.00</code> by default.
 1416  
      *
 1417  
      * @see <a href="http://en.wikipedia.org/wiki/SI_prefix#Computing>
 1418  
      * http://en.wikipedia.org/wiki/SI_prefix#Computing</a>
 1419  
      * @see <a href="http://en.wikipedia.org/wiki/Binary_prefix">
 1420  
      * http://en.wikipedia.org/wiki/Binary_prefix</a>
 1421  
      * @see <a href="http://en.wikipedia.org/wiki/Octet_(computing)">
 1422  
      * http://en.wikipedia.org/wiki/Octet_(computing)</a>
 1423  
      */
 1424  
     static class FileDecimalFormat
 1425  
         extends DecimalFormat
 1426  
     {
 1427  
         private static final long serialVersionUID = 4062503546523610081L;
 1428  
 
 1429  
         private final I18N i18n;
 1430  
 
 1431  
         private final Locale locale;
 1432  
 
 1433  
         /**
 1434  
          * Default constructor
 1435  
          *
 1436  
          * @param i18n
 1437  
          * @param locale
 1438  
          */
 1439  
         public FileDecimalFormat( I18N i18n, Locale locale )
 1440  
         {
 1441  1
             super( "#,###.00" );
 1442  
 
 1443  1
             this.i18n = i18n;
 1444  1
             this.locale = locale;
 1445  1
         }
 1446  
 
 1447  
         /** {@inheritDoc} */
 1448  
         public StringBuffer format( long fs, StringBuffer result, FieldPosition fieldPosition )
 1449  
         {
 1450  0
             if ( fs > 1024 * 1024 * 1024 )
 1451  
             {
 1452  0
                 result = super.format( (float) fs / ( 1024 * 1024 * 1024 ), result, fieldPosition );
 1453  0
                 result.append( " " ).append( getString( i18n, "report.dependencies.file.details.column.size.gb" ) );
 1454  0
                 return result;
 1455  
             }
 1456  
 
 1457  0
             if ( fs > 1024 * 1024 )
 1458  
             {
 1459  0
                 result = super.format( (float) fs / ( 1024 * 1024 ), result, fieldPosition );
 1460  0
                 result.append( " " ).append( getString( i18n, "report.dependencies.file.details.column.size.mb" ) );
 1461  0
                 return result;
 1462  
             }
 1463  
 
 1464  0
             result = super.format( (float) fs / ( 1024 ), result, fieldPosition );
 1465  0
             result.append( " " ).append( getString( i18n, "report.dependencies.file.details.column.size.kb" ) );
 1466  0
             return result;
 1467  
         }
 1468  
 
 1469  
         private String getString( I18N i18n, String key )
 1470  
         {
 1471  0
             return i18n.getString( "project-info-report", locale, key );
 1472  
         }
 1473  
     }
 1474  
 
 1475  
     /**
 1476  
      * Combine total and total by scope in a cell.
 1477  
      */
 1478  
     static class TotalCell
 1479  
     {
 1480  
         static final int SCOPES_COUNT = 5;
 1481  
 
 1482  
         final DecimalFormat decimalFormat;
 1483  
 
 1484  0
         long total = 0;
 1485  
 
 1486  0
         long totalCompileScope = 0;
 1487  
 
 1488  0
         long totalTestScope = 0;
 1489  
 
 1490  0
         long totalRuntimeScope = 0;
 1491  
 
 1492  0
         long totalProvidedScope = 0;
 1493  
 
 1494  0
         long totalSystemScope = 0;
 1495  
 
 1496  
         TotalCell( DecimalFormat decimalFormat )
 1497  0
         {
 1498  0
             this.decimalFormat = decimalFormat;
 1499  0
         }
 1500  
 
 1501  
         void incrementTotal( String scope )
 1502  
         {
 1503  0
             addTotal( 1, scope );
 1504  0
         }
 1505  
 
 1506  
         static String getScope( int index )
 1507  
         {
 1508  0
             switch ( index )
 1509  
             {
 1510  
                 case 0:
 1511  0
                     return Artifact.SCOPE_COMPILE;
 1512  
                 case 1:
 1513  0
                     return Artifact.SCOPE_TEST;
 1514  
                 case 2:
 1515  0
                     return Artifact.SCOPE_RUNTIME;
 1516  
                 case 3:
 1517  0
                     return Artifact.SCOPE_PROVIDED;
 1518  
                 case 4:
 1519  0
                     return Artifact.SCOPE_SYSTEM;
 1520  
                 default:
 1521  0
                     return null;
 1522  
             }
 1523  
         }
 1524  
 
 1525  
         long getTotal( int index )
 1526  
         {
 1527  0
             switch ( index )
 1528  
             {
 1529  
                 case 0:
 1530  0
                     return totalCompileScope;
 1531  
                 case 1:
 1532  0
                     return totalTestScope;
 1533  
                 case 2:
 1534  0
                     return totalRuntimeScope;
 1535  
                 case 3:
 1536  0
                     return totalProvidedScope;
 1537  
                 case 4:
 1538  0
                     return totalSystemScope;
 1539  
                 default:
 1540  0
                     return total;
 1541  
             }
 1542  
         }
 1543  
 
 1544  
         String getTotalString( int index )
 1545  
         {
 1546  0
             long total = getTotal( index );
 1547  
 
 1548  0
             if ( total <= 0 )
 1549  
             {
 1550  0
                 return "";
 1551  
             }
 1552  
 
 1553  0
             StringBuffer sb = new StringBuffer();
 1554  0
             if ( index >= 0 )
 1555  
             {
 1556  0
                 sb.append( getScope( index ) ).append( ": " );
 1557  
             }
 1558  0
             sb.append( decimalFormat.format( getTotal( index ) ) );
 1559  0
             return sb.toString();
 1560  
         }
 1561  
 
 1562  
         void addTotal( long add, String scope )
 1563  
         {
 1564  0
             total += add;
 1565  
 
 1566  0
             if ( Artifact.SCOPE_COMPILE.equals( scope ) )
 1567  
             {
 1568  0
                 totalCompileScope += add;
 1569  
             }
 1570  0
             else if ( Artifact.SCOPE_TEST.equals( scope ) )
 1571  
             {
 1572  0
                 totalTestScope += add;
 1573  
             }
 1574  0
             else if ( Artifact.SCOPE_RUNTIME.equals( scope ) )
 1575  
             {
 1576  0
                 totalRuntimeScope += add;
 1577  
             }
 1578  0
             else if ( Artifact.SCOPE_PROVIDED.equals( scope ) )
 1579  
             {
 1580  0
                 totalProvidedScope += add;
 1581  
             }
 1582  0
             else if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
 1583  
             {
 1584  0
                 totalSystemScope += add;
 1585  
             }
 1586  0
         }
 1587  
 
 1588  
         /** {@inheritDoc} */
 1589  
         public String toString()
 1590  
         {
 1591  0
             StringBuffer sb = new StringBuffer();
 1592  0
             sb.append( decimalFormat.format( total ) );
 1593  0
             sb.append( " (" );
 1594  
 
 1595  0
             boolean needSeparator = false;
 1596  0
             for ( int i = 0; i < SCOPES_COUNT; i++ )
 1597  
             {
 1598  0
                 if ( getTotal( i ) > 0 )
 1599  
                 {
 1600  0
                     if ( needSeparator )
 1601  
                     {
 1602  0
                         sb.append( ", " );
 1603  
                     }
 1604  0
                     sb.append( getTotalString( i ) );
 1605  0
                     needSeparator = true;
 1606  
                 }
 1607  
             }
 1608  
 
 1609  0
             sb.append( ")" );
 1610  
 
 1611  0
             return sb.toString();
 1612  
         }
 1613  
     }
 1614  
 }