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);