You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by to...@apache.org on 2015/10/22 14:40:37 UTC
svn commit: r1710006 - in /sling/trunk/contrib/extensions/resourcemerger: ./
src/main/java/org/apache/sling/resourcemerger/impl/
src/main/java/org/apache/sling/resourcemerger/impl/picker/
src/main/java/org/apache/sling/resourcemerger/spi/ src/test/java...
Author: tomekr
Date: Thu Oct 22 12:40:37 2015
New Revision: 1710006
URL: http://svn.apache.org/viewvc?rev=1710006&view=rev
Log:
SLING-4611 Performance: Consider optimizing MergedResource#getParent and getChild
Removed:
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProviderFactory.java
Modified:
sling/trunk/contrib/extensions/resourcemerger/pom.xml
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourcePickerWhiteboard.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/MergingResourcePicker.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/MergedResourcePicker.java
sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/package-info.java
sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
Modified: sling/trunk/contrib/extensions/resourcemerger/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/pom.xml?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/pom.xml (original)
+++ sling/trunk/contrib/extensions/resourcemerger/pom.xml Thu Oct 22 12:40:37 2015
@@ -84,7 +84,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.7.0</version>
+ <version>2.9.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -101,7 +101,13 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
- <version>0.2.0</version>
+ <version>1.1.11-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.resourceresolver</artifactId>
+ <version>1.2.7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java Thu Oct 22 12:40:37 2015
@@ -25,19 +25,18 @@ import java.util.List;
import java.util.Map;
import org.apache.sling.api.resource.ModifiableValueMap;
-import org.apache.sling.api.resource.ModifyingResourceProvider;
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.ResourceUtil;
import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
+import org.apache.sling.spi.resource.provider.ResolveContext;
/**
* This is a modifiable resource provider.
*/
public class CRUDMergingResourceProvider
- extends MergingResourceProvider
- implements ModifyingResourceProvider {
+ extends MergingResourceProvider {
public CRUDMergingResourceProvider(final String mergeRootPath,
final MergedResourcePicker picker,
@@ -90,15 +89,12 @@ public class CRUDMergingResourceProvider
return holder;
}
- /**
- * @see org.apache.sling.api.resource.ModifyingResourceProvider#create(org.apache.sling.api.resource.ResourceResolver, java.lang.String, java.util.Map)
- */
- public Resource create(final ResourceResolver resolver,
- final String path,
- final Map<String, Object> properties)
- throws PersistenceException {
+ @Override
+ public Resource create(final ResolveContext<Void> ctx, final String path, final Map<String, Object> properties) throws PersistenceException {
+ final ResourceResolver resolver = ctx.getResourceResolver();
+
// check if the resource exists
- final Resource mountResource = this.getResource(resolver, path);
+ final Resource mountResource = this.getResource(ctx, path, null);
if ( mountResource != null ) {
throw new PersistenceException("Resource at " + path + " already exists.", null, path, null);
}
@@ -127,25 +123,20 @@ public class CRUDMergingResourceProvider
}
// TODO check parent hiding
}
- return this.getResource(resolver, path);
+ return this.getResource(ctx, path, null);
}
- /**
- * @see org.apache.sling.api.resource.ModifyingResourceProvider#delete(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
- */
- public void delete(final ResourceResolver resolver, final String path)
- throws PersistenceException {
+ @Override
+ public void delete(final ResolveContext<Void> ctx, final Resource resource) throws PersistenceException {
+ final ResourceResolver resolver = ctx.getResourceResolver();
+ final String path = resource.getPath();
+
// deleting of the root mount resource is not supported
final String relativePath = getRelativePath(path);
if ( relativePath == null || relativePath.length() == 0 ) {
- throw new PersistenceException("Resource at " + path + " can't be created.", null, path, null);
+ throw new PersistenceException("Resource at " + path + " can't be deleted.", null, path, null);
}
- // check if the resource exists
- final Resource mntResource = this.getResource(resolver, path);
- if ( mntResource == null ) {
- throw new PersistenceException("Resource at " + path + " does not exist", null, path, null);
- }
final ExtendedResourceHolder holder = this.getAllResources(resolver, path, relativePath);
// we only support modifications if there is more than one location merged
if ( holder.count < 2 ) {
@@ -165,25 +156,20 @@ public class CRUDMergingResourceProvider
}
}
- /**
- * @see org.apache.sling.api.resource.ModifyingResourceProvider#revert(org.apache.sling.api.resource.ResourceResolver)
- */
- public void revert(final ResourceResolver resolver) {
+ @Override
+ public void revert(final ResolveContext<Void> ctx) {
// the provider for the merged resources will revert
}
- /**
- * @see org.apache.sling.api.resource.ModifyingResourceProvider#commit(org.apache.sling.api.resource.ResourceResolver)
- */
- public void commit(final ResourceResolver resolver) throws PersistenceException {
+ @Override
+ public void commit(final ResolveContext<Void> ctx) throws PersistenceException {
// the provider for the merged resources will commit
}
- /**
- * @see org.apache.sling.api.resource.ModifyingResourceProvider#hasChanges(org.apache.sling.api.resource.ResourceResolver)
- */
- public boolean hasChanges(final ResourceResolver resolver) {
+ @Override
+ public boolean hasChanges(final ResolveContext<Void> ctx) {
// the provider for the merged resources will return changes
return false;
}
+
}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java Thu Oct 22 12:40:37 2015
@@ -50,6 +50,9 @@ public class MergedResource extends Abst
/** Cache value map. */
private final ValueMap properties;
+ /** Resources which are merged together. */
+ private final List<Resource> mappedResources;
+
/**
* Constructor
*
@@ -65,6 +68,7 @@ public class MergedResource extends Abst
final List<ValueMap> valueMaps) {
this.resolver = resolver;
this.path = (relativePath.length() == 0 ? mergeRootPath : mergeRootPath + "/" + relativePath);
+ this.mappedResources = mappedResources;
this.properties = new DeepReadValueMapDecorator(this, new MergedValueMap(valueMaps));
// get resource type
final String slingPropRT = this.properties.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class);
@@ -130,6 +134,9 @@ public class MergedResource extends Abst
return resolver;
}
+ public List<Resource> getMappedResources() {
+ return mappedResources;
+ }
/**
* {@inheritDoc}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourcePickerWhiteboard.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourcePickerWhiteboard.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourcePickerWhiteboard.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourcePickerWhiteboard.java Thu Oct 22 12:40:37 2015
@@ -26,10 +26,9 @@ import java.util.concurrent.ConcurrentHa
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.sling.api.resource.ResourceProvider;
-import org.apache.sling.api.resource.ResourceProviderFactory;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
@@ -63,18 +62,23 @@ public class MergedResourcePickerWhitebo
if ( picker != null ) {
final String mergeRoot = PropertiesUtil.toString(reference.getProperty(MergedResourcePicker.MERGE_ROOT), null);
if (mergeRoot != null) {
- final ResourceProviderFactory providerFactory = new MergingResourceProviderFactory(mergeRoot, picker,
- PropertiesUtil.toBoolean(reference.getProperty(MergedResourcePicker.READ_ONLY), true),
- PropertiesUtil.toBoolean(reference.getProperty(MergedResourcePicker.TRAVERSE_PARENT), false));
+ boolean readOnly = PropertiesUtil.toBoolean(reference.getProperty(MergedResourcePicker.READ_ONLY), true);
+ boolean traverseParent = PropertiesUtil.toBoolean(reference.getProperty(MergedResourcePicker.TRAVERSE_PARENT), false);
+
+ MergingResourceProvider provider = readOnly ?
+ new MergingResourceProvider(mergeRoot, picker, true, traverseParent) :
+ new CRUDMergingResourceProvider(mergeRoot, picker, traverseParent);
+
final Dictionary<Object, Object> props = new Hashtable<Object, Object>();
- props.put(ResourceProvider.ROOTS, mergeRoot);
- props.put(ResourceProvider.OWNS_ROOTS, true);
+ props.put(ResourceProvider.PROPERTY_NAME, readOnly ? "Merging" : "CRUDMerging");
+ props.put(ResourceProvider.PROPERTY_ROOT, mergeRoot);
+ props.put(ResourceProvider.PROPERTY_MODIFIABLE, !readOnly);
+ props.put(ResourceProvider.PROPERTY_AUTHENTICATE, ResourceProvider.AUTHENTICATE_NO);
final Long key = (Long) reference.getProperty(Constants.SERVICE_ID);
- final ServiceRegistration reg = bundleContext.registerService(ResourceProviderFactory.class.getName(), providerFactory, props);
+ final ServiceRegistration reg = bundleContext.registerService(ResourceProvider.class.getName(), provider, props);
serviceRegistrations.put(key, reg);
-
}
return picker;
}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java Thu Oct 22 12:40:37 2015
@@ -18,20 +18,19 @@
*/
package org.apache.sling.resourcemerger.impl;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
-class MergingResourceProvider implements ResourceProvider {
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class MergingResourceProvider extends ResourceProvider<Void> {
protected final String mergeRootPath;
@@ -202,16 +201,26 @@ class MergingResourceProvider implements
return null;
}
+ @Override
+ public Resource getParent(ResolveContext<Void> ctx, Resource child) {
+ final String parentPath = ResourceUtil.getParent(child.getPath());
+ if (parentPath == null) {
+ return null;
+ }
+ return this.getResource(ctx, parentPath, child);
+ }
+
/**
* {@inheritDoc}
*/
- public Resource getResource(final ResourceResolver resolver, final String path) {
+ public Resource getResource(final ResolveContext<Void> ctx, final String path, final Resource parent) {
final String relativePath = getRelativePath(path);
if (relativePath != null) {
final ResourceHolder holder = new ResourceHolder(ResourceUtil.getName(path));
- final Iterator<Resource> resources = picker.pickResources(resolver, relativePath).iterator();
+ final ResourceResolver resolver = ctx.getResourceResolver();
+ final Iterator<Resource> resources = picker.pickResources(resolver, relativePath, parent).iterator();
if (!resources.hasNext()) {
return null;
@@ -228,8 +237,11 @@ class MergingResourceProvider implements
} else {
// check parent for hiding
// SLING 3521 : if parent is not readable, nothing is hidden
- final Resource parent = resource.getParent();
- hidden = (parent == null ? false : new ParentHidingHandler(parent, this.traverseHierarchie).isHidden(holder.name));
+ final Resource resourceParent = resource.getParent();
+ hidden = resourceParent != null && new ParentHidingHandler(resourceParent, this.traverseHierarchie).isHidden(holder.name);
+
+ // TODO Usually, the parent does not exist if the resource is a NonExistingResource. Ideally, this
+ // common case should be optimised
}
if (hidden) {
holder.resources.clear();
@@ -246,15 +258,15 @@ class MergingResourceProvider implements
/**
* {@inheritDoc}
*/
- public Iterator<Resource> listChildren(Resource resource) {
- final ResourceResolver resolver = resource.getResourceResolver();
+ public Iterator<Resource> listChildren(final ResolveContext<Void> ctx, final Resource parent) {
+ final ResourceResolver resolver = parent.getResourceResolver();
- final String relativePath = getRelativePath(resource.getPath());
+ final String relativePath = getRelativePath(parent.getPath());
if (relativePath != null) {
final List<ResourceHolder> candidates = new ArrayList<ResourceHolder>();
- final Iterator<Resource> resources = picker.pickResources(resolver, relativePath).iterator();
+ final Iterator<Resource> resources = picker.pickResources(resolver, relativePath, parent).iterator();
boolean isUnderlying = true;
while (resources.hasNext()) {
@@ -323,12 +335,4 @@ class MergingResourceProvider implements
return null;
}
-
- /**
- * {@inheritDoc}
- */
- public Resource getResource(final ResourceResolver resolver, final HttpServletRequest request, final String path) {
- return getResource(resolver, path);
- }
-
}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/MergingResourcePicker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/MergingResourcePicker.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/MergingResourcePicker.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/MergingResourcePicker.java Thu Oct 22 12:40:37 2015
@@ -33,6 +33,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.resourcemerger.api.ResourceMergerService;
+import org.apache.sling.resourcemerger.impl.MergedResource;
import org.apache.sling.resourcemerger.impl.MergedResourceConstants;
import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
@@ -60,23 +61,73 @@ public class MergingResourcePicker imple
private String mergeRootPath;
- public List<Resource> pickResources(final ResourceResolver resolver, final String relativePath) {
+ @Override
+ public List<Resource> pickResources(final ResourceResolver resolver, final String relativePath,
+ final Resource relatedResource) {
+ List<Resource> relatedMappedResources = null;
+ if (relatedResource instanceof MergedResource) {
+ relatedMappedResources = ((MergedResource) relatedResource).getMappedResources();
+
+ // Check if the path is the same
+ if (relatedResource.getPath().equals(mergeRootPath + '/' + relativePath)) {
+ return relatedMappedResources;
+ }
+ }
+
final List<Resource> resources = new ArrayList<Resource>();
final String[] searchPaths = resolver.getSearchPath();
for (int i = searchPaths.length - 1; i >= 0; i--) {
final String basePath = searchPaths[i];
final String fullPath = basePath + relativePath;
- final Resource resource = resolver.getResource(fullPath);
- if (resource != null) {
- resources.add(resource);
- } else {
- resources.add(new NonExistingResource(resolver, fullPath));
+
+ int baseIndex = resources.size();
+ Resource baseResource = null;
+ if (relatedMappedResources != null && relatedMappedResources.size() > baseIndex) {
+ baseResource = relatedMappedResources.get(baseIndex);
}
+
+ Resource resource = (baseResource != null) ? getFromBaseResource(resolver, baseResource, fullPath) : null;
+ if (resource == null) {
+ resource = resolver.getResource(fullPath);
+ if (resource == null) {
+ resource = new NonExistingResource(resolver, fullPath);
+ }
+ }
+ resources.add(resource);
}
return resources;
}
/**
+ * @return <code>null</code> if it did not try to resolve the resource. {@link NonExistingResource} if it could not
+ * find the resource.
+ */
+ private Resource getFromBaseResource(final ResourceResolver resolver, final Resource baseResource,
+ final String path) {
+ final Resource resource;
+ final String baseResourcePath = baseResource.getPath();
+ // Check if the path is a child of the base resource
+ if (path.startsWith(baseResourcePath + '/')) {
+ String relPath = path.substring(baseResourcePath.length() + 1);
+ resource = baseResource.getChild(relPath);
+ }
+ // Check if the path is a direct parent of the base resource
+ else if (baseResourcePath.startsWith(path) && baseResourcePath.lastIndexOf('/') == path.length()) {
+ resource = baseResource.getParent();
+ }
+ // The two resources are not related enough, retrieval cannot be optimised
+ else {
+ return null;
+ }
+ return (resource != null) ? resource : new NonExistingResource(resolver, path);
+ }
+
+ @Override
+ public List<Resource> pickResources(ResourceResolver resolver, String relativePath) {
+ return pickResources(resolver, relativePath, null);
+ }
+
+ /**
* {@inheritDoc}
*/
public String getMergedResourcePath(final String relativePath) {
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java Thu Oct 22 12:40:37 2015
@@ -51,7 +51,9 @@ public class OverridingResourcePicker im
public static final String DEFAULT_ROOT = "/mnt/override";
- public List<Resource> pickResources(ResourceResolver resolver, String relativePath) {
+ public List<Resource> pickResources(ResourceResolver resolver, String relativePath, Resource relatedResource) {
+ // TODO this method can be optimised by leveraging relatedResource (similar to MergingResourcePicker)
+
String absPath = "/" + relativePath;
final List<Resource> resources = new ArrayList<Resource>();
final Set<String> roots = new HashSet<String>();
@@ -96,6 +98,11 @@ public class OverridingResourcePicker im
return resources;
}
+ @Override
+ public List<Resource> pickResources(ResourceResolver resolver, String relativePath) {
+ return pickResources(resolver, relativePath, null);
+ }
+
private void findInheritanceRoot(final Resource target, final InheritanceRootInfo info) {
String superType = target.getResourceSuperType();
if (superType != null) {
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/MergedResourcePicker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/MergedResourcePicker.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/MergedResourcePicker.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/MergedResourcePicker.java Thu Oct 22 12:40:37 2015
@@ -59,13 +59,21 @@ public interface MergedResourcePicker {
String TRAVERSE_PARENT = "merge.traverseParent";
/**
+ * @see #pickResources(ResourceResolver, String, Resource)
+ * @deprecated
+ */
+ List<Resource> pickResources(ResourceResolver resolver, String relativePath);
+
+ /**
* Method invoked by the MergingResourceProvider to identify the resources to be merged for a given
* relative path. The resources returned may be either resources returned from the ResourceResolver
* directory or an instance of NonExistingResource.
*
* @param resolver the ResourceResolver
* @param relativePath the path relative to the merge root
+ * @param relatedResource an optional resource which is related to the given path (parent or child)
* @return a List of Resource objects
*/
- List<Resource> pickResources(ResourceResolver resolver, String relativePath);
+ List<Resource> pickResources(ResourceResolver resolver, String relativePath, Resource relatedResource);
+
}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/package-info.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/package-info.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/spi/package-info.java Thu Oct 22 12:40:37 2015
@@ -20,7 +20,7 @@
/**
* Provides a service to merge multiple physical resources into a single one
*/
-@Version("1.1.0")
+@Version("2.0.0")
package org.apache.sling.resourcemerger.spi;
import aQute.bnd.annotation.Version;
Modified: sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java Thu Oct 22 12:40:37 2015
@@ -36,6 +36,8 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.resourcemerger.impl.picker.MergingResourcePicker;
+import org.apache.sling.resourceresolver.impl.BasicResolveContext;
+import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.testing.resourceresolver.MockHelper;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions;
@@ -47,6 +49,7 @@ public class MergedResourceProviderTest
private ResourceResolver resolver;
private CRUDMergingResourceProvider provider;
+ private ResolveContext<Void> ctx;
@Before public void setup() throws Exception {
final MockResourceResolverFactoryOptions options = new MockResourceResolverFactoryOptions();
@@ -66,6 +69,7 @@ public class MergedResourceProviderTest
.p("b", "x")
.p("d", "1")
.resource(".X")
+ .resource("/apps/b").resource("c").resource("d").resource("e").resource("f")
.resource("/libs")
.resource("deleteTest")
.resource(".mvmTest").p("a", "1").p("b", "2")
@@ -79,9 +83,11 @@ public class MergedResourceProviderTest
.resource("/libs/a/Y/a")
.resource("/libs/a/Y/b")
.resource("/libs/a/Y/c")
+ .resource("/libs/b").resource("c").resource("d").resource("e").resource("f")
.commit();
this.provider = new CRUDMergingResourceProvider("/merged", new MergingResourcePicker(), false);
+ this.ctx = new BasicResolveContext(resolver, Collections.<String, String>emptyMap(), null);
}
@Test public void testHideChildren() {
@@ -98,17 +104,17 @@ public class MergedResourceProviderTest
assertNull(this.resolver.getResource("/apps/a/y"));
// now do the real checks
- assertNull(this.provider.getResource(this.resolver, "/merged/a/Z"));
- assertNotNull(this.provider.getResource(this.resolver, "/merged/a/Y"));
- assertNotNull(this.provider.getResource(this.resolver, "/merged/a/X"));
- assertNull(this.provider.getResource(this.resolver, "/merged/a/x"));
- assertNull(this.provider.getResource(this.resolver, "/merged/a/y"));
+ assertNull(this.provider.getResource(ctx, "/merged/a/Z", null));
+ assertNotNull(this.provider.getResource(ctx, "/merged/a/Y", null));
+ assertNotNull(this.provider.getResource(ctx, "/merged/a/X", null));
+ assertNull(this.provider.getResource(ctx, "/merged/a/x", null));
+ assertNull(this.provider.getResource(ctx, "/merged/a/y", null));
}
@Test public void testListChildren() {
- final Resource rsrcA = this.provider.getResource(this.resolver, "/merged/a");
+ final Resource rsrcA = this.provider.getResource(ctx, "/merged/a", null);
assertNotNull(rsrcA);
- final Iterator<Resource> i = this.provider.listChildren(rsrcA);
+ final Iterator<Resource> i = this.provider.listChildren(ctx, rsrcA);
assertNotNull(i);
final List<String> names = new ArrayList<String>();
while ( i.hasNext() ) {
@@ -124,9 +130,9 @@ public class MergedResourceProviderTest
}
@Test public void testListSubChildren() {
- final Resource rsrcY = this.provider.getResource(this.resolver, "/merged/a/Y");
+ final Resource rsrcY = this.provider.getResource(ctx, "/merged/a/Y", null);
assertNotNull(rsrcY);
- final Iterator<Resource> i = this.provider.listChildren(rsrcY);
+ final Iterator<Resource> i = this.provider.listChildren(ctx, rsrcY);
assertNotNull(i);
final List<String> names = new ArrayList<String>();
while ( i.hasNext() ) {
@@ -139,7 +145,7 @@ public class MergedResourceProviderTest
}
@Test public void testProperties() {
- final Resource rsrcA1 = this.provider.getResource(this.resolver, "/merged/a/1");
+ final Resource rsrcA1 = this.provider.getResource(ctx, "/merged/a/1", null);
final ValueMap vm = rsrcA1.adaptTo(ValueMap.class);
assertNotNull(vm);
assertEquals(3, vm.size());
@@ -150,24 +156,24 @@ public class MergedResourceProviderTest
@Test public void testResourceType() {
// a/2 defines the property and it's overlayed
- final Resource rsrcA2 = this.provider.getResource(this.resolver, "/merged/a/2");
+ final Resource rsrcA2 = this.provider.getResource(ctx, "/merged/a/2", null);
assertEquals("apps", rsrcA2.getResourceType());
// a/12 doesn't define the property and it's overlayed
- final Resource rsrcA1 = this.provider.getResource(this.resolver, "/merged/a/1");
+ final Resource rsrcA1 = this.provider.getResource(ctx, "/merged/a/1", null);
assertEquals("a/1", rsrcA1.getResourceType());
}
@Test public void testClearProperties() {
- final Resource rsrcA3 = this.provider.getResource(this.resolver, "/merged/a/3");
+ final Resource rsrcA3 = this.provider.getResource(ctx, "/merged/a/3", null);
final ValueMap vm = rsrcA3.adaptTo(ValueMap.class);
assertNotNull(vm);
assertEquals(0, vm.size());
}
@Test public void testHideProperties() {
- final Resource rsrcA4 = this.provider.getResource(this.resolver, "/merged/a/4");
+ final Resource rsrcA4 = this.provider.getResource(ctx, "/merged/a/4", null);
final ValueMap vm = rsrcA4.adaptTo(ValueMap.class);
assertNotNull(vm);
assertEquals(3, vm.size());
@@ -179,7 +185,7 @@ public class MergedResourceProviderTest
@Test public void testSimpleCreateAndDelete() throws PersistenceException {
final String path = "/merged/a/new";
try {
- final Resource rsrc = this.provider.create(this.resolver, path, Collections.singletonMap("foo", (Object)"bla"));
+ final Resource rsrc = this.provider.create(ctx, path, Collections.singletonMap("foo", (Object)"bla"));
assertNotNull(rsrc);
assertEquals(path, rsrc.getPath());
final ValueMap vm = ResourceUtil.getValueMap(rsrc);
@@ -191,8 +197,8 @@ public class MergedResourceProviderTest
assertEquals("bla", vmReal.get("foo"));
assertNull(this.resolver.getResource("/libs/a/new"));
- this.provider.delete(this.resolver, path);
- assertNull(this.provider.getResource(this.resolver, path));
+ this.provider.delete(ctx, rsrc);
+ assertNull(this.provider.getResource(ctx, path, null));
assertNull(this.resolver.getResource("/libs/a/new"));
assertNull(this.resolver.getResource("/apps/a/new"));
@@ -207,13 +213,13 @@ public class MergedResourceProviderTest
assertNotNull(this.resolver.getResource("/libs/deleteTest"));
assertNull(this.resolver.getResource("/apps/deleteTest"));
- final Resource rsrc = this.provider.getResource(this.resolver, path);
+ final Resource rsrc = this.provider.getResource(ctx, path, null);
assertNotNull(rsrc);
assertEquals(path, rsrc.getPath());
- this.provider.delete(this.resolver, path);
+ this.provider.delete(ctx, rsrc);
- assertNull(this.provider.getResource(this.resolver, path));
+ assertNull(this.provider.getResource(ctx, path, null));
assertNotNull(this.resolver.getResource("/libs/deleteTest"));
final Resource hidingRsrc = this.resolver.getResource("/apps/deleteTest");
assertNotNull(hidingRsrc);
@@ -231,14 +237,14 @@ public class MergedResourceProviderTest
assertNotNull(this.resolver.getResource("/libs/deleteTest"));
assertNull(this.resolver.getResource("/apps/deleteTest"));
- final Resource rsrc = this.provider.getResource(this.resolver, path);
+ final Resource rsrc = this.provider.getResource(ctx, path, null);
assertNotNull(rsrc);
assertEquals(path, rsrc.getPath());
- this.provider.delete(this.resolver, path);
- this.provider.create(this.resolver, path, Collections.singletonMap("foo", (Object)"bla"));
+ this.provider.delete(ctx, rsrc);
+ this.provider.create(ctx, path, Collections.singletonMap("foo", (Object)"bla"));
- assertNotNull(this.provider.getResource(this.resolver, path));
+ assertNotNull(this.provider.getResource(ctx, path, null));
assertNotNull(this.resolver.getResource("/libs/deleteTest"));
final Resource hidingRsrc = this.resolver.getResource("/apps/deleteTest");
assertNotNull(hidingRsrc);
@@ -256,7 +262,7 @@ public class MergedResourceProviderTest
assertNotNull(this.resolver.getResource("/libs/mvmTest"));
assertNull(this.resolver.getResource("/apps/mvmTest"));
- final Resource rsrc = this.provider.getResource(this.resolver, path);
+ final Resource rsrc = this.provider.getResource(ctx, path, null);
assertNotNull(rsrc);
final ValueMap beforeVM = rsrc.getValueMap();
assertEquals("1", beforeVM.get("a"));
@@ -273,7 +279,7 @@ public class MergedResourceProviderTest
assertNotNull(this.resolver.getResource("/libs/mvmTest"));
assertNotNull(this.resolver.getResource("/apps/mvmTest"));
- final Resource rsrc2 = this.provider.getResource(this.resolver, path);
+ final Resource rsrc2 = this.provider.getResource(ctx, path, null);
assertNotNull(rsrc2);
final ValueMap afterVM = rsrc2.getValueMap();
assertNull(afterVM.get("a"));
@@ -299,4 +305,37 @@ public class MergedResourceProviderTest
}
}
+
+ @Test public void testGetWithRelatedResource() {
+ final String path = "/merged/b/c/d";
+ String[] relatedPaths = new String[] {
+ null, // no related resource
+ "/merged/a", // not related
+ "/merged/b", // parent of parent
+ "/merged/b/c", // parent
+ "/merged/b/c/d", // itself
+ "/merged/b/c/d/e", // child
+ "/merged/b/c/d/e/f" // deep child
+ };
+ for (String relatedPath : relatedPaths) {
+ final Resource relatedResource;
+ if (relatedPath != null) {
+ relatedResource = provider.getResource(ctx, relatedPath, null);
+ assertNotNull("Not found: " + relatedPath, relatedResource);
+ } else {
+ relatedResource = null;
+ }
+ Resource resource = provider.getResource(ctx, path, relatedResource);
+ assertNotNull(resource);
+ assertEquals(path, resource.getPath());
+ assertTrue(resource instanceof MergedResource);
+
+ MergedResource mergedResource = (MergedResource) resource;
+ List<Resource> mappedResources = mergedResource.getMappedResources();
+ assertEquals(2, mappedResources.size());
+ assertEquals(mappedResources.get(0).getPath(), "/libs/b/c/d");
+ assertEquals(mappedResources.get(1).getPath(), "/apps/b/c/d");
+ }
+ }
+
}
Modified: sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java?rev=1710006&r1=1710005&r2=1710006&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java Thu Oct 22 12:40:37 2015
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -33,6 +34,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.resourcemerger.impl.picker.OverridingResourcePicker;
+import org.apache.sling.resourceresolver.impl.BasicResolveContext;
import org.apache.sling.testing.resourceresolver.MockHelper;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions;
@@ -46,6 +48,7 @@ public class OverridingResourceProviderT
private ResourceResolver resolver;
private MergingResourceProvider provider;
+ private BasicResolveContext ctx;
/*
* Tree is:
@@ -98,11 +101,12 @@ public class OverridingResourceProviderT
.commit();
this.provider = new MergingResourceProvider("/override", new OverridingResourcePicker(), false, true);
+ this.ctx = new BasicResolveContext(resolver, Collections.<String, String>emptyMap(), null);
}
@Test
public void testOverridingOnTarget() {
- final Resource rsrcA2 = this.provider.getResource(this.resolver, "/override/apps/a/2");
+ final Resource rsrcA2 = this.provider.getResource(ctx, "/override/apps/a/2", null);
final ValueMap vm = rsrcA2.adaptTo(ValueMap.class);
assertNotNull(vm);
assertEquals(3, vm.size()); //3rd is resource:superType
@@ -112,7 +116,7 @@ public class OverridingResourceProviderT
@Test
public void testOverridingViaParent() {
- final Resource rsrcA2 = this.provider.getResource(this.resolver, "/override/apps/a/2/c");
+ final Resource rsrcA2 = this.provider.getResource(ctx, "/override/apps/a/2/c", null);
final ValueMap vm = rsrcA2.adaptTo(ValueMap.class);
assertNotNull(vm);
assertEquals(2, vm.size());
@@ -122,16 +126,16 @@ public class OverridingResourceProviderT
@Test
public void testInheritingFromGrandParent() {
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/3/a"));
- assertNull(this.provider.getResource(this.resolver, "/override/apps/a/3/b"));
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/3/c"));
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/3/d"));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/3/a", null));
+ assertNull(this.provider.getResource(ctx, "/override/apps/a/3/b", null));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/3/c", null));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/3/d", null));
}
@Test
public void testHideChildrenFromList() {
- final Resource rsrcA2 = this.provider.getResource(this.resolver, "/override/apps/a/2");
- final Iterator<Resource> children = this.provider.listChildren(rsrcA2);
+ final Resource rsrcA2 = this.provider.getResource(ctx, "/override/apps/a/2", null);
+ final Iterator<Resource> children = this.provider.listChildren(ctx, rsrcA2);
final List<String> names = new ArrayList<String>();
while (children.hasNext()) {
names.add(children.next().getName());
@@ -143,18 +147,18 @@ public class OverridingResourceProviderT
@Test
public void testHideChildrenFromGet() {
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/1/b/1"));
- assertNull(this.provider.getResource(this.resolver, "/override/apps/a/2/b"));
- assertNull(this.provider.getResource(this.resolver, "/override/apps/a/2/b/1"));
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/2/d/1/a"));
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/2/d/1/b"));
- assertNotNull(this.provider.getResource(this.resolver, "/override/apps/a/2/d/1/b/1"));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/1/b/1", null));
+ assertNull(this.provider.getResource(ctx, "/override/apps/a/2/b", null));
+ assertNull(this.provider.getResource(ctx, "/override/apps/a/2/b/1", null));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/2/d/1/a", null));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/2/d/1/b", null));
+ assertNotNull(this.provider.getResource(ctx, "/override/apps/a/2/d/1/b/1", null));
}
// doing it this way because the mock resource resolver doesn't
// access the resource provider
private Resource getChildResource(Resource parent, String name) {
- final Iterator<Resource> children = this.provider.listChildren(parent);
+ final Iterator<Resource> children = this.provider.listChildren(ctx, parent);
while (children.hasNext()) {
final Resource candidate = children.next();
if (candidate.getName().equals(name)) {
@@ -166,7 +170,7 @@ public class OverridingResourceProviderT
@Test
public void testOverriddenIncludesChildFromSuper() {
- final Resource rsrcA2 = this.provider.getResource(this.resolver, "/override/apps/a/2");
+ final Resource rsrcA2 = this.provider.getResource(ctx, "/override/apps/a/2", null);
Resource d = getChildResource(rsrcA2, "d");
assertNotNull(d);
@@ -180,12 +184,12 @@ public class OverridingResourceProviderT
@Test
public void testLoopInInheritance() {
- final Resource rsrcA4 = this.provider.getResource(this.resolver, "/override/apps/a/4");
+ final Resource rsrcA4 = this.provider.getResource(ctx, "/override/apps/a/4", null);
Resource d = getChildResource(rsrcA4, "d");
assertNotNull(d);
- final Resource z = this.provider.getResource(this.resolver, "/override/apps/x/z");
+ final Resource z = this.provider.getResource(ctx, "/override/apps/x/z", null);
assertNotNull(z);
}
}