Skip to content

Commit c540f2b

Browse files
authored
Merge pull request #22 from c-a-services/show-issue-at-line
LineNumbers displaying on Issue #15
2 parents d402b2c + ee74852 commit c540f2b

File tree

10 files changed

+105
-6
lines changed

10 files changed

+105
-6
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
<!-- mandatory scope -->
3737
<scope>provided</scope>
3838
</dependency>
39+
<dependency>
40+
<groupId>org.sonarsource.analyzer-commons</groupId>
41+
<artifactId>sonar-xml-parsing</artifactId>
42+
<version>1.12.0.632</version>
43+
</dependency>
3944
<dependency>
4045
<groupId>org.jdom</groupId>
4146
<artifactId>jdom2</artifactId>

src/main/java/com/mulesoft/services/tools/sonarqube/rule/MuleRulesDefinition.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public interface PARAMS {
3636
String CATEGORY = "category";
3737
String SCOPE = "scope";
3838
String XPATH = "xpath-expression";
39+
String XPATH_LOCATION_HINT = "xpath-location-hint";
3940
}
4041

4142
@Override
@@ -97,8 +98,13 @@ private void addRuleTemplate(NewRepository repository, String language) {
9798
.setType(RuleParamType.STRING);
9899
x1Rule.createParam(PARAMS.XPATH).setDescription(prop.getProperty("rule.template.parameter.xpath"))
99100
.setType(RuleParamType.STRING);
101+
x1Rule.createParam(PARAMS.XPATH_LOCATION_HINT).setDescription(prop.getProperty("rule.template.parameter.xpathlocationhint"))
102+
.setType(RuleParamType.STRING);
100103
x1Rule.createParam(PARAMS.SCOPE).setDescription(prop.getProperty("rule.template.parameter.scope"))
101104
.setType(RuleParamType.STRING);
105+
106+
logger.info("addRuleTemplate x1Rule="+x1Rule);
107+
102108
}
103109

