sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1582628 - in /sling/trunk/bundles/resourceresolver/src: main/java/org/apache/sling/resourceresolver/impl/ main/java/org/apache/sling/resourceresolver/impl/mapping/ test/java/org/apache/sling/resourceresolver/impl/mapping/
Date Fri, 28 Mar 2014 07:04:20 GMT
Author: cziegeler
Date: Fri Mar 28 07:04:20 2014
New Revision: 1582628

URL: http://svn.apache.org/r1582628
Log:
SLING-3043 : Allow regexp filtering of vanity paths

Modified:
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
    sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java?rev=1582628&r1=1582627&r2=1582628&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
(original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
Fri Mar 28 07:04:20 2014
@@ -18,7 +18,10 @@
  */
 package org.apache.sling.resourceresolver.impl;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.collections.BidiMap;
@@ -197,7 +200,24 @@ public class CommonResourceResolverFacto
         return this.activator.isOptimizeAliasResolutionEnabled();
     }
 
-    public String[] getVanityPathWhiteList() {
-        return this.activator.getVanityPathWhiteList();
+    public List<VanityPathConfig> getVanityPathConfig() {
+        final String[] includes = this.activator.getVanityPathWhiteList();
+        final String[] excludes = this.activator.getVanityPathBlackList();
+        if ( includes == null && excludes == null ) {
+            return null;
+        }
+        final List<VanityPathConfig> configs = new ArrayList<VanityPathConfig>();
+        if ( includes != null ) {
+            for(final String val : includes) {
+                configs.add(new VanityPathConfig(val, false));
+            }
+        }
+        if ( excludes != null ) {
+            for(final String val : excludes) {
+                configs.add(new VanityPathConfig(val, true));
+            }
+        }
+        Collections.sort(configs);
+        return configs;
     }
 }
\ No newline at end of file

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java?rev=1582628&r1=1582627&r2=1582628&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
(original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
Fri Mar 28 07:04:20 2014
@@ -194,11 +194,18 @@ public class ResourceResolverFactoryActi
     private static final String PROP_ENABLE_OPTIMIZE_ALIAS_RESOLUTION = "resource.resolver.optimize.alias.resolution";
 
     @Property(unbounded=PropertyUnbounded.ARRAY,
-            label = "Vanity Path Prefix",
+            label = "Allowed Vanity Path Location",
             description ="This setting can contain a list of path prefixes, e.g. /libs/,
/content/. If " +
                     "such a list is configured, only vanity paths from resources starting
with this prefix " +
-                    " are considered. if the list is empty, all vanity paths are used.")
-    private static final String PROP_VANITY_PATH_PREFIX = "resource.resolver.vanitypath.whitelist";
+                    " are considered. If the list is empty, all vanity paths are used.")
+    private static final String PROP_ALLOWED_VANITY_PATH_PREFIX = "resource.resolver.vanitypath.whitelist";
+
+    @Property(unbounded=PropertyUnbounded.ARRAY,
+            label = "Denied Vanity Path Location",
+            description ="This setting can contain a list of path prefixes, e.g. /misc/.
If " +
+                    "such a list is configured,vanity paths from resources starting with
this prefix " +
+                    " are not considered. If the list is empty, all vanity paths are used.")
+    private static final String PROP_DENIED_VANITY_PATH_PREFIX = "resource.resolver.vanitypath.blacklist";
 
     /** Tracker for the resource decorators. */
     private final ResourceDecoratorTracker resourceDecoratorTracker = new ResourceDecoratorTracker();
@@ -249,6 +256,9 @@ public class ResourceResolverFactoryActi
     /** Vanity path whitelist */
     private String[] vanityPathWhiteList;
 
+    /** Vanity path blacklist */
+    private String[] vanityPathBlackList;
+
     private final FactoryPreconditions preconds = new FactoryPreconditions();
 
     /** Factory registration. */
@@ -319,6 +329,10 @@ public class ResourceResolverFactoryActi
         return this.vanityPathWhiteList;
     }
 
