| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.sling.resourceresolver.impl; |
| |
| import static java.util.Arrays.asList; |
| import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.spy; |
| import static org.mockito.Mockito.when; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.jcr.Session; |
| import javax.servlet.http.HttpServletRequest; |
| |
| import org.apache.sling.api.SlingException; |
| import org.apache.sling.api.resource.LoginException; |
| import org.apache.sling.api.resource.NonExistingResource; |
| import org.apache.sling.api.resource.PersistenceException; |
| 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.SyntheticResource; |
| import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; |
| import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; |
| import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; |
| import org.apache.sling.spi.resource.provider.ResolveContext; |
| import org.apache.sling.spi.resource.provider.ResourceContext; |
| import org.apache.sling.spi.resource.provider.ResourceProvider; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.internal.util.reflection.Whitebox; |
| import org.osgi.framework.Bundle; |
| |
| public class ResourceResolverImplTest { |
| |
| private CommonResourceResolverFactoryImpl commonFactory; |
| |
| private ResourceResolver resResolver; |
| |
| private ResourceResolverFactoryImpl resFac; |
| |
| private ResourceProviderTracker resourceProviderTracker; |
| |
| @Before public void setup() throws LoginException { |
| ResourceProvider<?> rp = new ResourceProvider<Object>() { |
| |
| @Override |
| public Resource getResource(ResolveContext<Object> ctx, String path, ResourceContext rCtx, Resource parent) { |
| return null; |
| } |
| |
| @Override |
| public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) { |
| return null; |
| } |
| }; |
| |
| List<ResourceProviderHandler> handlers = asList(createRPHandler(rp, "rp1", 0, "/")); |
| resourceProviderTracker = mock(ResourceProviderTracker.class); |
| ResourceProviderStorage storage = new ResourceProviderStorage(handlers); |
| when(resourceProviderTracker.getResourceProviderStorage()).thenReturn(storage); |
| ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator(); |
| activator.resourceProviderTracker = resourceProviderTracker; |
| activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker(); |
| commonFactory = new CommonResourceResolverFactoryImpl(activator); |
| final Bundle usingBundle = mock(Bundle.class); |
| resFac = new ResourceResolverFactoryImpl(commonFactory, usingBundle, null); |
| resResolver = resFac.getAdministrativeResourceResolver(null); |
| } |
| |
| @SuppressWarnings("deprecation") |
| @Test public void testClose() throws Exception { |
| final ResourceResolver rr = new ResourceResolverImpl(commonFactory, false, null, resourceProviderTracker); |
| assertTrue(rr.isLive()); |
| rr.close(); |
| assertFalse(rr.isLive()); |
| // close is always allowed to be called |
| rr.close(); |
| assertFalse(rr.isLive()); |
| // now check all public method - they should all throw! |
| try { |
| rr.adaptTo(Session.class); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.clone(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.findResources("a", "b"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getAttribute("a"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getAttributeNames(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getResource(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getResource(null, "/a"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getSearchPath(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getUserID(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.listChildren(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.map("/somepath"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.map(null, "/somepath"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.queryResources("a", "b"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve((HttpServletRequest)null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve("/path"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve(null, "/path"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| } |
| |
| @SuppressWarnings("deprecation") |
| @Test |
| public void testCloseWithStackTraceLogging() throws Exception { |
| ResourceResolverFactoryConfig config = mock(ResourceResolverFactoryConfig.class); |
| when(config.resource_resolver_log_closing()).thenReturn(true); |
| ResourceResolverFactoryActivator rrfa = spy(new ResourceResolverFactoryActivator()); |
| Whitebox.setInternalState(rrfa, "config", config); |
| CommonResourceResolverFactoryImpl crrfi = new CommonResourceResolverFactoryImpl(rrfa); |
| final ResourceResolver rr = new ResourceResolverImpl(crrfi, false, null, resourceProviderTracker); |
| assertTrue(rr.isLive()); |
| rr.close(); |
| assertFalse(rr.isLive()); |
| // close is always allowed to be called |
| rr.close(); |
| assertFalse(rr.isLive()); |
| // now check all public method - they should all throw! |
| try { |
| rr.adaptTo(Session.class); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.clone(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.findResources("a", "b"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getAttribute("a"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getAttributeNames(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getResource(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getResource(null, "/a"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getSearchPath(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.getUserID(); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.listChildren(null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.map("/somepath"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.map(null, "/somepath"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.queryResources("a", "b"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve((HttpServletRequest)null); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve("/path"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| try { |
| rr.resolve(null, "/path"); |
| fail(); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| } |
| |
| @SuppressWarnings("deprecation") |
| @Test public void testBasicAPIAssumptions() throws Exception { |
| |
| // null resource is accessing /, which exists of course |
| final Resource res00 = resResolver.resolve((String) null); |
| assertNotNull(res00); |
| assertTrue("Resource must be NonExistingResource", |
| res00 instanceof NonExistingResource); |
| assertEquals("Null path is expected to return root", "/", |
| res00.getPath()); |
| |
| // relative paths are treated as if absolute |
| final String path01 = "relPath/relPath"; |
| final Resource res01 = resResolver.resolve(path01); |
| assertNotNull(res01); |
| assertEquals("Expecting absolute path for relative path", "/" + path01, |
| res01.getPath()); |
| assertTrue("Resource must be NonExistingResource", |
| res01 instanceof NonExistingResource); |
| |
| final String no_resource_path = "/no_resource/at/this/location"; |
| final Resource res02 = resResolver.resolve(no_resource_path); |
| assertNotNull(res02); |
| assertEquals("Expecting absolute path for relative path", |
| no_resource_path, res02.getPath()); |
| assertTrue("Resource must be NonExistingResource", |
| res01 instanceof NonExistingResource); |
| |
| try { |
| resResolver.resolve((HttpServletRequest) null); |
| fail("Expected NullPointerException trying to resolve null request"); |
| } catch (NullPointerException npe) { |
| // expected |
| } |
| |
| final Resource res0 = resResolver.resolve(null, no_resource_path); |
| assertNotNull("Expecting resource if resolution fails", res0); |
| assertTrue("Resource must be NonExistingResource", |
| res0 instanceof NonExistingResource); |
| assertEquals("Path must be the original path", no_resource_path, |
| res0.getPath()); |
| |
| final HttpServletRequest req1 = mock(HttpServletRequest.class); |
| when(req1.getProtocol()).thenReturn("http"); |
| when(req1.getServerName()).thenReturn("localhost"); |
| when(req1.getPathInfo()).thenReturn(no_resource_path); |
| |
| final Resource res1 = resResolver.resolve(req1); |
| assertNotNull("Expecting resource if resolution fails", res1); |
| assertTrue("Resource must be NonExistingResource", |
| res1 instanceof NonExistingResource); |
| assertEquals("Path must be the original path", no_resource_path, |
| res1.getPath()); |
| |
| final HttpServletRequest req2 = mock(HttpServletRequest.class); |
| when(req2.getProtocol()).thenReturn("http"); |
| when(req2.getServerName()).thenReturn("localhost"); |
| when(req2.getPathInfo()).thenReturn(null); |
| final Resource res2 = resResolver.resolve(req2); |
| assertNotNull("Expecting resource if resolution fails", res2); |
| assertTrue("Resource must be NonExistingResource", |
| res2 instanceof NonExistingResource); |
| assertEquals("Path must be the the root path", "/", res2.getPath()); |
| |
| final Resource res3 = resResolver.getResource(null); |
| assertNull("Expected null resource for null path", res3); |
| |
| final Resource res4 = resResolver.getResource(null, null); |
| assertNull("Expected null resource for null path", res4); |
| |
| final Resource res5 = resResolver.getResource(res01, null); |
| assertNull("Expected null resource for null path", res5); |
| } |
| |
| @Test public void test_clone_based_on_anonymous() throws Exception { |
| final ResourceResolver anon0 = resFac.getResourceResolver((Map<String, Object>) null); |
| // no session |
| final Session anon0Session = anon0.adaptTo(Session.class); |
| assertNull("Session should not be available", anon0Session); |
| // no user information, so user id is null |
| assertEquals(null, anon0.getUserID()); |
| |
| // same user and workspace |
| final ResourceResolver anon1 = anon0.clone(null); |
| final Session anon1Session = anon1.adaptTo(Session.class); |
| assertEquals(anon0.getUserID(), anon1.getUserID()); |
| assertNull("Session should not be available", anon1Session); |
| anon1.close(); |
| |
| // same workspace but admin user |
| final Map<String, Object> admin0Cred = new HashMap<>(); |
| admin0Cred.put(ResourceResolverFactory.USER, "admin"); |
| admin0Cred.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray()); |
| final ResourceResolver admin0 = anon0.clone(admin0Cred); |
| assertEquals("admin", admin0.getUserID()); |
| admin0.close(); |
| |
| anon0.close(); |
| } |
| |
| @Test public void test_clone_based_on_admin() throws Exception { |
| final ResourceResolver admin0 = resFac.getAdministrativeResourceResolver((Map<String, Object>) null); |
| // no user information, so user id is null |
| assertEquals(null, admin0.getUserID()); |
| |
| // same user and workspace |
| final ResourceResolver admin1 = admin0.clone(null); |
| assertEquals(admin0.getUserID(), admin1.getUserID()); |
| admin1.close(); |
| |
| // same workspace but anonymous user |
| final Map<String, Object> anon0Cred = new HashMap<>(); |
| anon0Cred.put(ResourceResolverFactory.USER, "anonymous"); |
| final ResourceResolver anon0 = admin0.clone(anon0Cred); |
| assertEquals("anonymous", anon0.getUserID()); |
| anon0.close(); |
| |
| admin0.close(); |
| } |
| |
| @Test public void test_attributes_from_authInfo() throws Exception { |
| final Map<String, Object> authInfo = new HashMap<>(); |
| 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); |
| |
| 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<>(); |
| 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()); |
| |
| rr.close(); |
| } |
| |
| @Test public void testBasicCrud() throws Exception { |
| final Resource r = mock(Resource.class); |
| when(r.getPath()).thenReturn("/some"); |
| try { |
| this.resResolver.create(null, "a", null); |
| fail("Null parent resource should throw NPE"); |
| } catch (final NullPointerException npe) { |
| // correct |
| } |
| try { |
| this.resResolver.create(r, null, null); |
| fail("Null name should throw NPE"); |
| } catch (final NullPointerException npe) { |
| // correct |
| } |
| try { |
| this.resResolver.create(r, "a/b", null); |
| fail("Slash in name should throw illegal argument exception"); |
| } catch (final IllegalArgumentException pe) { |
| // correct |
| } |
| try { |
| this.resResolver.create(r, "a", null); |
| fail("This should be unsupported."); |
| } catch (final PersistenceException uoe) { |
| // correct |
| } |
| } |
| |
| @Test public void test_getResourceSuperType() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(); |
| |
| // the resources to test |
| final Resource r = resolver.add(new SyntheticResource(resolver, "/a", "a:b")); |
| final Resource r2 = resolver.add(new SyntheticResource(resolver, "/a2", "a:c")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/a/b", "x:y", "t:c")); |
| |
| assertEquals("t:c", resolver.getParentResourceType(r.getResourceType())); |
| assertNull(resolver.getParentResourceType(r2.getResourceType())); |
| } |
| |
| @Test public void testIsResourceType() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(); |
| |
| final Resource r = resolver.add(new SyntheticResourceWithSupertype(resolver, "/a", "a:b", "d:e")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/d/e", "x:y", "t:c")); |
| |
| assertTrue(resolver.isResourceType(r, "a:b")); |
| assertTrue(resolver.isResourceType(r, "d:e")); |
| assertFalse(resolver.isResourceType(r, "x:y")); |
| assertTrue(resolver.isResourceType(r, "t:c")); |
| assertFalse(resolver.isResourceType(r, "h:p")); |
| } |
| |
| @Test public void testIsResourceTypeWithPaths() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(); |
| |
| /** |
| * prepare resource type hierarchy |
| * /types/1 |
| * +- /types/2 |
| * +- /types/3 |
| */ |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/3")); |
| resolver.add(new SyntheticResource(resolver, "/types/3", "/types/component")); |
| |
| Resource resourceT1 = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1")); |
| Resource resourceT2 = resolver.add(new SyntheticResource(resolver, "/resourceT2", "/types/2")); |
| Resource resourceT3 = resolver.add(new SyntheticResource(resolver, "/resourceT3", "/types/3")); |
| |
| assertTrue(resolver.isResourceType(resourceT1, "/types/1")); |
| assertTrue(resolver.isResourceType(resourceT1, "/types/2")); |
| assertTrue(resolver.isResourceType(resourceT1, "/types/3")); |
| assertFalse(resolver.isResourceType(resourceT1, "/types/component")); |
| assertFalse(resolver.isResourceType(resourceT1, "/types/unknown")); |
| |
| assertFalse(resolver.isResourceType(resourceT2, "/types/1")); |
| assertTrue(resolver.isResourceType(resourceT2, "/types/2")); |
| assertTrue(resolver.isResourceType(resourceT2, "/types/3")); |
| assertFalse(resolver.isResourceType(resourceT2, "/types/component")); |
| assertFalse(resolver.isResourceType(resourceT2, "/types/unknown")); |
| |
| assertFalse(resolver.isResourceType(resourceT3, "/types/1")); |
| assertFalse(resolver.isResourceType(resourceT3, "/types/2")); |
| assertTrue(resolver.isResourceType(resourceT3, "/types/3")); |
| assertFalse(resolver.isResourceType(resourceT3, "/types/component")); |
| assertFalse(resolver.isResourceType(resourceT3, "/types/unknown")); |
| } |
| |
| /** |
| * @see <a href="https://issues.apache.org/jira/browse/SLING-6327">SLING-6327</a> |
| */ |
| @Test public void testIsResourceTypeWithMixedAbsoluteAndRelativePaths() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(new String[] {"/apps/", "/libs/"}); |
| |
| Resource resourceT1 = resolver.add(new SyntheticResource(resolver, "/resourceT1", "types/1")); |
| Resource resourceT2 = resolver.add(new SyntheticResource(resolver, "/resourceT2", "/apps/types/2")); |
| Resource resourceT3 = resolver.add(new SyntheticResource(resolver, "/resourceT3", "/libs/types/3")); |
| Resource resourceT4 = resolver.add(new SyntheticResource(resolver, "/resourceT3", "/someprefix/types/4")); |
| |
| assertTrue(resolver.isResourceType(resourceT1, "/libs/types/1")); |
| assertTrue(resolver.isResourceType(resourceT1, "/apps/types/1")); |
| assertTrue(resolver.isResourceType(resourceT1, "types/1")); |
| |
| assertTrue(resolver.isResourceType(resourceT2, "/apps/types/2")); |
| assertTrue(resolver.isResourceType(resourceT2, "types/2")); |
| assertTrue(resolver.isResourceType(resourceT2, "/libs/types/2")); |
| |
| assertTrue(resolver.isResourceType(resourceT3, "/apps/types/3")); |
| assertTrue(resolver.isResourceType(resourceT3, "types/3")); |
| assertTrue(resolver.isResourceType(resourceT3, "/libs/types/3")); |
| |
| assertFalse(resolver.isResourceType(resourceT4, "/apps/types/4")); |
| assertFalse(resolver.isResourceType(resourceT4, "types/4")); |
| assertFalse(resolver.isResourceType(resourceT4, "/libs/types/4")); |
| assertTrue(resolver.isResourceType(resourceT4, "/someprefix/types/4")); |
| } |
| |
| @Test(expected=SlingException.class) public void testIsResourceCyclicHierarchyDirect() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(); |
| |
| /** |
| * prepare resource type hierarchy |
| * /types/1 <---+ |
| * +- /types/2 -+ |
| */ |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/1")); |
| |
| Resource resource = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1")); |
| |
| assertTrue(resolver.isResourceType(resource, "/types/1")); |
| assertTrue(resolver.isResourceType(resource, "/types/2")); |
| |
| // this should throw a SlingException when detecting the cyclic hierarchy |
| resolver.isResourceType(resource, "/types/unknown"); |
| } |
| |
| @Test(expected=SlingException.class) public void testIsResourceCyclicHierarchyIndirect() { |
| final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver(); |
| |
| /** |
| * prepare resource type hierarchy |
| * /types/1 <----+ |
| * +- /types/2 | |
| * +- /types/3 -+ |
| */ |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/3")); |
| resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/3", "/types/component", "/types/1")); |
| |
| Resource resource = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1")); |
| |
| assertTrue(resolver.isResourceType(resource, "/types/1")); |
| assertTrue(resolver.isResourceType(resource, "/types/2")); |
| assertTrue(resolver.isResourceType(resource, "/types/3")); |
| |
| // this should throw a SlingException when detecting the cyclic hierarchy |
| resolver.isResourceType(resource, "/types/unknown"); |
| } |
| |
| private PathBasedResourceResolverImpl getPathBasedResourceResolver() { |
| return getPathBasedResourceResolver(new String[] {""}); |
| } |
| |
| |
| private PathBasedResourceResolverImpl getPathBasedResourceResolver(String[] searchPaths) { |
| try { |
| final List<ResourceResolver> resolvers = new ArrayList<>(); |
| final PathBasedResourceResolverImpl resolver = new PathBasedResourceResolverImpl(resolvers, resourceProviderTracker, searchPaths); |
| resolvers.add(resolver); |
| return resolver; |
| } |
| catch (LoginException ex) { |
| throw new RuntimeException(ex); |
| } |
| } |
| |
| private static class PathBasedResourceResolverImpl extends ResourceResolverImpl { |
| |
| private final Map<String, Resource> resources = new HashMap<>(); |
| |
| public PathBasedResourceResolverImpl(final List<ResourceResolver> resolvers, final ResourceProviderTracker resourceProviderTracker, final String[] searchPaths) throws LoginException { |
| this(new CommonResourceResolverFactoryImpl(new ResourceResolverFactoryActivator()) { |
| @Override |
| public ResourceResolver getAdministrativeResourceResolver( |
| Map<String, Object> authenticationInfo) throws LoginException { |
| return resolvers.get(0); |
| } |
| @Override |
| public ResourceResolver getServiceResourceResolver( |
| Map<String, Object> authenticationInfo) throws LoginException { |
| return resolvers.get(0); |
| } |
| @Override |
| public List<String> getSearchPath() { |
| return Arrays.asList(searchPaths); |
| } |
| |
| |
| }, resourceProviderTracker); |
| } |
| |
| public PathBasedResourceResolverImpl(CommonResourceResolverFactoryImpl factory, ResourceProviderTracker resourceProviderTracker) throws LoginException { |
| super(factory, false, null, resourceProviderTracker); |
| } |
| |
| public Resource add(final Resource r) { |
| this.resources.put(r.getPath(), r); |
| return r; |
| } |
| |
| @Override |
| public Resource getResource(final String path) { |
| final String p = (path.startsWith("/") ? path : "/" + path); |
| return this.resources.get(p); |
| } |
| } |
| |
| private static class SyntheticResourceWithSupertype extends SyntheticResource { |
| |
| private final String resourceSuperType; |
| |
| public SyntheticResourceWithSupertype(ResourceResolver resourceResolver, String path, |
| String resourceType, String resourceSuperType) { |
| super(resourceResolver, path, resourceType); |
| this.resourceSuperType = resourceSuperType; |
| } |
| |
| @Override |
| public String getResourceSuperType() { |
| return this.resourceSuperType; |
| } |
| |
| } |
| |
| } |