104110
private void addRule(NewRepository repository, Ruleset ruleset,
@@ -113,6 +119,8 @@ private void addRule(NewRepository repository, Ruleset ruleset,
113119
x1Rule.addTags(language);
114120
x1Rule.createParam(PARAMS.CATEGORY).setDefaultValue(ruleset.getCategory()).setType(RuleParamType.STRING);
115121
x1Rule.createParam(PARAMS.XPATH).setDefaultValue(rule.getValue()).setType(RuleParamType.STRING);
122+
logger.info("LocationHint="+rule.getLocationHint()+" for "+rule.getName());
123+
x1Rule.createParam(PARAMS.XPATH_LOCATION_HINT).setDefaultValue(rule.getLocationHint()).setType(RuleParamType.STRING);
116124
if (rule.getApplies() != null) {
117125
x1Rule.createParam(PARAMS.SCOPE).setDefaultValue(rule.getApplies()).setType(RuleParamType.STRING);
118126
}

src/main/java/com/mulesoft/services/tools/sonarqube/rule/scope/ApplicationStrategyScope.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void validate(XPathProcessor xpathValidator, Map<RuleKey, List<NewIssue>>
3737
String ruleId = rule.ruleKey().toString();
3838
boolean valid = xpathValidator.processXPath(rule.param(MuleRulesDefinition.PARAMS.XPATH).trim(),
3939
rootElement, Boolean.class).booleanValue();
40-
logger.info("Validation Result: " + valid + " : File: " + t.filename() + " :Rule:" + rule.ruleKey());
40+
logger.info("Validation Result: " + valid + " : File: " + t.filename() + " :Rule:" + rule.ruleKey()+" internalKey="+rule.internalKey());
4141
if (!valid && !valids.contains(ruleId) && !issues.containsKey(rule.ruleKey())) {
4242
NewIssue newIssue = context.newIssue().forRule(rule.ruleKey());
4343
NewIssueLocation primaryLocation = newIssue.newLocation().on(t);

src/main/java/com/mulesoft/services/tools/sonarqube/rule/scope/FileStrategyScope.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
import org.jdom2.Element;
1010
import org.jdom2.JDOMException;
1111
import org.jdom2.input.SAXBuilder;
12+
13+
import javax.xml.xpath.XPathConstants;
14+
import javax.xml.xpath.XPathExpressionException;
15+
import javax.xml.xpath.XPathFactory;
16+
1217
import org.sonar.api.batch.fs.InputFile;
1318
import org.sonar.api.batch.rule.ActiveRule;
1419
import org.sonar.api.batch.sensor.SensorContext;
@@ -18,6 +23,10 @@
1823
import org.sonar.api.utils.log.Logger;
1924
import org.sonar.api.utils.log.Loggers;
2025

26+
import org.sonarsource.analyzer.commons.xml.XmlFile;
27+
import org.sonarsource.analyzer.commons.xml.XmlTextRange;
28+
import org.w3c.dom.Node;
29+
2130
import com.mulesoft.services.tools.sonarqube.rule.MuleRulesDefinition;
2231
import com.mulesoft.services.xpath.XPathProcessor;
2332

@@ -35,8 +44,44 @@ public void validate(XPathProcessor xpathValidator, Map<RuleKey, List<NewIssue>>
3544
rootElement, Boolean.class).booleanValue();
3645
logger.info("Validation Result: " + valid + " : File: " + t.filename() + " :Rule:" + rule.ruleKey());
3746
if (!valid) {
47+
48+
XmlTextRange textRange;
49+
try {
50+
// see org.sonarsource.analyzer.commons.xml.checks.SonarXmlCheck.reportIssue(Node, String)
51+
SonarXmlCheckHelper tempSonarXmlCheckHelper = new SonarXmlCheckHelper();
52+
XmlFile xmlFile = XmlFile.create(t);
53+
tempSonarXmlCheckHelper.scanFile(context, rule.ruleKey(), xmlFile); // just to fill the properties
54+
String locationFindingXPath = rule.param(MuleRulesDefinition.PARAMS.XPATH_LOCATION_HINT).trim();
55+
if (locationFindingXPath == null || locationFindingXPath.length()==0) {
56+
logger.info("No locationFindingXPath:params="+rule.params());
57+
textRange = null;
58+
} else {
59+
Node locationElement = (Node)XPathFactory.newInstance().newXPath().compile(locationFindingXPath).evaluate(xmlFile.getDocument().getFirstChild(), XPathConstants.NODE);
60+
if (locationElement == null) {
61+
textRange= null;
62+
logger.warn("Did not find node for "+locationFindingXPath);
63+
} else {
64+
textRange = XmlFile.nodeLocation(locationElement);
65+
logger.info("Found textRange="+textRange);
66+
}
67+
}
68+
} catch (RuntimeException | XPathExpressionException e) {
69+
logger.error("Ignore",e);
70+
textRange= null;
71+
}
72+
3873
NewIssue newIssue = context.newIssue().forRule(rule.ruleKey());
39-
NewIssueLocation primaryLocation = newIssue.newLocation().on(t);
74+
NewIssueLocation primaryLocation;
75+
if (textRange == null) {
76+
primaryLocation = newIssue.newLocation().on(t);
77+
} else {
78+
primaryLocation = newIssue.newLocation().on(t) .at(t.newRange(
79+
textRange.getStartLine(),
80+
textRange.getStartColumn(),
81+
textRange.getEndLine(),
82+
textRange.getEndColumn()));
83+
}
84+
4085
newIssue.at(primaryLocation);
4186
addIssue(issues, rule, newIssue);
4287
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.mulesoft.services.tools.sonarqube.rule.scope;
2+
3+
import org.sonarsource.analyzer.commons.xml.XmlFile;
4+
import org.sonarsource.analyzer.commons.xml.checks.SonarXmlCheck;
5+
6+
/**
7+
*
8+
*/
9+
public class SonarXmlCheckHelper extends SonarXmlCheck {
10+
11+
/**
12+
*
13+
*/
14+
@Override
15+
public void scanFile(XmlFile aFile) {
16+
// nothing to do
17+
}
18+
19+
}

src/main/java/com/mulesoft/services/tools/validation/rules/Rule.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ public class Rule {
9999
protected String applies;
100100
@XmlAttribute(name = "type")
101101
protected String type;
102+
@XmlAttribute(name = "locationHint")
103+
private String locationHint;
102104

103105
/**
104106
* Gets the value of the value property.
@@ -269,4 +271,18 @@ public void setType(String value) {
269271
this.type = value;
270272
}
271273

274+
/**
275+
*
276+
*/
277+
public String getLocationHint() {
278+
return locationHint;
279+
}
280+
281+
/**
282+
* @see #locationHint
283+
*/
284+
public void setLocationHint(String aLocationHint) {
285+
locationHint = aLocationHint;
286+
}
287+
272288
}

src/main/resources/mule3.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rule.template.name=Track issues on Mule 3
1919
rule.template.description=Rule Template for mule 3
2020
rule.template.parameter.scope=The scope of the rules. It should either file or application
2121
rule.template.parameter.xpath=XPath expression to be evaluated
22+
rule.template.parameter.xpathlocationhint=XPath expression to find the node
2223
rule.template.parameter.category=Category of the rule
2324

2425

src/main/resources/mule4.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rule.template.name=Track issues on Mule 4
1919
rule.template.description=Rule Template for mule 4
2020
rule.template.parameter.scope=The scope of the rules. It should either file or application
2121
rule.template.parameter.xpath=XPath expression to be evaluated
22+
rule.template.parameter.xpathlocationhint=XPath expression to find the node
2223
rule.template.parameter.category=Category of the rule
2324

2425

src/test/resources/rules-3.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,17 @@
140140
</rule>
141141
<rule id="10" name="HTTP Listener should use HTTPS protocol"
142142
description="HTTP Listener should use HTTPS protocol"
143-
severity="MAJOR" type="vulnerability">
143+
severity="MAJOR" type="vulnerability"
144+
locationHint="//*[local-name()='listener-config']">
144145
count(//mule:mule/http:listener-config)=0
145146
or
146147
//mule:mule/http:listener-config/@protocol='HTTPS'
147148
</rule>
148149
<rule id="11"
149150
name="HTTP Listener should use a specific port property"
150151
description="HTTP Listener should use a specific port property"
151-
severity="MAJOR" type="code_smell">
152+
severity="MAJOR" type="code_smell"
153+
locationHint="//*[local-name()='listener-config']">
152154
count(//mule:mule/http:listener-config)=0
153155
or
154156
//mule:mule/http:listener-config/@port='${https.port}' or

src/test/resources/rules-4.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,17 @@
9797
</rule>
9898
<rule id="7" name="HTTP Listener should use HTTPS protocol"
9999
description="HTTP Listener should use HTTPS protocol"
100-
severity="MAJOR" type="vulnerability">
100+
severity="MAJOR" type="vulnerability"
101+
locationHint="//*[local-name()='listener-config']">
101102
count(//mule:mule/http:listener-config)=0
102103
or
103104
//mule:mule/http:listener-config/http:listener-connection/@protocol='HTTPS'
104105
</rule>
105106
<rule id="8"
106107
name="HTTP Listener should use a specific port property"
107108
description="HTTP Listener should use a specific port property"
108-
severity="MAJOR" type="code_smell">
109+
severity="MAJOR" type="code_smell"
110+
locationHint="//*[local-name()='listener-config']">
109111
count(//mule:mule/http:listener-config)=0
110112
or
111113
//mule:mule/http:listener-config/http:listener-connection/@port='${https.port}'

0 commit comments

Comments
 (0)