jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1443616 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/...
Date Thu, 07 Feb 2013 17:29:47 GMT
Author: angela
Date: Thu Feb  7 17:29:47 2013
New Revision: 1443616

URL: http://svn.apache.org/viewvc?rev=1443616&view=rev
Log:
OAK-480 : Authorizable Query

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ResultRowToAuthorizable.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManagerTest.java
    jackrabbit/oak/trunk/oak-jcr/pom.xml
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/FindAuthorizablesTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
Thu Feb  7 17:29:47 2013
@@ -391,7 +391,7 @@ public class UserManagerImpl implements 
 
     private UserQueryManager getQueryManager() {
         if (queryManager == null) {
-            queryManager = new UserQueryManager(this, namePathMapper, config, root.getQueryEngine());
+            queryManager = new UserQueryManager(this, namePathMapper, config, root);
         }
         return queryManager;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ResultRowToAuthorizable.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ResultRowToAuthorizable.java?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ResultRowToAuthorizable.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/ResultRowToAuthorizable.java
Thu Feb  7 17:29:47 2013
@@ -16,12 +16,19 @@
  */
 package org.apache.jackrabbit.oak.security.user.query;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 
 import com.google.common.base.Function;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType;
+import org.apache.jackrabbit.oak.spi.security.user.util.UserUtility;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,20 +40,41 @@ class ResultRowToAuthorizable implements
     private static final Logger log = LoggerFactory.getLogger(ResultRowToAuthorizable.class);
 
     private final UserManager userManager;
+    private final Root root;
+    private final AuthorizableType targetType;
 
-    ResultRowToAuthorizable(UserManager userManager) {
+    ResultRowToAuthorizable(@Nonnull UserManager userManager, @Nonnull Root root,
+                            @Nullable AuthorizableType targetType) {
         this.userManager = userManager;
+        this.root = root;
+        this.targetType = (targetType == null || AuthorizableType.AUTHORIZABLE == targetType)
? null : targetType;
     }
 
     @Override
     public Authorizable apply(ResultRow row) {
         if (row != null) {
-            try {
-                return userManager.getAuthorizableByPath(row.getPath());
-            } catch (RepositoryException e) {
-                log.debug("Failed to access authorizable " + row.getPath());
-            }
+            return getAuthorizable(row.getPath());
         }
         return null;
     }
+
+    //------------------------------------------------------------< private >---
+    @CheckForNull
+    private Authorizable getAuthorizable(String resultPath) {
+        Authorizable authorizable = null;
+        try {
+            Tree tree = root.getTree(resultPath);
+            AuthorizableType type = UserUtility.getType(tree);
+            while (tree != null && type == null) {
+                tree = tree.getParent();
+                type = UserUtility.getType(tree);
+            }
+            if (type != null && (targetType == null || targetType == type)) {
+                authorizable = userManager.getAuthorizableByPath(tree.getPath());
+            }
+        } catch (RepositoryException e) {
+            log.debug("Failed to access authorizable " + resultPath);
+        }
+        return authorizable;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManager.java
Thu Feb  7 17:29:47 2013
@@ -17,13 +17,16 @@
 package org.apache.jackrabbit.oak.security.user.query;
 
 import java.text.ParseException;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
 import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
+import com.google.common.base.Strings;
 import com.google.common.collect.Iterators;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Query;
@@ -31,6 +34,8 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.oak.api.QueryEngine;
 import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType;
@@ -41,7 +46,7 @@ import org.slf4j.LoggerFactory;
 
 /**
  * UserQueryManager... TODO
- *
+ * <p/>
  * TODO OAK-253: replace usage of XPATH
  */
 public class UserQueryManager {
@@ -51,14 +56,14 @@ public class UserQueryManager {
     private final UserManager userManager;
     private final NamePathMapper namePathMapper;
     private final ConfigurationParameters config;
-    private final QueryEngine queryEngine;
+    private final Root root;
 
     public UserQueryManager(UserManager userManager, NamePathMapper namePathMapper,
-                            ConfigurationParameters config, QueryEngine queryEngine) {
+                            ConfigurationParameters config, Root root) {
         this.userManager = userManager;
         this.namePathMapper = namePathMapper;
         this.config = config;
-        this.queryEngine = queryEngine;
+        this.root = root;
     }
 
     /**
@@ -122,11 +127,11 @@ public class UserQueryManager {
                 log.warn("Found bound {} and offset {} in limit. Discarding offset.", bound,
offset);
                 offset = 0;
             }
-            return findAuthorizables(statement.toString(), builder.getMaxCount(), offset);
+            return findAuthorizables(statement.toString(), builder.getMaxCount(), offset,
null);
         } else {
             // filtering by group name included in query -> enforce offset
             // and limit on the result set.
-            Iterator<Authorizable> result = findAuthorizables(statement.toString(),
Long.MAX_VALUE, 0);
+            Iterator<Authorizable> result = findAuthorizables(statement.toString(),
Long.MAX_VALUE, 0, null);
             Predicate groupFilter = new GroupPredicate(userManager,
                     builder.getGroupID(),
                     builder.isDeclaredMembersOnly());
@@ -139,17 +144,17 @@ public class UserQueryManager {
      * Find the authorizables matching the following search parameters within
      * the sub-tree defined by an authorizable tree:
      *
-     * @param relPath A relative path (or a name) pointing to properties within
-     * the tree defined by a given authorizable node.
-     * @param value The property value to look for.
+     * @param relPath          A relative path (or a name) pointing to properties within
+     *                         the tree defined by a given authorizable node.
+     * @param value            The property value to look for.
      * @param authorizableType Filter the search results to only return authorizable
-     * trees of a given type. Passing {@link org.apache.jackrabbit.oak.spi.security.user.AuthorizableType#AUTHORIZABLE}
indicates that
-     * no filtering for a specific authorizable type is desired. However, properties
-     * might still be search in the complete sub-tree of authorizables depending
-     * on the other query parameters.
+     *                         trees of a given type. Passing {@link org.apache.jackrabbit.oak.spi.security.user.AuthorizableType#AUTHORIZABLE}
indicates that
+     *                         no filtering for a specific authorizable type is desired.
However, properties
+     *                         might still be search in the complete sub-tree of authorizables
depending
+     *                         on the other query parameters.
      * @return An iterator of authorizable trees that match the specified
-     * search parameters and filters or an empty iterator if no result can be
-     * found.
+     *         search parameters and filters or an empty iterator if no result can be
+     *         found.
      * @throws javax.jcr.RepositoryException If an error occurs.
      */
     @Nonnull
@@ -162,26 +167,25 @@ public class UserQueryManager {
      * Find the authorizables matching the following search parameters within
      * the sub-tree defined by an authorizable tree:
      *
-     *
-     * @param relPath A relative path (or a name) pointing to properties within
-     * the tree defined by a given authorizable node.
-     * @param value The property value to look for.
+     * @param relPath          A relative path (or a name) pointing to properties within
+     *                         the tree defined by a given authorizable node.
+     * @param value            The property value to look for.
      * @param authorizableType Filter the search results to only return authorizable
-     * trees of a given type. Passing {@link org.apache.jackrabbit.oak.spi.security.user.AuthorizableType#AUTHORIZABLE}
indicates that
-     * no filtering for a specific authorizable type is desired. However, properties
-     * might still be search in the complete sub-tree of authorizables depending
-     * on the other query parameters.
-     * @param exact A boolean flag indicating if the value must match exactly or not.s
+     *                         trees of a given type. Passing {@link org.apache.jackrabbit.oak.spi.security.user.AuthorizableType#AUTHORIZABLE}
indicates that
+     *                         no filtering for a specific authorizable type is desired.
However, properties
+     *                         might still be search in the complete sub-tree of authorizables
depending
+     *                         on the other query parameters.
+     * @param exact            A boolean flag indicating if the value must match exactly
or not.s
      * @return An iterator of authorizable trees that match the specified
-     * search parameters and filters or an empty iterator if no result can be
-     * found.
+     *         search parameters and filters or an empty iterator if no result can be
+     *         found.
      * @throws javax.jcr.RepositoryException If an error occurs.
      */
     @Nonnull
     public Iterator<Authorizable> findAuthorizables(String relPath, String value,
                                                     AuthorizableType authorizableType, boolean
exact) throws RepositoryException {
         String statement = buildXPathStatement(relPath, value, authorizableType, exact);
-        return findAuthorizables(statement, Long.MAX_VALUE, 0);
+        return findAuthorizables(statement, Long.MAX_VALUE, 0, authorizableType);
     }
 
     //------------------------------------------------------------< private >---
@@ -203,12 +207,22 @@ public class UserQueryManager {
             ntName = null;
         } else {
             propName = Text.getName(relPath);
-            path = Text.getRelativeParent(relPath, 1);
+            String[] segments = Text.explode(relPath, '/', false);
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < segments.length - 1; i++) {
+                if (!PathUtils.denotesCurrent(segments[i])) {
+                    if (i > 0) {
+                        sb.append('/');
+                    }
+                    sb.append(segments[i]);
+                }
+            }
+            path = Strings.emptyToNull(sb.toString());
             ntName = QueryUtil.getNodeTypeName(type);
         }
 
         stmt.append("//");
-        if (path != null && !path.isEmpty()) {
+        if (path != null) {
             stmt.append(path);
         } else if (ntName != null) {
             stmt.append("element(*,").append(ntName).append(')');
@@ -238,15 +252,40 @@ public class UserQueryManager {
     }
 
     @Nonnull
-    private Iterator<Authorizable> findAuthorizables(String statement, long limit,
-                                                    long offset) throws RepositoryException
{
+    private Iterator<Authorizable> findAuthorizables(@Nonnull String statement,
+                                                     long limit,
+                                                     long offset,
+                                                     @Nullable AuthorizableType type) throws
RepositoryException {
         try {
+            QueryEngine queryEngine = root.getQueryEngine();
             Iterable<? extends ResultRow> resultRows = queryEngine.executeQuery(statement,
javax.jcr.query.Query.XPATH, limit, offset, null, namePathMapper).getRows();
-            Iterator<Authorizable> authorizables = Iterators.transform(resultRows.iterator(),
new ResultRowToAuthorizable(userManager));
-            return Iterators.filter(authorizables, Predicates.<Object>notNull());
+            Iterator<Authorizable> authorizables = Iterators.transform(resultRows.iterator(),
new ResultRowToAuthorizable(userManager, root, type));
+            return Iterators.filter(authorizables, new UniqueResultPredicate());
         } catch (ParseException e) {
             log.warn("Invalid user query: " + statement, e);
             throw new RepositoryException(e);
         }
     }
+
+    /**
+     * Predicate asserting that a given user/group is only included once in the
+     * result set.
+     */
+    private static final class UniqueResultPredicate implements Predicate<Authorizable>
{
+
+        private final Set<String> authorizableIds = new HashSet<String>();
+
+        @Override
+        public boolean apply(@Nullable Authorizable input) {
+            try {
+                if (input != null && !authorizableIds.contains(input.getID())) {
+                    authorizableIds.add(input.getID());
+                    return true;
+                }
+            } catch (RepositoryException e) {
+                log.debug("Failed to retrieve authorizable ID " + e.getMessage());
+            }
+            return false;
+        }
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManagerTest.java?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManagerTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/query/UserQueryManagerTest.java
Thu Feb  7 17:29:47 2013
@@ -53,7 +53,7 @@ public class UserQueryManagerTest extend
         user = userMgr.createUser("testUser", "pw");
         root.commit();
 
-        queryMgr = new UserQueryManager(userMgr, namePathMapper, getUserConfiguration().getConfigurationParameters(),
root.getQueryEngine());
+        queryMgr = new UserQueryManager(userMgr, namePathMapper, getUserConfiguration().getConfigurationParameters(),
root);
 
         valueFactory = new ValueFactoryImpl(root.getBlobFactory(), namePathMapper);
         propertyName = "testProperty";

Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Thu Feb  7 17:29:47 2013
@@ -222,7 +222,6 @@
       org.apache.jackrabbit.test.api.observation.AddEventListenerTest#testUUID
       org.apache.jackrabbit.test.api.observation.LockingTest#testAddLockToNode
       org.apache.jackrabbit.test.api.observation.LockingTest#testRemoveLockFromNode
-      org.apache.jackrabbit.oak.jcr.security.user.FindAuthorizablesTest#testFindAuthorizableByRelativePath
    <!-- OAK-343 -->
       org.apache.jackrabbit.oak.jcr.security.user.GroupTest#testCyclicGroups2           
                <!-- OAK-615 -->
       org.apache.jackrabbit.oak.jcr.version.VersionHistoryTest#testGetVersionHistoryFromNode
            <!-- OAK-601 -->
       org.apache.jackrabbit.oak.jcr.version.VersionHistoryTest#testGetVersionHistory    
                <!-- OAK-602 -->

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/FindAuthorizablesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/FindAuthorizablesTest.java?rev=1443616&r1=1443615&r2=1443616&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/FindAuthorizablesTest.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/FindAuthorizablesTest.java
Thu Feb  7 17:29:47 2013
@@ -80,7 +80,7 @@ public class FindAuthorizablesTest exten
 
         try {
             auth = userMgr.createGroup(p);
-            auth.setProperty("E-Mail", new Value[] { superuser.getValueFactory().createValue("anyVal")});
+            auth.setProperty("E-Mail", new Value[]{superuser.getValueFactory().createValue("anyVal")});
             superuser.save();
 
             boolean found = false;
@@ -109,18 +109,17 @@ public class FindAuthorizablesTest exten
 
         try {
             auth = userMgr.createGroup(p);
-            Value[] vs = new Value[] {
+            Value[] vs = new Value[]{
                     superuser.getValueFactory().createValue("v1"),
                     superuser.getValueFactory().createValue("v2")
             };
-            superuser.save();
-
             String relPath = "relPath/" + propertyName1;
             String relPath2 = "another/" + propertyName1;
             String relPath3 = "relPath/relPath/" + propertyName1;
             auth.setProperty(relPath, vs);
             auth.setProperty(relPath2, vs);
             auth.setProperty(relPath3, superuser.getValueFactory().createValue("v3"));
+            superuser.save();
 
             // relPath = "prop1", v = "v1" -> should find the target group
             Iterator<Authorizable> result = userMgr.findAuthorizables(propertyName1,
"v1");
@@ -128,7 +127,7 @@ public class FindAuthorizablesTest exten
             assertEquals(auth.getID(), result.next().getID());
             assertFalse("expected no more results", result.hasNext());
 
-            // relPath = "prop1", v = "v1" -> should find the target group
+            // relPath = "prop1", v = "v3" -> should find the target group
             result = userMgr.findAuthorizables(propertyName1, "v3");
             assertTrue("expected result", result.hasNext());
             assertEquals(auth.getID(), result.next().getID());
@@ -163,7 +162,7 @@ public class FindAuthorizablesTest exten
             superuser.save();
 
             boolean found = false;
-            Iterator<Authorizable> it = userMgr.findAuthorizables("./"+UserConstants.REP_PRINCIPAL_NAME,
null, UserManager.SEARCH_TYPE_USER);
+            Iterator<Authorizable> it = userMgr.findAuthorizables("./" + UserConstants.REP_PRINCIPAL_NAME,
null, UserManager.SEARCH_TYPE_USER);
             while (it.hasNext() && !found) {
                 User nu = (User) it.next();
                 found = nu.getID().equals(uid);



Mime
View raw message