View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.renderers;
5   
6   import net.sourceforge.pmd.IRuleViolation;
7   import net.sourceforge.pmd.PMD;
8   import net.sourceforge.pmd.Report;
9   import net.sourceforge.pmd.util.StringUtil;
10  
11  import java.io.IOException;
12  import java.io.Writer;
13  import java.text.SimpleDateFormat;
14  import java.util.Date;
15  import java.util.Iterator;
16  
17  public class XMLRenderer extends AbstractRenderer {
18  
19      public void render(Writer writer, Report report) throws IOException {
20  
21          StringBuffer buf = new StringBuffer();
22          writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + PMD.EOL + createVersionAttr() + createTimestampAttr() + createTimeElapsedAttr(report) + '>' + PMD.EOL);
23          String filename = null;
24  
25          // rule violations
26          for (Iterator i = report.iterator(); i.hasNext();) {
27              buf.setLength(0);
28              IRuleViolation rv = (IRuleViolation) i.next();
29              if (!rv.getFilename().equals(filename)) { // New File
30                  if (filename != null) {// Not first file ?
31                      buf.append("</file>").append(PMD.EOL);
32                  }
33                  filename = rv.getFilename();
34                  buf.append("<file name=\"");
35                  StringUtil.appendXmlEscaped(buf, filename);
36                  buf.append("\">").append(PMD.EOL);
37              }
38  
39              buf.append("<violation line=\"").append(rv.getBeginLine());
40              buf.append("\" rule=\"");
41              StringUtil.appendXmlEscaped(buf, rv.getRule().getName());
42              buf.append("\" ruleset=\"");
43              StringUtil.appendXmlEscaped(buf, rv.getRule().getRuleSetName());
44              buf.append('"');
45              maybeAdd("package", rv.getPackageName(), buf);
46              maybeAdd("class", rv.getClassName(), buf);
47              maybeAdd("method", rv.getMethodName(), buf);
48              maybeAdd("externalInfoUrl", rv.getRule().getExternalInfoUrl(), buf);
49              buf.append(" priority=\"");
50              buf.append(rv.getRule().getPriority());
51              buf.append("\">").append(PMD.EOL);
52              StringUtil.appendXmlEscaped(buf, rv.getDescription());
53  
54              buf.append(PMD.EOL);
55              buf.append("</violation>");
56              buf.append(PMD.EOL);
57              writer.write(buf.toString());
58          }
59          if (filename != null) { // Not first file ?
60              writer.write("</file>");
61              writer.write(PMD.EOL);
62          }
63  
64          // errors
65          for (Iterator i = report.errors(); i.hasNext();) {
66              buf.setLength(0);
67              Report.ProcessingError pe = (Report.ProcessingError) i.next();
68              buf.append("<error ").append("filename=\"");
69              StringUtil.appendXmlEscaped(buf, pe.getFile());
70              buf.append("\" msg=\"");
71              StringUtil.appendXmlEscaped(buf, pe.getMsg());
72              buf.append("\"/>").append(PMD.EOL);
73              writer.write(buf.toString());
74          }
75  
76          // suppressed violations
77          if (showSuppressedViolations) {
78              for (Iterator i = report.getSuppressedRuleViolations().iterator(); i.hasNext();) {
79                  buf.setLength(0);
80                  Report.SuppressedViolation suppressed = (Report.SuppressedViolation) i.next();
81                  buf.append("<suppressedviolation ").append("filename=\"");
82                  StringUtil.appendXmlEscaped(buf, suppressed.getRuleViolation().getFilename());
83                  buf.append("\" suppressiontype=\"");
84                  StringUtil.appendXmlEscaped(buf, suppressed.suppressedByNOPMD() ? "nopmd" : "annotation");
85                  buf.append("\" msg=\"");
86                  StringUtil.appendXmlEscaped(buf, suppressed.getRuleViolation().getDescription());
87                  buf.append("\" usermsg=\"");
88                  StringUtil.appendXmlEscaped(buf, suppressed.getUserMessage());
89                  buf.append("\"/>").append(PMD.EOL);
90                  writer.write(buf.toString());
91              }
92          }
93  
94          writer.write("</pmd>");
95      }
96  
97      private void maybeAdd(String attr, String value, StringBuffer buf) {
98          if (value != null && value.length() > 0) {
99              buf.append(' ').append(attr).append("=\"");
100             StringUtil.appendXmlEscaped(buf, value);
101             buf.append('"');
102         }
103     }
104 
105     private String createVersionAttr() {
106         return "<pmd version=\"" + PMD.VERSION + "\"";
107     }
108 
109     private String createTimestampAttr() {
110         return " timestamp=\"" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(new Date()) + "\"";
111     }
112 
113     private String createTimeElapsedAttr(Report rpt) {
114         Report.ReadableDuration d = new Report.ReadableDuration(rpt.getElapsedTimeInMillis());
115         return " elapsedTime=\"" + d.getTime() + "\"";
116     }
117 
118 }