1
2
3
4 package net.sourceforge.pmd.renderers;
5
6 import java.io.IOException;
7 import java.io.Writer;
8 import java.text.SimpleDateFormat;
9 import java.util.Date;
10 import java.util.Iterator;
11
12 import net.sourceforge.pmd.PMD;
13 import net.sourceforge.pmd.Report;
14 import net.sourceforge.pmd.RuleViolation;
15 import net.sourceforge.pmd.lang.rule.properties.StringProperty;
16 import net.sourceforge.pmd.util.StringUtil;
17
18
19
20
21 public class XMLRenderer extends AbstractIncrementingRenderer {
22
23 public static final String NAME = "xml";
24
25 public static final StringProperty ENCODING = new StringProperty("encoding", "XML encoding format, defaults to UTF-8.", "UTF-8", 0);
26
27 public XMLRenderer() {
28 super(NAME, "XML format.");
29 definePropertyDescriptor(ENCODING);
30 }
31
32 public XMLRenderer(String encoding) {
33 this();
34 setProperty(ENCODING, encoding);
35 }
36
37 public String defaultFileExtension() { return "xml"; }
38
39
40
41
42 @Override
43 public void start() throws IOException {
44 String encoding = getProperty(ENCODING);
45
46 Writer writer = getWriter();
47 StringBuilder buf = new StringBuilder(500);
48 buf.append("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>").append(PMD.EOL);
49 createVersionAttr(buf);
50 createTimestampAttr(buf);
51
52
53 buf.append('>').append(PMD.EOL);
54 writer.write(buf.toString());
55 }
56
57
58
59
60 @Override
61 public void renderFileViolations(Iterator<RuleViolation> violations) throws IOException {
62 Writer writer = getWriter();
63 StringBuilder buf = new StringBuilder(500);
64 String filename = null;
65
66
67 while (violations.hasNext()) {
68 buf.setLength(0);
69 RuleViolation rv = violations.next();
70 if (!rv.getFilename().equals(filename)) {
71 if (filename != null) {
72 buf.append("</file>").append(PMD.EOL);
73 }
74 filename = rv.getFilename();
75 buf.append("<file name=\"");
76 StringUtil.appendXmlEscaped(buf, filename);
77 buf.append("\">").append(PMD.EOL);
78 }
79
80 buf.append("<violation beginline=\"").append(rv.getBeginLine());
81 buf.append("\" endline=\"").append(rv.getEndLine());
82 buf.append("\" begincolumn=\"").append(rv.getBeginColumn());
83 buf.append("\" endcolumn=\"").append(rv.getEndColumn());
84 buf.append("\" rule=\"");
85 StringUtil.appendXmlEscaped(buf, rv.getRule().getName());
86 buf.append("\" ruleset=\"");
87 StringUtil.appendXmlEscaped(buf, rv.getRule().getRuleSetName());
88 buf.append('"');
89 maybeAdd("package", rv.getPackageName(), buf);
90 maybeAdd("class", rv.getClassName(), buf);
91 maybeAdd("method", rv.getMethodName(), buf);
92 maybeAdd("variable", rv.getVariableName(), buf);
93 maybeAdd("externalInfoUrl", rv.getRule().getExternalInfoUrl(), buf);
94 buf.append(" priority=\"");
95 buf.append(rv.getRule().getPriority().getPriority());
96 buf.append("\">").append(PMD.EOL);
97 StringUtil.appendXmlEscaped(buf, rv.getDescription());
98
99 buf.append(PMD.EOL);
100 buf.append("</violation>");
101 buf.append(PMD.EOL);
102 writer.write(buf.toString());
103 }
104 if (filename != null) {
105 writer.write("</file>");
106 writer.write(PMD.EOL);
107 }
108 }
109
110
111
112
113 @Override
114 public void end() throws IOException {
115 Writer writer = getWriter();
116 StringBuilder buf = new StringBuilder(500);
117
118 for (Report.ProcessingError pe : errors) {
119 buf.setLength(0);
120 buf.append("<error ").append("filename=\"");
121 StringUtil.appendXmlEscaped(buf, pe.getFile());
122 buf.append("\" msg=\"");
123 StringUtil.appendXmlEscaped(buf, pe.getMsg());
124 buf.append("\"/>").append(PMD.EOL);
125 writer.write(buf.toString());
126 }
127
128
129 if (showSuppressedViolations) {
130 for (Report.SuppressedViolation s : suppressed) {
131 buf.setLength(0);
132 buf.append("<suppressedviolation ").append("filename=\"");
133 StringUtil.appendXmlEscaped(buf, s.getRuleViolation().getFilename());
134 buf.append("\" suppressiontype=\"");
135 StringUtil.appendXmlEscaped(buf, s.suppressedByNOPMD() ? "nopmd" : "annotation");
136 buf.append("\" msg=\"");
137 StringUtil.appendXmlEscaped(buf, s.getRuleViolation().getDescription());
138 buf.append("\" usermsg=\"");
139 StringUtil.appendXmlEscaped(buf, s.getUserMessage() == null ? "" : s.getUserMessage());
140 buf.append("\"/>").append(PMD.EOL);
141 writer.write(buf.toString());
142 }
143 }
144
145 writer.write("</pmd>" + PMD.EOL);
146 }
147
148 private void maybeAdd(String attr, String value, StringBuilder buf) {
149 if (value != null && value.length() > 0) {
150 buf.append(' ').append(attr).append("=\"");
151 StringUtil.appendXmlEscaped(buf, value);
152 buf.append('"');
153 }
154 }
155
156 private void createVersionAttr(StringBuilder buffer) {
157 buffer.append("<pmd version=\"").append(PMD.VERSION).append('"');
158 }
159
160 private void createTimestampAttr(StringBuilder buffer) {
161 buffer.append(" timestamp=\"").append(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(new Date()))
162 .append('"');
163 }
164
165
166
167
168
169
170
171
172 }