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:34:22 UTC

[sling-org-apache-sling-featureflags] 03/25: Take II for the feature flags, separate into different contexts to avoid duplicate evaluation

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.featureflags-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-featureflags.git

commit 93f4097f4c7f1da4e4dff44216767f38998fdef0
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Dec 19 04:47:20 2013 +0000

    Take II for the feature flags, separate into different contexts to avoid duplicate evaluation
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/whiteboard/feature-flags@1552225 13f79535-47bb-0310-9956-ffa450edef68
---
 .../{Feature.java => ClientContext.java}           | 33 +++------
 .../extensions/featureflags/FeatureProvider.java   |  2 +-
 .../featureflags/{Feature.java => Features.java}   | 40 ++++++-----
 .../{Feature.java => ProviderContext.java}         | 35 ++++-----
 .../featureflags/impl/ClientContextImpl.java       | 60 ++++++++++++++++
 ...Filter.java => CurrentClientContextFilter.java} | 57 ++++-----------
 .../FeatureContextImpl.java}                       | 20 ++----
 .../featureflags/impl/FeatureManager.java          | 82 ++++++++++++++++------
 .../impl/{FeatureImpl.java => FeaturesImpl.java}   | 35 +++++----
 .../featureflags/impl/ResourceAccessImpl.java      |  9 ++-
 .../featureflags/impl/ResourceDecoratorImpl.java   |  8 ++-
 11 files changed, 225 insertions(+), 156 deletions(-)

diff --git a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java b/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
similarity index 54%
copy from src/main/java/org/apache/sling/extensions/featureflags/Feature.java
copy to src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
index ed901c5..d44387b 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
@@ -18,37 +18,26 @@
  */
 package org.apache.sling.extensions.featureflags;
 
+import java.util.Collection;
+
 import aQute.bnd.annotation.ProviderType;
 
 /**
- * The feature service is the central gateway for feature handling.
- * It can be used to query the available features and to
- * check whether a feature is enabled for the current execution
- * context.
+ * The client context can be used by client code to check whether
+ * a specific feature is enable.
+ * A client context can be created through the {@link Features} service.
  */
 @ProviderType
