You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2012/10/25 11:17:34 UTC

svn commit: r1402037 - in /sling/trunk/bundles: api/src/main/java/org/apache/sling/api/resource/ extensions/bundleresource/ extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/ extensions/fsresource/ extensions/fsresource/src/m...

Author: cziegeler
Date: Thu Oct 25 09:17:34 2012
New Revision: 1402037

URL: http://svn.apache.org/viewvc?rev=1402037&view=rev
Log:
SLING-2541 : General mechanism to chain resource providers

Modified:
    sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceMetadata.java
    sling/trunk/bundles/extensions/bundleresource/pom.xml
    sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
    sling/trunk/bundles/extensions/fsresource/pom.xml
    sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java
    sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java

Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceMetadata.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceMetadata.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceMetadata.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceMetadata.java Thu Oct 25 09:17:34 2012
@@ -106,6 +106,20 @@ public class ResourceMetadata extends Ha
     public static final String MODIFICATION_TIME = "sling.modificationTime";
 
     /**
+     * Returns whether the resource resolver should continue to search for a
+     * resource.
+     * A resource provider can set this flag to indicate that the resource
+     * resolver should search for a provider with a lower priority. If it
+     * finds a resource using such a provider, that resource is returned
+     * instead. If none is found this resource is returned.
+     * This flag should never be manipulated by application code!
+     * The value of this property has no meaning, the resource resolver
+     * just checks whether this flag is set or not.
+     * @since 2.2
+     */
+    public static final String INTERNAL_CONTINUE_RESOLVING = ":org.apache.sling.resource.internal.continue.resolving";
+
+    /**
      * Sets the {@link #CHARACTER_ENCODING} property to <code>encoding</code>
      * if not <code>null</code>.
      */

Modified: sling/trunk/bundles/extensions/bundleresource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/pom.xml?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/pom.xml (original)
+++ sling/trunk/bundles/extensions/bundleresource/pom.xml Thu Oct 25 09:17:34 2012
@@ -118,10 +118,6 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>javax.jcr</groupId>
-            <artifactId>jcr</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>

Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java Thu Oct 25 09:17:34 2012
@@ -25,9 +25,6 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Iterator;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
 import org.apache.sling.api.resource.AbstractResource;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceMetadata;
@@ -68,16 +65,6 @@ public class BundleResource extends Abst
         // able to return an item-based resource
         URL entry = bundle.getEntry(entryPath.concat("/"));
         if (entry != null) {
-            Session session = resourceResolver.adaptTo(Session.class);
-            if (session != null) {
-                try {
-                    if (session.itemExists(resourcePath)) {
-                        return null;
-                    }
-                } catch (RepositoryException re) {
-                    // don't care
-                }
-            }
 
             // append the slash to path for next steps
             resourcePath = resourcePath.concat("/");
@@ -93,7 +80,7 @@ public class BundleResource extends Abst
         // or a bundle file
         if (entry != null) {
             return new BundleResource(resourceResolver, bundle, mappedPath,
-                resourcePath);
+                    resourcePath);
         }
 
         // the bundle does not contain the path
@@ -117,6 +104,7 @@ public class BundleResource extends Abst
 
             this.path = resourcePath.substring(0, resourcePath.length() - 1);
             this.resourceType = NT_FOLDER;
+            metadata.put(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING, Boolean.TRUE);
 
         } else {
 
@@ -153,6 +141,7 @@ public class BundleResource extends Abst
         return resourceResolver;
     }
 
+    @Override
     @SuppressWarnings("unchecked")
     public <Type> Type adaptTo(Class<Type> type) {
         if (type == InputStream.class) {
@@ -165,9 +154,10 @@ public class BundleResource extends Abst
         return super.adaptTo(type);
     }
 
+    @Override
     public String toString() {
         return getClass().getSimpleName() + ", type=" + getResourceType()
-            + ", path=" + getPath();
+                + ", path=" + getPath();
     }
 
     // ---------- internal -----------------------------------------------------
@@ -186,7 +176,7 @@ public class BundleResource extends Abst
                 }
             } catch (IOException ioe) {
                 log.error(
-                    "getInputStream: Cannot get input stream for " + this, ioe);
+                        "getInputStream: Cannot get input stream for " + this, ioe);
             }
         }
 
@@ -198,8 +188,8 @@ public class BundleResource extends Abst
         if (url == null) {
             try {
                 url = new URL(BundleResourceURLStreamHandler.PROTOCOL, null,
-                    -1, path, new BundleResourceURLStreamHandler(
-                        bundle.getBundle(), mappedPath.getEntryPath(path)));
+                        -1, path, new BundleResourceURLStreamHandler(
+                                bundle.getBundle(), mappedPath.getEntryPath(path)));
             } catch (MalformedURLException mue) {
                 log.error("getURL: Cannot get URL for " + this, mue);
             }
