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 OnTheFlyRenderer {
18  
19      // FIXME - hardcoded character encoding, booooooo
20  	protected String encoding = "UTF-8";
21  
22      public void start() throws IOException {
23          Writer writer = getWriter();
24          StringBuffer buf = new StringBuffer();
25          buf.append("<?xml version=\"1.0\" encoding=\"" + this.encoding + "\"?>").append(PMD.EOL);
26          createVersionAttr(buf);
27          createTimestampAttr(buf);
28          // FIXME: elapsed time not available until the end of the processing
29          //buf.append(createTimeElapsedAttr(report));
30          buf.append('>').append(PMD.EOL);
31          writer.write(buf.toString());
32      }
33  
34      public void renderFileViolations(Iterator<IRuleViolation> violations) throws IOException {
35          Writer writer = getWriter();
36          StringBuffer buf = new StringBuffer();
37          String filename = null;
38  
39          // rule violations
40          while (violations.hasNext()) {
41              buf.setLength(0);
42              IRuleViolation rv = violations.next();
43              if (!rv.getFilename().equals(filename)) { // New File
44                  if (filename != null) {// Not first file ?
45                      buf.append("</file>").append(PMD.EOL);
46                  }
47                  filename = rv.getFilename();
48                  buf.append("<file name=\"");
49                  StringUtil.appendXmlEscaped(buf, filename);
50                  buf.append("\">").append(PMD.EOL);
51              }
52  
53              buf.append("<violation beginline=\"").append(rv.getBeginLine());
54              buf.append("\" endline=\"").append(rv.getEndLine());
55              buf.append("\" begincolumn=\"").append(rv.getBeginColumn());
56              buf.append("\" endcolumn=\"").append(rv.getEndColumn());
57              buf.append("\" rule=\"");
58              StringUtil.appendXmlEscaped(buf, rv.getRule().getName());
59              buf.append("\" ruleset=\"");
60              StringUtil.appendXmlEscaped(buf, rv.getRule().getRuleSetName());
61              buf.append('"');
62              maybeAdd("package", rv.getPackageName(), buf);
63              maybeAdd("class", rv.getClassName(), buf);
64              maybeAdd("method", rv.getMethodName(), buf);
65              maybeAdd("variable", rv.getVariableName(), buf);
66              maybeAdd("externalInfoUrl", rv.getRule().getExternalInfoUrl(), buf);
67              buf.append(" priority=\"");
68              buf.append(rv.getRule().getPriority());
69              buf.append("\">").append(PMD.EOL);
70              StringUtil.appendXmlEscaped(buf, rv.getDescription());
71  
72              buf.append(PMD.EOL);
73              buf.append("</violation>");
74              buf.append(PMD.EOL);
75              writer.write(buf.toString());
76          }
77          if (filename != null) { // Not first file ?
78              writer.write("</file>");
79              writer.write(PMD.EOL);
80          }
81      }
82  
83      public void end() throws IOException {
84          Writer writer = getWriter();
85          StringBuffer buf = new StringBuffer();
86          // errors
87          for (Report.ProcessingError pe: errors) {
88              buf.setLength(0);
89              buf.append("<error ").append("filename=\"");
90              StringUtil.appendXmlEscaped(buf, pe.getFile());
91              buf.append("\" msg=\"");
92              StringUtil.appendXmlEscaped(buf, pe.getMsg());
93              buf.append("\"/>").append(PMD.EOL);
94              writer.write(buf.toString());
95          }
96  
97          // suppressed violations
98          if (showSuppressedViolations) {
99              for (Report.SuppressedViolation s: suppressed) {
100                 buf.setLength(0);
101                 buf.append("<suppressedviolation ").append("filename=\"");
102                 StringUtil.appendXmlEscaped(buf, s.getRuleViolation().getFilename());
103                 buf.append("\" suppressiontype=\"");
104                 StringUtil.appendXmlEscaped(buf, s.suppressedByNOPMD() ? "nopmd" : "annotation");
105                 buf.append("\" msg=\"");
106                 StringUtil.appendXmlEscaped(buf, s.getRuleViolation().getDescription());
107                 buf.append("\" usermsg=\"");
108                 StringUtil.appendXmlEscaped(buf, (s.getUserMessage() == null ? "" : s.getUserMessage()));
109                 buf.append("\"/>").append(PMD.EOL);
110                 writer.write(buf.toString());
111             }
112         }
113 
114         writer.write("</pmd>");
115     }
116 
117     private void maybeAdd(String attr, String value, StringBuffer buf) {
118         if (value != null && value.length() > 0) {
119             buf.append(' ').append(attr).append("=\"");
120             StringUtil.appendXmlEscaped(buf, value);
121             buf.append('"');
122         }
123     }
124 
125     private void createVersionAttr(StringBuffer buffer) {
126         buffer.append("<pmd version=\"").append(PMD.VERSION).append('"');
127     }
128 
129     private void createTimestampAttr(StringBuffer buffer) {
130         buffer.append(" timestamp=\"").append(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(new Date())).append('"');
131     }
132 
133     private String createTimeElapsedAttr(Report rpt) {
134         Report.ReadableDuration d = new Report.ReadableDuration(rpt.getElapsedTimeInMillis());
135         return " elapsedTime=\"" + d.getTime() + "\"";
136     }
137 
138 }