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