Coverage Report - org.apache.maven.plugins.surefire.report.SurefireReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
SurefireReportGenerator
99%
355/360
73%
54/74
3
 
 1  
 package org.apache.maven.plugins.surefire.report;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *     http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.maven.doxia.sink.Sink;
 23  
 import org.apache.maven.reporting.MavenReportException;
 24  
 
 25  
 import java.io.File;
 26  
 import java.text.NumberFormat;
 27  
 import java.util.Iterator;
 28  
 import java.util.List;
 29  
 import java.util.ListIterator;
 30  
 import java.util.Locale;
 31  
 import java.util.Map;
 32  
 import java.util.ResourceBundle;
 33  
 import java.util.StringTokenizer;
 34  
 
 35  
 /**
 36  
  * @version $Id: SurefireReportGenerator.java 804676 2009-08-16 11:56:03Z vsiveton $
 37  
  */
 38  
 public class SurefireReportGenerator
 39  
 {
 40  
     private SurefireReportParser report;
 41  
 
 42  
     private List testSuites;
 43  
 
 44  
     private boolean showSuccess;
 45  
 
 46  
     private String xrefLocation;
 47  
 
 48  
     public SurefireReportGenerator( File[] reportsDirectories, Locale locale, boolean showSuccess, String xrefLocation )
 49  4
     {
 50  4
         report = new SurefireReportParser( reportsDirectories, locale );
 51  
 
 52  4
         this.xrefLocation = xrefLocation;
 53  
 
 54  4
         this.showSuccess = showSuccess;
 55  4
     }
 56  
 
 57  
     public void doGenerateReport( ResourceBundle bundle, Sink sink )
 58  
         throws MavenReportException
 59  
     {
 60  4
         testSuites = report.parseXMLReportFiles();
 61  
 
 62  4
         sink.head();
 63  
 
 64  4
         sink.title();
 65  4
         sink.text( bundle.getString( "report.surefire.header" ) );
 66  4
         sink.title_();
 67  
 
 68  4
         StringBuffer str = new StringBuffer();
 69  4
         str.append( "<script type=\"text/javascript\">\n" );
 70  4
         str.append( "function toggleDisplay(elementId) {\n" );
 71  4
         str.append( " var elm = document.getElementById(elementId + 'error');\n" );
 72  4
         str.append( " if (elm && typeof elm.style != \"undefined\") {\n" );
 73  4
         str.append( " if (elm.style.display == \"none\") {\n" );
 74  4
         str.append( " elm.style.display = \"\";\n" );
 75  4
         str.append( " document.getElementById(elementId + 'off').style.display = \"none\";\n" );
 76  4
         str.append( " document.getElementById(elementId + 'on').style.display = \"inline\";\n" );
 77  4
         str.append( " }" );
 78  4
         str.append( " else if (elm.style.display == \"\") {" );
 79  4
         str.append( " elm.style.display = \"none\";\n" );
 80  4
         str.append( " document.getElementById(elementId + 'off').style.display = \"inline\";\n" );
 81  4
         str.append( " document.getElementById(elementId + 'on').style.display = \"none\";\n" );
 82  4
         str.append( " } \n" );
 83  4
         str.append( " } \n" );
 84  4
         str.append( " }\n" );
 85  4
         str.append( "</script>" );
 86  4
         sink.rawText( str.toString() );
 87  
 
 88  4
         sink.head_();
 89  
 
 90  4
         sink.body();
 91  
 
 92  4
         sink.section1();
 93  4
         sink.sectionTitle1();
 94  4
         sink.text( bundle.getString( "report.surefire.header" ) );
 95  4
         sink.sectionTitle1_();
 96  4
         sink.section1_();
 97  
 
 98  4
         constructSummarySection( bundle, sink );
 99  
 
 100  4
         Map suitePackages = report.getSuitesGroupByPackage( testSuites );
 101  4
         if ( !suitePackages.isEmpty() )
 102  
         {
 103  4
             constructPackagesSection( bundle, sink, suitePackages );
 104  
         }
 105  
 
 106  4
         if ( !testSuites.isEmpty() )
 107  
         {
 108  4
             constructTestCasesSection( bundle, sink );
 109  
         }
 110  
 
 111  4
         List failureList = report.getFailureDetails( testSuites );
 112  4
         if ( !failureList.isEmpty() )
 113  
         {
 114  4
             constructFailureDetails( sink, bundle, failureList );
 115  
         }
 116  
 
 117  4
         sink.body_();
 118  
 
 119  4
         sink.flush();
 120  
 
 121  4
         sink.close();
 122  4
     }
 123  
 
 124  
     private void constructSummarySection( ResourceBundle bundle, Sink sink )
 125  
     {
 126  4
         Map summary = report.getSummary( testSuites );
 127  
 
 128  4
         sink.section1();
 129  4
         sink.sectionTitle1();
 130  4
         sink.text( bundle.getString( "report.surefire.label.summary" ) );
 131  4
         sink.sectionTitle1_();
 132  
 
 133  4
         sinkAnchor( sink, "Summary" );
 134  
 
 135  4
         constructHotLinks( sink, bundle );
 136  
 
 137  4
         sinkLineBreak( sink );
 138  
 
 139  4
         sink.table();
 140  
 
 141  4
         sink.tableRow();
 142  
 
 143  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.tests" ) );
 144  
 
 145  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.errors" ) );
 146  
 
 147  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.failures" ) );
 148  
 
 149  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.skipped" ) );
 150  
 
 151  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.successrate" ) );
 152  
 
 153  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.time" ) );
 154  
 
 155  4
         sink.tableRow_();
 156  
 
 157  4
         sink.tableRow();
 158  
 
 159  4
         sinkCell( sink, (String) summary.get( "totalTests" ) );
 160  
 
 161  4
         sinkCell( sink, (String) summary.get( "totalErrors" ) );
 162  
 
 163  4
         sinkCell( sink, (String) summary.get( "totalFailures" ) );
 164  
 
 165  4
         sinkCell( sink, (String) summary.get( "totalSkipped" ) );
 166  
 
 167  4
         sinkCell( sink, summary.get( "totalPercentage" ) + "%" );
 168  
 
 169  4
         sinkCell( sink, (String) summary.get( "totalElapsedTime" ) );
 170  
 
 171  4
         sink.tableRow_();
 172  
 
 173  4
         sink.table_();
 174  
 
 175  4
         sink.lineBreak();
 176  
 
 177  4
         sink.paragraph();
 178  4
         sink.rawText( bundle.getString( "report.surefire.text.note1" ) );
 179  4
         sink.paragraph_();
 180  
 
 181  4
         sinkLineBreak( sink );
 182  
 
 183  4
         sink.section1_();
 184  4
     }
 185  
 
 186  
     private void constructPackagesSection( ResourceBundle bundle, Sink sink, Map suitePackages )
 187  
     {
 188  4
         NumberFormat numberFormat = report.getNumberFormat();
 189  
 
 190  4
         sink.section1();
 191  4
         sink.sectionTitle1();
 192  4
         sink.text( bundle.getString( "report.surefire.label.packagelist" ) );
 193  4
         sink.sectionTitle1_();
 194  
 
 195  4
         sinkAnchor( sink, "Package_List" );
 196  
 
 197  4
         constructHotLinks( sink, bundle );
 198  
 
 199  4
         sinkLineBreak( sink );
 200  
 
 201  4
         sink.table();
 202  
 
 203  4
         sink.tableRow();
 204  
 
 205  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.package" ) );
 206  
 
 207  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.tests" ) );
 208  
 
 209  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.errors" ) );
 210  
 
 211  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.failures" ) );
 212  
 
 213  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.skipped" ) );
 214  
 
 215  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.successrate" ) );
 216  
 
 217  4
         sinkHeader( sink, bundle.getString( "report.surefire.label.time" ) );
 218  
 
 219  4
         sink.tableRow_();
 220  
 
 221  4
         Iterator packIter = suitePackages.keySet().iterator();
 222  
 
 223  8
         while ( packIter.hasNext() )
 224  
         {
 225  4
             sink.tableRow();
 226  
 
 227  4
             String packageName = (String) packIter.next();
 228  
 
 229  4
             List testSuiteList = (List) suitePackages.get( packageName );
 230  
 
 231  4
             Map packageSummary = report.getSummary( testSuiteList );
 232  
 
 233  4
             sinkCellLink( sink, packageName, "#" + packageName );
 234  
 
 235  4
             sinkCell( sink, (String) packageSummary.get( "totalTests" ) );
 236  
 
 237  4
             sinkCell( sink, (String) packageSummary.get( "totalErrors" ) );
 238  
 
 239  4
             sinkCell( sink, (String) packageSummary.get( "totalFailures" ) );
 240  
 
 241  4
             sinkCell( sink, (String) packageSummary.get( "totalSkipped" ) );
 242  
 
 243  4
             sinkCell( sink, packageSummary.get( "totalPercentage" ) + "%" );
 244  
 
 245  4
             sinkCell( sink, (String) packageSummary.get( "totalElapsedTime" ) );
 246  
 
 247  4
             sink.tableRow_();
 248  4
         }
 249  
 
 250  4
         sink.table_();
 251  
 
 252  4
         sink.lineBreak();
 253  
 
 254  4
         sink.paragraph();
 255  4
         sink.rawText( bundle.getString( "report.surefire.text.note2" ) );
 256  4
         sink.paragraph_();
 257  
 
 258  4
         packIter = suitePackages.keySet().iterator();
 259  
 
 260  8
         while ( packIter.hasNext() )
 261  
         {
 262  4
             String packageName = (String) packIter.next();
 263  
 
 264  4
             List testSuiteList = (List) suitePackages.get( packageName );
 265  
 
 266  4
             Iterator suiteIterator = testSuiteList.iterator();
 267  
 
 268  4
             sink.section2();
 269  4
             sink.sectionTitle2();
 270  4
             sink.text( packageName );
 271  4
             sink.sectionTitle2_();
 272  
 
 273  4
             sinkAnchor( sink, packageName );
 274  
 
 275  4
             sink.table();
 276  
 
 277  4
             sink.tableRow();
 278  
 
 279  4
             sinkHeader( sink, "" );
 280  
 
 281  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.class" ) );
 282  
 
 283  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.tests" ) );
 284  
 
 285  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.errors" ) );
 286  
 
 287  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.failures" ) );
 288  
 
 289  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.skipped" ) );
 290  
 
 291  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.successrate" ) );
 292  
 
 293  4
             sinkHeader( sink, bundle.getString( "report.surefire.label.time" ) );
 294  
 
 295  4
             sink.tableRow_();
 296  
 
 297  8
             while ( suiteIterator.hasNext() )
 298  
             {
 299  4
                 ReportTestSuite suite = (ReportTestSuite) suiteIterator.next();
 300  
 
 301  4
                 if ( showSuccess || suite.getNumberOfErrors() != 0 || suite.getNumberOfFailures() != 0 )
 302  
                 {
 303  
 
 304  4
                     sink.tableRow();
 305  
 
 306  4
                     sink.tableCell();
 307  
 
 308  4
                     sink.link( "#" + suite.getPackageName() + suite.getName() );
 309  
 
 310  4
                     if ( suite.getNumberOfErrors() > 0 )
 311  
                     {
 312  4
                         sinkIcon( "error", sink );
 313  
                     }
 314  0
                     else if ( suite.getNumberOfFailures() > 0 )
 315  
                     {
 316  0
                         sinkIcon( "junit.framework", sink );
 317  
                     }
 318  0
                     else if ( suite.getNumberOfSkipped() > 0 )
 319  
                     {
 320  0
                         sinkIcon( "skipped", sink );
 321  
                     }
 322  
                     else
 323  
                     {
 324  0
                         sinkIcon( "success", sink );
 325  
                     }
 326  
 
 327  4
                     sink.link_();
 328  
 
 329  4
                     sink.tableCell_();
 330  
 
 331  4
                     sinkCellLink( sink, suite.getName(), "#" + suite.getPackageName() + suite.getName() );
 332  
 
 333  4
                     sinkCell( sink, Integer.toString( suite.getNumberOfTests() ) );
 334  
 
 335  4
                     sinkCell( sink, Integer.toString( suite.getNumberOfErrors() ) );
 336  
 
 337  4
                     sinkCell( sink, Integer.toString( suite.getNumberOfFailures() ) );
 338  
 
 339  4
                     sinkCell( sink, Integer.toString( suite.getNumberOfSkipped() ) );
 340  
 
 341  4
                     String percentage = report.computePercentage( suite.getNumberOfTests(), suite.getNumberOfErrors(),
 342  
                                                                   suite.getNumberOfFailures(), suite
 343  
                         .getNumberOfSkipped() );
 344  4
                     sinkCell( sink, percentage + "%" );
 345  
 
 346  4
                     sinkCell( sink, numberFormat.format( suite.getTimeElapsed() ) );
 347  
 
 348  4
                     sink.tableRow_();
 349  
                 }
 350  4
             }
 351  
 
 352  4
             sink.table_();
 353  
 
 354  4
             sink.section2_();
 355  4
         }
 356  
 
 357  4
         sinkLineBreak( sink );
 358  
 
 359  4
         sink.section1_();
 360  4
     }
 361  
 
 362  
     private void constructTestCasesSection( ResourceBundle bundle, Sink sink )
 363  
     {
 364  4
         NumberFormat numberFormat = report.getNumberFormat();
 365  
 
 366  4
         sink.section1();
 367  4
         sink.sectionTitle1();
 368  4
         sink.text( bundle.getString( "report.surefire.label.testcases" ) );
 369  4
         sink.sectionTitle1_();
 370  
 
 371  4
         sinkAnchor( sink, "Test_Cases" );
 372  
 
 373  4
         constructHotLinks( sink, bundle );
 374  
 
 375  4
         ListIterator suiteIterator = testSuites.listIterator();
 376  
 
 377  8
         while ( suiteIterator.hasNext() )
 378  
         {
 379  4
             ReportTestSuite suite = (ReportTestSuite) suiteIterator.next();
 380  
 
 381  4
             List testCases = suite.getTestCases();
 382  
 
 383  4
             if ( testCases != null && !testCases.isEmpty() )
 384  
             {
 385  4
                 ListIterator caseIterator = testCases.listIterator();
 386  
 
 387  4
                 sink.section2();
 388  4
                 sink.sectionTitle2();
 389  4
                 sink.text( suite.getName() );
 390  4
                 sink.sectionTitle2_();
 391  
 
 392  4
                 sinkAnchor( sink, suite.getPackageName() + suite.getName() );
 393  
 
 394  4
                 sink.table();
 395  
 
 396  36
                 while ( caseIterator.hasNext() )
 397  
                 {
 398  32
                     ReportTestCase testCase = (ReportTestCase) caseIterator.next();
 399  
 
 400  32
                     if ( testCase.getFailure() != null || showSuccess )
 401  
                     {
 402  26
                         sink.tableRow();
 403  
 
 404  26
                         sink.tableCell();
 405  
 
 406  26
                         Map failure = testCase.getFailure();
 407  
 
 408  26
                         if ( failure != null )
 409  
                         {
 410  8
                             sink.link( "#" + testCase.getFullName() );
 411  
 
 412  8
                             sinkIcon( (String) failure.get( "type" ), sink );
 413  
 
 414  8
                             sink.link_();
 415  
                         }
 416  
                         else
 417  
                         {
 418  18
                             sinkIcon( "success", sink );
 419  
                         }
 420  
 
 421  26
                         sink.tableCell_();
 422  
 
 423  26
                         if ( failure != null )
 424  
                         {
 425  8
                             sink.tableCell();
 426  
 
 427  8
                             sinkLink( sink, testCase.getName(), "#" + testCase.getFullName() );
 428  
 
 429  8
                             sink.rawText( "  <div class=\"detailToggle\" style=\"display:inline\">" );
 430  
 
 431  8
                             sink.link( "javascript:toggleDisplay('" + testCase.getName() + "');" );
 432  
 
 433  8
                             sink.rawText( "<span style=\"display: inline;\" " + "id=\"" + testCase.getName() +
 434  
                                 "off\">+</span><span id=\"" + testCase.getName() + "on\" " +
 435  
                                 "style=\"display: none;\">-</span> " );
 436  8
                             sink.text( "[ Detail ]" );
 437  8
                             sink.link_();
 438  
 
 439  8
                             sink.rawText( "</div>" );
 440  
 
 441  8
                             sink.tableCell_();
 442  
                         }
 443  
                         else
 444  
                         {
 445  18
                             sinkCell( sink, testCase.getName() );
 446  
                         }
 447  
 
 448  26
                         sinkCell( sink, numberFormat.format( testCase.getTime() ) );
 449  
 
 450  26
                         sink.tableRow_();
 451  
 
 452  26
                         if ( failure != null )
 453  
                         {
 454  8
                             sink.tableRow();
 455  
 
 456  8
                             sinkCell( sink, "" );
 457  8
                             sinkCell( sink, (String) failure.get( "message" ) );
 458  8
                             sinkCell( sink, "" );
 459  8
                             sink.tableRow_();
 460  
 
 461  8
                             List detail = (List) failure.get( "detail" );
 462  8
                             if ( detail != null )
 463  
                             {
 464  
 
 465  8
                                 sink.tableRow();
 466  8
                                 sinkCell( sink, "" );
 467  
 
 468  8
                                 sink.tableCell();
 469  8
                                 sink.rawText(
 470  
                                     "  <div id=\"" + testCase.getName() + "error\" style=\"display:none;\">" );
 471  
 
 472  8
                                 Iterator it = detail.iterator();
 473  
 
 474  8
                                 sink.verbatim( true );
 475  44
                                 while ( it.hasNext() )
 476  
                                 {
 477  36
                                     sink.text( it.next().toString() );
 478  36
                                     sink.lineBreak();
 479  
                                 }
 480  8
                                 sink.verbatim_();
 481  
 
 482  8
                                 sink.rawText( "</div>" );
 483  8
                                 sink.tableCell_();
 484  
 
 485  8
                                 sinkCell( sink, "" );
 486  
 
 487  8
                                 sink.tableRow_();
 488  
                             }
 489  
                         }
 490  
                     }
 491  32
                 }
 492  
 
 493  4
                 sink.table_();
 494  
 
 495  4
                 sink.section2_();
 496  
             }
 497  4
         }
 498  
 
 499  4
         sinkLineBreak( sink );
 500  
 
 501  4
         sink.section1_();
 502  4
     }
 503  
 
 504  
     private void constructFailureDetails( Sink sink, ResourceBundle bundle, List failureList )
 505  
     {
 506  4
         Iterator failIter = failureList.iterator();
 507  
 
 508  4
         if ( failIter != null )
 509  
         {
 510  4
             sink.section1();
 511  4
             sink.sectionTitle1();
 512  4
             sink.text( bundle.getString( "report.surefire.label.failuredetails" ) );
 513  4
             sink.sectionTitle1_();
 514  
 
 515  4
             sinkAnchor( sink, "Failure_Details" );
 516  
 
 517  4
             constructHotLinks( sink, bundle );
 518  
 
 519  4
             sinkLineBreak( sink );
 520  
 
 521  4
             sink.table();
 522  
 
 523  12
             while ( failIter.hasNext() )
 524  
             {
 525  8
                 ReportTestCase tCase = (ReportTestCase) failIter.next();
 526  
 
 527  8
                 Map failure = tCase.getFailure();
 528  
 
 529  8
                 sink.tableRow();
 530  
 
 531  8
                 sink.tableCell();
 532  
 
 533  8
                 String type = (String) failure.get( "type" );
 534  8
                 sinkIcon( type, sink );
 535  
 
 536  8
                 sink.tableCell_();
 537  
 
 538  8
                 sinkCellAnchor( sink, tCase.getName(), tCase.getFullName() );
 539  
 
 540  8
                 sink.tableRow_();
 541  
 
 542  8
                 String message = (String) failure.get( "message" );
 543  
 
 544  8
                 sink.tableRow();
 545  
 
 546  8
                 sinkCell( sink, "" );
 547  
 
 548  8
                 StringBuffer sb = new StringBuffer();
 549  8
                 sb.append( type );
 550  
 
 551  8
                 if ( message != null )
 552  
                 {
 553  8
                     sb.append( ": " );
 554  8
                     sb.append( message );
 555  
                 }
 556  
 
 557  8
                 sinkCell( sink, sb.toString() );
 558  
 
 559  8
                 sink.tableRow_();
 560  
 
 561  8
                 List detail = (List) failure.get( "detail" );
 562  8
                 if ( detail != null )
 563  
                 {
 564  8
                     Iterator it = detail.iterator();
 565  
 
 566  8
                     boolean firstLine = true;
 567  
 
 568  8
                     String techMessage = "";
 569  44
                     while ( it.hasNext() )
 570  
                     {
 571  36
                         techMessage = it.next().toString();
 572  36
                         if ( firstLine )
 573  
                         {
 574  8
                             firstLine = false;
 575  
                         }
 576  
                         else
 577  
                         {
 578  28
                             sink.text( "    " );
 579  
                         }
 580  
                     }
 581  
 
 582  8
                     sink.tableRow();
 583  
 
 584  8
                     sinkCell( sink, "" );
 585  
 
 586  8
                     sink.tableCell();
 587  8
                     sink.rawText( "  <div id=\"" + tCase.getName() + "error\" >" );
 588  
 
 589  8
                     if ( xrefLocation != null )
 590  
                     {
 591  4
                         String path = tCase.getFullClassName().replace( '.', '/' );
 592  
 
 593  4
                         sink.link( xrefLocation + "/" + path + ".html#" +
 594  
                             getErrorLineNumber( tCase.getFullName(), techMessage ) );
 595  
                     }
 596  8
                     sink.text(
 597  
                         tCase.getFullClassName() + ":" + getErrorLineNumber( tCase.getFullName(), techMessage ) );
 598  
 
 599  8
                     if ( xrefLocation != null )
 600  
                     {
 601  4
                         sink.link_();
 602  
                     }
 603  8
                     sink.rawText( "</div>" );
 604  
 
 605  8
                     sink.tableCell_();
 606  
 
 607  8
                     sink.tableRow_();
 608  
                 }
 609  8
             }
 610  
 
 611  4
             sink.table_();
 612  
         }
 613  
 
 614  4
         sinkLineBreak( sink );
 615  
 
 616  4
         sink.section1_();
 617  4
     }
 618  
 
 619  
     private String getErrorLineNumber( String className, String source )
 620  
     {
 621  12
         StringTokenizer tokenizer = new StringTokenizer( source );
 622  
 
 623  12
         String lineNo = "";
 624  
 
 625  24
         while ( tokenizer.hasMoreTokens() )
 626  
         {
 627  24
             String token = tokenizer.nextToken();
 628  24
             if ( token.startsWith( className ) )
 629  
             {
 630  12
                 int idx = token.indexOf( ":" );
 631  12
                 lineNo = token.substring( idx + 1, token.indexOf( ")" ) );
 632  12
                 break;
 633  
             }
 634  12
         }
 635  12
         return lineNo;
 636  
     }
 637  
 
 638  
     private void constructHotLinks( Sink sink, ResourceBundle bundle )
 639  
     {
 640  16
         if ( !testSuites.isEmpty() )
 641  
         {
 642  16
             sink.paragraph();
 643  
 
 644  16
             sink.text( "[" );
 645  16
             sinkLink( sink, bundle.getString( "report.surefire.label.summary" ), "#Summary" );
 646  16
             sink.text( "]" );
 647  
 
 648  16
             sink.text( " [" );
 649  16
             sinkLink( sink, bundle.getString( "report.surefire.label.packagelist" ), "#Package_List" );
 650  16
             sink.text( "]" );
 651  
 
 652  16
             sink.text( " [" );
 653  16
             sinkLink( sink, bundle.getString( "report.surefire.label.testcases" ), "#Test_Cases" );
 654  16
             sink.text( "]" );
 655  
 
 656  16
             sink.paragraph_();
 657  
         }
 658  16
     }
 659  
 
 660  
     private void sinkLineBreak( Sink sink )
 661  
     {
 662  28
         sink.lineBreak();
 663  28
     }
 664  
 
 665  
     private void sinkIcon( String type, Sink sink )
 666  
     {
 667  38
         sink.figure();
 668  
 
 669  38
         if ( type.startsWith( "junit.framework" ) || "skipped".equals( type ) )
 670  
         {
 671  8
             sink.figureGraphics( "images/icon_warning_sml.gif" );
 672  
         }
 673  30
         else if ( type.startsWith( "success" ) )
 674  
         {
 675  18
             sink.figureGraphics( "images/icon_success_sml.gif" );
 676  
         }
 677  
         else
 678  
         {
 679  12
             sink.figureGraphics( "images/icon_error_sml.gif" );
 680  
         }
 681  
 
 682  38
         sink.figure_();
 683  38
     }
 684  
 
 685  
     private void sinkHeader( Sink sink, String header )
 686  
     {
 687  84
         sink.tableHeaderCell();
 688  84
         sink.text( header );
 689  84
         sink.tableHeaderCell_();
 690  84
     }
 691  
 
 692  
     private void sinkCell( Sink sink, String text )
 693  
     {
 694  180
         sink.tableCell();
 695  180
         sink.text( text );
 696  180
         sink.tableCell_();
 697  180
     }
 698  
 
 699  
     private void sinkLink( Sink sink, String text, String link )
 700  
     {
 701  64
         sink.link( link );
 702  64
         sink.text( text );
 703  64
         sink.link_();
 704  64
     }
 705  
 
 706  
     private void sinkCellLink( Sink sink, String text, String link )
 707  
     {
 708  8
         sink.tableCell();
 709  8
         sinkLink( sink, text, link );
 710  8
         sink.tableCell_();
 711  8
     }
 712  
 
 713  
     private void sinkCellAnchor( Sink sink, String text, String anchor )
 714  
     {
 715  8
         sink.tableCell();
 716  8
         sinkAnchor( sink, anchor );
 717  8
         sink.text( text );
 718  8
         sink.tableCell_();
 719  8
     }
 720  
 
 721  
     private void sinkAnchor( Sink sink, String anchor )
 722  
     {
 723  32
         sink.anchor( anchor );
 724  32
         sink.anchor_();
 725  32
     }
 726  
 }