99import org .jdom2 .Element ;
1010import org .jdom2 .JDOMException ;
1111import org .jdom2 .input .SAXBuilder ;
12+
13+ import javax .xml .xpath .XPathConstants ;
14+ import javax .xml .xpath .XPathExpressionException ;
15+ import javax .xml .xpath .XPathFactory ;
16+
1217import org .sonar .api .batch .fs .InputFile ;
1318import org .sonar .api .batch .rule .ActiveRule ;
1419import org .sonar .api .batch .sensor .SensorContext ;
1823import org .sonar .api .utils .log .Logger ;
1924import 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+
2130import com .mulesoft .services .tools .sonarqube .rule .MuleRulesDefinition ;
2231import 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 }
0 commit comments