@@ -208,6 +198,7 @@ public class BundleResource extends Abst
         return url;
     }
 
+    @Override
     public Iterator<Resource> listChildren() {
         return new BundleResourceIterator(this);
     }

Modified: sling/trunk/bundles/extensions/fsresource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/pom.xml?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/pom.xml (original)
+++ sling/trunk/bundles/extensions/fsresource/pom.xml Thu Oct 25 09:17:34 2012
@@ -89,10 +89,6 @@
             <artifactId>servlet-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>javax.jcr</groupId>
-            <artifactId>jcr</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
             <version>2.2.5-SNAPSHOT</version>

Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java (original)
+++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java Thu Oct 25 09:17:34 2012
@@ -110,6 +110,9 @@ public class FsResource extends Abstract
             metaData.setContentLength(file.length());
             metaData.setModificationTime(file.lastModified());
             metaData.setResolutionPath(resourcePath);
+            if ( this.file.isDirectory() ) {
+                metaData.put(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING, Boolean.TRUE);
+            }
         }
         return metaData;
     }
@@ -138,7 +141,7 @@ public class FsResource extends Abstract
         if (resourceType == null) {
             resourceType = file.isFile()
                     ? RESOURCE_TYPE_FILE
-                    : RESOURCE_TYPE_FOLDER;
+                            : RESOURCE_TYPE_FOLDER;
         }
 
         return resourceType;
@@ -149,6 +152,7 @@ public class FsResource extends Abstract
      * <code>File</code>, <code>InputStream</code> and <code>URL</code>
      * plus those supported by the adapter manager.
      */
+    @Override
     @SuppressWarnings("unchecked")
     public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
         if (type == File.class) {
@@ -163,8 +167,8 @@ public class FsResource extends Abstract
                     return (AdapterType) new FileInputStream(file);
                 } catch (IOException ioe) {
                     getLog().info(
-                        "adaptTo: Cannot open a stream on the file " + file,
-                        ioe);
+                            "adaptTo: Cannot open a stream on the file " + file,
+                            ioe);
                 }
 
             } else {
@@ -179,12 +183,12 @@ public class FsResource extends Abstract
                 return (AdapterType) file.toURI().toURL();
             } catch (MalformedURLException mue) {
                 getLog().info(
-                    "adaptTo: Cannot convert the file path " + file
+                        "adaptTo: Cannot convert the file path " + file
                         + " to an URL", mue);
             }
 
         } else if (type == ValueMap.class) {
-            
+
             // this resource simulates nt:file/nt:folder behavior by returning it as resource type
             // we should simulate the corresponding JCR properties in a value map as well
             if (file.exists() && file.canRead()) {
@@ -196,9 +200,9 @@ public class FsResource extends Abstract
                 props.put("jcr:created", lastModifed);
                 return (AdapterType) new ValueMapDecorator(props);
             }
-            
+
         }
-        
+
         return super.adaptTo(type);
     }
 

Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java (original)
+++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java Thu Oct 25 09:17:34 2012
@@ -24,8 +24,6 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.felix.scr.annotations.Component;
@@ -54,18 +52,18 @@ import org.osgi.service.event.EventAdmin
  * resource ({@link #PROP_PROVIDER_FILE}).
  */
 @Component(
-    name="org.apache.sling.fsprovider.internal.FsResourceProvider",
-    label="%resource.resolver.name",
-    description="%resource.resolver.description",
-    configurationFactory=true,
-    policy=ConfigurationPolicy.REQUIRE,
-    metatype=true
-)
+        name="org.apache.sling.fsprovider.internal.FsResourceProvider",
+        label="%resource.resolver.name",
+        description="%resource.resolver.description",
+        configurationFactory=true,
+        policy=ConfigurationPolicy.REQUIRE,
+        metatype=true
+        )
 @Service(ResourceProvider.class)
 @Properties({
     @Property(name="service.description", value="Sling Filesystem Resource Provider"),
     @Property(name="service.vendor", value="The Apache Software Foundation"),
-    @Property(name=ResourceProvider.ROOTS)    
+    @Property(name=ResourceProvider.ROOTS)
 })
 public class FsResourceProvider implements ResourceProvider {
 
@@ -148,8 +146,8 @@ public class FsResourceProvider implemen
                     String relPath = providerRoot.substring(parentPath.length());
                     if (relPath.indexOf('/') < 0) {
                         Resource res = getResource(
-                            parent.getResourceResolver(), providerRoot,
-                            providerFile);
+                                parent.getResourceResolver(), providerRoot,
+                                providerFile);
                         if (res != null) {
                             return Collections.singletonList(res).iterator();
                         }
@@ -220,7 +218,7 @@ public class FsResourceProvider implemen
         String providerFileName = (String) props.get(PROP_PROVIDER_FILE);
         if (providerFileName == null || providerFileName.length() == 0) {
             throw new IllegalArgumentException(PROP_PROVIDER_FILE
-                + " property must be set");
+                    + " property must be set");
         }
 
         this.providerRoot = providerRoot;
@@ -282,7 +280,7 @@ public class FsResourceProvider implemen
         // if the provider file does not exist, create an empty new folder
         if (!providerFile.exists() && !providerFile.mkdirs()) {
             throw new IllegalArgumentException(
-                "Cannot create provider file root " + providerFile);
+                    "Cannot create provider file root " + providerFile);
         }
 
         return providerFile;
