Coverage Report - org.apache.maven.plugin.pmd.CpdReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
CpdReportGenerator
87%
85/97
62%
10/16
2,6
 
 1  
 package org.apache.maven.plugin.pmd;
 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.util.Iterator;
 24  
 import java.util.Map;
 25  
 import java.util.ResourceBundle;
 26  
 
 27  
 import net.sourceforge.pmd.cpd.Match;
 28  
 import net.sourceforge.pmd.cpd.TokenEntry;
 29  
 
 30  
 import org.apache.maven.doxia.sink.Sink;
 31  
 import org.apache.maven.project.MavenProject;
 32  
 import org.codehaus.plexus.util.StringUtils;
 33  
 
 34  
 /**
 35  
  * Class that generated the CPD report.
 36  
  *
 37  
  * @author mperham
 38  
  * @version $Id: org.apache.maven.plugin.pmd.CpdReportGenerator.html 816698 2012-05-08 15:21:08Z hboutemy $
 39  
  */
 40  
 public class CpdReportGenerator
 41  
 {
 42  
     private Sink sink;
 43  
 
 44  
     private Map<File, PmdFileInfo> fileMap;
 45  
 
 46  
     private ResourceBundle bundle;
 47  
 
 48  
     private boolean aggregate;
 49  
 
 50  
     public CpdReportGenerator( Sink sink, Map<File, PmdFileInfo> fileMap, ResourceBundle bundle, boolean aggregate )
 51  4
     {
 52  4
         this.sink = sink;
 53  4
         this.fileMap = fileMap;
 54  4
         this.bundle = bundle;
 55  4
         this.aggregate = aggregate;
 56  4
     }
 57  
 
 58  
     /**
 59  
      * Method that returns the title of the CPD Report
 60  
      *
 61  
      * @return a String that contains the title
 62  
      */
 63  
     private String getTitle()
 64  
     {
 65  8
         return bundle.getString( "report.cpd.title" );
 66  
     }
 67  
 
 68  
     /**
 69  
      * Method that generates the start of the CPD report.
 70  
      */
 71  
     public void beginDocument()
 72  
     {
 73  4
         sink.head();
 74  4
         sink.title();
 75  4
         sink.text( getTitle() );
 76  4
         sink.title_();
 77  4
         sink.head_();
 78  
 
 79  4
         sink.body();
 80  
 
 81  4
         sink.section1();
 82  4
         sink.sectionTitle1();
 83  4
         sink.text( getTitle() );
 84  4
         sink.sectionTitle1_();
 85  
 
 86  4
         sink.paragraph();
 87  4
         sink.text( bundle.getString( "report.cpd.cpdlink" ) + " " );
 88  4
         sink.link( "http://pmd.sourceforge.net/cpd.html" );
 89  4
         sink.text( "CPD" );
 90  4
         sink.link_();
 91  4
         sink.text( " " + AbstractPmdReport.getPmdVersion() + "." );
 92  4
         sink.paragraph_();
 93  
 
 94  4
         sink.section1_();
 95  
 
 96  
         // TODO overall summary
 97  
 
 98  4
         sink.section1();
 99  4
         sink.sectionTitle1();
 100  4
         sink.text( bundle.getString( "report.cpd.dupes" ) );
 101  4
         sink.sectionTitle1_();
 102  
 
 103  
         // TODO files summary
 104  4
     }
 105  
 
 106  
     /**
 107  
      * Method that generates a line of CPD report according to a TokenEntry.
 108  
      */
 109  
     private void generateFileLine( TokenEntry tokenEntry )
 110  
     {
 111  
         // Get information for report generation
 112  8
         String filename = tokenEntry.getTokenSrcID();
 113  8
         File file = new File( filename );
 114  8
         PmdFileInfo fileInfo = fileMap.get( file );
 115  8
         File sourceDirectory = fileInfo.getSourceDirectory();
 116  8
         filename = StringUtils.substring( filename, sourceDirectory.getAbsolutePath().length() + 1 );
 117  8
         String xrefLocation = fileInfo.getXrefLocation();
 118  8
         MavenProject projectFile = fileInfo.getProject();
 119  8
         int line = tokenEntry.getBeginLine();
 120  
 
 121  8
         sink.tableRow();
 122  8
         sink.tableCell();
 123  8
         sink.text( filename );
 124  8
         sink.tableCell_();
 125  8
         if ( aggregate )
 126  
         {
 127  0
             sink.tableCell();
 128  0
             sink.text( projectFile.getName() );
 129  0
             sink.tableCell_();
 130  
         }
 131  8
         sink.tableCell();
 132  
 
 133  8
         if ( xrefLocation != null )
 134  
         {
 135  0
             sink.link( xrefLocation + "/" + filename.replaceAll( "\\.java$", ".html" ).replace( '\\', '/' )
 136  
                     + "#" + line );
 137  
         }
 138  8
         sink.text( String.valueOf( line ) );
 139  8
         if ( xrefLocation != null )
 140  
         {
 141  0
             sink.link_();
 142  
         }
 143  
 
 144  8
         sink.tableCell_();
 145  8
         sink.tableRow_();
 146  8
     }
 147  
 
 148  
     /**
 149  
      * Method that generates the contents of the CPD report
 150  
      *
 151  
      * @param matches
 152  
      */
 153  
     @SuppressWarnings( "deprecation" )
 154  
     public void generate( Iterator<Match> matches )
 155  
     {
 156  4
         beginDocument();
 157  
 
 158  4
         if ( !matches.hasNext() )
 159  
         {
 160  0
             sink.paragraph();
 161  0
             sink.text( bundle.getString( "report.cpd.noProblems" ) );
 162  0
             sink.paragraph_();
 163  
         }
 164  
 
 165  8
         while ( matches.hasNext() )
 166  
         {
 167  4
             Match match = matches.next();
 168  
             
 169  4
             String code = match.getSourceCodeSlice();
 170  
             
 171  4
             sink.table();
 172  4
             sink.tableRow();
 173  4
             sink.tableHeaderCell();
 174  4
             sink.text( bundle.getString( "report.cpd.column.file" ) );
 175  4
             sink.tableHeaderCell_();
 176  4
             if ( aggregate )
 177  
             {
 178  0
                 sink.tableHeaderCell();
 179  0
                 sink.text( bundle.getString( "report.cpd.column.project" ) );
 180  0
                 sink.tableHeaderCell_();
 181  
             }
 182  4
             sink.tableHeaderCell();
 183  4
             sink.text( bundle.getString( "report.cpd.column.line" ) );
 184  4
             sink.tableHeaderCell_();
 185  4
             sink.tableRow_();
 186  
 
 187  
             // Iterating on every token entry
 188  4
             for ( Iterator<TokenEntry> occurrences = match.iterator(); occurrences.hasNext(); )
 189  
             {
 190  
 
 191  8
                 TokenEntry mark = occurrences.next();
 192  8
                 generateFileLine( mark );
 193  8
             }
 194  
            
 195  
             // Source snippet
 196  4
             sink.tableRow();
 197  
 
 198  
 
 199  4
             int colspan = 2;
 200  4
             if ( aggregate )
 201  
             {
 202  0
                 ++colspan;
 203  
             }
 204  
             // TODO Cleaner way to do this?
 205  4
             sink.rawText( "<td colspan='" + colspan + "'>" );
 206  4
             sink.verbatim( false );
 207  4
             sink.text( code );
 208  4
             sink.verbatim_();
 209  4
             sink.rawText( "</td>" );
 210  4
             sink.tableRow_();
 211  4
             sink.table_();
 212  4
         }
 213  
 
 214  4
         sink.section1_();
 215  4
         sink.body_();
 216  4
         sink.flush();
 217  4
         sink.close();
 218  4
     }
 219  
 }