Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Commit

Permalink
[FIXED JENKINS-17789] Convert Gendarme parser to native warnings parser.
Browse files Browse the repository at this point in the history
  • Loading branch information
uhafner committed Aug 17, 2013
1 parent 725e226 commit 4e43e23
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 27 deletions.
@@ -0,0 +1,56 @@
package hudson.plugins.warnings.parser.gendarme;

//CHECKSTYLE:OFF
@SuppressWarnings("javadoc")
public class DotNetAssembly {
private final String fullName;
private String name;
private String version;
private String culture;
private String publicKeyToken;

public DotNetAssembly(final String fullName) {
this.fullName = fullName;

String[] splitted = this.fullName.split(",");
int cpt = 0;
for (String s : splitted) {
if (cpt == 0) {
name = s.trim();
}
else {
String[] keyValue = s.trim().split("=");
if (keyValue[0].equals("Version")) {
version = keyValue[1];
}
else if (keyValue[0].equals("Culture")) {
culture = keyValue[1];
}
else if (keyValue[0].equals("PublicKeyToken")) {
publicKeyToken = keyValue[1];
}
}
cpt++;
}
}

public String getFullName() {
return fullName;
}

public String getName() {
return name;
}

public String getVersion() {
return version;
}

public String getCulture() {
return culture;
}

public String getPublicKeyToken() {
return publicKeyToken;
}
}
@@ -0,0 +1,158 @@
package hudson.plugins.warnings.parser.gendarme;

import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import hudson.plugins.analysis.util.model.FileAnnotation;
import hudson.plugins.analysis.util.model.Priority;
import hudson.plugins.violations.types.fxcop.XmlElementUtil;
import hudson.plugins.warnings.parser.AbstractWarningsParser;
import hudson.plugins.warnings.parser.Messages;
import hudson.plugins.warnings.parser.ParsingCanceledException;

import hudson.util.IOException2;

/**
* Parses Gendarme violations.
*
* @author mathias.kluba@gmail.com
*/
public class GendarmeParser extends AbstractWarningsParser {
private static final long serialVersionUID = 1677715364464119907L;

private static final Pattern FILE_PATTERN = Pattern.compile("^(.*)\\(.(\\d+)\\).*$");

/**
* Creates a new instance of {@link GendarmeParser}.
*/
public GendarmeParser() {
super(Messages._Warnings_Gendarme_ParserName(),
Messages._Warnings_Gendarme_LinkName(),
Messages._Warnings_Gendarme_TrendName());
}

/** {@inheritDoc} */
@Override
public Collection<FileAnnotation> parse(final Reader reader) throws IOException, ParsingCanceledException {
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(reader));

NodeList mainNode = doc.getElementsByTagName("gendarme-output");

Element rootElement = (Element)mainNode.item(0);
Element resultsElement = (Element)rootElement.getElementsByTagName("results").item(0);
Element rulesElement = (Element)rootElement.getElementsByTagName("rules").item(0);

Map<String, GendarmeRule> rules = parseRules(XmlElementUtil.getNamedChildElements(rulesElement, "rule"));
return parseViolations(XmlElementUtil.getNamedChildElements(resultsElement, "rule"), rules);
}
catch (ParserConfigurationException pce) {
throw new IOException2(pce);
}
catch (SAXException se) {
throw new IOException2(se);
}
}

private List<FileAnnotation> parseViolations(final List<Element> ruleElements, final Map<String, GendarmeRule> rules) {
List<FileAnnotation> warnings = new ArrayList<FileAnnotation>();
for (Element ruleElement : ruleElements) {
String ruleName = ruleElement.getAttribute("Name");
String problem = ruleElement.getElementsByTagName("problem").item(0).getTextContent();
List<Element> targetElements = XmlElementUtil.getNamedChildElements(ruleElement, "target");

GendarmeRule rule = rules.get(ruleName);
for (Element targetElement : targetElements) {
Element defectElement = (Element)targetElement.getElementsByTagName("defect").item(0);
String source = defectElement.getAttribute("Source");

String fileName = extractFileNameMatch(rule, source, 1);
Priority priority = extractPriority(defectElement);
int line = convertLineNumber(extractFileNameMatch(rule, source, 2));

warnings.add(createWarning(fileName, line, rule.getName(), problem, priority));
}
}
return warnings;
}

