You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2014/01/17 16:09:31 UTC

svn commit: r1559130 - in /sling/whiteboard/fmeschbe/featureflags/feature-flags: ./ src/main/java/org/apache/sling/featureflags/ src/main/java/org/apache/sling/featureflags/impl/

Author: fmeschbe
Date: Fri Jan 17 15:09:31 2014
New Revision: 1559130

URL: http://svn.apache.org/r1559130
Log:
Feature Flags Simplification Prototype

- Remove ResourceAccessImpl and ResourceHiding because not
   needed: Hiding is implemented in the ResourceResolver
- Rename ResourceDecoratorImpl by FeatureResourceDecoratorImpl
   and remove ResourceHiding because not needed any more: Features
   services can now implement ResourceDecorator and will be called
   when decorating resources and if enabled
- Simplify Features and ResourceDecorator service registration and
   remove FeatureManager (bridge) service

Added:
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java   (with props)
Removed:
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ResourceAccessImpl.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ResourceDecoratorImpl.java
Modified:
    sling/whiteboard/fmeschbe/featureflags/feature-flags/pom.xml
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ClientContext.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
    sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeaturesImpl.java

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/pom.xml?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/pom.xml (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/pom.xml Fri Jan 17 15:09:31 2014
@@ -48,12 +48,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.resourceaccesssecurity</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
             <version>2.2.0</version>
             <scope>provided</scope>

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ClientContext.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ClientContext.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ClientContext.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/ClientContext.java Fri Jan 17 15:09:31 2014
@@ -31,7 +31,12 @@ import aQute.bnd.annotation.ProviderType
 public interface ClientContext {
 
     /**
-     * Returns <code>true</code> if the feature is enabled.
+     * Returns {@code true} if the named feature is enabled.
+     *
+     * @param featureName The name of the feature.
+     * @return {@code true} if the named feature is enabled. {@code false} is
+     *         returned if the named feature is not enabled, is not known or the
+     *         {@code featureName} parameter is {@code null} or an empty String.
      */
     boolean isEnabled(String featureName);
 

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java Fri Jan 17 15:09:31 2014
@@ -18,23 +18,15 @@
  */
 package org.apache.sling.featureflags;
 
-import org.apache.sling.api.adapter.Adaptable;
-
 import aQute.bnd.annotation.ConsumerType;
 
 /**
  * A feature is defined by its name.
- * Depending on the functionality the feature implements it can
- * be adapted to different services, like
- * <ul>
- *   <li>{@link ResourceHiding}</li>
- *   <li>{@link ResourceTypeMapping}</li>
- * </ul>
  *
  * Features are registered as OSGi services.
  */
 @ConsumerType
-public interface Feature extends Adaptable {
+public interface Feature {
 
     /**
      * Checks whether the feature is enabled for the current execution

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java Fri Jan 17 15:09:31 2014
@@ -32,6 +32,16 @@ import aQute.bnd.annotation.ProviderType
 public interface Features {
 
     /**
+     * Resource property of type String or String[] listing the features
+     * applicable to a resource.
+     * <p>
+     * If the ResourceResolver supports feature flags, the respective resource
+     * property is expected to be copied into the ResourceMetadata as a String[]
+     * property of this name.
+     */
+    String FEATURE_PROPERTY = "sling:features";
+
+    /**
      * Get the list of all available feature names. A feature is available
      * if there is a registered {@link Feature} service.
      */

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java Fri Jan 17 15:09:31 2014
@@ -21,15 +21,11 @@ package org.apache.sling.featureflags.im
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-
+import org.apache.sling.api.resource.ResourceDecorator;
 import org.apache.sling.featureflags.ClientContext;
 import org.apache.sling.featureflags.Feature;
 import org.apache.sling.featureflags.ExecutionContext;
-import org.apache.sling.featureflags.ResourceHiding;
-import org.apache.sling.featureflags.ResourceTypeMapping;
 
 /**
  * Implementation of the client context
@@ -40,25 +36,15 @@ public class ClientContextImpl implement
 
     private final List<Feature> enabledFeatures;
 
-    private final List<ResourceHiding> hidingFeatures;
-
-    private final Map<String, String> mapperFeatures = new HashMap<String, String>();
+    private final List<ResourceDecorator> mapperFeatures = new ArrayList<ResourceDecorator>();
 
     public ClientContextImpl(final ExecutionContext featureContext, final List<Feature> features) {
         this.enabledFeatures = Collections.unmodifiableList(features);
-        final List<ResourceHiding> hiding = new ArrayList<ResourceHiding>();
-        for(final Feature f : this.enabledFeatures) {
-            final ResourceHiding rh = f.adaptTo(ResourceHiding.class);
-            if ( rh != null ) {
-                hiding.add(rh);
-            }
-            final ResourceTypeMapping rm = f.adaptTo(ResourceTypeMapping.class);
-            if ( rm != null ) {
-                final Map<String, String> mapping = rm.getResourceTypeMapping();
-                mapperFeatures.putAll(mapping);
+        for (final Feature f : this.enabledFeatures) {
+            if (f instanceof ResourceDecorator) {
+                mapperFeatures.add((ResourceDecorator) f);
             }
         }
-        this.hidingFeatures = hiding;
         this.featureContext = featureContext;
     }
 
@@ -81,11 +67,7 @@ public class ClientContextImpl implement
         return this.enabledFeatures;
     }
 
-    public Collection<ResourceHiding> getHidingFeatures() {
-        return this.hidingFeatures;
-    }
-
-    public Map<String, String> getResourceTypeMapping() {
+    public List<ResourceDecorator> getResourceDecorators() {
         return this.mapperFeatures;
     }
 }

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java Fri Jan 17 15:09:31 2014
@@ -26,17 +26,22 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
 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.ResourceDecorator;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.featureflags.ClientContext;
+import org.apache.sling.featureflags.ExecutionContext;
 import org.apache.sling.featureflags.Feature;
 import org.apache.sling.featureflags.Features;
-import org.apache.sling.featureflags.ExecutionContext;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,7 +54,7 @@ import org.slf4j.LoggerFactory;
            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
            policy=ReferencePolicy.DYNAMIC,
            referenceInterface=Feature.class)
-public class FeatureManager implements Features {
+public class FeatureManager {
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -57,6 +62,30 @@ public class FeatureManager implements F
 
     private Map<String, FeatureDescription> activeFeatures = new TreeMap<String, FeatureDescription>();
 
+    private ServiceRegistration featuresService;
+
+    private ServiceRegistration resourceDecorator;
+
+    @Activate
+    private void activate(BundleContext bundleContext) {
+        this.featuresService = bundleContext.registerService(Features.class.getName(), new FeaturesImpl(this), null);
+        this.resourceDecorator = bundleContext.registerService(ResourceDecorator.class.getName(),
+            new FeatureResourceDecorator(this), null);
+    }
+
+    @Deactivate
+    private void deactivate() {
+        if (this.featuresService != null) {
+            this.featuresService.unregister();
+            this.featuresService = null;
+        }
+
+        if (this.resourceDecorator != null) {
+            this.resourceDecorator.unregister();
+            this.resourceDecorator = null;
+        }
+    }
+
     /**
      * Bind a new feature
      */
@@ -124,7 +153,6 @@ public class FeatureManager implements F
         }
     };
 
-    @Override
     public ClientContext getCurrentClientContext() {
         ClientContext result = perThreadClientContext.get();
         if ( result == null ) {
@@ -143,7 +171,6 @@ public class FeatureManager implements F
         perThreadClientContext.remove();
     }
 
-    @Override
     public ClientContext createClientContext(final ResourceResolver resolver) {
         if ( resolver == null ) {
             throw new IllegalArgumentException("Resolver must not be null.");
@@ -153,7 +180,6 @@ public class FeatureManager implements F
         return ctx;
     }
 
-    @Override
     public ClientContext createClientContext(final SlingHttpServletRequest request) {
         if ( request == null ) {
             throw new IllegalArgumentException("Request must not be null.");
@@ -178,7 +204,6 @@ public class FeatureManager implements F
         return ctx;
     }
 
-    @Override
     public Feature[] getAvailableFeatures() {
         final List<Feature> result = new ArrayList<Feature>();
         for(final Map.Entry<String, FeatureDescription> entry : this.activeFeatures.entrySet()) {
@@ -188,7 +213,6 @@ public class FeatureManager implements F
         return result.toArray(new Feature[result.size()]);
     }
 
-    @Override
     public Feature getFeature(final String name) {
         final FeatureDescription desc = this.activeFeatures.get(name);
         if ( desc != null ) {
@@ -197,12 +221,10 @@ public class FeatureManager implements F
         return null;
     }
 
-    @Override
     public String[] getAvailableFeatureNames() {
         return this.activeFeatures.keySet().toArray(new String[this.activeFeatures.size()]);
     }
 
-    @Override
     public boolean isAvailable(final String featureName) {
         return this.activeFeatures.containsKey(featureName);
     }

Added: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java?rev=1559130&view=auto
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java (added)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java Fri Jan 17 15:09:31 2014
@@ -0,0 +1,57 @@
+/*
+ * 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.featureflags.impl;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceDecorator;
+import org.apache.sling.featureflags.ClientContext;
+
+/**
+ * Resource decorator implementing the resource type mapping
+ */
+public class FeatureResourceDecorator implements ResourceDecorator {
+
+    private final FeatureManager manager;
+
+    FeatureResourceDecorator(final FeatureManager manager) {
+        this.manager = manager;
+    }
+
+    @Override
+    public Resource decorate(final Resource resource) {
+        Resource result = resource;
+        final ClientContext info = manager.getCurrentClientContext();
+        if (info instanceof ClientContextImpl) {
+            for (ResourceDecorator rd : ((ClientContextImpl) info).getResourceDecorators()) {
+                Resource r = rd.decorate(resource);
+                if (r != null) {
+                    result = r;
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Resource decorate(final Resource resource, final HttpServletRequest request) {
+        return this.decorate(resource);
+    }
+}

Propchange: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureResourceDecorator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeaturesImpl.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeaturesImpl.java?rev=1559130&r1=1559129&r2=1559130&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeaturesImpl.java (original)
+++ sling/whiteboard/fmeschbe/featureflags/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeaturesImpl.java Fri Jan 17 15:09:31 2014
@@ -18,9 +18,6 @@
  */
 package org.apache.sling.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.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.featureflags.ClientContext;
@@ -30,12 +27,13 @@ import org.apache.sling.featureflags.Fea
 /**
  * This is a wrapper around the internal feature manager.
  */
-@Component
-@Service(value=Features.class)
 public class FeaturesImpl implements Features {
 
-    @Reference
-    private FeatureManager manager;
+    private final FeatureManager manager;
+
+    FeaturesImpl(final FeatureManager manager) {
+        this.manager = manager;
+    }
 
     @Override
     public String[] getAvailableFeatureNames() {