This repository has been archived by the owner on Apr 6, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FIXED JENKINS-17789] Convert Gendarme parser to native warnings parser.
- Loading branch information
Showing
8 changed files
with
352 additions
and
27 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
src/main/java/hudson/plugins/warnings/parser/gendarme/DotNetAssembly.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
158 changes: 158 additions & 0 deletions
158
src/main/java/hudson/plugins/warnings/parser/gendarme/GendarmeParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/main/java/hudson/plugins/warnings/parser/gendarme/GendarmeRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/hudson/plugins/warnings/parser/gendarme/GendarmeRuleType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package hudson.plugins.warnings.parser.gendarme; | ||
|
||
//CHECKSTYLE:OFF | ||
@SuppressWarnings("javadoc") | ||
public enum GendarmeRuleType { | ||
Method, | ||
Type, | ||
Assembly | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
src/test/java/hudson/plugins/warnings/parser/GendarmeParserTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"; | ||
} | ||
} |
Oops, something went wrong.