Coverage Report - org.apache.maven.plugin.pmd.CpdReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
CpdReportGenerator
87%
100/115
55%
11/20
3,5
 
 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.PMD;
 28  
 import net.sourceforge.pmd.cpd.Match;
 29  
 
 30  
 import org.apache.maven.project.MavenProject;
 31  
 import org.codehaus.doxia.sink.Sink;
 32  
 import org.codehaus.plexus.util.StringUtils;
 33  
 
 34  
 /**
 35  
  * Class that generated the CPD report.
 36  
  *
 37  
  * @author mperham
 38  
  * @version $Id: $
 39  
  */
 40  
 public class CpdReportGenerator
 41  
 {
 42  
     private Sink sink;
 43  
 
 44  
     private Map fileMap;
 45  
 
 46  
     private ResourceBundle bundle;
 47  
     
 48  
     private boolean aggregate;
 49  
 
 50  
     public CpdReportGenerator( Sink sink, Map fileMap, ResourceBundle bundle, boolean aggregate )
 51  3
     {
 52  3
         this.sink = sink;
 53  3
         this.fileMap = fileMap;
 54  3
         this.bundle = bundle;
 55  3
         this.aggregate = aggregate;
 56  3
     }
 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  6
         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  3
         sink.head();
 74  3
         sink.title();
 75  3
         sink.text( getTitle() );
 76  3
         sink.title_();
 77  3
         sink.head_();
 78  
 
 79  3
         sink.body();
 80  
 
 81  3
         sink.section1();
 82  3
         sink.sectionTitle1();
 83  3
         sink.text( getTitle() );
 84  3
         sink.sectionTitle1_();
 85  
 
 86  3
         sink.paragraph();
 87  3
         sink.text( bundle.getString( "report.cpd.cpdlink" ) + " " );
 88  3
         sink.link( "http://pmd.sourceforge.net/cpd.html" );
 89  3
         sink.text( "CPD" );
 90  3
         sink.link_();
 91  3
         sink.text( " " + PMD.VERSION + "." );
 92  3
         sink.paragraph_();
 93  
 
 94  
         // TODO overall summary
 95  
 
 96  3
         sink.section1_();
 97  3
         sink.section1();
 98  3
         sink.sectionTitle1();
 99  3
         sink.text( bundle.getString( "report.cpd.dupes" ) );
 100  3
         sink.sectionTitle1_();
 101  
 
 102  
         // TODO files summary
 103  3
     }
 104  
 
 105  
     /**
 106  
      * Method that generates the contents of the CPD report
 107  
      *
 108  
      * @param matches
 109  
      */
 110  
     public void generate( Iterator matches )
 111  
     {
 112  3
         beginDocument();
 113  
 
 114  3
         if ( !matches.hasNext() )
 115  
         {
 116  0
             sink.text( "CPD found no problems in your source code." );            
 117  
         }
 118  
 
 119  6
         while ( matches.hasNext() )
 120  
         {
 121  3
             Match match = (Match) matches.next();
 122  3
             String filename1 = match.getFirstMark().getTokenSrcID();
 123  
             
 124  3
             File file = new File( filename1 );
 125  3
             PmdFileInfo fileInfo = (PmdFileInfo) fileMap.get( file );
 126  3
             File sourceDirectory = fileInfo.getSourceDirectory();
 127  3
             String xrefLocation = fileInfo.getXrefLocation();
 128  3
             MavenProject projectFile1 = fileInfo.getProject();
 129  
             
 130  3
             filename1 = StringUtils.substring( filename1, sourceDirectory.getAbsolutePath().length() + 1 );
 131  
 
 132  3
             String filename2 = match.getSecondMark().getTokenSrcID();
 133  3
             file = new File( filename2 );
 134  3
             fileInfo = (PmdFileInfo) fileMap.get( file );
 135  3
             sourceDirectory = fileInfo.getSourceDirectory();
 136  3
             String xrefLocation2 = fileInfo.getXrefLocation();
 137  3
             filename2 = StringUtils.substring( filename2, sourceDirectory.getAbsolutePath().length() + 1 );
 138  3
             MavenProject projectFile2 = fileInfo.getProject();
 139  
 
 140  3
             String code = match.getSourceCodeSlice();
 141  3
             int line1 = match.getFirstMark().getBeginLine();
 142  3
             int line2 = match.getSecondMark().getBeginLine();
 143  
 
 144  3
             sink.paragraph();
 145  3
             sink.table();
 146  3
             sink.tableRow();
 147  3
             sink.tableHeaderCell();
 148  3
             sink.text( bundle.getString( "report.cpd.column.file" ) );
 149  3
             sink.tableHeaderCell_();
 150  3
             if ( aggregate )
 151  
             {
 152  0
                 sink.tableHeaderCell();
 153  0
                 sink.text( bundle.getString( "report.cpd.column.project" ) );
 154  0
                 sink.tableHeaderCell_();
 155  
             }
 156  3
             sink.tableHeaderCell();
 157  3
             sink.text( bundle.getString( "report.cpd.column.line" ) );
 158  3
             sink.tableHeaderCell_();
 159  3
             sink.tableRow_();
 160  
 
 161  
             // File 1
 162  3
             sink.tableRow();
 163  3
             sink.tableCell();
 164  3
             sink.text( filename1 );
 165  3
             sink.tableCell_();
 166  3
             if ( aggregate )
 167  
             {
 168  0
                 sink.tableCell();
 169  0
                 sink.text( projectFile1.getName() );
 170  0
                 sink.tableCell_();
 171  
             }
 172  3
             sink.tableCell();
 173  
 
 174  3
             if ( xrefLocation != null )
 175  
             {
 176  0
                 sink.link( xrefLocation + "/" + filename1.replaceAll( "\\.java$", ".html" ).replace( '\\', '/' ) 
 177  
                            + "#" + line1 );
 178  
             }
 179  3
             sink.text( String.valueOf( line1 ) );
 180  3
             if ( xrefLocation != null )
 181  
             {
 182  0
                 sink.link_();
 183  
             }
 184  
 
 185  3
             sink.tableCell_();
 186  3
             sink.tableRow_();
 187  
 
 188  
             // File 2
 189  3
             sink.tableRow();
 190  3
             sink.tableCell();
 191  3
             sink.text( filename2 );
 192  3
             sink.tableCell_();
 193  3
             if ( aggregate )
 194  
             {
 195  0
                 sink.tableCell();
 196  0
                 sink.text( projectFile2.getName() );
 197  0
                 sink.tableCell_();
 198  
             }
 199  3
             sink.tableCell();
 200  
             
 201  
             
 202  
             
 203  3
             if ( xrefLocation != null )
 204  
             {
 205  0
                 sink.link( xrefLocation2 + "/" + filename2.replaceAll( "\\.java$", ".html" ).replace( '\\', '/' ) 
 206  
                            + "#" + line2 );
 207  
             }
 208  3
             sink.text( String.valueOf( line2 ) );
 209  3
             if ( xrefLocation != null )
 210  
             {
 211  0
                 sink.link_();
 212  
             }
 213  3
             sink.tableCell_();
 214  3
             sink.tableRow_();
 215  
 
 216  
             // Source snippet
 217  3
             sink.tableRow();
 218  
 
 219  
             
 220  3
             int colspan = 2;
 221  3
             if ( aggregate ) 
 222  
             {
 223  0
                 ++colspan;
 224  
             }        
 225  
             // TODO Cleaner way to do this?
 226  3
             sink.rawText( "<td colspan='" + colspan + "'>" );
 227  3
             sink.verbatim( false );
 228  3
             sink.text( code );
 229  3
             sink.verbatim_();
 230  3
             sink.rawText( "</td>" );
 231  3
             sink.tableRow_();
 232  3
             sink.table();
 233  3
             sink.paragraph_();
 234  
         }
 235  
 
 236  3
         sink.section1_();
 237  3
         sink.body_();
 238  3
         sink.flush();
 239  3
         sink.close();
 240  3
     }
 241  
 }