Author: fmeschbe
Date: Thu Aug 12 15:44:46 2010
New Revision: 984840

URL: http://svn.apache.org/viewvc?rev=984840&view=rev
Log:
SLING-1646 Add unit tests for new ResourceResolver methods
SLING-1647 Add JCR specific resource resolver creation constants; adapt the 
implementation classes and add/adapt unit tests

Modified:
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
    
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
    
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
    
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
    
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
 Thu Aug 12 15:44:46 2010
@@ -28,8 +28,8 @@ public class JcrResourceConstants {
     /**
      * The namespace URI used by Sling JCR for items and node types used by
      * Sling (value is "http://sling.apache.org/jcr/sling/1.0";). This URI is
-     * ensured to be mapped to the Sling namespace prefix <em>sling</em> for
-     * any session used by the JCR Resource bundle through the
+     * ensured to be mapped to the Sling namespace prefix <em>sling</em> for 
any
+     * session used by the JCR Resource bundle through the
      * <code>Sling-Namespaces</code> bundle manifest header.
      */
     public static final String SLING_NAMESPACE_URI = 
SlingConstants.NAMESPACE_URI_ROOT
@@ -52,4 +52,58 @@ public class JcrResourceConstants {
      * the primary node type is used as the resource super type.
      */
     public static final String SLING_RESOURCE_SUPER_TYPE_PROPERTY = 
"sling:resourceSuperType";
+
+    /**
+     * The name of the property providing the JCR credentials to be used by the
+     * resource resolver factory method instead of the <code>user.name</code>
+     * and <code>user.password</code> properties. If this propery is provided
+     * and set to an object of type <code>javax.jcr.Credentials</code> the
+     * <code>user.name</code> property is ignored.
+     * <p>
+     * This property is ignored by the
+     * {...@link 
org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)}
+     * method or if the authentication info has a
+     * {...@link #AUTHENTICATION_INFO_SESSION} property set to a
+     * <code>javax.jcr.Session</code> object.
+     * <p>
+     * The type of this property, if present, is
+     * <code>javax.jcr.Credentials</code>.
+     *
+     * @since 2.1
+     * @see 
org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
+     */
+    public static final String AUTHENTICATION_INFO_CREDENTIALS = 
"user.jcr.credentials";
+
+    /**
+     * The name of the authentication info property containing the workspace
+     * name to which the JCR based resource resolver should provide access.
+     * <p>
+     * The type of this property, if present, is <code>String</code>.
+     *
+     * @since 2.1
+     */
+    public static final String AUTHENTICATION_INFO_WORKSPACE = 
"user.jcr.workspace";
+
+    /**
+     * The name of the authentication info property containing a JCR Session to
+     * which a JCR based resource resolver should provide access. If this
+     * property is set in the authentication info map, all other properties are
+     * ignored for the creation of the resource resolver with the exception of
+     * the <code>user.impersonation</code> which is still respected.
+     * <p>
+     * The session provided by as this property and used as the basis of newly
+     * created resource resolver must not be logged out before the resource
+     * resolver is closed. On the other closing the resource resolver not 
logout
+     * this session.
+     * <p>
+     * This property is ignored by the
+     * {...@link 
org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)}
+     * method.
+     * <p>
+     * The type of this property, if present, is 
<code>javax.jcr.Session</code>.
+     *
+     * @since 2.1
+     */
+    public static final String AUTHENTICATION_INFO_SESSION = 
"user.jcr.session";
+
 }

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
 Thu Aug 12 15:44:46 2010
@@ -21,6 +21,7 @@ package org.apache.sling.jcr.resource;
 import javax.jcr.Session;
 
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 
 /**
  * The <code>JcrResourceResolverFactory</code> interface defines the service
@@ -31,17 +32,31 @@ import org.apache.sling.api.resource.Res
  * is implemented by this bundle and the implementation registered as a service
  * for use by client applications.
  *
- * @deprecated Use the {...@link 
org.apache.sling.api.resource.ResourceResolverFactory}
+ * @deprecated Since 2.1. Use the
+ *             {...@link org.apache.sling.api.resource.ResourceResolverFactory}
  */
 @Deprecated
-public interface JcrResourceResolverFactory {
+public interface JcrResourceResolverFactory extends ResourceResolverFactory {
 
     /**
      * Returns a <code>ResourceResolver</code> for the given session. Calling
      * this method repeatedly returns a new instance on each call.
+     * <p>
+     * This method is equivalent to:
      *
-     * @param session The JCR <code>Session</code> used by the created
-     *            resource manager to access the repository.
+     * <pre>
+     * Map&lt;String, Object&gt; authInfo = new HashMap&lt;String, 
Object&gt;();
+     * authInfo.put(SESSION, session);
+     * return getResourceResolver(authInfo);
+     * </pre>
+     * <p>
+     * <b>Note:</b> Closing the <code>ResourceResolver</code> returned by this
+     * method will <b>not</b> close the provided <code>Session</code> ! 
Likewise
+     * the provided <code>Session</code> should not be logged out before 
closing
+     * the returned <code>ResourceResolver</code>.
+     *
+     * @param session The JCR <code>Session</code> used by the created resource
+     *            manager to access the repository.
      */
     ResourceResolver getResourceResolver(Session session);
 

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
 Thu Aug 12 15:44:46 2010
@@ -37,6 +37,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.jcr.resource.JcrResourceConstants;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
@@ -87,8 +88,9 @@ public class JcrResourceListener impleme
     throws LoginException, RepositoryException {
         this.workspaceName = workspaceName;
         final Map<String,Object> authInfo = new HashMap<String,Object>();
-        if ( workspaceName != null ) {
-            authInfo.put(JcrResourceResolverFactoryImpl.AUTH_INFO_WORKSPACE, 
workspaceName);
+        if (workspaceName != null) {
+            authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE,
+                workspaceName);
         }
         this.resolver = factory.getAdministrativeResourceResolver(authInfo);
         this.session = resolver.adaptTo(Session.class);
@@ -158,7 +160,7 @@ public class JcrResourceListener impleme
             // paths from changed and added
             addedEvents.remove(e.getKey());
             changedEvents.remove(e.getKey());
-          
+
             // Launch an OSGi event
             final Dictionary<String, String> properties = new 
Hashtable<String, String>();
             properties.put(SlingConstants.PROPERTY_PATH, 
createWorkspacePath(e.getKey()));
@@ -169,7 +171,7 @@ public class JcrResourceListener impleme
         // add is stronger than changed
         for (Entry<String, Event> e : addedEvents.entrySet()) {
             changedEvents.remove(e.getKey());
-            
+
             // Launch an OSGi event.
             sendOsgiEvent(e.getKey(), e.getValue(), 
SlingConstants.TOPIC_RESOURCE_ADDED, localEA);
         }

Modified: 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
 Thu Aug 12 15:44:46 2010
@@ -20,6 +20,7 @@ package org.apache.sling.jcr.resource.in
 
 import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -37,10 +38,12 @@ import org.apache.commons.collections.bi
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.ResourceDecorator;
 import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.resource.JcrResourceConstants;
 import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
 import org.apache.sling.jcr.resource.internal.helper.MapEntries;
 import org.apache.sling.jcr.resource.internal.helper.Mapping;
@@ -84,22 +87,6 @@ import org.slf4j.LoggerFactory;
 public class JcrResourceResolverFactoryImpl implements
         JcrResourceResolverFactory, ResourceResolverFactory {
 
-    /**
-     * The name of the authentication info property containing the workspace 
name.
-     * This is only used internally and should never be used from anyone 
outside
-     * this bundle as we might change this mechanism.
-     */
-    static final String AUTH_INFO_WORKSPACE = "internal.user.jcr.workspace";
-
-    /**
-     * The name of the session attribute which is set if the session created by
-     * the {...@link #handleSecurity(HttpServletRequest, HttpServletResponse)}
-     * method is an impersonated session. The value of this attribute is the
-     * name of the primary user authenticated with the credentials extracted
-     * from the request using the authenitcation handler.
-     */
-    private static final String SESSION_ATTR_IMPERSONATOR = "impersonator";
-
     public final static class ResourcePattern {
         public final Pattern pattern;
 
@@ -245,8 +232,113 @@ public class JcrResourceResolverFactoryI
      *
      * @see 
org.apache.sling.jcr.resource.JcrResourceResolverFactory#getResourceResolver(javax.jcr.Session)
      */
-    public JcrResourceResolver getResourceResolver(Session session) {
-        return getResourceResolver(session, true, null);
+    public ResourceResolver getResourceResolver(Session session) {
+        Map<String, Object> authInfo = new HashMap<String, Object>(1);
+        authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, 
session);
+        try {
+            return getResourceResolver(authInfo);
+        } catch (LoginException le) {
+            // we don't expect a LoginException here because just a
+            // ResourceResolver wrapping the given session is to be created.
+            throw new InternalError("Unexpected LoginException");
+        }
+    }
+
+    // ---------- Resource Resolver Factory 
------------------------------------
+
+    /**
+     * @see 
org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
+     */
+    public ResourceResolver getAdministrativeResourceResolver(
+            final Map<String, Object> authenticationInfo) throws 
LoginException {
+        return getResourceResolverInternal(authenticationInfo, true);
+    }
+
+    /**
+     * @see 
org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
+     */
+    public ResourceResolver getResourceResolver(
+            final Map<String, Object> authenticationInfo) throws 
LoginException {
+        return getResourceResolverInternal(authenticationInfo, false);
+    }
+
+    /**
+     * Create a new ResourceResolver wrapping a Session object. Carries map of
+     * authentication info in order to create a new resolver as needed.
+     */
+    private ResourceResolver getResourceResolverInternal(
+            final Map<String, Object> authenticationInfo, final boolean 
isAdmin)
+            throws LoginException {
+
+        // by default any session used by the resource resolver returned is
+        // closed when the resource resolver is closed
+        boolean logoutSession = true;
+
+        // derive the session to be used
+        Session session;
+        try {
+            final String workspace = getWorkspace(authenticationInfo);
+            if (isAdmin) {
+                // requested admin session to any workspace (or default)
+                session = getRepository().loginAdministrative(workspace);
+
+            } else {
+
+                session = getSession(authenticationInfo);
+                if (session == null) {
+                    // requested non-admin session to any workspace (or 
default)
+                    final Credentials credentials = 
getCredentials(authenticationInfo);
+                    session = getRepository().login(credentials, workspace);
+
+                } else if (workspace != null) {
+                    // session provided by map; but requested a different
+                    // workspace impersonate can only change the user not 
switch
+                    // the workspace as a workaround we login to the requested
+                    // workspace with admin and then switch to the provided
+                    // session's user (if required)
+                    Session tmpSession = null;
+                    try {
+                        tmpSession = getRepository().loginAdministrative(
+                            workspace);
+                        if 
(tmpSession.getUserID().equals(session.getUserID())) {
+                            session = tmpSession;
+                            tmpSession = null;
+                        } else {
+                            session = tmpSession.impersonate(new 
SimpleCredentials(
+                                session.getUserID(), new char[0]));
+                        }
+                    } finally {
+                        if (tmpSession != null) {
+                            tmpSession.logout();
+                        }
+                    }
+
+                } else {
+                    // session provided; no special workspace; just make sure
+                    // the session is not logged out when the resolver is 
closed
+                    logoutSession = false;
+                }
+            }
+        } catch (RepositoryException re) {
+            throw getLoginException(re);
+        }
+
+        session = handleImpersonation(session, authenticationInfo, 
logoutSession);
+
+        final JcrResourceProviderEntry sessionRoot = new 
JcrResourceProviderEntry(
+            session, rootProviderEntry, this.getDynamicClassLoader(),
+            useMultiWorkspaces);
+
+        if (logoutSession) {
+            return new JcrResourceResolver(sessionRoot, this, isAdmin,
+                authenticationInfo, useMultiWorkspaces);
+        }
+
+        return new JcrResourceResolver(sessionRoot, this, isAdmin,
+            authenticationInfo, useMultiWorkspaces) {
+            protected void closeSession() {
+            }
+        };
     }
 
     // ---------- Implementation helpers --------------------------------------
@@ -473,52 +565,6 @@ public class JcrResourceResolverFactoryI
         return repository;
     }
 
-    // ---------- Resource Resolver Factory 
------------------------------------
-
-    /**
-     * @see 
org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
-     */
-    public JcrResourceResolver getAdministrativeResourceResolver(final 
Map<String, Object> authenticationInfo)
-    throws LoginException {
-        final String workspace = getWorkspace(authenticationInfo);
-        final Session session;
-        try {
-            session = this.getRepository().loginAdministrative(workspace);
-        } catch (RepositoryException re) {
-            throw getLoginException(re);
-        }
-        return this.getResourceResolver(handleSudo(session, 
authenticationInfo), true, authenticationInfo);
-    }
-
-    /**
-     * Create a new ResourceResolver wrapping a Session object. Carries map of
-     * authentication info in order to create a new resolver as needed.
-     */
-    private JcrResourceResolver getResourceResolver(final Session session,
-                                                 final boolean isAdmin,
-                                                 final Map<String, Object> 
authenticationInfo) {
-        final JcrResourceProviderEntry sessionRoot = new 
JcrResourceProviderEntry(
-            session, rootProviderEntry, this.getDynamicClassLoader(), 
useMultiWorkspaces);
-
-        return new JcrResourceResolver(sessionRoot, this, isAdmin, 
authenticationInfo, useMultiWorkspaces);
-    }
-
-    /**
-     * @see 
org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
-     */
-    public JcrResourceResolver getResourceResolver(final Map<String, Object> 
authenticationInfo)
-    throws LoginException {
-        final Credentials credentials = getCredentials(authenticationInfo);
-        final String workspace = getWorkspace(authenticationInfo);
-        final Session session;
-        try {
-            session = this.getRepository().login(credentials, workspace);
-        } catch (RepositoryException re) {
-            throw getLoginException(re);
-        }
-        return this.getResourceResolver(handleSudo(session, 
authenticationInfo), false, authenticationInfo);
-    }
-
     /**
      * Create a login exception from a repository exception.
      * If the repository exception is a  {...@link javax.jcr.LoginException}
@@ -551,6 +597,23 @@ public class JcrResourceResolverFactoryI
     }
 
     /**
+     * Returns the session provided as the user.jcr.session property of the
+     * <code>authenticationInfo</code> map or <code>null</code> if the
+     * property is not contained in the map or is not a 
<code>javax.jcr.Session</code>.
+     * @param authenticationInfo Optional authentication info.
+     * @return The user.jcr.session property or <code>null</code>
+     */
+    private Session getSession(final Map<String, Object> authenticationInfo) {
+        if (authenticationInfo != null) {
+            final Object sessionObject = 
authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_SESSION);
+            if (sessionObject instanceof Session) {
+                return (Session) sessionObject;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Return the workspace name.
      * If the workspace name is provided, it is returned, otherwise
      * <code>null</code> is returned.
@@ -558,8 +621,11 @@ public class JcrResourceResolverFactoryI
      * @return The configured workspace name or <code>null</code>
      */
     private String getWorkspace(final Map<String, Object> authenticationInfo) {
-        if ( authenticationInfo != null ) {
-            return (String) authenticationInfo.get(AUTH_INFO_WORKSPACE);
+        if (authenticationInfo != null) {
+            final Object workspaceObject = 
authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE);
+            if (workspaceObject instanceof String) {
+                return (String) workspaceObject;
+            }
         }
         return null;
     }
@@ -572,39 +638,47 @@ public class JcrResourceResolverFactoryI
      * @return The configured sudo user information or <code>null</code>
      */
     private String getSudoUser(final Map<String, Object> authenticationInfo) {
-        if ( authenticationInfo != null ) {
-            return (String) 
authenticationInfo.get(ResourceResolverFactory.SUDO_USER_ID);
+        if (authenticationInfo != null) {
+            final Object sudoObject = 
authenticationInfo.get(ResourceResolverFactory.USER_IMPERSONATION);
+            if (sudoObject instanceof String) {
+                return (String) sudoObject;
+            }
         }
         return null;
     }
 
     /**
-     * Handle the sudo if configured.
-     * If the authentication info does not contain a sudo info, this method 
simply returns
-     * the passed in session.
-     * If a sudo user info is available, the session is tried to be 
impersonated. The new
-     * impersonated session is returned. The original session is closed. The 
session is
-     * also closed if the impersonation fails.
+     * Handle the sudo if configured. If the authentication info does not
+     * contain a sudo info, this method simply returns the passed in session. 
If
+     * a sudo user info is available, the session is tried to be impersonated.
+     * The new impersonated session is returned. The original session is 
closed.
+     * The session is also closed if the impersonation fails.
+     *
      * @param session The session.
      * @param authenticationInfo The optional authentication info.
+     * @param logoutSession whether to logout the <code>session</code> after
+     *            impersonation or not.
      * @return The original session or impersonated session.
      * @throws LoginException If something goes wrong.
      */
-    private Session handleSudo(final Session session,
-            final Map<String, Object> authenticationInfo) throws 
LoginException {
+    private Session handleImpersonation(final Session session,
+            final Map<String, Object> authenticationInfo, boolean 
logoutSession)
+            throws LoginException {
         final String sudoUser = getSudoUser(authenticationInfo);
         if (sudoUser != null && !session.getUserID().equals(sudoUser)) {
             try {
                 final SimpleCredentials creds = new SimpleCredentials(sudoUser,
                     new char[0]);
                 copyAttributes(creds, authenticationInfo);
-                creds.setAttribute(SESSION_ATTR_IMPERSONATOR,
+                creds.setAttribute(ResourceResolver.USER_IMPERSONATOR,
                     session.getUserID());
                 return session.impersonate(creds);
             } catch (RepositoryException re) {
                 throw getLoginException(re);
             } finally {
-                session.logout();
+                if (logoutSession) {
+                    session.logout();
+                }
             }
         }
         return session;
@@ -628,15 +702,15 @@ public class JcrResourceResolverFactoryI
             return null;
         }
 
-        final Object credentialsObject = 
authenticationInfo.get("user.jcr.credentials");
+        final Object credentialsObject = 
authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS);
         if (credentialsObject instanceof Credentials) {
             return (Credentials) credentialsObject;
         }
 
         // otherwise try to create SimpleCredentials if the userId is set
-        final Object userId = authenticationInfo.get("user.name");
+        final Object userId = authenticationInfo.get(USER);
         if (userId instanceof String) {
-            final Object password = authenticationInfo.get("user.password");
+            final Object password = authenticationInfo.get(PASSWORD);
             final SimpleCredentials credentials = new SimpleCredentials(
                 (String) userId, ((password instanceof char[])
                         ? (char[]) password
@@ -669,10 +743,26 @@ public class JcrResourceResolverFactoryI
         final Iterator<Map.Entry<String, Object>> i = 
source.entrySet().iterator();
         while (i.hasNext()) {
             final Map.Entry<String, Object> current = i.next();
-            if (!"user.password".equals(current.getKey())
-                && !"user.jcr.credentials".equals(current.getKey())) {
+            if (isAttributeVisible(current.getKey())) {
                 target.setAttribute(current.getKey(), current.getValue());
             }
         }
     }
+
+    /**
+     * Returns <code>true</code> unless the name is
+     * <code>user.jcr.credentials</code> (
+     * {...@link JcrResourceConstants#AUTHENTICATION_INFO_CREDENTIALS}) or 
contains
+     * the string <code>password</code> as in <code>user.password</code> (
+     * {...@link 
org.apache.sling.api.resource.ResourceResolverFactory#PASSWORD})
+     *
+     * @param name The name to check whether it is visible or not
+     * @return <code>true</code> if the name is assumed visible
+     * @throws NullPointerException if <code>name</code> is <code>null</code>
+     */
+    static boolean isAttributeVisible(final String name) {
+        return 
!name.equals(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS)
+            && !name.contains("password");
+    }
+
 }
\ No newline at end of file

Modified: 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
 Thu Aug 12 15:44:46 2010
@@ -23,13 +23,16 @@ import java.lang.reflect.Field;
 import java.security.Principal;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 
+import javax.jcr.Credentials;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.Node;
 import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.Cookie;
@@ -42,6 +45,7 @@ import org.apache.sling.api.SlingConstan
 import org.apache.sling.api.resource.NonExistingResource;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.SyntheticResource;
 import org.apache.sling.api.resource.ValueMap;
@@ -243,7 +247,7 @@ public class JcrResourceResolverTest ext
         assertEquals("Path must be the the root path", "/", res2.getPath());
     }
 
-    public void testClone_based_on_anonymous() throws Exception {
+    public void test_clone_based_on_anonymous() throws Exception {
         final ResourceResolver anon0 = resFac.getResourceResolver((Map<String, 
Object>) null);
         final Session anon0Session = anon0.adaptTo(Session.class);
         assertEquals("anonymous", anon0.getUserID());
@@ -258,8 +262,8 @@ public class JcrResourceResolverTest ext
 
         // same workspace but admin user
         final Map<String, Object> admin0Cred = new HashMap<String, Object>();
-        admin0Cred.put("user.name", "admin");
-        admin0Cred.put("user.password", "admin".toCharArray());
+        admin0Cred.put(ResourceResolverFactory.USER, "admin");
+        admin0Cred.put(ResourceResolverFactory.PASSWORD, 
"admin".toCharArray());
         final ResourceResolver admin0 = anon0.clone(admin0Cred);
         final Session admin0Session = admin0.adaptTo(Session.class);
         assertEquals("admin", admin0.getUserID());
@@ -269,7 +273,7 @@ public class JcrResourceResolverTest ext
 
         // same user but different workspace
         final Map<String, Object> anon2Cred = new HashMap<String, Object>();
-        anon2Cred.put("internal.user.jcr.workspace", "ws2");
+        anon2Cred.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE, 
"ws2");
         final ResourceResolver anon2 = anon0.clone(anon2Cred);
         final Session anon2Session = anon2.adaptTo(Session.class);
         assertEquals("anonymous", anon2.getUserID());
@@ -278,9 +282,10 @@ public class JcrResourceResolverTest ext
 
         // different user and workspace
         final Map<String, Object> admin1Cred = new HashMap<String, Object>();
-        admin1Cred.put("user.name", "admin");
-        admin1Cred.put("user.password", "admin".toCharArray());
-        admin1Cred.put("internal.user.jcr.workspace", "ws2");
+        admin1Cred.put(ResourceResolverFactory.USER, "admin");
+        admin1Cred.put(ResourceResolverFactory.PASSWORD, 
"admin".toCharArray());
+        admin1Cred.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE,
+            "ws2");
         final ResourceResolver admin1 = anon0.clone(admin1Cred);
         final Session admin1Session = admin1.adaptTo(Session.class);
         assertEquals("admin", admin1.getUserID());
@@ -290,7 +295,7 @@ public class JcrResourceResolverTest ext
         anon0.close();
     }
 
-    public void testClone_based_on_admin() throws Exception {
+    public void test_clone_based_on_admin() throws Exception {
         final ResourceResolver admin0 = 
resFac.getAdministrativeResourceResolver((Map<String, Object>) null);
         final Session admin0Session = admin0.adaptTo(Session.class);
         assertEquals("admin", admin0.getUserID());
@@ -305,7 +310,7 @@ public class JcrResourceResolverTest ext
 
         // same workspace but anonymous user
         final Map<String, Object> anon0Cred = new HashMap<String, Object>();
-        anon0Cred.put("user.name", "anonymous");
+        anon0Cred.put(ResourceResolverFactory.USER, "anonymous");
         final ResourceResolver anon0 = admin0.clone(anon0Cred);
         final Session anon0Session = anon0.adaptTo(Session.class);
         assertEquals("anonymous", anon0.getUserID());
@@ -315,7 +320,8 @@ public class JcrResourceResolverTest ext
 
         // same user but different workspace
         final Map<String, Object> admin2Cred = new HashMap<String, Object>();
-        admin2Cred.put("internal.user.jcr.workspace", "ws2");
+        admin2Cred.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE,
+            "ws2");
         final ResourceResolver admin2 = admin0.clone(admin2Cred);
         final Session admin2Session = admin2.adaptTo(Session.class);
         assertEquals("admin", admin2.getUserID());
@@ -324,15 +330,109 @@ public class JcrResourceResolverTest ext
 
         // different user and workspace
         final Map<String, Object> anon1Cred = new HashMap<String, Object>();
-        anon1Cred.put("user.name", "anonymous");
-        anon1Cred.put("internal.user.jcr.workspace", "ws2");
+        anon1Cred.put(ResourceResolverFactory.USER, "anonymous");
+        anon1Cred.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE, 
"ws2");
         final ResourceResolver anon1 = admin0.clone(anon1Cred);
         final Session anon1Session = anon1.adaptTo(Session.class);
         assertEquals("anonymous", anon1.getUserID());
         assertEquals("ws2", anon1Session.getWorkspace().getName());
         anon1.close();
 
-        anon0.close();
+        admin0.close();
+    }
+
+    public void test_attributes_from_session() throws Exception {
+        // test assumes admin password is admin (which is default)
+
+        final Credentials creds0 = new SimpleCredentials("admin",
+            "admin".toCharArray());
+        final Session session0 = getRepository().login(creds0);
+        final ResourceResolver resolver0 = 
resFac.getResourceResolver(session0);
+
+        final Iterator<String> attrNames0 = resolver0.getAttributeNames();
+        assertTrue("Expected one attribute", attrNames0.hasNext());
+        final String attrName0 = attrNames0.next();
+        assertEquals("Expected attribute name to address session",
+            JcrResourceConstants.AUTHENTICATION_INFO_SESSION, attrName0);
+        assertFalse("Expected no more attributes", attrNames0.hasNext());
+        assertEquals("Expected session attribute to be the session", session0,
+            resolver0.getAttribute(attrName0));
+
+        assertEquals("Expected no Session attributes", 0,
+            session0.getAttributeNames().length);
+
+        resolver0.close();
+        assertTrue("Expect session to still be live after resolver close",
+            session0.isLive());
+        session0.logout();
+
+        final SimpleCredentials creds1 = new SimpleCredentials("admin",
+            "admin".toCharArray());
+        creds1.setAttribute("testAttributeString", "AStringValue");
+        creds1.setAttribute("testAttributeNumber", 999);
+        final Session session1 = getRepository().login(creds1);
+        final ResourceResolver resolver1 = 
resFac.getResourceResolver(session1);
+
+        assertEquals("Expected 2 Session attributes", 2,
+            session1.getAttributeNames().length);
+        assertEquals("AStringValue",
+            session1.getAttribute("testAttributeString"));
+        assertEquals(999, session1.getAttribute("testAttributeNumber"));
+
+        assertEquals(
+            session1,
+            
resolver1.getAttribute(JcrResourceConstants.AUTHENTICATION_INFO_SESSION));
+        assertEquals("AStringValue",
+            resolver1.getAttribute("testAttributeString"));
+        assertEquals(999, resolver1.getAttribute("testAttributeNumber"));
+
+        final Iterator<String> attrNames1 = resolver1.getAttributeNames();
+        assertTrue("Expecting first attribute", attrNames1.hasNext());
+        attrNames1.next();
+        assertTrue("Expecting second attribute", attrNames1.hasNext());
+        attrNames1.next();
+        assertTrue("Expecting third attribute", attrNames1.hasNext());
+        attrNames1.next();
+        assertFalse("Expecting no more attribute", attrNames1.hasNext());
+
+        resolver1.close();
+        assertTrue("Expect session to still be live after resolver close",
+            session1.isLive());
+        session1.logout();
+    }
+
+    public void test_attributes_from_authInfo() throws Exception {
+        final Map<String, Object> authInfo = new HashMap<String, Object>();
+        authInfo.put(ResourceResolverFactory.USER, "admin");
+        authInfo.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
+        authInfo.put("testAttributeString", "AStringValue");
+        authInfo.put("testAttributeNumber", 999);
+        final ResourceResolver rr = resFac.getResourceResolver(authInfo);
+        final Session s = rr.adaptTo(Session.class);
+
+        assertEquals("Expect 3 session attributes", 3,
+            s.getAttributeNames().length);
+        assertEquals("AStringValue", s.getAttribute("testAttributeString"));
+        assertEquals(999, s.getAttribute("testAttributeNumber"));
+        assertEquals("admin", s.getAttribute(ResourceResolverFactory.USER));
+        assertNull(session.getAttribute(ResourceResolverFactory.PASSWORD));
+
+        assertEquals("AStringValue", rr.getAttribute("testAttributeString"));
+        assertEquals(999, rr.getAttribute("testAttributeNumber"));
+        assertEquals("admin", rr.getAttribute(ResourceResolverFactory.USER));
+        assertNull(rr.getAttribute(ResourceResolverFactory.PASSWORD));
+
+        final HashSet<String> validNames = new HashSet<String>();
+        validNames.add(ResourceResolverFactory.USER);
+        validNames.add("testAttributeString");
+        validNames.add("testAttributeNumber");
+        final Iterator<String> names = rr.getAttributeNames();
+        assertTrue(validNames.remove(names.next()));
+        assertTrue(validNames.remove(names.next()));
+        assertTrue(validNames.remove(names.next()));
+        assertFalse("Expect no more names", names.hasNext());
+        assertTrue("Expect validNames set to be empty now",
+            validNames.isEmpty());
     }
 
     public void testGetResource() throws Exception {

Modified: 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
 Thu Aug 12 15:44:46 2010
@@ -19,6 +19,7 @@
 package org.apache.sling.jcr.resource.internal.helper;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -271,6 +272,14 @@ public class ResourceProviderEntryTest e
         public String getUserID() {
             return null;
         }
+
+        public Object getAttribute(String name) {
+            return null;
+        }
+
+        public Iterator<String> getAttributeNames() {
+            return Collections.<String> emptyList().iterator();
+        }
     }
 
     private static class TestResource extends AbstractResource {
@@ -307,6 +316,5 @@ public class ResourceProviderEntryTest e
         public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
             return null;
         }
-
     }
 }

Modified: 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java?rev=984840&r1=984839&r2=984840&view=diff
==============================================================================
--- 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
 (original)
+++ 
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
 Thu Aug 12 15:44:46 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.jcr.resource.internal.helper.jcr;
 
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -116,4 +117,12 @@ public class MockResourceResolver implem
     public String getUserID() {
         return session.getUserID();
     }
+
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    public Iterator<String> getAttributeNames() {
+        return Collections.<String> emptyList().iterator();
+    }
 }


Reply via email to