1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.plugins.pmd.exec;
20  
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FilterReader;
24  import java.io.IOException;
25  import java.io.InputStreamReader;
26  import java.io.Reader;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.List;
30  
31  import org.apache.maven.plugins.pmd.model.PmdErrorDetail;
32  import org.apache.maven.plugins.pmd.model.PmdFile;
33  import org.apache.maven.plugins.pmd.model.ProcessingError;
34  import org.apache.maven.plugins.pmd.model.SuppressedViolation;
35  import org.apache.maven.plugins.pmd.model.Violation;
36  import org.apache.maven.plugins.pmd.model.io.xpp3.PmdXpp3Reader;
37  import org.apache.maven.reporting.MavenReportException;
38  
39  
40  
41  
42  public class PmdResult {
43      private final List<ProcessingError> processingErrors = new ArrayList<>();
44      private final List<Violation> violations = new ArrayList<>();
45      private final List<SuppressedViolation> suppressedViolations = new ArrayList<>();
46  
47      public static final PmdResult EMPTY = new PmdResult();
48  
49      private PmdResult() {}
50  
51      public PmdResult(File pmdFile, String encoding) throws MavenReportException {
52          loadResult(pmdFile, encoding);
53      }
54  
55      public boolean hasViolations() {
56          return !violations.isEmpty();
57      }
58  
59      private void loadResult(File pmdFile, String encoding) throws MavenReportException {
60          try (Reader reader1 = new BomFilter(encoding, new InputStreamReader(new FileInputStream(pmdFile), encoding))) {
61              PmdXpp3Reader reader = new PmdXpp3Reader();
62              PmdErrorDetail details = reader.read(reader1, false);
63              processingErrors.addAll(details.getErrors());
64              suppressedViolations.addAll(details.getSuppressedViolations());
65  
66              for (PmdFile file : details.getFiles()) {
67                  String filename = file.getName();
68                  for (Violation violation : file.getViolations()) {
69                      violation.setFileName(filename);
70                      violations.add(violation);
71                  }
72              }
73          } catch (Exception e) {
74              throw new MavenReportException(e.getMessage(), e);
75          }
76      }
77  
78      
79      
80      
81      private static class BomFilter extends FilterReader {
82          private static final char BOM = '\uFEFF';
83          private final boolean filter;
84  
85          BomFilter(String encoding, Reader in) {
86              super(in);
87              filter = !"UTF-8".equalsIgnoreCase(encoding);
88          }
89  
90          @Override
91          public int read() throws IOException {
92              int c = super.read();
93  
94              if (!filter) {
95                  return c;
96              }
97  
98              while (c != -1 && c == BOM) {
99                  c = super.read();
100             }
101             return c;
102         }
103 
104         @Override
105         public int read(char[] cbuf, int off, int len) throws IOException {
106             int count = super.read(cbuf, off, len);
107 
108             if (!filter) {
109                 return count;
110             }
111 
112             if (count != -1) {
113                 for (int i = off; i < off + count; i++) {
114                     if (cbuf[i] == BOM) {
115                         
116                         System.arraycopy(cbuf, i + 1, cbuf, i, off + count - 1 - i);
117                         count--;
118                     }
119                 }
120             }
121             return count;
122         }
123     }
124 
125     public Collection<Violation> getViolations() {
126         return violations;
127     }
128 
129     public Collection<SuppressedViolation> getSuppressedViolations() {
130         return suppressedViolations;
131     }
132 
133     public Collection<ProcessingError> getErrors() {
134         return processingErrors;
135     }
136 }