1   package org.apache.maven.plugins.pmd;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import java.io.File;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.ResourceBundle;
26  
27  import org.apache.maven.doxia.sink.Sink;
28  import org.apache.maven.plugins.pmd.model.CpdFile;
29  import org.apache.maven.plugins.pmd.model.Duplication;
30  import org.apache.maven.project.MavenProject;
31  import org.codehaus.plexus.util.StringUtils;
32  
33  
34  
35  
36  
37  
38  
39  public class CpdReportGenerator
40  {
41      private Sink sink;
42  
43      private Map<File, PmdFileInfo> fileMap;
44  
45      private ResourceBundle bundle;
46  
47      private boolean aggregate;
48  
49      public CpdReportGenerator( Sink sink, Map<File, PmdFileInfo> fileMap, ResourceBundle bundle, boolean aggregate )
50      {
51          this.sink = sink;
52          this.fileMap = fileMap;
53          this.bundle = bundle;
54          this.aggregate = aggregate;
55      }
56  
57      
58  
59  
60  
61  
62      private String getTitle()
63      {
64          return bundle.getString( "report.cpd.title" );
65      }
66  
67      
68  
69  
70      public void beginDocument()
71      {
72          sink.head();
73          sink.title();
74          sink.text( getTitle() );
75          sink.title_();
76          sink.head_();
77  
78          sink.body();
79  
80          sink.section1();
81          sink.sectionTitle1();
82          sink.text( getTitle() );
83          sink.sectionTitle1_();
84  
85          sink.paragraph();
86          sink.text( bundle.getString( "report.cpd.cpdlink" ) + " " );
87          sink.link( "https://pmd.github.io/latest/pmd_userdocs_cpd.html" );
88          sink.text( "CPD" );
89          sink.link_();
90          sink.text( " " + AbstractPmdReport.getPmdVersion() + "." );
91          sink.paragraph_();
92  
93          sink.section1_();
94  
95          
96  
97          sink.section1();
98          sink.sectionTitle1();
99          sink.text( bundle.getString( "report.cpd.dupes" ) );
100         sink.sectionTitle1_();
101 
102         
103     }
104 
105     
106 
107 
108     private void generateFileLine( CpdFile duplicationMark )
109     {
110         
111         String filename = duplicationMark.getPath();
112         File file = new File( filename );
113         PmdFileInfo fileInfo = fileMap.get( file );
114         File sourceDirectory = fileInfo.getSourceDirectory();
115         filename = StringUtils.substring( filename, sourceDirectory.getAbsolutePath().length() + 1 );
116         String xrefLocation = fileInfo.getXrefLocation();
117         MavenProject projectFile = fileInfo.getProject();
118         int line = duplicationMark.getLine();
119 
120         sink.tableRow();
121         sink.tableCell();
122         sink.text( filename );
123         sink.tableCell_();
124         if ( aggregate )
125         {
126             sink.tableCell();
127             sink.text( projectFile.getName() );
128             sink.tableCell_();
129         }
130         sink.tableCell();
131 
132         if ( xrefLocation != null )
133         {
134             sink.link( xrefLocation + "/" + filename.replaceAll( "\\.java$", ".html" ).replace( '\\', '/' ) + "#L"
135                 + line );
136         }
137         sink.text( String.valueOf( line ) );
138         if ( xrefLocation != null )
139         {
140             sink.link_();
141         }
142 
143         sink.tableCell_();
144         sink.tableRow_();
145     }
146 
147     
148 
149 
150 
151 
152     public void generate( List<Duplication> duplications )
153     {
154         beginDocument();
155 
156         if ( duplications.isEmpty() )
157         {
158             sink.paragraph();
159             sink.text( bundle.getString( "report.cpd.noProblems" ) );
160             sink.paragraph_();
161         }
162 
163         for ( Duplication duplication : duplications )
164         {
165             String code = duplication.getCodefragment();
166 
167             sink.table();
168             sink.tableRow();
169             sink.tableHeaderCell();
170             sink.text( bundle.getString( "report.cpd.column.file" ) );
171             sink.tableHeaderCell_();
172             if ( aggregate )
173             {
174                 sink.tableHeaderCell();
175                 sink.text( bundle.getString( "report.cpd.column.project" ) );
176                 sink.tableHeaderCell_();
177             }
178             sink.tableHeaderCell();
179             sink.text( bundle.getString( "report.cpd.column.line" ) );
180             sink.tableHeaderCell_();
181             sink.tableRow_();
182 
183             
184             for ( CpdFile mark : duplication.getFiles() )
185             {
186                 generateFileLine( mark );
187             }
188 
189             
190             sink.tableRow();
191 
192             int colspan = 2;
193             if ( aggregate )
194             {
195                 ++colspan;
196             }
197             
198             sink.rawText( "<td colspan='" + colspan + "'>" );
199             sink.verbatim( null );
200             sink.text( code );
201             sink.verbatim_();
202             sink.rawText( "</td>" );
203             sink.tableRow_();
204             sink.table_();
205         }
206 
207         sink.section1_();
208         sink.body_();
209         sink.flush();
210         sink.close();
211     }
212 }