Skip to content

Commit

Permalink
Move parsers into parser top-level package.
Browse files Browse the repository at this point in the history
  • Loading branch information
uhafner committed Jan 7, 2025
1 parent 7847052 commit fe65632
Show file tree
Hide file tree
Showing 69 changed files with 2,382 additions and 2,747 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected Optional<Issue> createIssue(final Matcher matcher, final LookaheadStre
final String cat;

/* Ansible-lint has changed the style of parseable output. This requires
* to distinguish between rule names in square brackets and rule names
* distinguishing between rule names in square brackets and rule names
* containing square brackets. */
if (matcher.group("cat") != null) {
cat = matcher.group("cat");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package edu.hm.hafner.analysis.parser.ccm;
package edu.hm.hafner.analysis.parser;

import java.io.IOException;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
Expand All @@ -14,6 +16,8 @@
import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.analysis.SecureDigester;
import edu.hm.hafner.analysis.Severity;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
* A parser for CCM XML files.
Expand Down Expand Up @@ -112,4 +116,130 @@ private boolean isMetricModeratePriority(final Metric metric) {
return StringUtils.contains(metricClassification, "moderate")
|| "B".equals(metricClassification);
}

/**
* Entity used by {@link CcmParser} to represent the root node of CCM results file.
*
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
@SuppressWarnings("all")
@SuppressFBWarnings("EI")
public static class Ccm {
/**
* List of metrics present in the XML file.
*/
private List<Metric> metrics = new ArrayList<>();

public List<Metric> getMetrics() {
return metrics;
}

public void setMetrics(List<Metric> metrics) {
this.metrics = metrics;
}

public void addMetric(Metric metric) {
this.metrics.add(metric);
}
}

/**
* Entity representing the Metric from CCM.exe output.
*
* <p>
* It has the {@link #complexity}, {@link #unit}, {@link #classification} and {@link #file} fields.
* </p>
*
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
@SuppressWarnings("all")
public static class Metric {
/**
* Total CC of the method.
*/
private int complexity;

/**
* String containing Class_Name::Method_Name
*/
@CheckForNull
private String unit;

/**
* CCM outputs a String with a classification such as "complex, high risk", "untestable, very high risk", etc. As
* there is no documentation on which values are used to determine a method's CC classification CCM Plugin only
* outputs this value. But does not use the information as a constraint in any place.
*/
@CheckForNull
private String classification;

/**
* The file name (e.g.:\ascx\request\open\form.ascx.cs).
*/
@CheckForNull
private String file;

/**
* The start line number of the measurement
*/
private int startLineNumber;

/**
* The end line number of the measurement
*/
private int endLineNumber;

public int getComplexity() {
return complexity;
}

public void setComplexity(int complexity) {
this.complexity = complexity;
}

@CheckForNull
public String getUnit() {
return unit;
}

public void setUnit(String unit) {
this.unit = unit;
}

@CheckForNull
public String getClassification() {
return classification;
}

public void setClassification(String classification) {
this.classification = classification;
}

@CheckForNull
public String getFile() {
return file;
}

public void setFile(String file) {
this.file = file;
}

public int getStartLineNumber() {
return startLineNumber;
}

public void setStartLineNumber(int startLineNumber) {
this.startLineNumber = startLineNumber;
}

public int getEndLineNumber() {
return endLineNumber;
}

public void setEndLineNumber(int endLineNumber) {
this.endLineNumber = endLineNumber;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package edu.hm.hafner.analysis.parser.findbugs;
package edu.hm.hafner.analysis.parser;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -45,7 +45,7 @@ public FindBugsMessages() {

private void loadMessages(final String fileName, final Map<String, String> messagesCache,
final Map<String, String> shortMessagesCache) throws IOException, SAXException {
try (var file = FindBugsMessages.class.getResourceAsStream(fileName)) {
try (var file = FindBugsMessages.class.getResourceAsStream("findbugs/" + fileName)) {
List<Pattern> patterns = parse(file);
for (Pattern pattern : patterns) {
messagesCache.put(pattern.getType(), pattern.getDescription());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package edu.hm.hafner.analysis.parser.findbugs; // NOPMD
package edu.hm.hafner.analysis.parser; // NOPMD

import java.io.IOException;
import java.io.Reader;
Expand Down Expand Up @@ -30,7 +30,7 @@
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.ba.SourceFinder;

import static edu.hm.hafner.analysis.parser.findbugs.FindBugsParser.PriorityProperty.*;
import static edu.hm.hafner.analysis.parser.FindBugsParser.PriorityProperty.*;

/**
* A parser for the native FindBugs XML files.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package edu.hm.hafner.analysis.parser.fxcop;
package edu.hm.hafner.analysis.parser;

import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;

import edu.hm.hafner.analysis.IssueBuilder;
Expand All @@ -11,6 +15,7 @@
import edu.hm.hafner.analysis.ReaderFactory;
import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.analysis.util.XmlElementUtil;
import edu.umd.cs.findbugs.annotations.CheckForNull;

/**
* Parses a fxcop xml report file.
Expand Down Expand Up @@ -201,4 +206,159 @@ private String getString(final Element element, final String name) {
}
}
}

/**
* Internal model for a FxCop rule.
*
* @author Erik Ramfelt
*/
@SuppressWarnings({"PMD", "all", "CheckStyle"})
public static class FxCopRule {
private final String typeName;
private final String category;
private final String checkId;
@CheckForNull
private String name;
@CheckForNull
private String url;
@CheckForNull
private String description;

public FxCopRule(final String typeName, final String category, final String checkId) {
this.typeName = typeName;
this.category = category;
this.checkId = checkId;
}

@CheckForNull
public String getName() {
return name;
}

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

@CheckForNull
public String getUrl() {
return url;
}

public void setUrl(final String url) {
this.url = url;
}

@CheckForNull
public String getDescription() {
return description;
}

public void setDescription(final String description) {
this.description = description;
}

public String getTypeName() {
return typeName;
}

public String getCategory() {
return category;
}

public String getCheckId() {
return checkId;
}
}

/**
* Internal set containing rules for FxCop.
*
* @author Erik Ramfelt
*/
@SuppressWarnings({"PMD", "all", "CheckStyle"})
public static class FxCopRuleSet {
private final Map<String, FxCopRule> rules = new HashMap<>();

/***
* Parse the element and insert the rule into the rule set.
* @param element the element
*/
public void addRule(final Element element) {
var rule = new FxCopRule(element.getAttribute("TypeName"), element.getAttribute("Category"), element
.getAttribute("CheckId"));
rule.setUrl(getNamedTagText(element, "Url"));
rule.setDescription(getNamedTagText(element, "Description"));
rule.setName(getNamedTagText(element, "Name"));

rules.put(getRuleKey(rule.getCategory(), rule.getCheckId()), rule);
}

/**
* Returns the text value of the named child element if it exists
*
* @param element
* the element to check look for child elements
* @param tagName
* the name of the child element
*
* @return the text value; or "" if no element was found
*/
private String getNamedTagText(final Element element, final String tagName) {
Optional<Element> foundElement = XmlElementUtil.getFirstChildElementByName(element, tagName);
if (foundElement.isPresent()) {
return foundElement.get().getTextContent();
}
else {
return StringUtils.EMPTY;
}
}

/**
* Returns if the rule set contains a rule for the specified category and id
*
* @param category
* the rule category
* @param checkId
* the rule id
*
* @return {@code true} if the rule set contains a rule for the specified category and id, {@code false} otherwise
*/
public boolean contains(final String category, final String checkId) {
return rules.containsKey(getRuleKey(category, checkId));
}

/**
* Returns the specified rule if it exists
*
* @param category
* the rule category
* @param checkId
* the id of the rule
*
* @return the rule; null otherwise
*/
@CheckForNull
public FxCopRule getRule(final String category, final String checkId) {
var key = getRuleKey(category, checkId);
FxCopRule rule = null;
if (rules.containsKey(key)) {
rule = rules.get(key);
}
return rule;
}

/**
* Returns the key for the map
*
* @param category
* category of the rule
* @param checkId
* id of the rule
*
* @return category + "#" + checkid
*/
private String getRuleKey(final String category, final String checkId) {
return category + "#" + checkId;
}
}
}
Loading

0 comments on commit fe65632

Please sign in to comment.