/*
 * 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.mappingchain.ResourceUriMappingChain;
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();
        activator.resourceUriMappingChain = new ResourceUriMappingChain();
        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;
        }

    }

}