+    public String[] getVanityPathBlackList() {
+        return this.vanityPathBlackList;
+    }
+
     // ---------- SCR Integration ---------------------------------------------
 
     /** Activates this component, called by SCR before registering as a service */
@@ -384,7 +398,7 @@ public class ResourceResolverFactoryActi
         this.enableVanityPath = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_VANITY_PATH),
DEFAULT_ENABLE_VANITY_PATH);
         // vanity path white list
         this.vanityPathWhiteList = null;
-        final String[] vanityPathPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_VANITY_PATH_PREFIX));
+        String[] vanityPathPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_ALLOWED_VANITY_PATH_PREFIX));
         if ( vanityPathPrefixes != null ) {
             final List<String> prefixList = new ArrayList<String>();
             for(final String value : vanityPathPrefixes) {
@@ -400,6 +414,24 @@ public class ResourceResolverFactoryActi
                 this.vanityPathWhiteList = prefixList.toArray(new String[prefixList.size()]);
             }
         }
+        // vanity path black list
+        this.vanityPathBlackList = null;
+        vanityPathPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_DENIED_VANITY_PATH_PREFIX));
+        if ( vanityPathPrefixes != null ) {
+            final List<String> prefixList = new ArrayList<String>();
+            for(final String value : vanityPathPrefixes) {
+                if ( value.trim().length() > 0 ) {
+                    if ( value.trim().endsWith("/") ) {
+                        prefixList.add(value.trim());
+                    } else {
+                        prefixList.add(value.trim() + "/");
+                    }
+                }
+            }
+            if ( prefixList.size() > 0 ) {
+                this.vanityPathBlackList = prefixList.toArray(new String[prefixList.size()]);
+            }
+        }
 
         this.enableOptimizeAliasResolution = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_OPTIMIZE_ALIAS_RESOLUTION),
DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION);
 

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java?rev=1582628&r1=1582627&r2=1582628&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
(original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
Fri Mar 28 07:04:20 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.sling.resourceresolver.impl.mapping;
 
+import java.util.List;
 import java.util.Map;
 
 import org.apache.sling.api.resource.ResourceResolverFactory;
@@ -41,9 +42,23 @@ public interface MapConfigurationProvide
 
     boolean isOptimizeAliasResolutionEnabled();
 
+    public class VanityPathConfig implements Comparable<VanityPathConfig> {
+        public final boolean isExclude;
+        public final String prefix;
+
+        public VanityPathConfig(final String prefix, final boolean isExclude) {
+            this.prefix = prefix;
+            this.isExclude = isExclude;
+        }
+
+        public int compareTo(VanityPathConfig o2) {
+            return new Integer(o2.prefix.length()).compareTo(this.prefix.length());
+        }
+    }
+
     /**
-     * A list of white list prefixes all ending with a slash.
+     * A list of white and black list prefixes all ending with a slash.
      * If <code>null</code> is returned, all paths are allowed.
      */
-    String[] getVanityPathWhiteList();
+    List<VanityPathConfig> getVanityPathConfig();
 }

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java?rev=1582628&r1=1582627&r2=1582628&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
(original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
Fri Mar 28 07:04:20 2014
@@ -50,6 +50,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl;
 import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
+import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -112,7 +113,7 @@ public class MapEntries implements Event
 
     private final boolean enableOptimizeAliasResolution;
 
-    private final String[] vanityPathWhiteList;
+    private final List<VanityPathConfig> vanityPathConfig;
 
     @SuppressWarnings("unchecked")
     private MapEntries() {
@@ -128,7 +129,7 @@ public class MapEntries implements Event
         this.eventAdmin = null;
         this.enabledVanityPaths = true;
         this.enableOptimizeAliasResolution = true;
-        this.vanityPathWhiteList = null;
+        this.vanityPathConfig = null;
     }
 
     @SuppressWarnings("unchecked")
@@ -138,7 +139,7 @@ public class MapEntries implements Event
         this.factory = factory;
         this.mapRoot = factory.getMapRoot();
         this.enabledVanityPaths = factory.isVanityPathEnabled();
-        this.vanityPathWhiteList = factory.getVanityPathWhiteList();
+        this.vanityPathConfig = factory.getVanityPathConfig();
         this.enableOptimizeAliasResolution = factory.isOptimizeAliasResolutionEnabled();
         this.eventAdmin = eventAdmin;
 
@@ -590,11 +591,11 @@ public class MapEntries implements Event
             }
 
             // check whitelist
