Recently, we were trying to write a PMD rule to spot all occurances of Spring JDBC template's query* methods. Looking at some sample AST xml code, I wrote the following innocuous XPATH expression.
//PrimaryPrefix[Name[starts-with(#Image,'jdbcTemplate.query')]]
But very soon, we realized that this is not adequate. If someone writes "this.jdbcTemplate.queryForObject" then "this" becomes the "Primary Prefix" and "jdbcTemplate" becomes the "Suffix". Also the variable name of the JDBCTemplate object instance could be anything.
I thought it would be fairly easy to construct a XPATH expression to find out the occurance of a particular Class method call - anywhere in the code, but looking at the AST tree, I am just not able to figure it out. Is a XPATH really possible, or we have to write Java code?
I would suggest using the Sonar architectural rules engine to find this kind of violation.
Related
When I evaluate this XPath expression: //superhero[n0:name="Superman"]/n1:name on this xml:
<n0:rootElement xmlns:n0='http://example.com' xmlns:n1='http://example.com'>
<superheroes>
<superhero>
<n0:name>Superman</n0:name>
<n1:name>Clark</n1:name>
</superhero>
<superhero>
<n0:name>Spiderman</n0:name>
<n1:name>Peter</n1:name>
</superhero>
</superheroes>
</n0:rootElement>
using an XPath evaluator, I get the expected result.
But when I send it to an XQuery processor, I get an error message saying that
Namespace prefix 'n0' has not been declared. Weird, huh?
It's always the prefix in the brackets (is it called a filter, maybe?) that gets the complaint.
I've used http://www.xpathtester.com to verify the difference between XPath and XQuery interpretations.
It works fine with https://codebeautify.org/Xpath-Tester which is XPath only.
If I replace n0: or n1: with *: it works in for XQuery processors, but not for XPath testers.
This is of course a toy example I've written up to clarify my issue. In production I'm calling an external service which I believe is driven by Saxon-HE. I know it accepts XQuery so I'm guessing it is in "XQuery-mode" for XPath expressions.
There isn't much I can do to the xml file since I receive it from another source. Is there a better XQuery expression I can use?
Is this a bug, or by design?
Different XPath engines provide different ways of binding the namespace prefixes used in the expression. Some, I believe, pick up the namespace bindings from the source document. So it's not a non-conformance with the standard, it's the fact that the standard leaves it up to the particular processor how the original context is established.
The underlying problem is that you probably want your query to work regardless what namespace prefixes are used in the source document. Picking up the namespace bindings from the source document is handy for ad-hoc queries, but it means that a query that does the right thing with one document will fail with a different one.
In XQuery you can declare any namespaces you want to use in your query:
declare namespace n0 = 'http://example.com';
declare namespace n1 = 'http://example.com';
//superhero[n0:name="Superman"]/n1:name
https://xqueryfiddle.liberty-development.net/bdxZ8S
See the spec at https://www.w3.org/TR/xquery-31/#id-namespace-declaration
What is currently the best way to write SonarQube 4.5 checks for :
Bytecode Analysis
Source Analysis
Unfortunately, I could not find an up-to-date web page providing a clear explanation, and I see that existing checks use many deprecated classes and methods, use "bridges" about to be abandonned, checks are regularly removed from the codebase (such as the XPath rule).
I would like to be sure that the checks I'm about to write will be well written and durable.
So...
should I use BytecodeVisitor to analyse bytecode ?
should I use BaseTreeVisitor to analyse sourcecode ?
What is the replacement for org.sonar.api.rules.RuleRepository ?
What is the replacement for org.sonar.api.resources.Java ?
What is the replacement for org.sonar.api.rules.AnnotationRuleParser ?
How can I write XPath like rules (BaseTreeVisitor is using SSLR and if I'm not wrong SonarQube is moving away from SSLR / AbstractXPathCheck is part of sslr squid bridge.)
What else should I know ?
In other words I'm a bit lost.
Thank you in advance for your help.
First thanks for your feedback,
There are in fact many questions in your question (sic) :
The way to write custom checks for Java as of today is to use the BaseTreeVisitor. All the other ways are now deprecated and we are working to be able to remove them (but it is not always straightforward as some of them requires a complete semantic analysis to be removed). What is currently lacking from this api is the access to the semantic analysis to be able to request type information read from bytecode.
You can have a look at this project : https://github.com/SonarSource/sonar-examples/tree/master/plugins/java-custom-rules
For all the other questions, please ask them on the mailing list.
(Small notes though : BaseTreeVisitor does not use SSLR directly, the java plugin is not moving away from SSLR rather from one class, specifically ASTNode, in order to work on a SyntaxTree with a class specific for each type of node, The drop of Xpath checks occurs in that logic of moving away from a non-typed SyntaxTree).
I am trying to learn how to use the DrRacket debugger's annotate function. My ultimate aim is to build a REPL that you can execute from within a closure and have access to everything that's in scope. (see my previous question on that topic and Greg Hendershott's well-researched answer) For the time being, I'm just trying to explore how the annotate function works. You can see my first exploratory attempt at using it, and the results, here.
The error, which is happing inside of the annotator, seems to arise when it tries to match he application of string-append. The matcher is looking for a #%plain-app and the expanded syntax I'm presenting to it contains an #%app. I'm unsure if I should be expanding the syntax differently so it comes out as a #%plain-app or if there's something else I'm doing wrong to produce the syntax I'm feeding into the annotator. Does anybody see where my error is?
This revision to my previous pasterack post is swallowed without complaint. It seems that the syntax match must take place on a top-level syntax object (ruling out anything that could happen in an expansion phase, like a macro), and expansion must take place with a current namespace attached. There are some more subtleties in the syntax match, particularly around the fact that the syntax object needs to be free-identifier=? to #%plain-app. For all the gory details, refer to the mailing list thread I started.
Currently, I'm writing something to do Unit testing for XSLT2 functions, the idea is very simple:
Create a custom-library.xsl, which contains some custom XSLT2 functions.
Create a data XML contains the test cases, as following XML Schema xslunit.xsd:
schema structure http://xml.bodz.net/schema/xslunit/xslunit.png
Run the test cases by transform it, using xslunit-xslt2.xsl, and get the test result html.
Now, the question is, there is function-call in the test cases, and I have to evaluate it in the XSLT (file xslunit-xslt2.xsl). But I can't find a way to evaluate an XPath.
Though, it may be easy to using some kind of Java extensions, but I really don't want to bring in another trouble. I hope everything can just work with-in XSLT2 only.
No, pure XSLT 2.0 does not have support do evaluate an XPath expression found in your XML data. Saxon 9 (in its commercial editions) however has an extension function: http://www.saxonica.com/documentation/extensions/functions/evaluate.xml. And AltovaXML Tools has a similar one: http://manual.altova.com/AltovaXML/altovaxmlcommunity/index.html?xextaltova_general.htm
Update a decade later: XSLT 3.0 has an instruction <xsl:evaluate> which evaluates an XPath expression supplied dynamically as a string.
I am currently using a CMS which uses an ORM with its own bespoke query language (i.e. with select/where/orderby like statements). I refer to this mini-language as a DSL, but I might have the terminology wrong.
We are writing controls for this CMS, but I would prefer not to couple the controls to the CMS, because we have some doubts about whether we want to continue with this CMS in the longer term.
We can decouple our controls from the CMS fairly easily, by using our own DAL/abstraction layer or what not.
Then I remembered that on most of the CMS controls, they provide a property (which is design-time editable) where users can type in a query to control what gets populated in the data source. Nice feature - the question is how can I abstract this feature?
It then occurred to me that maybe a DSL framework existed out there that could provide me with a simple query language that could be turned into a LINQ expression at runtime. Thus decoupling me from the CMS' query DSL.
Does such a thing exist? Am I wasting my time? (probably the latter)
Thanks
this isn't going to answer your question fully, but there is an extension for LINQ that allows you to specify predicates for LINQ queries as strings called Dynamic LINQ, so if you want to store the conditions in some string-based format, you could probably build your language on top of this. You'd still need to find a way to represent different clauses (where/orderby/etc.) but for the predicates passed as arguments to these, you could use Dynamic LINQ.
Note that Dynamic LINQ allows you to parse the string, but AFAIK doesn't have any way to turn existing Expression tree into that string... so there would be some work needed to do that.
(but I'm not sure if I fully understand the question, so maybe I'm totally of :-))