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"
   }
}

Reply via email to