Tuesday, November 24, 2020

Create Sonar Plugin - Scanner Basic - Convert Issues xml to Java

The flow of the plugin is
  • Call third party jar - command line execution of the jar
  • generate violation/issues xml
  • convert xml to java
  • for each file , get the Input file and set the violations and save as a new issue - create inside context.


Sample of violation report

---------------------------------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<violations>
<file name="C:\sample\sample-project\src\main\java\sample.sql">
<violation>
<message>Avoid multiple declarations of labels and variables.</message>
<line>7</line>
<column>25</column>
<type>Tech-Defects</type>
<severity>1</severity>
<rule id="1" name="Avoid multiple declarations of labels and variables."/>
</violation>
</violations>


----------------------------------------------------------------------------------------------------------------------- 

we need to have a java file structure to map with xml tags. basically 3
  1. Violations
  2. File
  3. Violation - there can be multiples of violation.
  4. Rule
---------- classes as follows ---------------------------------------------------------------------------


package com.plugin.sonar.report.foo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;

import java.util.ArrayList;
import java.util.List;

public class Violations {

@JacksonXmlElementWrapper(useWrapping = false)
private List<File> file = new ArrayList<>();

public List<File> getFile() {
return file;
}

public void setFile(List<File> file) {
this.file = file;
}

@Override
public String toString() {
return "Violations{" +
"file=" + file +
'}';
}
}

--------------------------------------------------------

package com.plugin.sonar.report.foo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlID;
import java.util.ArrayList;
import java.util.List;

@XmlAccessorType(XmlAccessType.FIELD)
public class File {
@XmlAttribute(name = "name")
@XmlID
private String name;

@JacksonXmlElementWrapper(useWrapping = false)
private List<Violation> violation = new ArrayList<>();

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<Violation> getViolation() {
return violation;
}

public void setViolation(List<Violation> violation) {
this.violation = violation;
}

@Override
public String toString() {
return "File{" +
"name='" + name + '\'' +
", violation=" + violation +
'}';
}
}

----------------------------------------------------------------

package com.plugin.sonar.report.foo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

@XmlAccessorType(XmlAccessType.FIELD)
public class Violation {
private String message;
private int line;
private int column;
private String type;
private String severity;
private Rule rule;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getLine() {
return line;
}

public void setLine(int line) {
this.line = line;
}

public int getColumn() {
return column;
}

public void setColumn(int column) {
this.column = column;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getSeverity() {
return severity;
}

public void setSeverity(String severity) {
this.severity = severity;
}

public Rule getRule() {
return rule;
}

public void setRule(Rule rule) {
this.rule = rule;
}

@Override
public String toString() {
return "Violation{" +
"message='" + message + '\'' +
", line=" + line +
", column=" + column +
", type='" + type + '\'' +
", severity='" + severity + '\'' +
", rule=" + rule +
'}';
}
}

----------------------------------------------------------------------------

package com.plugin.sonar.report.foo;

import javax.xml.bind.annotation.XmlAttribute;

public class Rule {
@XmlAttribute(name = "id")
private String id;

@XmlAttribute(name = "name")
private String name;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Rule{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
-------------------------------------------------------------------------------
Now we have all  the objects

 We can write a class "Converter" to handle this process

----------------------------------------------------------------------------------------------------------

package com.plugin.sonar.util;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.plugin.sonar.report.foo.Violations;
import com.plugin.sonar.exception.FooPluginException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import java.io.File;

public final class Converter {

private static final Logger LOG = Loggers.get(Converter.class);

private Converter() {
}

public static Violations convertXMLToJava(String filePath) throws FooPluginException {
LOG.info("File path here " + filePath);
File xmlFile = new File(filePath);
try {
XmlMapper xmlMapper = new XmlMapper();
Violations violations = xmlMapper.readValue(xmlFile, Violations.class);
LOG.info(">>>>>>Converting violation xml to pojo \n" + violations.toString());
return violations;
} catch (Exception e) {
LOG.error(e.getLocalizedMessage(), e);
LOG.error("Error converting violation xml");
throw new FooPluginException("Error converting violation xml");
}
}
}

No comments:

Post a Comment