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