jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Parvulescu <alex.parvule...@gmail.com>
Subject Re: svn commit: r1373392 - in /jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user: ./ query/
Date Fri, 17 Aug 2012 09:35:12 GMT
I've created OAK-253

best,
alex

https://issues.apache.org/jira/browse/OAK-253



On Fri, Aug 17, 2012 at 11:13 AM, Alex Parvulescu <alex.parvulescu@gmail.com
> wrote:

> Hi Angela,
>
> I fully agree with you about the need to have this code in oak.
> That is why my email started with...
>
> > I'd like to raise a concern
>
> XPath to SQL2 conversion is a WIP, the level of support for XPath queries
> is still under discussion, which makes the platform you are building the
> user parts on unstable.
> I just wanted to make sure that the risk is known.
>
> On the other hand, I'm sure that the extensive range of tests that cover
> this functionality assures us that there are no obvious problems.
>
> > do you volunteer to take care of that? that would be perfect.
> I'll create an issue to make sure we don't forget to come back to the code
> later on.
>
>
> thanks,
> alex
>
>
> On Fri, Aug 17, 2012 at 11:01 AM, Angela Schreiber <anchela@adobe.com>wrote:
>
>> hi alex
>>
>> for backward compatibility the form jr-user-query implementation
>> and the authorizable-query-utility present in jackrabbit-jcr-commons
>> is required to work as is as nobody will have time to fix all
>> usages of that in our products.
>>
>> we may - just in case we have time left - add a additional implementation
>> of michael's user-query API and start deprecating
>> the old one in a subsequent release of oak. do you volunteer
>> to take care of that? that would be perfect.
>>
>> kind regards
>> angela
>>
>>
>> On 8/17/12 10:43 AM, Alex Parvulescu wrote:
>>
>>> Hi,
>>>
>>> I'd like to raise a concern here about the XPath query builder that made
>>> its way into oak-jcr with this commit.
>>>
>>> There is no native XPath support in Oak. Currently the XPath queries are
>>> beaing translated into (more or less) equivalent SQL2 queries. See
>>> also OAK-225.
>>> So under these circumstances it doesn't make sense to build a query
>>> programatically as XPath just to have it translated into SQL2 at a later
>>> stage.
>>>
>>> thoughts?
>>>
>>> thanks,
>>> alex
>>>
>>>
>>> On Wed, Aug 15, 2012 at 3:24 PM,<angela@apache.org>  wrote:
>>>
>>>  Author: angela
>>>> Date: Wed Aug 15 13:24:21 2012
>>>> New Revision: 1373392
>>>>
>>>> URL: http://svn.apache.org/viewvc?**rev=1373392&view=rev<http://svn.apache.org/viewvc?rev=1373392&view=rev>
>>>> Log:
>>>> OAK-50 : Implement User Management (WIP)
>>>>
>>>> Added:
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/Condition.java
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ConditionVisitor.**java
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/RelationOp.java
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ResultIterator.java
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/XPathQueryBuilder.**java
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/**XPathQueryEvaluator.java
>>>> Modified:
>>>>
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/UserManagerImpl.java
>>>>
>>>> Modified:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/UserManagerImpl.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/UserManagerImpl.java?rev=**1373392&r1=1373391&r2=1373392&**
>>>> view=diff<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java?rev=1373392&r1=1373391&r2=1373392&view=diff>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/UserManagerImpl.java
>>>> (original)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/UserManagerImpl.java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -41,6 +41,8 @@ import org.apache.jackrabbit.oak.api.**Pro<http://org.apache.jackrabbit.oak.api.Pro>
>>>>   import org.apache.jackrabbit.oak.api.**Root;
>>>>   import org.apache.jackrabbit.oak.api.**Tree;
>>>>   import org.apache.jackrabbit.oak.jcr.**SessionDelegate;
>>>> +import
>>>> org.apache.jackrabbit.oak.jcr.**security.user.query.**
>>>> XPathQueryBuilder;
>>>> +import
>>>> org.apache.jackrabbit.oak.jcr.**security.user.query.**
>>>> XPathQueryEvaluator;
>>>>   import org.apache.jackrabbit.oak.jcr.**value.ValueConverter;
>>>>   import org.apache.jackrabbit.oak.**security.user.**UserProviderImpl;
>>>>   import org.apache.jackrabbit.oak.spi.**security.principal.**
>>>> EveryonePrincipal;
>>>> @@ -142,8 +144,9 @@ public class UserManagerImpl implements
>>>>
>>>>       @Override
>>>>       public Iterator<Authorizable>  findAuthorizables(Query query)
>>>> throws
>>>> RepositoryException {
>>>> -        // TODO : execute the specified query
>>>> -        throw new UnsupportedOperationException(**"Not Implemented");
>>>> +        XPathQueryBuilder builder = new XPathQueryBuilder();
>>>> +        query.build(builder);
>>>> +        return new XPathQueryEvaluator(builder, this,
>>>> sessionDelegate.**getQueryManager(),
>>>> sessionDelegate.**getNamePathMapper()).eval();
>>>>       }
>>>>
>>>>       @Override
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/Condition.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/query/Condition.java?rev=**1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/Condition.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/Condition.java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/Condition.java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,190 @@
>>>> +/*
>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>>>> + * contributor license agreements.  See the NOTICE file distributed
>>>> with
>>>> + * this work for additional information regarding copyright ownership.
>>>> + * The ASF licenses this file to You under the Apache License, Version
>>>> 2.0
>>>> + * (the "License"); you may not use this file except in compliance with
>>>> + * the License.  You may obtain a copy of the License at
>>>> + *
>>>> + *      http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0>
>>>> + *
>>>> + * Unless required by applicable law or agreed to in writing, software
>>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>> + * See the License for the specific language governing permissions and
>>>> + * limitations under the License.
>>>> + */
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +import java.util.ArrayList;
>>>> +import java.util.Iterator;
>>>> +import java.util.List;
>>>> +import javax.jcr.RepositoryException;
>>>> +import javax.jcr.Value;
>>>> +
>>>> +
>>>> +interface Condition {
>>>> +
>>>> +    void accept(ConditionVisitor visitor) throws RepositoryException;
>>>> +
>>>> +    //----------------------------**--------------<  Condition
>>>> implementations>---
>>>> +
>>>> +    static class Node implements Condition {
>>>> +        private final String pattern;
>>>> +
>>>> +        public Node(String pattern) {
>>>> +            this.pattern = pattern;
>>>> +        }
>>>> +
>>>> +        public String getPattern() {
>>>> +            return pattern;
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) throws
>>>> RepositoryException {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class Property implements Condition {
>>>> +        private final String relPath;
>>>> +        private final RelationOp op;
>>>> +        private final Value value;
>>>> +        private final String pattern;
>>>> +
>>>> +        public Property(String relPath, RelationOp op, Value value) {
>>>> +            this.relPath = relPath;
>>>> +            this.op = op;
>>>> +            this.value = value;
>>>> +            pattern = null;
>>>> +        }
>>>> +
>>>> +        public Property(String relPath, RelationOp op, String pattern)
>>>> {
>>>> +            this.relPath = relPath;
>>>> +            this.op = op;
>>>> +            value = null;
>>>> +            this.pattern = pattern;
>>>> +        }
>>>> +
>>>> +        public Property(String relPath, RelationOp op) {
>>>> +            this.relPath = relPath;
>>>> +            this.op = op;
>>>> +            value = null;
>>>> +            pattern = null;
>>>> +        }
>>>> +
>>>> +        public String getRelPath() {
>>>> +            return relPath;
>>>> +        }
>>>> +
>>>> +        public RelationOp getOp() {
>>>> +            return op;
>>>> +        }
>>>> +
>>>> +        public Value getValue() {
>>>> +            return value;
>>>> +        }
>>>> +
>>>> +        public String getPattern() {
>>>> +            return pattern;
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) throws
>>>> RepositoryException {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class Contains implements Condition {
>>>> +        private final String relPath;
>>>> +        private final String searchExpr;
>>>> +
>>>> +        public Contains(String relPath, String searchExpr) {
>>>> +            this.relPath = relPath;
>>>> +            this.searchExpr = searchExpr;
>>>> +        }
>>>> +
>>>> +        public String getRelPath() {
>>>> +            return relPath;
>>>> +        }
>>>> +
>>>> +        public String getSearchExpr() {
>>>> +            return searchExpr;
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class Impersonation implements Condition {
>>>> +        private final String name;
>>>> +
>>>> +        public Impersonation(String name) {
>>>> +            this.name = name;
>>>> +        }
>>>> +
>>>> +        public String getName() {
>>>> +            return name;
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class Not implements Condition {
>>>> +        private final Condition condition;
>>>> +
>>>> +        public Not(Condition condition) {
>>>> +            this.condition = condition;
>>>> +        }
>>>> +
>>>> +        public Condition getCondition() {
>>>> +            return condition;
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) throws
>>>> RepositoryException {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    abstract static class Compound implements Condition,
>>>> Iterable<Condition>  {
>>>> +        private final List<Condition>  conditions = new
>>>> ArrayList<Condition>();
>>>> +
>>>> +        public Compound() {
>>>> +            super();
>>>> +        }
>>>> +
>>>> +        public Compound(Condition condition1, Condition condition2) {
>>>> +            conditions.add(condition1);
>>>> +            conditions.add(condition2);
>>>> +        }
>>>> +
>>>> +        public void addCondition(Condition condition) {
>>>> +            conditions.add(condition);
>>>> +        }
>>>> +
>>>> +        public Iterator<Condition>  iterator() {
>>>> +            return conditions.iterator();
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class And extends Compound {
>>>> +        public And(Condition condition1, Condition condition2) {
>>>> +            super(condition1, condition2);
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) throws
>>>> RepositoryException {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    static class Or extends Compound {
>>>> +        public Or(Condition condition1, Condition condition2) {
>>>> +            super(condition1, condition2);
>>>> +        }
>>>> +
>>>> +        public void accept(ConditionVisitor visitor) throws
>>>> RepositoryException {
>>>> +            visitor.visit(this);
>>>> +        }
>>>> +    }
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ConditionVisitor.**java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/query/ConditionVisitor.**java?rev=1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/ConditionVisitor.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ConditionVisitor.**java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ConditionVisitor.**java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,36 @@
>>>> +/*
>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>>>> + * contributor license agreements.  See the NOTICE file distributed
>>>> with
>>>> + * this work for additional information regarding copyright ownership.
>>>> + * The ASF licenses this file to You under the Apache License, Version
>>>> 2.0
>>>> + * (the "License"); you may not use this file except in compliance with
>>>> + * the License.  You may obtain a copy of the License at
>>>> + *
>>>> + *      http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0>
>>>> + *
>>>> + * Unless required by applicable law or agreed to in writing, software
>>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>> + * See the License for the specific language governing permissions and
>>>> + * limitations under the License.
>>>> + */
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +import javax.jcr.RepositoryException;
>>>> +
>>>> +interface ConditionVisitor {
>>>> +
>>>> +    void visit(Condition.Node node) throws RepositoryException;
>>>> +
>>>> +    void visit(Condition.Property condition) throws
>>>> RepositoryException;
>>>> +
>>>> +    void visit(Condition.Contains condition);
>>>> +
>>>> +    void visit(Condition.Impersonation condition);
>>>> +
>>>> +    void visit(Condition.Not condition) throws RepositoryException;
>>>> +
>>>> +    void visit(Condition.And condition) throws RepositoryException;
>>>> +
>>>> +    void visit(Condition.Or condition) throws RepositoryException;
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/RelationOp.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/query/RelationOp.java?**rev=1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/RelationOp.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/RelationOp.java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/RelationOp.java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,28 @@
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +/**
>>>> + * Relational operators for comparing a property to a value. Correspond
>>>> + * to the general comparison operators as define in JSR-170.
>>>> + * The {@link #EX} tests for existence of a property.
>>>> + */
>>>> +enum RelationOp {
>>>> +
>>>> +    NE("!="),
>>>> +    EQ("="),
>>>> +    LT("<"),
>>>> +    LE("<="),
>>>> +    GT(">"),
>>>> +    GE("=>"),
>>>> +    EX(""),
>>>> +    LIKE("like");
>>>> +
>>>> +    private final String op;
>>>> +
>>>> +    RelationOp(String op) {
>>>> +        this.op = op;
>>>> +    }
>>>> +
>>>> +    String getOp() {
>>>> +        return op;
>>>> +    }
>>>> +}
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ResultIterator.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/query/ResultIterator.**java?rev=1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/ResultIterator.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ResultIterator.java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/ResultIterator.java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,120 @@
>>>> +/*
>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>>>> + * contributor license agreements.  See the NOTICE file distributed
>>>> with
>>>> + * this work for additional information regarding copyright ownership.
>>>> + * The ASF licenses this file to You under the Apache License, Version
>>>> 2.0
>>>> + * (the "License"); you may not use this file except in compliance with
>>>> + * the License.  You may obtain a copy of the License at
>>>> + *
>>>> + *      http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0>
>>>> + *
>>>> + * Unless required by applicable law or agreed to in writing, software
>>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>> + * See the License for the specific language governing permissions and
>>>> + * limitations under the License.
>>>> + */
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +import java.util.Iterator;
>>>> +import java.util.**NoSuchElementException;
>>>> +
>>>> +/**
>>>> + * Implements a query result iterator which only returns a maximum
>>>> number
>>>> of
>>>> + * element from an underlying iterator starting at a given offset.
>>>> + *
>>>> + * @param<T>  element type of the query results
>>>> + *
>>>> + * TODO move to query-commons ?
>>>> + */
>>>> +public class ResultIterator<T>  implements Iterator<T>  {
>>>> +
>>>> +    public final static int OFFSET_NONE = 0;
>>>> +    public final static int MAX_ALL = -1;
>>>> +
>>>> +    private final Iterator<T>  iterator;
>>>> +    private final long offset;
>>>> +    private final long max;
>>>> +    private int pos;
>>>> +    private T next;
>>>> +
>>>> +    /**
>>>> +     * Create a new {@code ResultIterator} with a given offset and
>>>> maximum
>>>> +     *
>>>> +     * @param offset Offset to start iteration at. Must be non negative
>>>> +     * @param max Maximum elements this iterator should return.
>>>> +     * Set to {@link #MAX_ALL} for all results.
>>>> +     * @param iterator the underlying iterator
>>>> +     * @throws IllegalArgumentException if offset is negative
>>>> +     */
>>>> +    private ResultIterator(long offset, long max, Iterator<T>
>>>>  iterator) {
>>>> +        if (offset<  OFFSET_NONE) {
>>>> +            throw new IllegalArgumentException("**Offset must not be
>>>> negative");
>>>> +        }
>>>> +        this.iterator = iterator;
>>>> +        this.offset = offset;
>>>> +        this.max = max;
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Returns an iterator respecting the specified {@code offset} and
>>>> {@code max}.
>>>> +     *
>>>> +     * @param offset   offset to start iteration at. Must be non
>>>> negative
>>>> +     * @param max      maximum elements this iterator should return.
>>>> Set
>>>> to
>>>> +     * {@link #MAX_ALL} for all
>>>> +     * @param iterator the underlying iterator
>>>> +     * @param<T>       element type
>>>> +     * @return an iterator which only returns the elements in the given
>>>> bounds
>>>> +     */
>>>> +    public static<T>  Iterator<T>  create(long offset, long max,
>>>> Iterator<T>  iterator) {
>>>> +        if (offset == OFFSET_NONE&&  max == MAX_ALL) {
>>>>
>>>> +            // no constraints on offset nor max ->  return the original
>>>> iterator.
>>>> +            return iterator;
>>>> +        } else {
>>>> +            return new ResultIterator<T>(offset, max, iterator);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    //----------------------------**------------------------------**-<
>>>> Iterator>---
>>>> +    @Override
>>>> +    public boolean hasNext() {
>>>> +        if (next == null) {
>>>> +            fetchNext();
>>>> +        }
>>>> +        return next != null;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public T next() {
>>>> +        if (!hasNext()) {
>>>> +            throw new NoSuchElementException();
>>>> +        }
>>>> +        return consumeNext();
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void remove() {
>>>> +        throw new UnsupportedOperationException(**);
>>>> +    }
>>>> +
>>>> +    //----------------------------**------------------------------**
>>>> --<
>>>> private>---
>>>> +
>>>> +    private void fetchNext() {
>>>> +        for (; pos<  offset&&  iterator.hasNext(); pos++) {
>>>>
>>>> +            next = iterator.next();
>>>> +        }
>>>> +
>>>> +        if (pos<  offset || !iterator.hasNext() || max>= 0&&  pos -
>>>>
>>>> offset + 1>  max) {
>>>> +            next = null;
>>>> +        } else {
>>>> +            next = iterator.next();
>>>> +            pos++;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    private T consumeNext() {
>>>> +        T element = next;
>>>> +        next = null;
>>>> +        return element;
>>>> +    }
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/XPathQueryBuilder.**java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**
>>>> user/query/XPathQueryBuilder.**java?rev=1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/XPathQueryBuilder.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/XPathQueryBuilder.**java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/XPathQueryBuilder.**java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,195 @@
>>>> +/*
>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>>>> + * contributor license agreements.  See the NOTICE file distributed
>>>> with
>>>> + * this work for additional information regarding copyright ownership.
>>>> + * The ASF licenses this file to You under the Apache License, Version
>>>> 2.0
>>>> + * (the "License"); you may not use this file except in compliance with
>>>> + * the License.  You may obtain a copy of the License at
>>>> + *
>>>> + *      http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0>
>>>> + *
>>>> + * Unless required by applicable law or agreed to in writing, software
>>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>> + * See the License for the specific language governing permissions and
>>>> + * limitations under the License.
>>>> + */
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +import javax.jcr.Value;
>>>> +
>>>> +import org.apache.jackrabbit.api.**security.user.Authorizable;
>>>> +import org.apache.jackrabbit.api.**security.user.QueryBuilder;
>>>> +
>>>> +public class XPathQueryBuilder implements QueryBuilder<Condition>  {
>>>> +
>>>> +    private Class<? extends Authorizable>  selector =
>>>> Authorizable.class;
>>>> +    private String groupName;
>>>> +    private boolean declaredMembersOnly;
>>>> +    private Condition condition;
>>>> +    private String sortProperty;
>>>> +    private Direction sortDirection = Direction.ASCENDING;
>>>> +    private boolean sortIgnoreCase;
>>>> +    private Value bound;
>>>> +    private long offset;
>>>> +    private long maxCount = -1;
>>>> +
>>>> +    //----------------------------**---------------------------<
>>>> QueryBuilder>---
>>>> +    @Override
>>>> +    public void setSelector(Class<? extends Authorizable>  selector) {
>>>> +        this.selector = selector;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setScope(String groupName, boolean declaredOnly) {
>>>> +        this.groupName = groupName;
>>>> +        declaredMembersOnly = declaredOnly;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setCondition(Condition condition) {
>>>> +        this.condition = condition;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setSortOrder(String propertyName, Direction direction,
>>>> boolean ignoreCase) {
>>>> +        sortProperty = propertyName;
>>>> +        sortDirection = direction;
>>>> +        sortIgnoreCase = ignoreCase;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setSortOrder(String propertyName, Direction direction)
>>>> {
>>>> +        setSortOrder(propertyName, direction, false);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setLimit(Value bound, long maxCount) {
>>>> +        offset = 0;   // Unset any previously set offset
>>>> +        this.bound = bound;
>>>> +        this.maxCount = maxCount;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void setLimit(long offset, long maxCount) {
>>>> +        bound = null; // Unset any previously set bound
>>>> +        this.offset = offset;
>>>> +        this.maxCount = maxCount;
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition nameMatches(String pattern) {
>>>> +        return new Condition.Node(pattern);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition neq(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.NE, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition eq(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.EQ, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition lt(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.LT, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition le(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.LE, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition gt(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.GT, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition ge(String relPath, Value value) {
>>>> +        return new Condition.Property(relPath, RelationOp.GE, value);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition exists(String relPath) {
>>>> +        return new Condition.Property(relPath, RelationOp.EX);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition like(String relPath, String pattern) {
>>>> +        return new Condition.Property(relPath, RelationOp.LIKE,
>>>> pattern);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition contains(String relPath, String searchExpr) {
>>>> +        return new Condition.Contains(relPath, searchExpr);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition impersonates(String name) {
>>>> +        return new Condition.Impersonation(name);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition not(Condition condition) {
>>>> +        return new Condition.Not(condition);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition and(Condition condition1, Condition condition2) {
>>>> +        return new Condition.And(condition1, condition2);
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public Condition or(Condition condition1, Condition condition2) {
>>>> +        return new Condition.Or(condition1, condition2);
>>>> +    }
>>>> +
>>>> +    //----------------------------**------------------------------**-<
>>>> internal>---
>>>> +
>>>> +    Condition property(String relPath, RelationOp op, Value value) {
>>>> +        return new Condition.Property(relPath, op, value);
>>>> +    }
>>>> +
>>>> +    Class<? extends Authorizable>  getSelector() {
>>>> +        return selector;
>>>> +    }
>>>> +
>>>> +    String getGroupName() {
>>>> +        return groupName;
>>>> +    }
>>>> +
>>>> +    boolean isDeclaredMembersOnly() {
>>>> +        return declaredMembersOnly;
>>>> +    }
>>>> +
>>>> +    Condition getCondition() {
>>>> +        return condition;
>>>> +    }
>>>> +
>>>> +    String getSortProperty() {
>>>> +        return sortProperty;
>>>> +    }
>>>> +
>>>> +    Direction getSortDirection() {
>>>> +        return sortDirection;
>>>> +    }
>>>> +
>>>> +    boolean getSortIgnoreCase() {
>>>> +        return sortIgnoreCase;
>>>> +    }
>>>> +
>>>> +    Value getBound() {
>>>> +        return bound;
>>>> +    }
>>>> +
>>>> +    long getOffset() {
>>>> +        return offset;
>>>> +    }
>>>> +
>>>> +    long getMaxCount() {
>>>> +        return maxCount;
>>>> +    }
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>> Added:
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/**XPathQueryEvaluator.java
>>>> URL:
>>>> http://svn.apache.org/viewvc/**jackrabbit/oak/trunk/oak-jcr/**
>>>> src/main/java/org/apache/**jackrabbit/oak/jcr/security/**user/query/**
>>>> XPathQueryEvaluator.java?rev=**1373392&view=auto<http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/query/XPathQueryEvaluator.java?rev=1373392&view=auto>
>>>>
>>>> ==============================**==============================**
>>>> ==================
>>>> ---
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/**XPathQueryEvaluator.java
>>>> (added)
>>>> +++
>>>> jackrabbit/oak/trunk/oak-jcr/**src/main/java/org/apache/**
>>>> jackrabbit/oak/jcr/security/**user/query/**XPathQueryEvaluator.java
>>>> Wed Aug 15 13:24:21 2012
>>>> @@ -0,0 +1,340 @@
>>>> +/*
>>>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>>>> + * contributor license agreements.  See the NOTICE file distributed
>>>> with
>>>> + * this work for additional information regarding copyright ownership.
>>>> + * The ASF licenses this file to You under the Apache License, Version
>>>> 2.0
>>>> + * (the "License"); you may not use this file except in compliance with
>>>> + * the License.  You may obtain a copy of the License at
>>>> + *
>>>> + *      http://www.apache.org/**licenses/LICENSE-2.0<http://www.apache.org/licenses/LICENSE-2.0>
>>>> + *
>>>> + * Unless required by applicable law or agreed to in writing, software
>>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>> + * See the License for the specific language governing permissions and
>>>> + * limitations under the License.
>>>> + */
>>>> +package org.apache.jackrabbit.oak.jcr.**security.user.query;
>>>> +
>>>> +import java.util.Iterator;
>>>> +import javax.annotation.Nonnull;
>>>> +import javax.jcr.Node;
>>>> +import javax.jcr.PropertyType;
>>>> +import javax.jcr.RepositoryException;
>>>> +import javax.jcr.Value;
>>>> +import javax.jcr.query.Query;
>>>> +import javax.jcr.query.QueryManager;
>>>> +
>>>> +import com.google.common.base.**Function;
>>>> +import com.google.common.base.**Predicate;
>>>> +import com.google.common.base.**Predicates;
>>>> +import com.google.common.collect.**Iterators;
>>>> +import org.apache.jackrabbit.api.**security.user.Authorizable;
>>>> +import org.apache.jackrabbit.api.**security.user.Group;
>>>> +import org.apache.jackrabbit.api.**security.user.QueryBuilder;
>>>> +import org.apache.jackrabbit.api.**security.user.User;
>>>> +import org.apache.jackrabbit.api.**security.user.UserManager;
>>>> +import org.apache.jackrabbit.oak.jcr.**security.user.UserManagerImpl;
>>>> +import org.apache.jackrabbit.oak.**namepath.NamePathMapper;
>>>> +import org.apache.jackrabbit.oak.spi.**security.user.UserConstants;
>>>> +import org.apache.jackrabbit.util.**Text;
>>>> +import org.slf4j.Logger;
>>>> +import org.slf4j.LoggerFactory;
>>>> +
>>>> +/**
>>>> + * This evaluator for {@link
>>>> org.apache.jackrabbit.api.**security.user.Query}s use XPath
>>>> + * and some minimal client side filtering.
>>>> + */
>>>> +public class XPathQueryEvaluator implements ConditionVisitor {
>>>> +    static final Logger log =
>>>> LoggerFactory.getLogger(**XPathQueryEvaluator.class);
>>>> +
>>>> +    private final XPathQueryBuilder builder;
>>>> +    private final UserManager userManager;
>>>> +    private final QueryManager queryManager;
>>>> +    private final NamePathMapper namePathMapper;
>>>> +
>>>> +    private final StringBuilder xPath = new StringBuilder();
>>>> +
>>>> +    public XPathQueryEvaluator(**XPathQueryBuilder builder,
>>>> UserManagerImpl
>>>> userManager,
>>>> +                               QueryManager queryManager,
>>>> NamePathMapper
>>>> namePathMapper) {
>>>> +        this.builder = builder;
>>>> +        this.userManager = userManager;
>>>> +        this.queryManager = queryManager;
>>>> +        this.namePathMapper = namePathMapper;
>>>> +    }
>>>> +
>>>> +    public Iterator<Authorizable>  eval() throws RepositoryException {
>>>> +        xPath.append("//element(*,")
>>>> +                .append(getNtName(builder.**getSelector()))
>>>> +                .append(')');
>>>> +
>>>> +        Value bound = builder.getBound();
>>>> +        long offset = builder.getOffset();
>>>> +        if (bound != null&&  offset>  0) {
>>>>
>>>> +            log.warn("Found bound {} and offset {} in limit. Discarding
>>>> offset.", bound, offset);
>>>> +            offset = 0;
>>>> +        }
>>>> +
>>>> +        Condition condition = builder.getCondition();
>>>> +        String sortCol = builder.getSortProperty();
>>>> +        QueryBuilder.Direction sortDir = builder.getSortDirection();
>>>> +        if (bound != null) {
>>>> +            if (sortCol == null) {
>>>> +                log.warn("Ignoring bound {} since no sort order is
>>>> specified");
>>>> +            } else {
>>>> +                Condition boundCondition = builder.property(sortCol,
>>>> getCollation(sortDir), bound);
>>>> +                condition = condition == null
>>>> +                        ? boundCondition
>>>> +                        : builder.and(condition, boundCondition);
>>>> +            }
>>>> +        }
>>>> +
>>>> +        if (condition != null) {
>>>> +            xPath.append('[');
>>>> +            condition.accept(this);
>>>> +            xPath.append(']');
>>>> +        }
>>>> +
>>>> +        if (sortCol != null) {
>>>> +            boolean ignoreCase = builder.getSortIgnoreCase();
>>>> +            xPath.append(" order by ")
>>>> +                    .append(ignoreCase ? "" : "fn:lower-case(")
>>>> +                    .append(sortCol)
>>>> +                    .append(ignoreCase ? " " : ") ")
>>>> +                    .append(sortDir.getDirection()**);
>>>> +        }
>>>> +
>>>> +        Query query = queryManager.createQuery(**xPath.toString(),
>>>> Query.XPATH);
>>>> +        long maxCount = builder.getMaxCount();
>>>> +        if (maxCount == 0) {
>>>> +            return Iterators.emptyIterator();
>>>> +        }
>>>> +
>>>> +        // If we are scoped to a group and have a limit, we have to
>>>> apply
>>>> the limit
>>>> +        // here (inefficient!) otherwise we can apply the limit in the
>>>> query
>>>> +        if (builder.getGroupName() == null) {
>>>> +            if (offset>  0) {
>>>> +                query.setOffset(offset);
>>>> +            }
>>>> +            if (maxCount>  0) {
>>>> +                query.setLimit(maxCount);
>>>> +            }
>>>> +            return toAuthorizables(execute(query)**);
>>>> +        } else {
>>>> +            Iterator<Authorizable>  result =
>>>> toAuthorizables(execute(query)**);
>>>> +            Iterator<Authorizable>  filtered = filter(result,
>>>> builder.getGroupName(), builder.isDeclaredMembersOnly(**));
>>>> +            return ResultIterator.create(offset, maxCount, filtered);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    //----------------------------**-----------------------<
>>>> ConditionVisitor>---
>>>> +    @Override
>>>> +    public void visit(Condition.Node condition) throws
>>>> RepositoryException {
>>>> +        xPath.append('(')
>>>> +                .append("jcr:like(")
>>>> +
>>>>   .append(namePathMapper.**getJcrName(UserConstants.REP_**
>>>> PRINCIPAL_NAME))
>>>> +                .append(",'")
>>>> +                .append(condition.getPattern()**)
>>>> +                .append("')")
>>>> +                .append(" or ")
>>>> +                .append("jcr:like(fn:name(.),'**")
>>>> +                .append(escape(condition.**getPattern()))
>>>> +                .append("')")
>>>> +                .append(')');
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.Property condition) throws
>>>> RepositoryException {
>>>> +        RelationOp relOp = condition.getOp();
>>>> +        if (relOp == RelationOp.EX) {
>>>> +            xPath.append(condition.**getRelPath());
>>>> +        } else if (relOp == RelationOp.LIKE) {
>>>> +            xPath.append("jcr:like(")
>>>> +                    .append(condition.getRelPath()**)
>>>> +                    .append(",'")
>>>> +                    .append(condition.getPattern()**)
>>>> +                    .append("')");
>>>> +        } else {
>>>> +            xPath.append(condition.**getRelPath())
>>>> +                    .append(condition.getOp().**getOp())
>>>> +                    .append(format(condition.**getValue()));
>>>> +        }
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.Contains condition) {
>>>> +        xPath.append("jcr:contains(")
>>>> +                .append(condition.getRelPath()**)
>>>> +                .append(",'")
>>>> +                .append(condition.**getSearchExpr())
>>>> +                .append("')");
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.Impersonation condition) {
>>>> +        xPath.append("@rep:**impersonators='")
>>>> +                .append(condition.getName())
>>>> +                .append('\'');
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.Not condition) throws
>>>> RepositoryException
>>>> {
>>>> +        xPath.append("not(");
>>>> +        condition.getCondition().**accept(this);
>>>> +        xPath.append(')');
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.And condition) throws
>>>> RepositoryException
>>>> {
>>>> +        int count = 0;
>>>> +        for (Condition c : condition) {
>>>> +            xPath.append(count++>  0 ? " and " : "");
>>>> +            c.accept(this);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    @Override
>>>> +    public void visit(Condition.Or condition) throws
>>>> RepositoryException {
>>>> +        int pos = xPath.length();
>>>> +
>>>> +        int count = 0;
>>>> +        for (Condition c : condition) {
>>>> +            xPath.append(count++>  0 ? " or " : "");
>>>> +            c.accept(this);
>>>> +        }
>>>> +
>>>> +        // Surround or clause with parentheses if it contains more than
>>>> one term
>>>> +        if (count>  1) {
>>>> +            xPath.insert(pos, '(');
>>>> +            xPath.append(')');
>>>> +        }
>>>> +    }
>>>> +
>>>> +    //----------------------------**------------------------------**
>>>> --<
>>>> private>---
>>>> +    /**
>>>> +     * Escape {@code string} for matching in jcr escaped node names
>>>> +     *
>>>> +     * @param string string to escape
>>>> +     * @return escaped string
>>>> +     */
>>>> +    @Nonnull
>>>> +    public static String escape(String string) {
>>>> +        StringBuilder result = new StringBuilder();
>>>> +
>>>> +        int k = 0;
>>>> +        int j;
>>>> +        do {
>>>> +            j = string.indexOf('%', k); // split on %
>>>> +            if (j<  0) {
>>>> +                // jcr escape trail
>>>> +
>>>>   result.append(Text.**escapeIllegalJcrChars(string.**substring(k)));
>>>> +            } else if (j>  0&&  string.charAt(j - 1) == '\\') {
>>>>
>>>> +                // literal occurrence of % ->  jcr escape
>>>> +
>>>>   result.append(Text.**escapeIllegalJcrChars(string.**substring(k, j)
>>>> + '%'));
>>>> +            } else {
>>>> +                // wildcard occurrence of % ->  jcr escape all but %
>>>> +
>>>>   result.append(Text.**escapeIllegalJcrChars(string.**substring(k,
>>>> j))).append('%');
>>>> +            }
>>>> +
>>>> +            k = j + 1;
>>>> +        } while (j>= 0);
>>>> +
>>>> +        return result.toString();
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    private String getNtName(Class<? extends Authorizable>  selector) {
>>>> +        String ntName;
>>>> +        if (User.class.isAssignableFrom(**selector)) {
>>>> +            ntName = namePathMapper.getJcrName(**
>>>> UserConstants.NT_REP_USER);
>>>> +        } else if (Group.class.isAssignableFrom(**selector)) {
>>>> +            ntName =
>>>> namePathMapper.getJcrName(**UserConstants.NT_REP_GROUP);
>>>> +        } else {
>>>> +            ntName =
>>>> namePathMapper.getJcrName(**UserConstants.NT_REP_**AUTHORIZABLE);
>>>> +        }
>>>> +        if (ntName == null) {
>>>> +            log.warn("Failed to retrieve JCR name for authorizable node
>>>> type.");
>>>> +            ntName = UserConstants.NT_REP_**AUTHORIZABLE;
>>>> +        }
>>>> +        return ntName;
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    private static String format(Value value) throws
>>>> RepositoryException {
>>>> +        switch (value.getType()) {
>>>> +            case PropertyType.STRING:
>>>> +            case PropertyType.BOOLEAN:
>>>> +                return '\'' + value.getString() + '\'';
>>>> +
>>>> +            case PropertyType.LONG:
>>>> +            case PropertyType.DOUBLE:
>>>> +                return value.getString();
>>>> +
>>>> +            case PropertyType.DATE:
>>>> +                return "xs:dateTime('" + value.getString() + "')";
>>>> +
>>>> +            default:
>>>> +                throw new RepositoryException("Property of type " +
>>>> PropertyType.nameFromValue(**value.getType()) +
>>>> +                        " not supported");
>>>> +        }
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    private static RelationOp getCollation(QueryBuilder.**Direction
>>>> direction) throws RepositoryException {
>>>> +        switch (direction) {
>>>> +            case ASCENDING:
>>>> +                return RelationOp.GT;
>>>> +            case DESCENDING:
>>>> +                return RelationOp.LT;
>>>> +            default:
>>>> +                throw new RepositoryException("Unknown sort order " +
>>>> direction);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    @SuppressWarnings("unchecked")
>>>> +    private static Iterator<Node>  execute(Query query) throws
>>>> RepositoryException {
>>>> +        return query.execute().getNodes();
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    private Iterator<Authorizable>  toAuthorizables(Iterator<Node>
>>>>  nodes) {
>>>> +        Function<Node, Authorizable>  transformer = new Function<Node,
>>>> Authorizable>() {
>>>> +            public Authorizable apply(Node node) {
>>>> +                try {
>>>> +                    return
>>>> userManager.**getAuthorizableByPath(node.**getPath());
>>>> +                } catch (RepositoryException e) {
>>>> +                    log.warn("Cannot create authorizable from node {}",
>>>> node);
>>>> +                    log.debug(e.getMessage(), e);
>>>> +                    return null;
>>>> +                }
>>>> +            }
>>>> +        };
>>>> +
>>>> +        return Iterators.transform(nodes, transformer);
>>>> +    }
>>>> +
>>>> +    @Nonnull
>>>> +    private Iterator<Authorizable>  filter(Iterator<Authorizable>
>>>> authorizables,
>>>> +                                          String groupName,
>>>> +                                          final boolean
>>>> declaredMembersOnly) throws RepositoryException {
>>>> +        Predicate<Authorizable>  predicate;
>>>> +        Authorizable authorizable =
>>>> userManager.getAuthorizable(**groupName);
>>>> +        if (authorizable == null || !authorizable.isGroup()) {
>>>> +            predicate = Predicates.alwaysFalse();
>>>> +        } else {
>>>> +            final Group group = (Group) authorizable;
>>>> +            predicate = new Predicate<Authorizable>() {
>>>> +                public boolean apply(Authorizable authorizable) {
>>>> +                    try {
>>>> +                        return (declaredMembersOnly) ?
>>>> group.isDeclaredMember(**authorizable) : group.isMember(authorizable);
>>>> +                    } catch (RepositoryException e) {
>>>> +                        log.debug("Cannot determine group membership
>>>> for
>>>> {}", authorizable, e.getMessage());
>>>> +                        return false;
>>>> +                    }
>>>> +                }
>>>> +            };
>>>> +        }
>>>> +        return Iterators.filter(**authorizables, predicate);
>>>> +    }
>>>> +}
>>>> \ No newline at end of file
>>>>
>>>>
>>>>
>>>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message