Author: cziegeler Date: Fri Apr 30 14:24:35 2010 New Revision: 939684 URL: http://svn.apache.org/viewvc?rev=939684&view=rev Log: SLING-1514 : Remove the dependency to the Sling JCR API
Modified: sling/trunk/bundles/servlets/resolver/pom.xml sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/WorkspaceResourceResolver.java sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestAndDefaultSlingServletResolverTest.java sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestNoDefaultSlingServletResolverTest.java sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java Modified: sling/trunk/bundles/servlets/resolver/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/pom.xml?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/pom.xml (original) +++ sling/trunk/bundles/servlets/resolver/pom.xml Fri Apr 30 14:24:35 2010 @@ -54,6 +54,9 @@ <extensions>true</extensions> <configuration> <instructions> + <Import-Package> + javax.jcr;resolution:=optional,* + </Import-Package> <Private-Package> org.apache.sling.servlets.resolver.* </Private-Package> Modified: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java (original) +++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java Fri Apr 30 14:24:35 2010 @@ -38,10 +38,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.jcr.Credentials; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.SimpleCredentials; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -54,9 +50,11 @@ import org.apache.sling.api.SlingHttpSer import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.request.RequestProgressTracker; import org.apache.sling.api.request.RequestUtil; +import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; 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.api.resource.SyntheticResource; import org.apache.sling.api.scripting.SlingScript; import org.apache.sling.api.scripting.SlingScriptResolver; @@ -64,8 +62,6 @@ import org.apache.sling.api.servlets.Opt import org.apache.sling.api.servlets.ServletResolver; import org.apache.sling.commons.osgi.OsgiUtil; import org.apache.sling.engine.servlets.ErrorHandler; -import org.apache.sling.jcr.api.SlingRepository; -import org.apache.sling.jcr.resource.JcrResourceResolverFactory; import org.apache.sling.servlets.resolver.internal.defaults.DefaultErrorHandlerServlet; import org.apache.sling.servlets.resolver.internal.defaults.DefaultServlet; import org.apache.sling.servlets.resolver.internal.helper.AbstractResourceCollector; @@ -166,15 +162,7 @@ public class SlingServletResolver implem private ServletContext servletContext; /** @scr.reference */ - private JcrResourceResolverFactory jcrResourceResolverFactory; - - /** @scr.reference */ - private SlingRepository repository; - - /** The session used for script resolution. */ - private ConcurrentHashMap<String, Session> scriptSessions; - - private Session defaultScriptSession; + private ResourceResolverFactory resourceResolverFactory; /** The resource resolver used for script resolution. */ private ConcurrentHashMap<String, WorkspaceResourceResolver> scriptResolvers; @@ -205,12 +193,6 @@ public class SlingServletResolver implem private ServiceRegistration eventHandlerReg; /** - * The workspace name which should be used as a default for script - * resolution. - */ - private String defaultScriptWorkspaceName; - - /** * If true, the primary workspace name for script resolution will be the * same as that used to resolve the request's resource. */ @@ -247,15 +229,16 @@ public class SlingServletResolver implem } Servlet servlet = null; - String wspName = getWorkspaceName(request); if (this.useRequestWorkspace) { + final String wspName = getWorkspaceName(request); // First, we use a resource resolver using the same workspace as the // resource WorkspaceResourceResolver scriptResolver = getScriptResolver(wspName); servlet = resolveServlet(request, type, scriptResolver); - if (servlet == null && defaultScriptWorkspaceName != wspName && this.useDefaultWorkspace) { + if (servlet == null && this.useDefaultWorkspace + && !WorkspaceResourceResolver.isSameWorkspace(wspName, defaultScriptResolver.getWorkspaceName()) ) { servlet = resolveServlet(request, type, defaultScriptResolver); } @@ -425,8 +408,6 @@ public class SlingServletResolver implem */ public void handleError(int status, String message, SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { - String wspName = getWorkspaceName(request); - WorkspaceResourceResolver scriptResolver = getScriptResolver(wspName); // do not handle, if already handling .... if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) != null) { @@ -440,6 +421,7 @@ public class SlingServletResolver implem tracker.startTimer(timerName); try { + final WorkspaceResourceResolver scriptResolver = getScriptResolver(getWorkspaceName(request)); // find the error handler component Resource resource = getErrorResource(request); @@ -480,10 +462,7 @@ public class SlingServletResolver implem } public void handleError(Throwable throwable, SlingHttpServletRequest request, SlingHttpServletResponse response) - throws IOException { - String wspName = getWorkspaceName(request); - WorkspaceResourceResolver scriptResolver = getScriptResolver(wspName); - + throws IOException { // do not handle, if already handling .... if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) != null) { log.error("handleError: Recursive invocation. Not further handling Throwable:", throwable); @@ -496,6 +475,7 @@ public class SlingServletResolver implem tracker.startTimer(timerName); try { + final WorkspaceResourceResolver scriptResolver = getScriptResolver(getWorkspaceName(request)); // find the error handler component Servlet servlet = null; @@ -527,7 +507,6 @@ public class SlingServletResolver implem tracker.logTimer(timerName, "Using handler {0}", RequestUtil.getServletName(servlet)); handleError(servlet, request, response); - } finally { tracker.logTimer(timerName, "Error handler finished"); @@ -759,11 +738,17 @@ public class SlingServletResolver implem * Package scoped to help with testing. */ String getWorkspaceName(SlingHttpServletRequest request) { - return request.getResourceResolver().adaptTo(Session.class).getWorkspace().getName(); + return WorkspaceResourceResolver.getWorkspaceName(request.getResourceResolver()); } + /** + * Get a resource resolver for the given workspace. + * If the login to the given workspace does not work, we return the default resource resolver! + * @param wspName The workspace name or null for the default workspace + * @return A resource resolver + */ private WorkspaceResourceResolver getScriptResolver(String wspName) { - if (wspName.equals(defaultScriptWorkspaceName)) { + if (wspName == null || wspName.equals(defaultScriptResolver.getWorkspaceName())) { return defaultScriptResolver; } @@ -772,47 +757,33 @@ public class SlingServletResolver implem return scriptResolver; } - // create the script session - Session scriptSession = createScriptSession(wspName); - - Session sessionFromMap = scriptSessions.putIfAbsent(wspName, scriptSession); - if (sessionFromMap != null) { - // another session was bound while this session was being created - // abandon ship - scriptSession.logout(); - scriptSession = sessionFromMap; - } - - scriptResolver = new WorkspaceResourceResolver(this.jcrResourceResolverFactory.getResourceResolver(scriptSession), - wspName); - WorkspaceResourceResolver resolverFromMap = scriptResolvers.putIfAbsent(wspName, scriptResolver); - if (resolverFromMap != null) { - // another resolver was bound while this resolver was being created - // abandon ship - scriptResolver = resolverFromMap; + try { + scriptResolver = new WorkspaceResourceResolver(this.resourceResolverFactory.getResourceResolver(createAuthenticationInfo(wspName))); + WorkspaceResourceResolver resolverFromMap = scriptResolvers.putIfAbsent(wspName, scriptResolver); + if (resolverFromMap != null) { + // another resolver was bound while this resolver was being created + // abandon ship + scriptResolver.close(); + scriptResolver = resolverFromMap; + } + } catch (LoginException le) { + log.warn("Unable to login into workspace " + wspName + " : " + le.getMessage(), le); + scriptResolver = defaultScriptResolver; } - return scriptResolver; } - private Session createScriptSession(String wspName) { - Session scriptSession = null; - try { - scriptSession = this.repository.loginAdministrative(wspName); - } catch (RepositoryException e) { - throw new SlingException("Unable to create new admin session.", e); - } + private Map<String, Object> createAuthenticationInfo(String wspName) { + final Map<String, Object> authInfo = new HashMap<String, Object>(); // if a script user is configured we use this user to read the scripts final String scriptUser = OsgiUtil.toString(context.getProperties().get(PROP_SCRIPT_USER), null); if (scriptUser != null && scriptUser.length() > 0) { - Credentials creds = new SimpleCredentials(scriptUser, new char[0]); - try { - scriptSession = scriptSession.impersonate(creds); - } catch (RepositoryException e) { - throw new SlingException("Unable to impersonate to script user: " + scriptUser, e); - } + authInfo.put(ResourceResolverFactory.SUDO_USER_ID, scriptUser); + } + if ( wspName != null ) { + authInfo.put("user.jcr.workspace", wspName); } - return scriptSession; + return authInfo; } // ---------- SCR Integration ---------------------------------------------- @@ -820,7 +791,7 @@ public class SlingServletResolver implem /** * Activate this component. */ - protected void activate(ComponentContext context) { + protected void activate(ComponentContext context) throws LoginException { // from configuration if available final Dictionary<?, ?> properties = context.getProperties(); Object servletRoot = properties.get(PROP_SERVLET_ROOT); @@ -841,20 +812,15 @@ public class SlingServletResolver implem this.useDefaultWorkspace = OsgiUtil.toBoolean(properties.get(PROP_USE_DEFAULT_WORKSPACE), DEFAULT_USE_DEFAULT_WORKSPACE); this.useRequestWorkspace = OsgiUtil.toBoolean(properties.get(PROP_USE_REQUEST_WORKSPACE), DEFAULT_USE_REQUEST_WORKSPACE); - this.scriptSessions = new ConcurrentHashMap<String, Session>(); this.scriptResolvers = new ConcurrentHashMap<String, WorkspaceResourceResolver>(); String defaultWorkspaceProp = (String) properties.get(PROP_DEFAULT_SCRIPT_WORKSPACE); if ( defaultWorkspaceProp != null && defaultWorkspaceProp.trim().length() == 0 ) { defaultWorkspaceProp = null; } - this.defaultScriptSession = createScriptSession(defaultWorkspaceProp); - // we load the workspaceName out of the session to ensure the value is - // non-null - this.defaultScriptWorkspaceName = this.defaultScriptSession.getWorkspace().getName(); - this.defaultScriptResolver = new WorkspaceResourceResolver(jcrResourceResolverFactory - .getResourceResolver(defaultScriptSession), defaultScriptWorkspaceName); + this.defaultScriptResolver = new WorkspaceResourceResolver( + resourceResolverFactory.getAdministrativeResourceResolver(this.createAuthenticationInfo(defaultWorkspaceProp))); servletResourceProviderFactory = new ServletResourceProviderFactory(servletRoot, this.defaultScriptResolver.getSearchPath()); @@ -924,19 +890,17 @@ public class SlingServletResolver implem } // close sessions - if (this.scriptSessions != null && (!this.scriptSessions.isEmpty())) { - for (Session session : this.scriptSessions.values()) { - session.logout(); + if (this.scriptResolvers != null ) { + for (final ResourceResolver resolver : this.scriptResolvers.values()) { + resolver.close(); } + this.scriptResolvers = null; } - this.scriptSessions = null; - this.scriptResolvers = null; - if (this.defaultScriptSession != null) { - this.defaultScriptSession.logout(); + if (this.defaultScriptResolver != null) { + this.defaultScriptResolver.close(); + this.defaultScriptResolver = null; } - this.defaultScriptSession = null; - this.defaultScriptResolver = null; this.context = null; this.cache = null; Modified: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/WorkspaceResourceResolver.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/WorkspaceResourceResolver.java?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/WorkspaceResourceResolver.java (original) +++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/WorkspaceResourceResolver.java Fri Apr 30 14:24:35 2010 @@ -19,6 +19,7 @@ package org.apache.sling.servlets.resolv import java.util.Iterator; import java.util.Map; +import javax.jcr.Session; import javax.servlet.http.HttpServletRequest; import org.apache.sling.api.resource.Resource; @@ -27,17 +28,15 @@ import org.apache.sling.api.resource.Res /** * This is a facade around ResourceResolver in order to provide access to the * workspace name. - * - * TODO - should ResourceResolver have a getWorkspaceName() method? */ public class WorkspaceResourceResolver implements ResourceResolver { - private ResourceResolver delegate; - private String workspaceName; + private final ResourceResolver delegate; + private final String workspaceName; - public WorkspaceResourceResolver(ResourceResolver delegate, String workspaceName) { + public WorkspaceResourceResolver(ResourceResolver delegate) { this.delegate = delegate; - this.workspaceName = workspaceName; + this.workspaceName = getWorkspaceName(delegate); } /** {...@inheritdoc} */ @@ -107,4 +106,23 @@ public class WorkspaceResourceResolver i public void close() { delegate.close(); } + + public static boolean isSameWorkspace(final String wspName1, final String wspName2) { + if ( wspName1 == null && wspName2 == null ) { + return true; + } + return wspName1.equals(wspName2); + } + + public static String getWorkspaceName(final ResourceResolver resolver) { + try { + final Session s = resolver.adaptTo(Session.class); + if ( s != null ) { + return s.getWorkspace().getName(); + } + } catch (NoClassDefFoundError t) { + // if the session class is not available - we have no workspaces + } + return null; + } } Modified: sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestAndDefaultSlingServletResolverTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestAndDefaultSlingServletResolverTest.java?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestAndDefaultSlingServletResolverTest.java (original) +++ sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestAndDefaultSlingServletResolverTest.java Fri Apr 30 14:24:35 2010 @@ -16,13 +16,7 @@ */ package org.apache.sling.servlets.resolver.internal; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Workspace; - import org.apache.sling.commons.testing.osgi.MockComponentContext; -import org.apache.sling.jcr.api.SlingRepository; -import org.jmock.Expectations; import org.jmock.Mockery; /** @@ -44,22 +38,4 @@ public class ResolveFromRequestAndDefaul return "default"; } - @Override - protected void addExpectations(final SlingRepository repository) - throws RepositoryException { - final Session defaultSession = this.context.mock(Session.class); - final Workspace defaultWorkspace = this.context.mock(Workspace.class); - - this.context.checking(new Expectations() { - { - one(repository).loginAdministrative(with(aNull(String.class))); - will(returnValue(defaultSession)); - one(defaultSession).getWorkspace(); - will(returnValue(defaultWorkspace)); - one(defaultWorkspace).getName(); - will(returnValue("default")); - } - }); - } - } Modified: sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestNoDefaultSlingServletResolverTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestNoDefaultSlingServletResolverTest.java?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestNoDefaultSlingServletResolverTest.java (original) +++ sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/ResolveFromRequestNoDefaultSlingServletResolverTest.java Fri Apr 30 14:24:35 2010 @@ -16,13 +16,7 @@ */ package org.apache.sling.servlets.resolver.internal; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Workspace; - import org.apache.sling.commons.testing.osgi.MockComponentContext; -import org.apache.sling.jcr.api.SlingRepository; -import org.jmock.Expectations; import org.jmock.Mockery; /** @@ -39,29 +33,4 @@ public class ResolveFromRequestNoDefault protected void configureComponentContext(MockComponentContext mockComponentContext) { mockComponentContext.setProperty(SlingServletResolver.PROP_USE_REQUEST_WORKSPACE, "true"); } - - @Override - protected void addExpectations(final SlingRepository repository) - throws RepositoryException { - final Session defaultSession = this.context.mock(Session.class); - final Workspace defaultWorkspace = this.context.mock(Workspace.class); - - final Session requestSession = this.context.mock(Session.class); - - this.context.checking(new Expectations() { - { - one(repository).loginAdministrative(with(aNull(String.class))); - will(returnValue(defaultSession)); - one(defaultSession).getWorkspace(); - will(returnValue(defaultWorkspace)); - one(defaultWorkspace).getName(); - will(returnValue("default")); - - - one(repository).loginAdministrative(with(equal("fromRequest"))); - will(returnValue(requestSession)); - } - }); - } - } Modified: sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java?rev=939684&r1=939683&r2=939684&view=diff ============================================================================== --- sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java (original) +++ sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java Fri Apr 30 14:24:35 2010 @@ -25,16 +25,16 @@ import static org.junit.Assert.assertTru import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; +import java.util.Map; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Workspace; import javax.servlet.Servlet; import javax.servlet.http.HttpServlet; import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.LoginException; 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.servlets.OptingServlet; import org.apache.sling.commons.testing.osgi.MockBundle; @@ -43,10 +43,7 @@ import org.apache.sling.commons.testing. import org.apache.sling.commons.testing.sling.MockResource; import org.apache.sling.commons.testing.sling.MockResourceResolver; import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest; -import org.apache.sling.jcr.api.SlingRepository; -import org.apache.sling.jcr.resource.JcrResourceResolverFactory; import org.apache.sling.servlets.resolver.internal.resource.MockServletResource; -import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; import org.jmock.integration.junit4.JUnit4Mockery; @@ -77,12 +74,25 @@ public class SlingServletResolverTest { public void close() { // nothing to do; } + + @Override + public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) { + return null; + } }; mockResourceResolver.setSearchPath("/"); - final JcrResourceResolverFactory factory = new JcrResourceResolverFactory() { + final ResourceResolverFactory factory = new ResourceResolverFactory() { + + public ResourceResolver getAdministrativeResourceResolver( + Map<String, Object> authenticationInfo) + throws LoginException { + return mockResourceResolver; + } - public ResourceResolver getResourceResolver(Session session) { + public ResourceResolver getResourceResolver( + Map<String, Object> authenticationInfo) + throws LoginException { return mockResourceResolver; } }; @@ -97,21 +107,13 @@ public class SlingServletResolverTest { }; - // set sling repository - final SlingRepository repository = this.context.mock(SlingRepository.class); - addExpectations(repository); - Class<?> resolverClass = servletResolver.getClass().getSuperclass(); // set resource resolver factory - final Field resolverField = resolverClass.getDeclaredField("jcrResourceResolverFactory"); + final Field resolverField = resolverClass.getDeclaredField("resourceResolverFactory"); resolverField.setAccessible(true); resolverField.set(servletResolver, factory); - final Field repositoryField = resolverClass.getDeclaredField("repository"); - repositoryField.setAccessible(true); - repositoryField.set(servletResolver, repository); - MockBundle bundle = new MockBundle(1L); MockComponentContext mockComponentContext = new MockComponentContext( bundle, SlingServletResolverTest.this.servlet); @@ -156,20 +158,6 @@ public class SlingServletResolverTest { protected void configureComponentContext(MockComponentContext mockComponentContext) { } - protected void addExpectations(final SlingRepository repository) - throws RepositoryException { - final Session session = this.context.mock(Session.class); - final Workspace workspace = this.context.mock(Workspace.class); - this.context.checking(new Expectations() {{ - one(repository).loginAdministrative(with(aNull(String.class))); - will(returnValue(session)); - one(session).getWorkspace(); - will(returnValue(workspace)); - one(workspace).getName(); - will(returnValue("default")); - }}); - } - @Test public void testAcceptsRequest() { MockSlingHttpServletRequest secureRequest = new MockSlingHttpServletRequest( SERVLET_PATH, null, SERVLET_EXTENSION, null, null);