On 20.8.12 16:05, Chetan Mehrotra wrote:
While trying to run Granite over Oak the User Admin UI was failing to load
because of problem in executing an XPath query
Initial Query (in JSON) [4] is passed to
o.a.j.commons.jackrabbit.user.AuthorizableQueryManager which internally
converts it into XPath using a builder pattern and generates following
XPath query
//element(*,rep:Authorizable)[(((jcr:contains(profile/@givenName,'**') or
jcr:contains(profile/@familyName,'**')) or
jcr:contains(profile/@email,'**')) or (jcr:like(rep:principalName,'%%') or
jcr:like(fn:name(.),'%%')))] order by @rep:principalName ascending
This query when passed to o.a.j.oak.query.XPathToSQL2Converter results in
an exception
Issue - #1
---------------
Caused by: java.text.ParseException: Query:
//element(*,rep:Authorizable)[(((jcr:contains(profile/@givenName,'**') or
jcr:contains(profile/@familyName,'**')) or
jcr:contains(profile/@email,'**')) or (jcr:like(rep:principalName,(*)'%%')
or jcr:like(fn:name(.),'%%')))] order by @rep:principalName ascending;
expected: (
at
org.apache.jackrabbit.oak.query.XPathToSQL2Converter.getSyntaxError(XPathToSQL2Converter.java:743)
at
org.apache.jackrabbit.oak.query.XPathToSQL2Converter.read(XPathToSQL2Converter.java:435)
On debugging issue is shown at char 183 and is around
jcr:like(rep:principalName,(*)'%%') . So it appears that
XPathQueryEvaluator.visit(XPathQueryBuilder.NodeCondition) [1] should add
'@' before appending the rep:principalName property name as its a property
condition
Thanks for spotting this. It is a bug in XPathQueryEvaluator which seems
to be also present in JR2. AFAIK JR2 is very lenient wrt. the presence
of the @ for properties. Could you provide a patch for this for JR2 and
Oak? I'll take care of the rest then.
Issue - #2
---------------
Temp fixing the issue with principalName and moving further leads to second
issue
java.text.ParseException: Query:
//element(*,rep:Authorizable)[(((jcr:contains(profile/@givenName,'**') or
jcr:contains(profile/@familyName,'**')) or
jcr:contains(profile/@email,'**')) or (jcr:like(@rep:principalName,'%%') or
jcr:like(fn:name(.(*)),'%%')))] order by @rep:principalName ascending;
expected: )
at
org.apache.jackrabbit.oak.query.XPathToSQL2Converter.getSyntaxError(XPathToSQL2Converter.java:743)
Now here issue is at jcr:like(fn:name(.(*)),'%%'). And checking various
example it appears that fn:name does not take any argument. So again
possibly an issue with [1]
Most probably this is the same situation like with #1 above. Could you
check whether fixing this in XPathQueryEvaluator would also work with
JR2? If so I suggest we fix it there (again both in JR2 and Oak).
Michael
Summary
=========
Given above details it appears that issue exists in
XPathQueryEvaluator.visit(XPathQueryBuilder.NodeCondition)
[1] and [2]. However such a generated XPath works in JR2 but fails to get
converted in Oak. So my query is
1. Should it be fixed in [2] and possibly at [1]
2. OR XPathToSQL2Converter is adapted to support such cases for backward
compatibility
A test case is provided at [3]
regards
Chetan
[1]
https://github.com/apache/jackrabbit/blob/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/XPathQueryEvaluator.java#L135
[2]
https://github.com/apache/jackrabbit-oak/blob/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/XPathQueryEvaluator.java#L132
[3]
@Test
public void testXpath2Sql2() throws ParseException {
String notWorking =
"//element(*,rep:Authorizable)[(((jcr:contains(profile/@givenName,'**') or
jcr:contains(profile/@familyName,'**')) or
jcr:contains(profile/@email,'**')) or (jcr:like(rep:principalName,'%%') or
jcr:like(fn:name(.),'%%')))] order by @rep:principalName ascending";
String working =
"//element(*,rep:Authorizable)[(((jcr:contains(profile/@givenName,'**') or
jcr:contains(profile/@familyName,'**')) or
jcr:contains(profile/@email,'**')) or (jcr:like(@rep:principalName,'%%') or
jcr:like(fn:name(),'%%')))] order by @rep:principalName ascending";
XPathToSQL2Converter xc = new XPathToSQL2Converter();
xc.convert(notWorking);
}
[4] {
"condition": [
[
{
"contains": {
"property": "profile\/@givenName",
"expression": "**"
}
},
{
"contains": {
"property": "profile\/@familyName",
"expression": "**"
}
},
{
"contains": {
"property": "profile\/@email",
"expression": "**"
}
},
{
"named": "%%"
}
]
],
"selector": "authorizable",
"sort": {
"property": "@rep:principalName",
"direction": "asc"
}
}