You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:58:58 UTC
[sling-org-apache-sling-resourcemerger] 18/24: SLING-2986 : Fix
resource hiding when parent resource contains attribute but child resource
is not available. Reduce resource getting to a minimum
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.resourcemerger-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourcemerger.git
commit d3fa422413894cc8cdc2e82fa080b3d0ccef4b31
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Feb 7 13:38:39 2014 +0000
SLING-2986 : Fix resource hiding when parent resource contains attribute but child resource is not available. Reduce resource getting to a minimum
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/resourcemerger@1565644 13f79535-47bb-0310-9956-ffa450edef68
---
.../sling/resourcemerger/impl/MergedResource.java | 45 +----
.../impl/MergedResourceProvider.java | 199 ++++++++++++++++-----
.../sling/resourcemerger/impl/MergedValueMap.java | 49 +++--
.../impl/MergedResourceProviderTest.java | 31 ++--
4 files changed, 196 insertions(+), 128 deletions(-)
diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
index df1da1a..01a223e 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
@@ -48,19 +48,6 @@ public class MergedResource extends AbstractResource {
* Constructor
*
* @param resolver Resource resolver
- * @param mergeRootPath Merge root path
- * @param relativePath Relative path
- */
- MergedResource(final ResourceResolver resolver,
- final String mergeRootPath,
- final String relativePath) {
- this(resolver, mergeRootPath, relativePath, null);
- }
-
- /**
- * Constructor
- *
- * @param resolver Resource resolver
* @param mergeRootPath Merge root path
* @param relativePath Relative path
* @param mappedResources List of physical mapped resources' paths
@@ -68,38 +55,25 @@ public class MergedResource extends AbstractResource {
MergedResource(final ResourceResolver resolver,
final String mergeRootPath,
final String relativePath,
- final List<String> mappedResources) {
+ final List<Resource> mappedResources,
+ final List<ValueMap> valueMaps) {
this.resolver = resolver;
this.path = (relativePath.length() == 0 ? mergeRootPath : mergeRootPath + "/" + relativePath);
this.relativePath = (relativePath.length() == 0 ? "/" : relativePath);
if ( mappedResources != null ) {
- this.mappedResources.addAll(mappedResources);
+ for(final Resource rsrc : mappedResources) {
+ this.mappedResources.add(rsrc.getPath());
+ }
}
- this.resourceType = this.adaptTo(ValueMap.class).get(ResourceResolver.PROPERTY_RESOURCE_TYPE, this.relativePath);
+ this.properties = new MergedValueMap(valueMaps);
+ this.resourceType = this.properties.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, this.relativePath);
metadata.put("sling.mergedResource", true);
- metadata.put("sling.mappedResources", mappedResources.toArray(new String[mappedResources.size()]));
- }
-
-
- // ---- MergedResource interface ------------------------------------------
-
- public String getRelativePath() {
- return relativePath;
+ metadata.put("sling.mappedResources", this.mappedResources.toArray(new String[this.mappedResources.size()]));
}
/**
* {@inheritDoc}
*/
- public Iterable<String> getMappedResources() {
- return mappedResources;
- }
-
-
- // ---- Resource interface ------------------------------------------------
-
- /**
- * {@inheritDoc}
- */
public String getPath() {
return this.path;
}
@@ -141,9 +115,6 @@ public class MergedResource extends AbstractResource {
@SuppressWarnings("unchecked")
public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
if (type == ValueMap.class) {
- if ( this.properties == null ) {
- this.properties = new MergedValueMap(this);
- }
return (AdapterType) this.properties;
}
diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourceProvider.java b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourceProvider.java
index a152c2f..ad787a7 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourceProvider.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResourceProvider.java
@@ -56,46 +56,100 @@ public class MergedResourceProvider implements ResourceProvider {
final String relativePath = getRelativePath(path);
if ( relativePath != null ) {
- final List<String> mappedResources = new ArrayList<String>();
- // Loop over provided base paths
- for (final String basePath : resolver.getSearchPath()) {
+ final ResourceHolder holder = new ResourceHolder(ResourceUtil.getName(path));
+
+ // Loop over provided base paths, start with least import
+ final String[] searchPaths = resolver.getSearchPath();
+ for(int i=searchPaths.length-1; i >= 0; i--) {
+ final String basePath = searchPaths[i];
+
// Try to get the corresponding physical resource for this base path
- final Resource baseRes = resolver.getResource(basePath + "/" + relativePath);
- if (baseRes != null) {
- // check if resource is hidden
+ final String fullPath = basePath + "/" + relativePath;
+
+ // check parent for hiding
+ final Resource parent = resolver.getResource(ResourceUtil.getParent(fullPath));
+ if ( parent != null ) {
boolean hidden = false;
- final ValueMap props = ResourceUtil.getValueMap(baseRes);
- if ( props.get(MergedResourceConstants.PN_HIDE_RESOURCE, Boolean.FALSE) ) {
- hidden = true;
- }
- if ( !hidden ) {
- // check parent
- final ValueMap parentProps = ResourceUtil.getValueMap(baseRes.getParent());
- final String[] childrenToHideArray = parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
- if ( childrenToHideArray != null ) {
- for(final String name : childrenToHideArray ) {
- if ( name.equals(baseRes.getName()) || name.equals("*") ) {
- hidden = true;
- break;
- }
+ final ValueMap parentProps = ResourceUtil.getValueMap(parent);
+ final String[] childrenToHideArray = parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
+ if ( childrenToHideArray != null ) {
+ for(final String name : childrenToHideArray ) {
+ if ( name.equals(holder.name) || name.equals("*") ) {
+ hidden = true;
+ break;
}
}
}
- if ( !hidden ) {
- // Physical resource exists, add it to the list of mapped resources
- mappedResources.add(0, baseRes.getPath());
+ if ( hidden ) {
+ holder.resources.clear();
} else {
- mappedResources.clear();
+ final Resource baseRes = resolver.getResource(fullPath);
+ if (baseRes != null) {
+ holder.resources.add(baseRes);
+ }
}
}
}
+ return createMergedResource(resolver, relativePath, holder);
+ }
+
+ return null;
+ }
+
+ private static final class ResourceHolder {
+ public final String name;
+ public final List<Resource> resources = new ArrayList<Resource>();
+ public final List<ValueMap> valueMaps = new ArrayList<ValueMap>();
+
+ public ResourceHolder(final String n) {
+ this.name = n;
+ }
+ }
- if (!mappedResources.isEmpty()) {
- // Create a new merged resource based on the list of mapped physical resources
- return new MergedResource(resolver, mergeRootPath, relativePath, mappedResources);
+ /**
+ * Create the merged resource based on the provided resources
+ */
+ private Resource createMergedResource(final ResourceResolver resolver,
+ final String relativePath,
+ final ResourceHolder holder) {
+ int index = 0;
+ while ( index < holder.resources.size() ) {
+ final Resource baseRes = holder.resources.get(index);
+ // check if resource is hidden
+ boolean hidden = false;
+ final ValueMap props = ResourceUtil.getValueMap(baseRes);
+ holder.valueMaps.add(props);
+ if ( props.get(MergedResourceConstants.PN_HIDE_RESOURCE, Boolean.FALSE) ) {
+ hidden = true;
+ }
+ if ( !hidden ) {
+ // check parent
+ final ValueMap parentProps = ResourceUtil.getValueMap(baseRes.getParent());
+ final String[] childrenToHideArray = parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
+ if ( childrenToHideArray != null ) {
+ for(final String name : childrenToHideArray ) {
+ if ( name.equals(baseRes.getName()) || name.equals("*") ) {
+ hidden = true;
+ break;
+ }
+ }
+ }
+ }
+ if ( hidden ) {
+ // clear everything up to now
+ for(int i=0;i<=index;i++) {
+ holder.resources.remove(0);
+ }
+ holder.valueMaps.clear();
+ index = -1; // start at zero
}
+ index++;
}
+ if (!holder.resources.isEmpty()) {
+ // create a new merged resource based on the list of mapped physical resources
+ return new MergedResource(resolver, mergeRootPath, relativePath, holder.resources, holder.valueMaps);
+ }
return null;
}
@@ -108,35 +162,82 @@ public class MergedResourceProvider implements ResourceProvider {
final String relativePath = getRelativePath(resource.getPath());
if ( relativePath != null ) {
- final List<String> names = new ArrayList<String>();
- // Loop over provided base paths
- for (final String basePath : resolver.getSearchPath()) {
- final Resource baseResource = resolver.getResource(basePath + "/" + relativePath);
- if ( baseResource != null ) {
- for(final Resource child : baseResource.getChildren()) {
- final String rsrcName = child.getName();
- if ( !names.contains(rsrcName) ) {
- names.add(rsrcName);
- }
- // Check if children need reordering
- int orderBeforeIndex = -1;
- final ValueMap vm = ResourceUtil.getValueMap(child);
- final String orderBefore = vm.get(MergedResourceConstants.PN_ORDER_BEFORE, String.class);
- if (orderBefore != null && !orderBefore.equals(rsrcName)) {
- // search entry
- orderBeforeIndex = names.indexOf(orderBefore);
+ final List<ResourceHolder> candidates = new ArrayList<ResourceHolder>();
+
+ // Loop over provided base paths, start with least import
+ final String[] searchPaths = resolver.getSearchPath();
+ for(int i=searchPaths.length-1; i >= 0; i--) {
+ final String basePath = searchPaths[i];
+ final Resource parentResource = resolver.getResource(basePath + "/" + relativePath);
+ if ( parentResource != null ) {
+ final ValueMap parentProps = ResourceUtil.getValueMap(parentResource);
+ List<String> childrenToHide = new ArrayList<String>();
+ boolean hideAll = false;
+ final String[] childrenToHideArray = parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
+ if ( childrenToHideArray != null ) {
+ for(final String name : childrenToHideArray ) {
+ if ( name.equals("*") ) {
+ hideAll = true;
+ } else {
+ childrenToHide.add(name);
+ }
}
+ }
+ if ( hideAll ) {
+ candidates.clear();
+ } else {
+ for(final Resource child : parentResource.getChildren()) {
+ final String rsrcName = child.getName();
+ ResourceHolder holder = null;
+ for(final ResourceHolder current : candidates) {
+ if ( current.name.equals(rsrcName) ) {
+ holder = current;
+ break;
+ }
+ }
+ if ( holder == null ) {
+ holder = new ResourceHolder(rsrcName);
+ candidates.add(holder);
+ }
+ holder.resources.add(child);
+
+ // Check if children need reordering
+ int orderBeforeIndex = -1;
+ final ValueMap vm = ResourceUtil.getValueMap(child);
+ final String orderBefore = vm.get(MergedResourceConstants.PN_ORDER_BEFORE, String.class);
+ if (orderBefore != null && !orderBefore.equals(rsrcName)) {
+ // search entry
+ int index = 0;
+ while (index < candidates.size()) {
+ final ResourceHolder current = candidates.get(index);
+ if ( current.name.equals(orderBefore) ) {
+ orderBeforeIndex = index;
+ break;
+ }
+ index++;
+ }
+ }
- if (orderBeforeIndex > -1) {
- names.add(orderBeforeIndex, rsrcName);
- names.remove(names.size() - 1);
+ if (orderBeforeIndex > -1) {
+ candidates.add(orderBeforeIndex, holder);
+ candidates.remove(candidates.size() - 1);
+ }
+ }
+ if ( childrenToHide.size() > 0 ) {
+ final Iterator<ResourceHolder> iter = candidates.iterator();
+ while ( iter.hasNext() ) {
+ final ResourceHolder holder = iter.next();
+ if ( childrenToHide.contains(holder.name) ) {
+ iter.remove();
+ }
+ }
}
}
}
}
final List<Resource> children = new ArrayList<Resource>();
- for(final String name : names) {
- final Resource mergedResource = this.getResource(resolver, resource.getPath() + "/" + name);
+ for(final ResourceHolder holder : candidates) {
+ final Resource mergedResource = this.createMergedResource(resolver, relativePath + '/' + holder.name, holder);
if ( mergedResource != null ) {
children.add(mergedResource);
}
diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java b/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
index 3a888fa..4bb186d 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
@@ -20,10 +20,9 @@ package org.apache.sling.resourcemerger.impl;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
@@ -50,34 +49,30 @@ public class MergedValueMap extends ValueMapDecorator {
*
* @param resource The merged resource to get properties from
*/
- public MergedValueMap(final MergedResource resource) {
+ public MergedValueMap(final List<ValueMap> valueMaps) {
super(new HashMap<String, Object>());
- // Iterate over physical resources
- for (final String r : resource.getMappedResources()) {
- final Resource rsrc = resource.getResourceResolver().getResource(r);
- if ( rsrc != null ) {
- final ValueMap vm = ResourceUtil.getValueMap(rsrc);
- if (this.isEmpty()) {
- // Add all properties
- this.putAll(vm);
- } else {
- // Get properties to add or override
- for (final String key : vm.keySet()) {
- if (!isExcludedProperty(key)) {
- this.put(key, vm.get(key));
- }
+ // Iterate over value maps
+ for (final ValueMap vm : valueMaps) {
+ if (this.isEmpty()) {
+ // Add all properties
+ this.putAll(vm);
+ } else {
+ // Get properties to add or override
+ for (final String key : vm.keySet()) {
+ if (!isExcludedProperty(key)) {
+ this.put(key, vm.get(key));
}
+ }
- // Get properties to hide
- final String[] propertiesToHide = vm.get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
- if ( propertiesToHide != null ) {
- for (final String propName : propertiesToHide) {
- if (propName.equals("*")) {
- this.clear();
- break;
- } else {
- this.remove(propName);
- }
+ // Get properties to hide
+ final String[] propertiesToHide = vm.get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
+ if ( propertiesToHide != null ) {
+ for (final String propName : propertiesToHide) {
+ if (propName.equals("*")) {
+ this.clear();
+ break;
+ } else {
+ this.remove(propName);
}
}
}
diff --git a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
index e6d703f..08bbab2 100644
--- a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
+++ b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
@@ -45,25 +45,26 @@ public class MergedResourceProviderTest {
final ResourceResolverFactory factory = new MockResourceResolverFactory();
this.resolver = factory.getAdministrativeResourceResolver(null);
MockHelper.create(this.resolver).resource("/apps")
- .resource("a")
+ .resource("a").p(MergedResourceConstants.PN_HIDE_CHILDREN, new String[] {"Z", "x", "y"})
.resource("1").p("a", "1").p("b", "2")
- .resource("./2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "apps")
- .resource("./3").p("e", "2")
- .p(MergedResourceConstants.PN_HIDE_PROPERTIES, "*")
- .p("b", "x")
- .p("d", "1")
- .resource("./4").p("e", "2")
- .p(MergedResourceConstants.PN_HIDE_PROPERTIES, new String[] {"a", "c"})
- .p("b", "x")
- .p("d", "1")
- .resource("./X")
+ .resource(".2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "apps")
+ .resource(".3").p("e", "2")
+ .p(MergedResourceConstants.PN_HIDE_PROPERTIES, "*")
+ .p("b", "x")
+ .p("d", "1")
+ .resource(".4").p("e", "2")
+ .p(MergedResourceConstants.PN_HIDE_PROPERTIES, new String[] {"a", "c"})
+ .p("b", "x")
+ .p("d", "1")
+ .resource(".X")
.resource("/libs")
.resource("a")
.resource("1").p("a", "5").p("c", "2")
- .resource("./2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "libs")
- .resource("./3").p("a", "1").p("b", "2").p("c", "3")
- .resource("./4").p("a", "1").p("b", "2").p("c", "3")
- .resource("./Y")
+ .resource(".2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "libs")
+ .resource(".3").p("a", "1").p("b", "2").p("c", "3")
+ .resource(".4").p("a", "1").p("b", "2").p("c", "3")
+ .resource(".Y")
+ .resource(".Z")
.commit();
this.provider = new MergedResourceProvider("/merged");
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.