View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.cpd;
5   
6   import net.sourceforge.pmd.PMD;
7   import net.sourceforge.pmd.util.StringUtil;
8   
9   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      public String render(Iterator<Match> matches) {
27          StringBuffer buffer = new StringBuffer(300);
28          buffer.append("<?xml version=\"1.0\" encoding=\"");
29          buffer.append(encoding);
30          buffer.append("\"?>").append(PMD.EOL);
31          buffer.append("<pmd-cpd>").append(PMD.EOL);
32          Match match;
33          while (matches.hasNext()) {
34              match = matches.next();
35              buffer.append("<duplication lines=\"");
36              buffer.append(match.getLineCount());
37              buffer.append("\" tokens=\"");
38              buffer.append(match.getTokenCount());
39              buffer.append("\">").append(PMD.EOL);
40  
41              TokenEntry mark;
42              for (Iterator<TokenEntry> iterator = match.iterator(); iterator.hasNext();) {
43                  mark = iterator.next();
44                  buffer.append("<file line=\"");
45                  buffer.append(mark.getBeginLine());
46                  buffer.append("\" path=\"");
47                  buffer.append(encode(mark.getTokenSrcID()));
48                  buffer.append("\"/>").append(PMD.EOL);
49              }
50              String codeFragment = match.getSourceCodeSlice();
51              if (codeFragment != null) {
52                  buffer.append("<codefragment>").append(PMD.EOL);
53                  buffer.append("<![CDATA[").append(PMD.EOL);
54                  buffer.append(StringUtil.replaceString(codeFragment, "]]>", "]]&gt;")).append(PMD.EOL + "]]>" + PMD.EOL + "</codefragment>" + PMD.EOL);
55              }
56              buffer.append("</duplication>").append(PMD.EOL);
57          }
58          buffer.append("</pmd-cpd>");
59          return buffer.toString();
60      }
61      
62  
63      /*
64      * <p>Fixes bug : https://sourceforge.net/tracker/?func=detail&aid=2832322&group_id=56262&atid=479921</p>
65      * 
66      * TODO: The following method - and its static arrays - should
67      * most likely be place somewhere else, like some kind of utility
68      * classes to solve issue on encoding.
69  	*/
70  	private static String encode(String path) {
71  		for ( int i = 0; i < BASIC_ESCAPE.length; i++ ) {
72  			if ( path.indexOf(BASIC_ESCAPE[i][0]) != -1 ) {
73  				path = path.replaceAll(BASIC_ESCAPE[i][0],BASIC_ESCAPE[i][1]);
74  			}
75  		}
76  		return path;
77  	}
78  	
79  	/* 
80  	 * Cut'n'paster from Apache Commons Lang
81  	 * 
82  	 */
83  	public static final String[][] BASIC_ESCAPE = {
84          {"\"", "&quot;"}, // " - double-quote
85          {"&", "&amp;"},   // & - ampersand
86          {"<", "&lt;"},    // < - less-than
87          {">", "&gt;"},    // > - greater-than
88      };
89  
90  }