private Priority extractPriority(final Element defectElement) {
String severityString = defectElement.getAttribute("Severity");
Priority priority;
if ("Low".equals(severityString)) {
priority = Priority.LOW;
}
else if ("High".equals(severityString)) {
priority = Priority.HIGH;
}
else {
priority = Priority.NORMAL;
}
return priority;
}

private String extractFileNameMatch(final GendarmeRule rule, final String source, final int group) {
String fileName = StringUtils.EMPTY;
if (rule.getType() == GendarmeRuleType.Method) {
Matcher matcher = FILE_PATTERN.matcher(source);
if (matcher.matches()) {
fileName = matcher.group(group);
}
}
return fileName;
}

private Map<String, GendarmeRule> parseRules(final List<Element> ruleElements) {
Map<String, GendarmeRule> rules = new HashMap<String, GendarmeRule>();

for (Element ruleElement : ruleElements) {
GendarmeRule rule = new GendarmeRule();
rule.setName(ruleElement.getAttribute("Name"));
rule.setTypeName(ruleElement.getTextContent());

String typeString = ruleElement.getAttribute("Type");
if ("Type".equals(typeString)) {
rule.setType(GendarmeRuleType.Type);
}
else if ("Method".equals(typeString)) {
rule.setType(GendarmeRuleType.Method);
}
else if ("Assembly".equals(typeString)) {
rule.setType(GendarmeRuleType.Assembly);
}
try {
rule.setUrl(new URL(ruleElement.getAttribute("Uri")));
}
catch (MalformedURLException e) {
rule.setUrl(null);
}

// add the rule to the cache
rules.put(rule.getName(), rule);
}

return rules;
}
}
@@ -0,0 +1,44 @@
package hudson.plugins.warnings.parser.gendarme;

import java.net.URL;

// CHECKSTYLE:OFF
@SuppressWarnings("javadoc")
public class GendarmeRule {
private String name;
private String typeName;
private GendarmeRuleType type;
private URL url;

public String getTypeName() {
return typeName;
}

public void setTypeName(final String typeName) {
this.typeName = typeName;
}

public String getName() {
return name;
}

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

public GendarmeRuleType getType() {
return type;
}

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

public URL getUrl() {
return url;
}

public void setUrl(final URL url) {
this.url = url;
}
}
@@ -0,0 +1,9 @@
package hudson.plugins.warnings.parser.gendarme;

//CHECKSTYLE:OFF
@SuppressWarnings("javadoc")
public enum GendarmeRuleType {
Method,
Type,
Assembly
}
Expand Up @@ -258,8 +258,6 @@ public void issue4260() throws IOException {
assertEquals(WRONG_NUMBER_OF_WARNINGS_DETECTED, 1, warnings.size());
}



@Override
protected String getWarningsFile() {
return "gcc.txt";
Expand Down
@@ -0,0 +1,47 @@
package hudson.plugins.warnings.parser;

import static org.junit.Assert.*;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import org.junit.Test;

import hudson.plugins.analysis.util.model.FileAnnotation;
import hudson.plugins.analysis.util.model.Priority;
import hudson.plugins.warnings.parser.gendarme.GendarmeParser;

/**
* Tests the class {@link GendarmeParser}.
*
* @author Ulli Hafner
*/
public class GendarmeParserTest extends ParserTester {
/**
* Tests the Gendarme parser with a file of 3 warnings.
*
* @throws IOException
* in case of an exception
*/
@Test
public void testParseViolationData() throws IOException {
Collection<FileAnnotation> results = new GendarmeParser().parse(openFile());
assertEquals(WRONG_NUMBER_OF_WARNINGS_DETECTED, 3, results.size());

Iterator<FileAnnotation> iterator = results.iterator();

checkWarning(iterator.next(), 0, "This assembly is not decorated with the [CLSCompliant] attribute.",
"", "MarkAssemblyWithCLSCompliantRule", Priority.HIGH);
checkWarning(iterator.next(), 10, "This method does not use any instance fields, properties or methods and can be made static.",
"c:/Dev/src/hudson/Hudson.Domain/Dog.cs", "MethodCanBeMadeStaticRule", Priority.LOW);
checkWarning(iterator.next(), 22, "This method does not use any instance fields, properties or methods and can be made static.",
"c:/Dev/src/hudson/Hudson.Domain/Dog.cs", "MethodCanBeMadeStaticRule", Priority.LOW);
}

/** {@inheritDoc} */
@Override
protected String getWarningsFile() {
return "gendarme/Gendarme.xml";
}
}

0 comments on commit 4e43e23

Please sign in to comment.