-            if ( this.vanityPathWhiteList != null ) {
+            if ( this.vanityPathConfig != null ) {
                 boolean allowed = false;
-                for(final String prefix : this.vanityPathWhiteList) {
-                    if ( resource.getPath().startsWith(prefix) ) {
-                        allowed = true;
+                for(final VanityPathConfig config : this.vanityPathConfig) {
+                    if ( resource.getPath().startsWith(config.prefix) ) {
+                        allowed = !config.isExclude;
                         break;
                     }
                 }

Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java?rev=1582628&r1=1582627&r2=1582628&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
(original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
Fri Mar 28 07:04:20 2014
@@ -29,14 +29,18 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 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.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -66,8 +70,20 @@ public class MapEntriesTest {
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
+        final List<VanityPathConfig> configs = new ArrayList<MapConfigurationProvider.VanityPathConfig>();
+        configs.add(new VanityPathConfig("/libs/", false));
+        configs.add(new VanityPathConfig("/libs/denied", true));
+        configs.add(new VanityPathConfig("/foo/", false));
+        configs.add(new VanityPathConfig("/baa/", false));
+        configs.add(new VanityPathConfig("/justVanityPath", false));
+        configs.add(new VanityPathConfig("/badVanityPath", false));
+        configs.add(new VanityPathConfig("/redirectingVanityPath", false));
+        configs.add(new VanityPathConfig("/redirectingVanityPath301", false));
+
+        Collections.sort(configs);
         when(resourceResolverFactory.getAdministrativeResourceResolver(null)).thenReturn(resourceResolver);
         when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
+        when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs);
         when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(true);
         when(resourceResolver.findResources(anyString(), eq("sql"))).thenReturn(
                 Collections.<Resource> emptySet().iterator());
@@ -213,4 +229,52 @@ public class MapEntriesTest {
         return new ValueMapDecorator(data);
     }
 
+    private Resource getVanityPathResource(final String path) {
+        Resource rsrc = mock(Resource.class);
+        when(rsrc.getPath()).thenReturn(path);
+        when(rsrc.getName()).thenReturn(ResourceUtil.getName(path));
+        when(rsrc.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/vanity"
+ path));
+        return rsrc;
+    }
+
+    @Test
+    public void test_vanity_path_registration_include_exclude() {
+        final String[] validPaths = {"/libs/somewhere", "/libs/a/b", "/foo/a", "/baa/a"};
+        final String[] invalidPaths = {"/libs/denied/a", "/libs/denied/b/c", "/nowhere"};
+
+        final List<Resource> resources = new ArrayList<Resource>();
+        for(final String val : validPaths) {
+            resources.add(getVanityPathResource(val));
+        }
+        for(final String val : invalidPaths) {
+            resources.add(getVanityPathResource(val));
+        }
+
+
+        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>()
{
+
+            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable
{
+                if (invocation.getArguments()[0].toString().contains("sling:vanityPath"))
{
+                    return resources.iterator();
+                } else {
+                    return Collections.<Resource> emptySet().iterator();
+                }
+            }
+        });
+
+        mapEntries.doInit();
+
+        List<MapEntry> entries = mapEntries.getResolveMaps();
+        // each valid resource results in 2 entries
+        assertEquals(validPaths.length * 2, entries.size());
+
+        final Set<String> resultSet = new HashSet<String>();
+        for(final String p : validPaths) {
+            resultSet.add(p + "$1");
+            resultSet.add(p + ".html");
+        }
+        for (final MapEntry entry : entries) {
+            assertTrue(resultSet.remove(entry.getRedirect()[0]));
+        }
+    }
 }



Mime
View raw message