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
100
101
102
103 private ReportTree violationTree = new ReportTree();
104
105
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
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 }