View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd;
5   
6   import net.sourceforge.pmd.dfa.report.ReportTree;
7   import net.sourceforge.pmd.stat.Metric;
8   
9   import java.util.ArrayList;
10  import java.util.HashMap;
11  import java.util.HashSet;
12  import java.util.Iterator;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  import java.util.TreeSet;
17  
18  public class Report {
19  
20      public static class ReadableDuration {
21          private long duration;
22  
23          public ReadableDuration(long duration) {
24              this.duration = duration;
25          }
26  
27          public String getTime() {
28              long seconds = 0;
29              long minutes = 0;
30              long hours = 0;
31  
32              if (duration > 1000) {
33                  seconds = duration / 1000;
34              }
35  
36              if (seconds > 60) {
37                  minutes = seconds / 60;
38                  seconds = seconds % 60;
39              }
40  
41              if (minutes > 60) {
42                  hours = minutes / 60;
43                  minutes = minutes % 60;
44              }
45  
46              StringBuffer res = new StringBuffer();
47              if (hours > 0) {
48                  res.append(hours + "h ");
49              }
50              if (hours > 0 || minutes > 0) {
51                  res.append(minutes + "m ");
52              }
53              res.append(seconds + "s");
54              return res.toString();
55          }
56      }
57  
58      public static class ProcessingError {
59          private String msg;
60          private String file;
61  
62          public ProcessingError(String msg, String file) {
63              this.msg = msg;
64              this.file = file;
65          }
66  
67          public String getMsg() {
68              return msg;
69          }
70  
71          public String getFile() {
72              return file;
73          }
74      }
75  
76      public static class SuppressedViolation {
77          private IRuleViolation rv;
78          private boolean isNOPMD;
79  
80          public SuppressedViolation(IRuleViolation rv, boolean isNOPMD) {
81              this.isNOPMD = isNOPMD;
82              this.rv = rv;
83          }
84  
85          public boolean suppressedByNOPMD() {
86              return this.isNOPMD;
87          }
88  
89          public boolean suppressedByAnnotation() {
90              return !this.isNOPMD;
91          }
92  
93          public IRuleViolation getRuleViolation() {
94              return this.rv;
95          }
96      }
97  
98      /*
99       * The idea is to store the violations in a tree instead of a list, to do
100      * better and faster sort and filter mechanism and to visualize the result
101      * als tree. (ide plugins).
102      * */
103     private ReportTree violationTree = new ReportTree();
104 
105     // Note that this and the above data structure are both being maintained for a bit
106     private Set violations = new TreeSet(new RuleViolation.RuleViolationComparator());
107     private Set metrics = new HashSet();
108     private List listeners = new ArrayList();
109     private List errors = new ArrayList();
110     private Set linesToExclude = new HashSet();
111     private long start;
112     private long end;
113 
114     private List suppressedRuleViolations = new ArrayList();
115 
116     public void exclude(Set lines) {
117         linesToExclude = lines;
118     }
119 
120     public Map getCountSummary() {
121         Map summary = new HashMap();
122         for (Iterator iter = violationTree.iterator(); iter.hasNext();) {
123             IRuleViolation rv = (IRuleViolation) iter.next();
124             String key = (rv.getPackageName() == "" ? "" : (rv.getPackageName() + ".")) + rv.getClassName();
125             Object o = summary.get(key);
126             if (o == null) {
127                 Integer value = new Integer(1);
128                 summary.put(key, value);
129             } else {
130                 Integer value = (Integer) o;
131                 summary.put(key, new Integer(value.intValue() + 1));
132             }
133         }
134         return summary;
135     }
136 
137     public ReportTree getViolationTree() {
138         return this.violationTree;
139     }
140 
141 
142     /***
143      * @return a Map summarizing the Report: String (rule name) ->Integer (count of violations)
144      */
145     public Map getSummary() {
146         Map summary = new HashMap();
147         for (Iterator i = violations.iterator(); i.hasNext();) {
148             IRuleViolation rv = (IRuleViolation) i.next();
149             if (!summary.containsKey(rv.getRule().getName())) {
150                 summary.put(rv.getRule().getName(), new Integer(0));
151             }
152             Integer count = (Integer) summary.get(rv.getRule().getName());
153             count = new Integer(count.intValue() + 1);
154             summary.put(rv.getRule().getName(), count);
155         }
156         return summary;
157     }
158 
159     public void addListener(ReportListener listener) {
160         listeners.add(listener);
161     }
162 
163     public List getSuppressedRuleViolations() {
164         return this.suppressedRuleViolations;
165     }
166 
167     public void addRuleViolation(IRuleViolation violation) {
168         // NOPMD excluder
169         if (linesToExclude.contains(new Integer(violation.getBeginLine()))) {
170             suppressedRuleViolations.add(new SuppressedViolation(violation, true));
171             return;
172         }
173 
174         if (violation.isSuppressed()) {
175             suppressedRuleViolations.add(new SuppressedViolation(violation, false));
176             return;
177         }
178 
179 
180         violations.add(violation);
181         violationTree.addRuleViolation(violation);
182         for (Iterator i = listeners.iterator(); i.hasNext();) {
183             ReportListener listener = (ReportListener) i.next();
184             listener.ruleViolationAdded(violation);
185         }
186     }
187 
188     public void addMetric(Metric metric) {
189         metrics.add(metric);
190         for (Iterator i = listeners.iterator(); i.hasNext();) {
191             ReportListener listener = (ReportListener) i.next();
192             listener.metricAdded(metric);
193         }
194     }
195 
196     public void addError(ProcessingError error) {
197         errors.add(error);
198     }
199 
200     public boolean hasMetrics() {
201         return !metrics.isEmpty();
202     }
203 
204     public Iterator metrics() {
205         return metrics.iterator();
206     }
207 
208     public boolean isEmpty() {
209         return !violations.iterator().hasNext() && errors.isEmpty();
210     }
211 
212     public boolean treeIsEmpty() {
213         return !violationTree.iterator().hasNext();
214     }
215 
216     public Iterator treeIterator() {
217         return violationTree.iterator();
218     }
219 
220     public Iterator iterator() {
221         return violations.iterator();
222     }
223 
224     public Iterator errors() {
225         return errors.iterator();
226     }
227 
228     public int treeSize() {
229         return violationTree.size();
230     }
231 
232     public int size() {
233         return violations.size();
234     }
235 
236     public void start() {
237         start = System.currentTimeMillis();
238     }
239 
240     public void end() {
241         end = System.currentTimeMillis();
242     }
243 
244     public long getElapsedTimeInMillis() {
245         return end - start;
246     }
247 }