Author: jvazquez
Date: Fri Jan  9 00:59:05 2009
New Revision: 732981

URL: http://svn.apache.org/viewvc?rev=732981&view=rev
Log:
SLING-818: Create a utility class to simplify accessing JSR283 classes in 
Jackrabbit 1.5 
https://issues.apache.org/jira/browse/SLING-818

Added:
    
incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java
Removed:
    
incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/RepositoryUtil.java

Added: 
incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java?rev=732981&view=auto
==============================================================================
--- 
incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java
 (added)
+++ 
incubator/sling/trunk/jcr/base/src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java
 Fri Jan  9 00:59:05 2009
@@ -0,0 +1,228 @@
+package org.apache.sling.jcr.base.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.util.Map;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlException;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlList;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.api.jsr283.security.Privilege;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.jcr.base.internal.PooledSession;
+
+/**
+ * A simple utility class providing utilities with respect to 
+ * access control over repositories.
+ */
+public class AccessControlUtil {
+       
+       // the name of the accessor method for the AccessControlManager
+    private static final String METHOD_GET_ACCESS_CONTROL_MANAGER = 
"getAccessControlManager";
+    // the name of the accessor method for the UserManager
+    private static final String METHOD_GET_USER_MANAGER = "getUserManager";
+    // the name of the accessor method for the PrincipalManager
+    private static final String METHOD_GET_PRINCIPAL_MANAGER = 
"getPrincipalManager";
+    // the name of the JackrabbitAccessControlList method getPath
+    private static final String METHOD_JACKRABBIT_ACL_GET_PATH = "getPath";
+    // the name of the JackrabbitAccessControlList method 
+    private static final String METHOD_JACKRABBIT_ACL_IS_EMPTY = "isEmpty";
+    // the name of the JackrabbitAccessControlList method 
+    private static final String METHOD_JACKRABBIT_ACL_SIZE = "size";
+    // the name of the JackrabbitAccessControlList method 
+    private static final String METHOD_JACKRABBIT_ACL_ADD_ENTRY = "addEntry";
+    
+       
+    // ---------- SessionImpl methods 
-----------------------------------------------------
+    
+       /**
+     * Returns the <code>AccessControlManager</code> for the given
+     * <code>session</code>. If the session does not have a
+     * <code>getAccessControlManager</code> method, a
+     * <code>UnsupportedRepositoryOperationException</code> is thrown. 
Otherwise
+     * the <code>AccessControlManager</code> is returned or if the call fails,
+     * the respective exception is thrown.
+     * 
+     * @param session The JCR Session whose <code>AccessControlManager</code> 
is
+     *            to be returned. If the session is a pooled session, the
+     *            session underlying the pooled session is actually used.
+     * @return The <code>AccessControlManager</code> of the session
+     * @throws UnsupportedRepositoryOperationException If the session has no
+     *             <code>getAccessControlManager</code> method or the exception
+     *             thrown by the method.
+     * @throws RepositoryException Forwarded from the
+     *             <code>getAccessControlManager</code> method call.
+     */
+       public static AccessControlManager getAccessControlManager(Session 
session)
+                                                                               
        throws UnsupportedRepositoryOperationException, RepositoryException {
+                // unwrap a pooled session
+        if (session instanceof PooledSession) {
+            session = ((PooledSession) session).getSession();
+        }
+        
+        return safeInvokeRepoMethod(session, 
METHOD_GET_ACCESS_CONTROL_MANAGER, AccessControlManager.class);
+       }
+       
+       // ---------- JackrabbitSession methods 
-----------------------------------------------
+       
+       /**
+        * Returns the <code>UserManager</code> for the given
+     * <code>session</code>. If the session does not have a
+     * <code>getUserManager</code> method, a
+     * <code>UnsupportedRepositoryOperationException</code> is thrown. 
Otherwise
+     * the <code>UserManager</code> is returned or if the call fails,
+     * the respective exception is thrown.
+        * 
+        * @param session  The JCR Session whose <code>UserManager</code> is
+     *            to be returned. If the session is not a 
<code>JackrabbitSession</code>
+     *            uses reflection to retrive the manager from the repository.
+        * @return The <code>UserManager</code> of the session.
+        * @throws AccessDeniedException If this session is not allowed 
+        *                        to access user data.
+        * @throws UnsupportedRepositoryOperationException If the session has no
+     *            <code>getUserManager</code> method or the exception
+     *            thrown by the method.
+        * @throws RepositoryException Forwarded from the
+     *             <code>getUserManager</code> method call.
+        */
+       public static UserManager getUserManager(Session session) 
+                                                                               
throws AccessDeniedException, UnsupportedRepositoryOperationException, 
RepositoryException {
+               JackrabbitSession jackrabbitSession = 
getJackrabbitSession(session);
+               if(jackrabbitSession != null) {
+                       return jackrabbitSession.getUserManager();
+               } else {
+                       return safeInvokeRepoMethod(session, 
METHOD_GET_USER_MANAGER, UserManager.class);
+               }
+       }
+       
+       /**
+        * Returns the <code>PrincipalManager</code> for the given
+     * <code>session</code>. If the session does not have a
+     * <code>PrincipalManager</code> method, a
+     * <code>UnsupportedRepositoryOperationException</code> is thrown. 
Otherwise
+     * the <code>PrincipalManager</code> is returned or if the call fails,
+     * the respective exception is thrown.
+        * 
+        * @param session  The JCR Session whose <code>PrincipalManager</code> 
is
+     *            to be returned. If the session is not a 
<code>JackrabbitSession</code>
+     *            uses reflection to retrive the manager from the repository.
+        * @return The <code>PrincipalManager</code> of the session.
+        * @throws AccessDeniedException
+        * @throws UnsupportedRepositoryOperationException If the session has 
no 
+        *                              <code>PrincipalManager</code> method or 
the exception
+     *                 thrown by the method.
+        * @throws RepositoryException Forwarded from the
+     *             <code>PrincipalManager</code> method call.
+        */
+       public static PrincipalManager getPrincipalManager(Session session)
+                                                                               
throws AccessDeniedException, UnsupportedRepositoryOperationException, 
RepositoryException {
+               JackrabbitSession jackrabbitSession = 
getJackrabbitSession(session);
+               if(jackrabbitSession != null) {
+                       return jackrabbitSession.getPrincipalManager();
+               } else {
+                       return safeInvokeRepoMethod(session, 
METHOD_GET_PRINCIPAL_MANAGER, PrincipalManager.class);
+               }
+       }
+       
+       // ---------- AccessControlList methods 
-----------------------------------------------
+       
+       /**
+        * Returns the path of the node <code>AccessControlList</code> acl
+        * has been created for.
+        */
+       public static String getPath(AccessControlList acl) throws 
RepositoryException {
+                       return safeInvokeRepoMethod(acl, 
METHOD_JACKRABBIT_ACL_GET_PATH, String.class);
+       }
+       
+       /**
+        * Returns <code>true</code> if <code>AccessControlList</code> acl
+        * does not yet define any entries.
+        */
+    public static boolean isEmpty(AccessControlList acl) throws 
RepositoryException {
+               return safeInvokeRepoMethod(acl, 
METHOD_JACKRABBIT_ACL_IS_EMPTY, Boolean.class);
+    }
+    
+    /**
+     * Returns the number of acl entries or 0 if the acl is empty.
+     */
+    public static int size(AccessControlList acl) throws RepositoryException {
+               return safeInvokeRepoMethod(acl, METHOD_JACKRABBIT_ACL_SIZE, 
Integer.class);
+    }
+    
+    /**
+     * Same as {...@link #addEntry(AccessControlList, Principal, Privilege[], 
boolean, Map)} using
+     * some implementation specific restrictions.
+     */
+    public static boolean addEntry(AccessControlList acl, Principal principal, 
Privilege privileges[], boolean isAllow)
+                                                               throws 
AccessControlException, RepositoryException {
+               return safeInvokeRepoMethod(acl, 
METHOD_JACKRABBIT_ACL_ADD_ENTRY, Boolean.class, principal, privileges, isAllow);
+    }
+    
+    /**
+     * Adds an access control entry to the acl consisting of the specified
+     * <code>principal</code>, the specified <code>privileges</code>, the
+     * <code>isAllow</code> flag and an optional map containing additional
+     * restrictions.
+     * <p/>
+     * This method returns <code>true</code> if this policy was modified,
+     * <code>false</code> otherwise.
+     */
+    @SuppressWarnings("unchecked")
+       public static boolean addEntry(AccessControlList acl, Principal 
principal, Privilege privileges[], boolean isAllow, Map restrictions)
+                                                                               
                                        throws 
UnsupportedRepositoryOperationException, RepositoryException {
+               return safeInvokeRepoMethod(acl, 
METHOD_JACKRABBIT_ACL_ADD_ENTRY, Boolean.class, principal, privileges, isAllow, 
restrictions);
+    }
+
+    // ---------- internal 
-----------------------------------------------------
+    
+    /**
+     * Use reflection to invoke a repository method.
+     */
+    @SuppressWarnings("unchecked")
+       private static <T> T safeInvokeRepoMethod(Object target, String 
methodName, Class<T> returnType, Object... args) 
+                                                                               
                        throws UnsupportedRepositoryOperationException, 
RepositoryException {
+       try {
+                       Method m = target.getClass().getMethod(methodName);
+                       return (T) m.invoke(target, args);
+       } catch (InvocationTargetException ite) {
+            // wraps the exception thrown by the method
+            Throwable t = ite.getCause();
+            if (t instanceof UnsupportedRepositoryOperationException) {
+                throw (UnsupportedRepositoryOperationException) t;
+            } else if (t instanceof AccessDeniedException) {
+                throw (AccessDeniedException) t;
+            } else if (t instanceof AccessControlException) {
+                throw (AccessControlException) t;
+            } else if (t instanceof RepositoryException) {
+                throw (RepositoryException) t;
+            } else if (t instanceof RuntimeException) {
+                throw (RuntimeException) t;
+            } else if (t instanceof Error) {
+                throw (Error) t;
+            } else {
+                throw new RepositoryException(methodName, t);
+            }
+        } catch (Throwable t) {
+            // any other problem is just encapsulated
+            throw new RepositoryException(methodName, t);
+        }
+       }
+       
+    /**
+     * Unwrap the jackrabbit session.
+     */
+       private static JackrabbitSession getJackrabbitSession(Session session) {
+               if (session instanceof JackrabbitSession)
+                       return (JackrabbitSession) session;
+               else 
+                       return null;
+       }
+}


Reply via email to