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