01 /**
02 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03 */
04 package net.sourceforge.pmd.cpd;
05
06 import net.sourceforge.pmd.PMD;
07 import net.sourceforge.pmd.util.StringUtil;
08
09 import java.util.Iterator;
10
11 /**
12 * @author Philippe T'Seyen
13 */
14 public class XMLRenderer implements Renderer {
15
16 private String encoding;
17
18 public XMLRenderer() {
19 this(System.getProperty("file.encoding"));
20 }
21
22 public XMLRenderer(String e) {
23 this.encoding = e;
24 }
25
26 // FUTURE: Use a XML API - rather than StringBuffer to generate XML Report.
27 // The most convenient would be to use one shipped in the JRE, and this should
28 // also allow us to get ride of the encode below, as the XML API choosed will
29 // do that for us...
30 public String render(Iterator<Match> matches) {
31 StringBuffer buffer = new StringBuffer(300);
32 buffer.append("<?xml version=\"1.0\" encoding=\"");
33 buffer.append(encoding);
34 buffer.append("\"?>").append(PMD.EOL);
35 buffer.append("<pmd-cpd>").append(PMD.EOL);
36 Match match;
37 while (matches.hasNext()) {
38 match = matches.next();
39 buffer.append("<duplication lines=\"");
40 buffer.append(match.getLineCount());
41 buffer.append("\" tokens=\"");
42 buffer.append(match.getTokenCount());
43 buffer.append("\">").append(PMD.EOL);
44
45 TokenEntry mark;
46 for (Iterator<TokenEntry> iterator = match.iterator(); iterator.hasNext();) {
47 mark = iterator.next();
48 buffer.append("<file line=\"");
49 buffer.append(mark.getBeginLine());
50 buffer.append("\" path=\"");
51 buffer.append(XMLRenderer.encode(mark.getTokenSrcID()));
52 buffer.append("\"/>").append(PMD.EOL);
53 }
54 String codeFragment = match.getSourceCodeSlice();
55 if (codeFragment != null) {
56 buffer.append("<codefragment>").append(PMD.EOL);
57 buffer.append("<![CDATA[").append(PMD.EOL);
58 buffer.append(StringUtil.replaceString(codeFragment, "]]>", "]]>")).append(PMD.EOL + "]]>" + PMD.EOL + "</codefragment>" + PMD.EOL);
59 }
60 buffer.append("</duplication>").append(PMD.EOL);
61 }
62 buffer.append("</pmd-cpd>");
63 return buffer.toString();
64 }
65
66 /*
67 * <p>Fixes bug : https://sourceforge.net/tracker/?func=detail&aid=2832322&group_id=56262&atid=479921</p>
68 *
69 * TODO: The following method - and its static arrays - should
70 * most likely be place somewhere else, like some kind of utility
71 * classes to solve issue on encoding.
72 */
73 private static String encode(String path) {
74 for ( int i = 0; i < BASIC_ESCAPE.length; i++ ) {
75 if ( path.indexOf(BASIC_ESCAPE[i][0]) != -1 ) {
76 path = path.replaceAll(BASIC_ESCAPE[i][0],BASIC_ESCAPE[i][1]);
77 }
78 }
79 return path;
80 }
81
82 /*
83 * Cut'n'paster from Apache Commons Lang
84 *
85 */
86 public static final String[][] BASIC_ESCAPE = {
87 {"\"", """}, // " - double-quote
88 {"&", "&"}, // & - ampersand
89 {"<", "<"}, // < - less-than
90 {">", ">"}, // > - greater-than
91 };
92 }
|