-public interface Feature {
-
+public interface ClientContext {
 
     /**
-     * Checks whether the feature is enabled for the given
-     * execution context.
-     *
-     * The actual check is delegated to the {@link FeatureProvider}
-     * providing the feature.
+     * Returns <code>true</code> if the feature is enabled.
      */
-    boolean isEnabled(String featureName, ExecutionContext context);
-
-    /** Get the list of active feature flags */
-    String[] getFeatureNames();
+    boolean isEnabled(String featureName);
 
     /**
-     * Checks whether a feature with the given name is available.
-     * A feature is available if there is a {@link FeatureProvider}
-     * for that feature.
-     * @param featureName
-     * @return
+     * Returns a list of all enabled features
+     * @return The list of features, the list might be empty.
      */
-    boolean isAvailable(String featureName);
-
+    Collection<String> getEnabledFeatures();
 }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java b/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
index 66264b9..fad43bc 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
@@ -34,7 +34,7 @@ public interface FeatureProvider {
      * Checks whether the feature is enabled for the current execution
      * context.
      */
-    boolean isEnabled(String featureName, ExecutionContext context);
+    boolean isEnabled(String featureName, ProviderContext context);
 
     /**
      * Return the list of available features from this provider.
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java b/src/main/java/org/apache/sling/extensions/featureflags/Features.java
similarity index 57%
copy from src/main/java/org/apache/sling/extensions/featureflags/Feature.java
copy to src/main/java/org/apache/sling/extensions/featureflags/Features.java
index ed901c5..f955039 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/Features.java
@@ -18,37 +18,45 @@
  */
 package org.apache.sling.extensions.featureflags;
 
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+
 import aQute.bnd.annotation.ProviderType;
 
 /**
- * The feature service is the central gateway for feature handling.
- * It can be used to query the available features and to
- * check whether a feature is enabled for the current execution
- * context.
+ * The features service is the central gateway for feature handling.
+ * It can be used to query the available features and to create
+ * client contexts to be used for enabled feature checking.
  */
 @ProviderType
-public interface Feature {
-
+public interface Features {
 
     /**
-     * Checks whether the feature is enabled for the given
-     * execution context.
-     *
-     * The actual check is delegated to the {@link FeatureProvider}
-     * providing the feature.
+     * Get the list of all active features
      */
-    boolean isEnabled(String featureName, ExecutionContext context);
-
-    /** Get the list of active feature flags */
     String[] getFeatureNames();
 
     /**
      * Checks whether a feature with the given name is available.
      * A feature is available if there is a {@link FeatureProvider}
      * for that feature.
-     * @param featureName
-     * @return
      */
     boolean isAvailable(String featureName);
 
+    /**
+     * Returns the current client context, if available
+     */
+    ClientContext getCurrentClientContext();
+
+    /**
+     * Create a client context for the resource resolver.
+     * @throws IllegalArgumentException If resolver is null
+     */
+    ClientContext createClientContext(ResourceResolver resolver);
+
+    /**
+     * Create a client context for the request.
+     * @throws IllegalArgumentException If request is null
+     */
+    ClientContext createClientContext(SlingHttpServletRequest request);
 }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java b/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
similarity index 54%
rename from src/main/java/org/apache/sling/extensions/featureflags/Feature.java
rename to src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
index ed901c5..8af8a8c 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
@@ -18,37 +18,28 @@
  */
 package org.apache.sling.extensions.featureflags;
 
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+
 import aQute.bnd.annotation.ProviderType;
 
 /**
- * The feature service is the central gateway for feature handling.
- * It can be used to query the available features and to
- * check whether a feature is enabled for the current execution
- * context.
+ * The provider context contains all information that is passed to a
+ * {@link FeatureProvider} in order to check whether a feature
+ * is enabled.
  */
 @ProviderType
-public interface Feature {
-
+public interface ProviderContext {
 
     /**
-     * Checks whether the feature is enabled for the given
-     * execution context.
-     *
-     * The actual check is delegated to the {@link FeatureProvider}
-     * providing the feature.
+     * Return the associated request if available
+     * @return the request or <code>null</code>
      */
-    boolean isEnabled(String featureName, ExecutionContext context);
-
-    /** Get the list of active feature flags */
-    String[] getFeatureNames();
+    SlingHttpServletRequest getRequest();
 
     /**
-     * Checks whether a feature with the given name is available.
-     * A feature is available if there is a {@link FeatureProvider}
-     * for that feature.
-     * @param featureName
-     * @return
+     * Return the associated resource resolver.
+     * @return the resource resolver
      */
-    boolean isAvailable(String featureName);
-
+    ResourceResolver getResourceResolver();
 }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
new file mode 100644
index 0000000..b4228e3
--- /dev/null
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.extensions.featureflags.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sling.extensions.featureflags.ClientContext;
+import org.apache.sling.extensions.featureflags.ProviderContext;
+
+/**
+ * Implementation of the client context
+ */
+public class ClientContextImpl implements ClientContext {
+
+    private final ProviderContext featureContext;
+
+    private final List<String> enabledFeatures = new ArrayList<String>();
+
+    public ClientContextImpl(final ProviderContext featureContext) {
+        this.featureContext = featureContext;
+    }
+
+    public void addFeature(final String name) {
+        this.enabledFeatures.add(name);
+        Collections.sort(this.enabledFeatures);
+    }
+
+    public ProviderContext getFeatureContext() {
+        return this.featureContext;
+    }
+
+    @Override
+    public boolean isEnabled(final String featureName) {
+        return this.enabledFeatures.contains(featureName);
+    }
+
+    @Override
+    public Collection<String> getEnabledFeatures() {
+        return this.enabledFeatures;
+    }
+}
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
similarity index 52%
rename from src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java
rename to src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
index 8103bc4..349538f 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
@@ -19,9 +19,6 @@
 package org.apache.sling.extensions.featureflags.impl;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -35,68 +32,40 @@ import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.extensions.featureflags.ExecutionContext;
-import org.apache.sling.extensions.featureflags.Feature;
 
+/**
+ * This general servlet filter sets the current client context to the
+ * current request.
+ */
 @Component
 @Service(value=Filter.class)
 @Property(name="pattern", value="/.*")
-public class ExecutionContextFilter implements Filter {
-
-    private static ThreadLocal<ExecutionContextInfo> EXECUTION_CONTEXT;
+public class CurrentClientContextFilter implements Filter {
 
     @Reference
-    private Feature feature;
-
-    public static ExecutionContextInfo getCurrentExecutionContextInfo() {
-        final ThreadLocal<ExecutionContextInfo> local = EXECUTION_CONTEXT;
-        if ( local != null ) {
-            return local.get();
-        }
-        return null;
-    }
-
-    @Override
-    public void destroy() {
-        EXECUTION_CONTEXT = null;
-    }
+    private FeatureManager manager;
 
     @Override
     public void doFilter(final ServletRequest req, final ServletResponse res,
             final FilterChain chain)
     throws IOException, ServletException {
-        final ThreadLocal<ExecutionContextInfo> local = EXECUTION_CONTEXT;
-        if ( local != null && req instanceof SlingHttpServletRequest ) {
-            local.set(new ExecutionContextInfo((SlingHttpServletRequest)req, feature));
+        if ( req instanceof SlingHttpServletRequest ) {
+            manager.setCurrentClientContext((SlingHttpServletRequest)req);
         }
         try {
             chain.doFilter(req, res);
         } finally {
-            if ( local != null && req instanceof SlingHttpServletRequest ) {
-                local.set(null);
-            }
+            manager.unsetCurrentClientContext();
         }
     }
 
     @Override
     public void init(final FilterConfig config) throws ServletException {
-        EXECUTION_CONTEXT = new ThreadLocal<ExecutionContextInfo>();
+        // nothing to do
     }
 
-    public final class ExecutionContextInfo {
-
-        public final ExecutionContext context;
-        public final List<String> enabledFeatures = new ArrayList<String>();
-
-        public ExecutionContextInfo(final SlingHttpServletRequest req,
-                final Feature feature) {
-            this.context = ExecutionContext.fromRequest(req);
-            for(final String name : feature.getFeatureNames()) {
-                if ( feature.isEnabled(name, context) ) {
-                    enabledFeatures.add(name);
-                }
-            }
-            Collections.sort(enabledFeatures);
-        }
+    @Override
+    public void destroy() {
+        // nothing to do
     }
 }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
similarity index 72%
rename from src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java
rename to src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
index 8e00dfd..e31dc15 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
@@ -16,40 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.extensions.featureflags;
+package org.apache.sling.extensions.featureflags.impl;
 
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.extensions.featureflags.ProviderContext;
 
-public class ExecutionContext {
+public class FeatureContextImpl implements ProviderContext {
 
     private final ResourceResolver resourceResolver;
 
     private final SlingHttpServletRequest request;
 
-    public static ExecutionContext fromRequest(final SlingHttpServletRequest request) {
-        return new ExecutionContext(request);
-    }
-
-    public static ExecutionContext fromResourceResolver(final ResourceResolver resourceResolver) {
-        return new ExecutionContext(resourceResolver);
-    }
-
-    private ExecutionContext(final ResourceResolver resourceResolver) {
+    public FeatureContextImpl(final ResourceResolver resourceResolver) {
         this.request = null;
         this.resourceResolver = resourceResolver;
     }
 
-
-    private ExecutionContext(final SlingHttpServletRequest request) {
+    public FeatureContextImpl(final SlingHttpServletRequest request) {
         this.request = request;
         this.resourceResolver = request.getResourceResolver();
     }
 
+    @Override
     public SlingHttpServletRequest getRequest() {
         return this.request;
     }
 
+    @Override
     public ResourceResolver getResourceResolver() {
         return this.resourceResolver;
     }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
index dad36fe..2fbf286 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
@@ -28,10 +28,13 @@ import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.extensions.featureflags.ExecutionContext;
-import org.apache.sling.extensions.featureflags.Feature;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.extensions.featureflags.ClientContext;
+import org.apache.sling.extensions.featureflags.ProviderContext;
 import org.apache.sling.extensions.featureflags.FeatureProvider;
+import org.apache.sling.extensions.featureflags.Features;
 import org.osgi.framework.Constants;
 
 /**
@@ -43,11 +46,11 @@ import org.osgi.framework.Constants;
            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
            policy=ReferencePolicy.DYNAMIC,
            referenceInterface=FeatureProvider.class)
-public class FeatureManager implements Feature {
+public class FeatureManager implements Features {
 
     private final Map<String, List<FeatureProviderDescription>> providers = new HashMap<String, List<FeatureProviderDescription>>();
 
-    private Map<String, FeatureProviderDescription> activeProviders = new HashMap<String, FeatureProviderDescription>();
+    private Map<String, FeatureProvider> activeProviders = new HashMap<String, FeatureProvider>();
 
     /**
      * Bind a new feature provider
@@ -112,22 +115,63 @@ public class FeatureManager implements Feature {
     }
 
     private void calculateActiveProviders() {
-        final Map<String, FeatureProviderDescription> activeMap = new HashMap<String, FeatureManager.FeatureProviderDescription>();
+        final Map<String, FeatureProvider> activeMap = new HashMap<String, FeatureProvider>();
         for(final Map.Entry<String, List<FeatureProviderDescription>> entry : this.providers.entrySet()) {
-            activeMap.put(entry.getKey(), entry.getValue().get(0));
+            activeMap.put(entry.getKey(), entry.getValue().get(0).getProvider());
         }
         this.activeProviders = activeMap;
     }
 
+    private final ThreadLocal<ClientContextImpl> perThreadClientContext = new ThreadLocal<ClientContextImpl>();
+
+    @Override
+    public ClientContext getCurrentClientContext() {
+        return perThreadClientContext.get();
+    }
+
+    public void setCurrentClientContext(final SlingHttpServletRequest request) {
+        final ProviderContext featureContext = new FeatureContextImpl(request);
+        final ClientContextImpl ctx = this.createClientContext(featureContext);
+        perThreadClientContext.set(ctx);
+    }
+
+    public void unsetCurrentClientContext() {
+        perThreadClientContext.remove();
+    }
+
     @Override
-    public boolean isEnabled(final String featureName, final ExecutionContext context) {
-        boolean result = false;
-        final FeatureProviderDescription desc = this.activeProviders.get(featureName);
-        if ( desc != null ) {
-            final FeatureProvider prod = desc.getProvider();
-            result = prod.isEnabled(featureName, context);
+    public ClientContext createClientContext(final ResourceResolver resolver) {
+        if ( resolver == null ) {
+            throw new IllegalArgumentException("Resolver must not be null.");
         }
-        return result;
+        final ProviderContext featureContext = new FeatureContextImpl(resolver);
+        final ClientContext ctx = this.createClientContext(featureContext);
+        return ctx;
+    }
+
+    @Override
+    public ClientContext createClientContext(final SlingHttpServletRequest request) {
+        if ( request == null ) {
+            throw new IllegalArgumentException("Request must not be null.");
+        }
+        final ProviderContext featureContext = new FeatureContextImpl(request);
+        final ClientContext ctx = this.createClientContext(featureContext);
+        return ctx;
+    }
+
+    private ClientContextImpl createClientContext(final ProviderContext featureContext) {
+        final ClientContextImpl ctx = new ClientContextImpl(featureContext);
+
+        for(final Map.Entry<String, FeatureProvider> entry : this.activeProviders.entrySet()) {
+            final String name = entry.getKey();
+            final FeatureProvider provider = entry.getValue();
+
+            if ( provider.isEnabled(name, featureContext) ) {
+                ctx.addFeature(name);
+            }
+        }
+
+        return ctx;
     }
 
     @Override
@@ -142,13 +186,12 @@ public class FeatureManager implements Feature {
 
     /**
      * Checks whether a resource should be hidden for a feature.
-     * This check is only executed if {@link #isEnabled(String, ExecutionContext)}
+     * This check is only executed if {@link #isEnabled(String, ClientContext)}
      * return true for the given feature/context.
      */
     public boolean hideResource(final String featureName, final Resource resource) {
-        final FeatureProviderDescription desc = this.activeProviders.get(featureName);
-        if ( desc != null ) {
-            final FeatureProvider prod = desc.getProvider();
+        final FeatureProvider prod = this.activeProviders.get(featureName);
+        if ( prod != null ) {
             return prod.hideResource(featureName, resource);
         }
         return false;
@@ -207,9 +250,8 @@ public class FeatureManager implements Feature {
     }
 
     public String getResourceType(final String featureName, final String resourceType) {
-        final FeatureProviderDescription desc = this.activeProviders.get(featureName);
-        if ( desc != null ) {
-            final FeatureProvider prod = desc.getProvider();
+        final FeatureProvider prod = this.activeProviders.get(featureName);
+        if ( prod != null ) {
             final Map<String, String> mapping = prod.getResourceTypeMapping(featureName);
             if ( mapping != null ) {
                 return mapping.get(resourceType);
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
similarity index 62%
rename from src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java
rename to src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
index b42dca9..5c8bd1a 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
@@ -21,34 +21,43 @@ package org.apache.sling.extensions.featureflags.impl;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.extensions.featureflags.ExecutionContext;
-import org.apache.sling.extensions.featureflags.Feature;
-import org.apache.sling.extensions.featureflags.FeatureProvider;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.extensions.featureflags.ClientContext;
+import org.apache.sling.extensions.featureflags.Features;
 
 /**
- * This service implements the feature handling.
- * It keeps track of all {@link FeatureProvider} services.
+ * This is a wrapper around the internal feature manager.
  */
 @Component
-@Service(value=Feature.class)
-public class FeatureImpl implements Feature {
+@Service(value=Features.class)
+public class FeaturesImpl implements Features {
 
     @Reference
     private FeatureManager manager;
 
     @Override
-    public boolean isEnabled(final String featureName, final ExecutionContext context) {
-        return this.manager.isEnabled(featureName, context);
-    }
-
-    @Override
     public String[] getFeatureNames() {
         return this.manager.getFeatureNames();
     }
 
     @Override
     public boolean isAvailable(final String featureName) {
-        // TODO Auto-generated method stub
         return this.manager.isAvailable(featureName);
     }
+
+    @Override
+    public ClientContext getCurrentClientContext() {
+        return this.manager.getCurrentClientContext();
+    }
+
+    @Override
+    public ClientContext createClientContext(final ResourceResolver resolver) {
+        return this.manager.createClientContext(resolver);
+    }
+
+    @Override
+    public ClientContext createClientContext(final SlingHttpServletRequest request) {
+        return this.manager.createClientContext(request);
+    }
 }
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
index 5840a3a..befc1c1 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
@@ -22,9 +22,13 @@ import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.extensions.featureflags.ClientContext;
 import org.apache.sling.resourceaccesssecurity.AllowingResourceAccessGate;
 import org.apache.sling.resourceaccesssecurity.ResourceAccessGate;
 
+/**
+ * Resource access gate implementing the hiding of resources.
+ */
 @Component
 @Service(value=ResourceAccessGate.class)
 public class ResourceAccessImpl
@@ -37,10 +41,9 @@ public class ResourceAccessImpl
     @Override
     public GateResult canRead(final Resource resource) {
         boolean available = true;
-        final ExecutionContextFilter.ExecutionContextInfo info = ExecutionContextFilter.getCurrentExecutionContextInfo();
+        final ClientContext info = manager.getCurrentClientContext();
         if ( info != null ) {
-            for(final String name : info.enabledFeatures) {
-                // we can't check as Feature does not have the api (TODO - we deny for now)
+            for(final String name : info.getEnabledFeatures()) {
                 available = !manager.hideResource(name, resource);
                 if ( !available) {
                     break;
diff --git a/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java b/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
index 5d2cbad..d5de62b 100644
--- a/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
+++ b/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
@@ -26,7 +26,11 @@ import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceDecorator;
 import org.apache.sling.api.resource.ResourceWrapper;
+import org.apache.sling.extensions.featureflags.ClientContext;
 
+/**
+ * Resource decorator implementing the resource type mapping
+ */
 @Component
 @Service(value=ResourceDecorator.class)
 public class ResourceDecoratorImpl implements ResourceDecorator {
@@ -36,9 +40,9 @@ public class ResourceDecoratorImpl implements ResourceDecorator {
 
     @Override
     public Resource decorate(final Resource resource) {
-        final ExecutionContextFilter.ExecutionContextInfo info = ExecutionContextFilter.getCurrentExecutionContextInfo();
+        final ClientContext info = manager.getCurrentClientContext();
         if ( info != null ) {
-            for(final String name : info.enabledFeatures) {
+            for(final String name : info.getEnabledFeatures()) {
 
                 final String resourceType = resource.getResourceType();
                 final String overwriteType = manager.getResourceType(name, resourceType);

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.