@@ -314,21 +312,6 @@ public class FsResourceProvider implemen
 
         if (file != null) {
 
-            // if the file is a directory, and a repository item exists for
-            // the path, do not return the directory here
-            if (file.isDirectory()) {
-                Session session = resourceResolver.adaptTo(Session.class);
-                if (session != null) {
-                    try {
-                        if (session.itemExists(resourcePath)) {
-                            return null;
-                        }
-                    } catch (RepositoryException re) {
-                        // don't care
-                    }
-                }
-            }
-
             // if the file exists, but is not a directory or no repository entry
             // exists, return it as a resource
             if (file.exists()) {

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java Thu Oct 25 09:17:34 2012
@@ -120,8 +120,8 @@ public class ResourceIterator implements
     private final ResourceResolverContext resourceResolverContext;
 
     public ResourceIterator(final ResourceResolverContext ctx,
-                    final Resource parentResource,
-                    final RootResourceProviderEntry rootProviderEntry) {
+            final Resource parentResource,
+            final RootResourceProviderEntry rootProviderEntry) {
         this.resourceResolverContext = ctx;
         this.parentResource = parentResource;
         this.rootProviderEntry = rootProviderEntry;
@@ -141,7 +141,7 @@ public class ResourceIterator implements
 
         if (log.isDebugEnabled()) {
             log.debug(" Provider Set for path {} {} ", path, Arrays
-                            .toString(providersSet.toArray(new ProviderHandler[providersSet.size()])));
+                    .toString(providersSet.toArray(new ProviderHandler[providersSet.size()])));
         }
         this.iteratorPath = path;
         providers = providersSet.iterator();
@@ -173,7 +173,7 @@ public class ResourceIterator implements
     private Resource seek() {
         while (delayedIter == null) {
             while ((resources == null || !resources.hasNext())
-                            && providers.hasNext()) {
+                    && providers.hasNext()) {
                 final ProviderHandler provider = providers.next();
                 resources = provider.listChildren(this.resourceResolverContext, parentResource);
                 log.debug("     Checking Provider {} ", provider);
@@ -214,18 +214,17 @@ public class ResourceIterator implements
                     final ResourceProviderEntry rpw = baseEntryValues.next();
                     final String resPath = iteratorPath + rpw.getPath();
                     if (!visited.contains(resPath)) {
-                        final ResourceResolver rr = parentResource
-                                        .getResourceResolver();
+                        final ResourceResolver rr = parentResource.getResourceResolver();
                         final Resource res = rpw.getResourceFromProviders(this.resourceResolverContext, rr,
-                                        resPath);
+                                resPath);
                         if (res == null) {
                             if (!delayed.containsKey(resPath)) {
                                 delayed.put(
+                                        resPath,
+                                        new SyntheticResource(
+                                                rr,
                                                 resPath,
-                                                new SyntheticResource(
-                                                                rr,
-                                                                resPath,
-                                                                ResourceProvider.RESOURCE_TYPE_SYNTHETIC));
+                                                ResourceProvider.RESOURCE_TYPE_SYNTHETIC));
                             }
                         } else {
                             // return the real resource immediately, add
@@ -234,7 +233,7 @@ public class ResourceIterator implements
                             delayed.remove(resPath);
                             visited.add(resPath);
                             log.debug("   B  resource {} {}", resPath,
-                                            res.getClass());
+                                    res.getClass());
                             return res;
                         }
                     }
@@ -273,7 +272,7 @@ public class ResourceIterator implements
      *         <code>null</code> if there is no entry at the given location
      */
     private ResourceProviderEntry getResourceProviders(final String path,
-                    final Set<ProviderHandler> providers) {
+            final Set<ProviderHandler> providers) {
 
         // collect providers along the ancestor path segements
         final String[] elements = ResourceProviderEntry.split(path);
@@ -283,7 +282,7 @@ public class ResourceIterator implements
                 base = base.get(element);
                 if (log.isDebugEnabled()) {
                     log.debug("Loading from {}  {} ", element,
-                                    base.getResourceProviders().length);
+                            base.getResourceProviders().length);
                 }
                 for (final ProviderHandler rp : base.getResourceProviders()) {
                     log.debug("Adding {} for {} ", rp, path);

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java?rev=1402037&r1=1402036&r2=1402037&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java Thu Oct 25 09:17:34 2012
@@ -29,6 +29,7 @@ import java.util.Set;
 import org.apache.commons.collections.FastTreeMap;
 import org.apache.sling.api.resource.ModifyingResourceProvider;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceProvider;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.SyntheticResource;
@@ -118,8 +119,8 @@ public class ResourceProviderEntry imple
      *             if an error occurrs trying to access an existing resource.
      */
     public Resource getResource(final ResourceResolverContext ctx,
-                    final ResourceResolver resourceResolver,
-                    final String path) {
+            final ResourceResolver resourceResolver,
+            final String path) {
         return getInternalResource(ctx, resourceResolver, path);
     }
 
@@ -265,8 +266,8 @@ public class ResourceProviderEntry imple
      * @return null if no resource was found, a resource if one was found.
      */
     private Resource getInternalResource(final ResourceResolverContext ctx,
-                    final ResourceResolver resourceResolver,
-                    final String fullPath) {
+            final ResourceResolver resourceResolver,
+            final String fullPath) {
         try {
 
             if (fullPath == null || fullPath.length() == 0 || fullPath.charAt(0) != '/') {
@@ -277,19 +278,29 @@ public class ResourceProviderEntry imple
             final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
             this.populateProviderPath(entries, elements);
 
+            Resource fallbackResource = null;
+
             // the path is in reverse order end first
             for (int i = entries.size() - 1; i >= 0; i--) {
                 final ProviderHandler[] rps = entries.get(i).getResourceProviders();
                 for (final ProviderHandler rp : rps) {
 
+                    boolean foundFallback = false;
                     final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
                     if (resource != null) {
-                        LOGGER.debug("Resolved Full {} using {} from {} ", new Object[] { fullPath, rp, Arrays.toString(rps) });
-                        return resource;
+                        if ( resource.getResourceMetadata() != null && resource.getResourceMetadata().get(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING) != null ) {
+                            LOGGER.debug("Resolved Full {} using {} from {} - continue resolving flag is set!", new Object[] { fullPath, rp, Arrays.toString(rps) });
+                            fallbackResource = resource;
+                            fallbackResource.getResourceMetadata().remove(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING);
+                            foundFallback = true;
+                        } else {
+                            LOGGER.debug("Resolved Full {} using {} from {} ", new Object[] { fullPath, rp, Arrays.toString(rps) });
+                            return resource;
+                        }
                     }
-                    if ( rp.ownsRoots() ) {
+                    if ( rp.ownsRoots() && !foundFallback ) {
                         LOGGER.debug("Resource null {} ", fullPath);
-                        return null;
+                        return fallbackResource;
                     }
                 }
             }
@@ -300,6 +311,11 @@ public class ResourceProviderEntry imple
                 return resource;
             }
 
+            if ( fallbackResource != null ) {
+                LOGGER.debug("Using first found resource {} for {}", fallbackResource, fullPath);
+                return fallbackResource;
+            }
+
             // query: /libs/sling/servlet/default
             // resource Provider: libs/sling/servlet/default/GET.servlet
             // list will match libs, sling, servlet, default
@@ -320,21 +336,36 @@ public class ResourceProviderEntry imple
     }
 
     public Resource getResourceFromProviders(final ResourceResolverContext ctx,
-                    final ResourceResolver resourceResolver, final String fullPath) {
+            final ResourceResolver resourceResolver,
+            final String fullPath) {
+        Resource fallbackResource = null;
         final ProviderHandler[] rps = getResourceProviders();
         for (final ProviderHandler rp : rps) {
+            boolean foundFallback = false;
+
             final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
             if (resource != null) {
-                LOGGER.debug("Resolved Base {} using {} ", fullPath, rp);
-                return resource;
+                if ( resource.getResourceMetadata() != null && resource.getResourceMetadata().get(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING) != null ) {
+                    LOGGER.debug("Resolved Base {} using {} - continue resolving flag is set!", fullPath, rp);
+                    fallbackResource = resource;
+                    fallbackResource.getResourceMetadata().remove(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING);
+                    foundFallback = true;
+                } else {
+                    LOGGER.debug("Resolved Base {} using {} ", fullPath, rp);
+                    return resource;
+                }
+            }
+            if ( rp.ownsRoots() && !foundFallback ) {
+                LOGGER.debug("Resource null {} ", fullPath);
+                return fallbackResource;
             }
         }
-        return null;
+        return fallbackResource;
     }
 
     public ModifyingResourceProvider getModifyingProvider(final ResourceResolverContext ctx,
-                    final ResourceResolver resourceResolver,
-                    final String fullPath) {
+            final ResourceResolver resourceResolver,
+            final String fullPath) {
         final String[] elements = split(fullPath);
         final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
         this.populateProviderPath(entries, elements);