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 7a1c95e2990b7102354a0521959217b115349f27
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Fri Jan 10 07:29:24 2014 +0000

    Remove FeatureProvider interface, Features are OSGi services now - rename 
ProviderContext to ExecutionContext
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/feature-flags@1557045
 13f79535-47bb-0310-9956-ffa450edef68
---
 ...{ProviderContext.java => ExecutionContext.java} |   5 +-
 .../org/apache/sling/featureflags/Feature.java     |   6 +
 .../apache/sling/featureflags/FeatureProvider.java |  39 -----
 .../org/apache/sling/featureflags/Features.java    |  11 +-
 .../apache/sling/featureflags/ResourceHiding.java  |   6 +-
 .../sling/featureflags/ResourceTypeMapping.java    |   6 +-
 .../sling/featureflags/impl/ClientContextImpl.java |   8 +-
 ...rContextImpl.java => ExecutionContextImpl.java} |   8 +-
 .../sling/featureflags/impl/FeatureManager.java    | 159 ++++++++++-----------
 9 files changed, 102 insertions(+), 146 deletions(-)

diff --git a/src/main/java/org/apache/sling/featureflags/ProviderContext.java 
b/src/main/java/org/apache/sling/featureflags/ExecutionContext.java
similarity index 92%
rename from src/main/java/org/apache/sling/featureflags/ProviderContext.java
rename to src/main/java/org/apache/sling/featureflags/ExecutionContext.java
index 08b400b..d01bd67 100644
--- a/src/main/java/org/apache/sling/featureflags/ProviderContext.java
+++ b/src/main/java/org/apache/sling/featureflags/ExecutionContext.java
@@ -25,11 +25,10 @@ import aQute.bnd.annotation.ProviderType;
 
 /**
  * The provider context contains all information that is passed to a
- * {@link FeatureProvider} in order to check whether a feature
- * is enabled.
+ * {@link Feature} in order to check whether a feature is enabled.
  */
 @ProviderType
-public interface ProviderContext {
+public interface ExecutionContext {
 
     /**
      * Return the associated request if available
diff --git a/src/main/java/org/apache/sling/featureflags/Feature.java 
b/src/main/java/org/apache/sling/featureflags/Feature.java
index cedbb61..ca83b08 100644
--- a/src/main/java/org/apache/sling/featureflags/Feature.java
+++ b/src/main/java/org/apache/sling/featureflags/Feature.java
@@ -35,6 +35,12 @@ import aQute.bnd.annotation.ConsumerType;
 public interface Feature extends Adaptable {
 
     /**
+     * Checks whether the feature is enabled for the current execution
+     * context.
+     */
+    boolean isEnabled(ExecutionContext context);
+
+    /**
      * The name of the feature.
      */
     String getName();
diff --git a/src/main/java/org/apache/sling/featureflags/FeatureProvider.java 
b/src/main/java/org/apache/sling/featureflags/FeatureProvider.java
deleted file mode 100644
index 704246e..0000000
--- a/src/main/java/org/apache/sling/featureflags/FeatureProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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;
-
-import aQute.bnd.annotation.ConsumerType;
-
-/**
- * A feature provider activates one more features.
- */
-@ConsumerType
-public interface FeatureProvider {
-
-    /**
-     * Checks whether the feature is enabled for the current execution
-     * context.
-     */
-    boolean isEnabled(Feature feature, ProviderContext context);
-
-    /**
-     * Return the list of available features from this provider.
-     */
-    Feature[] getFeatures();
-}
diff --git a/src/main/java/org/apache/sling/featureflags/Features.java 
b/src/main/java/org/apache/sling/featureflags/Features.java
index 1b054a9..8b6a810 100644
--- a/src/main/java/org/apache/sling/featureflags/Features.java
+++ b/src/main/java/org/apache/sling/featureflags/Features.java
@@ -33,13 +33,13 @@ public interface Features {
 
     /**
      * Get the list of all available feature names. A feature is available
-     * if there is a {@link FeatureProvider}
+     * if there is a registered {@link Feature} service.
      */
     String[] getAvailableFeatureNames();
 
     /**
      * Get the list of all available features. A feature is available
-     * if there is a {@link FeatureProvider}
+     * if there is a registered {@link Feature} service.
      */
     Feature[] getAvailableFeatures();
 
@@ -51,13 +51,14 @@ public interface Features {
 
     /**
      * Checks whether a feature with the given name is available.
-     * A feature is available if there is a {@link FeatureProvider}
-     * for that feature.
+     * A feature is available if there is a registered {@link Feature} service.
      */
     boolean isAvailable(String featureName);
 
     /**
-     * Returns the current client context, if available
+     * Returns the current client context.
+     * This method always returns a client context object
+     * @return A client context.
      */
     ClientContext getCurrentClientContext();
 
diff --git a/src/main/java/org/apache/sling/featureflags/ResourceHiding.java 
b/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
index 7bd21ba..d19fab6 100644
--- a/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
+++ b/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
@@ -31,11 +31,11 @@ public interface ResourceHiding {
 
     /**
      * Checks whether a resource should be hidden for a feature.
-     * This check is only executed if {@link 
FeatureProvider#isEnabled(Feature, ExecutionContext)}
+     * This check is only executed if {@link 
Feature#isEnabled(ExecutionContext)}
      * return true for the given feature/context. The caller of this
-     * method must ensure to call {@link FeatureProvider#isEnabled(Feature, 
ExecutionContext)}
+     * method must ensure to call {@link Feature#isEnabled(ExecutionContext)}
      * before calling this method and only call this method if
-     * {@link FeatureProvider#isEnabled(Feature, ExecutionContext)} returned 
<code>true</code>
+     * {@link Feature#isEnabled(ExecutionContext)} returned <code>true</code>
      */
     boolean hideResource(Resource resource);
 }
diff --git 
a/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java 
b/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
index 7f6f3c6..a9ca5f4 100644
--- a/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
+++ b/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
@@ -31,11 +31,11 @@ public interface ResourceTypeMapping {
 
     /**
      * Returns the resource type mapping for a feature.
-     * This mapping is only executed if {@link 
FeatureProvider#isEnabled(Feature, ExecutionContext)}
+     * This mapping is only executed if {@link 
Feature#isEnabled(ExecutionContext)}
      * return true for the given feature/context. The caller of this
-     * method must ensure to call {@link FeatureProvider#isEnabled(Feature, 
ExecutionContext)}
+     * method must ensure to call {@link Feature#isEnabled(ExecutionContext)}
      * before calling this method and only call this method if
-     * {@link FeatureProvider#isEnabled(Feature, ExecutionContext)} returned 
<code>true</code>
+     * {@link Feature#isEnabled(ExecutionContext)} returned <code>true</code>
      */
     Map<String, String> getResourceTypeMapping();
 }
diff --git 
a/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java 
b/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
index 03b0506..b71ebe4 100644
--- a/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
+++ b/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
@@ -27,7 +27,7 @@ import java.util.Map;
 
 import org.apache.sling.featureflags.ClientContext;
 import org.apache.sling.featureflags.Feature;
-import org.apache.sling.featureflags.ProviderContext;
+import org.apache.sling.featureflags.ExecutionContext;
 import org.apache.sling.featureflags.ResourceHiding;
 import org.apache.sling.featureflags.ResourceTypeMapping;
 
@@ -36,7 +36,7 @@ import org.apache.sling.featureflags.ResourceTypeMapping;
  */
 public class ClientContextImpl implements ClientContext {
 
-    private final ProviderContext featureContext;
+    private final ExecutionContext featureContext;
 
     private final List<Feature> enabledFeatures;
 
@@ -44,7 +44,7 @@ public class ClientContextImpl implements ClientContext {
 
     private final Map<String, String> mapperFeatures = new HashMap<String, 
String>();
 
-    public ClientContextImpl(final ProviderContext featureContext, final 
List<Feature> features) {
+    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) {
@@ -62,7 +62,7 @@ public class ClientContextImpl implements ClientContext {
         this.featureContext = featureContext;
     }
 
-    public ProviderContext getFeatureContext() {
+    public ExecutionContext getFeatureContext() {
         return this.featureContext;
     }
 
diff --git 
a/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java 
b/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java
similarity index 85%
rename from 
src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java
rename to 
src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java
index e162b16..555575f 100644
--- a/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java
+++ b/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java
@@ -20,23 +20,23 @@ package org.apache.sling.featureflags.impl;
 
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.featureflags.ProviderContext;
+import org.apache.sling.featureflags.ExecutionContext;
 
 /**
  * Implementation of the provider context.
  */
-public class ProviderContextImpl implements ProviderContext {
+public class ExecutionContextImpl implements ExecutionContext {
 
     private final ResourceResolver resourceResolver;
 
     private final SlingHttpServletRequest request;
 
-    public ProviderContextImpl(final ResourceResolver resourceResolver) {
+    public ExecutionContextImpl(final ResourceResolver resourceResolver) {
         this.request = null;
         this.resourceResolver = resourceResolver;
     }
 
-    public ProviderContextImpl(final SlingHttpServletRequest request) {
+    public ExecutionContextImpl(final SlingHttpServletRequest request) {
         this.request = request;
         this.resourceResolver = request.getResourceResolver();
     }
diff --git 
a/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java 
b/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
index c9813e3..fd601f6 100644
--- a/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
+++ b/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
@@ -19,6 +19,7 @@
 package org.apache.sling.featureflags.impl;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -33,110 +34,107 @@ import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.featureflags.ClientContext;
 import org.apache.sling.featureflags.Feature;
-import org.apache.sling.featureflags.FeatureProvider;
 import org.apache.sling.featureflags.Features;
-import org.apache.sling.featureflags.ProviderContext;
+import org.apache.sling.featureflags.ExecutionContext;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * This service implements the feature handling.
- * It keeps track of all {@link FeatureProvider} services.
+ * It keeps track of all {@link Feature} services.
  */
 @Component
-@Reference(name="featureProvider",
+@Reference(name="feature",
            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
            policy=ReferencePolicy.DYNAMIC,
-           referenceInterface=FeatureProvider.class)
+           referenceInterface=Feature.class)
 public class FeatureManager implements Features {
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    private final Map<String, List<FeatureProviderDescription>> providers = 
new HashMap<String, List<FeatureProviderDescription>>();
+    private final Map<String, List<FeatureDescription>> allFeatures = new 
HashMap<String, List<FeatureDescription>>();
 
-    private Map<String, FeatureDescription> activeProviders = new 
TreeMap<String, FeatureDescription>();
+    private Map<String, FeatureDescription> activeFeatures = new 
TreeMap<String, FeatureDescription>();
 
     /**
-     * Bind a new feature provider
+     * Bind a new feature
      */
-    protected void bindFeatureProvider(final FeatureProvider provider, final 
Map<String, Object> props) {
-        final Feature[] features = provider.getFeatures();
-        if ( features != null && features.length > 0 ) {
-            synchronized ( this.providers ) {
-                boolean changed = false;
-                for(final Feature f : features) {
-                    final String name = f.getName();
-                    final FeatureProviderDescription info = new 
FeatureProviderDescription(provider, props, f);
-
-                    List<FeatureProviderDescription> candidates = 
this.providers.get(name);
-                    if ( candidates == null ) {
-                        candidates = new 
ArrayList<FeatureProviderDescription>();
-                        this.providers.put(name, candidates);
-                    }
-                    candidates.add(info);
-                    Collections.sort(candidates);
-                    changed = true;
-                }
-                if ( changed ) {
-                    this.calculateActiveProviders();
-                }
+    protected void bindFeature(final Feature f, final Map<String, Object> 
props) {
+        synchronized ( this.allFeatures ) {
+            final String name = f.getName();
+            final FeatureDescription info = new FeatureDescription(f, props);
+
+            List<FeatureDescription> candidates = this.allFeatures.get(name);
+            if ( candidates == null ) {
+                candidates = new ArrayList<FeatureDescription>();
+                this.allFeatures.put(name, candidates);
             }
+            candidates.add(info);
+            Collections.sort(candidates);
+
+            this.calculateActiveProviders();
         }
     }
 
     /**
-     * Unbind a feature provider
+     * Unbind a feature
      */
-    protected void unbindFeatureProvider(final FeatureProvider provider, final 
Map<String, Object> props) {
-        final Feature[] features = provider.getFeatures();
-        if ( features != null && features.length > 0 ) {
-            synchronized ( this.providers ) {
-                boolean changed = false;
-                for(final Feature f : features) {
-                    final String name = f.getName();
-                    final FeatureProviderDescription info = new 
FeatureProviderDescription(provider, props, f);
-
-                    final List<FeatureProviderDescription> candidates = 
this.providers.get(name);
-                    if ( candidates != null ) { // sanity check
-                        candidates.remove(info);
-                        if ( candidates.size() == 0 ) {
-                            this.providers.remove(name);
-                            changed = true;
-                        }
-                    }
-                }
-                if ( changed ) {
-                    this.calculateActiveProviders();
+    protected void unbindFeature(final Feature f, final Map<String, Object> 
props) {
+        synchronized ( this.allFeatures ) {
+            final String name = f.getName();
+            final FeatureDescription info = new FeatureDescription(f, props);
+
+            final List<FeatureDescription> candidates = 
this.allFeatures.get(name);
+            if ( candidates != null ) { // sanity check
+                candidates.remove(info);
+                if ( candidates.size() == 0 ) {
+                    this.allFeatures.remove(name);
                 }
             }
+            this.calculateActiveProviders();
         }
     }
 
     private void calculateActiveProviders() {
         final Map<String, FeatureDescription> activeMap = new TreeMap<String, 
FeatureDescription>();
-        for(final Map.Entry<String, List<FeatureProviderDescription>> entry : 
this.providers.entrySet()) {
-            final FeatureProviderDescription desc = entry.getValue().get(0);
-            final FeatureDescription info = new FeatureDescription();
-            info.feature = desc.feature;
-            info.provider = desc.provider;
-            activeMap.put(entry.getKey(), info);
+        for(final Map.Entry<String, List<FeatureDescription>> entry : 
this.allFeatures.entrySet()) {
+            final FeatureDescription desc = entry.getValue().get(0);
+
+            activeMap.put(entry.getKey(), desc);
             if ( entry.getValue().size() > 1 ) {
-                logger.warn("More than one feature provider for feature {}", 
entry.getKey());
+                logger.warn("More than one feature service for feature {}", 
entry.getKey());
             }
         }
-        this.activeProviders = activeMap;
+        this.activeFeatures = activeMap;
     }
 
     private final ThreadLocal<ClientContextImpl> perThreadClientContext = new 
ThreadLocal<ClientContextImpl>();
 
+    private final ClientContext defaultClientContext = new ClientContext() {
+
+        @Override
+        public boolean isEnabled(final String featureName) {
+            return false;
+        }
+
+        @Override
+        public Collection<Feature> getEnabledFeatures() {
+            return Collections.emptyList();
+        }
+    };
+
     @Override
     public ClientContext getCurrentClientContext() {
-        return perThreadClientContext.get();
+        ClientContext result = perThreadClientContext.get();
+        if ( result == null ) {
+            result = defaultClientContext;
+        }
+        return result;
     }
 
     public void setCurrentClientContext(final SlingHttpServletRequest request) 
{
-        final ProviderContext providerContext = new 
ProviderContextImpl(request);
+        final ExecutionContext providerContext = new 
ExecutionContextImpl(request);
         final ClientContextImpl ctx = 
this.createClientContext(providerContext);
         perThreadClientContext.set(ctx);
     }
@@ -150,7 +148,7 @@ public class FeatureManager implements Features {
         if ( resolver == null ) {
             throw new IllegalArgumentException("Resolver must not be null.");
         }
-        final ProviderContext providerContext = new 
ProviderContextImpl(resolver);
+        final ExecutionContext providerContext = new 
ExecutionContextImpl(resolver);
         final ClientContext ctx = this.createClientContext(providerContext);
         return ctx;
     }
@@ -160,18 +158,18 @@ public class FeatureManager implements Features {
         if ( request == null ) {
             throw new IllegalArgumentException("Request must not be null.");
         }
-        final ProviderContext providerContext = new 
ProviderContextImpl(request);
+        final ExecutionContext providerContext = new 
ExecutionContextImpl(request);
         final ClientContext ctx = this.createClientContext(providerContext);
         return ctx;
     }
 
-    private ClientContextImpl createClientContext(final ProviderContext 
providerContext) {
+    private ClientContextImpl createClientContext(final ExecutionContext 
providerContext) {
         final List<Feature> enabledFeatures = new ArrayList<Feature>();
 
-        for(final Map.Entry<String, FeatureDescription> entry : 
this.activeProviders.entrySet()) {
+        for(final Map.Entry<String, FeatureDescription> entry : 
this.activeFeatures.entrySet()) {
             final Feature f = entry.getValue().feature;
 
-            if ( entry.getValue().provider.isEnabled(f, providerContext) ) {
+            if ( entry.getValue().feature.isEnabled(providerContext) ) {
                 enabledFeatures.add(f);
             }
         }
@@ -183,7 +181,7 @@ public class FeatureManager implements Features {
     @Override
     public Feature[] getAvailableFeatures() {
         final List<Feature> result = new ArrayList<Feature>();
-        for(final Map.Entry<String, FeatureDescription> entry : 
this.activeProviders.entrySet()) {
+        for(final Map.Entry<String, FeatureDescription> entry : 
this.activeFeatures.entrySet()) {
             final Feature f = entry.getValue().feature;
             result.add(f);
         }
@@ -192,7 +190,7 @@ public class FeatureManager implements Features {
 
     @Override
     public Feature getFeature(final String name) {
-        final FeatureDescription desc = this.activeProviders.get(name);
+        final FeatureDescription desc = this.activeFeatures.get(name);
         if ( desc != null ) {
             return desc.feature;
         }
@@ -201,28 +199,25 @@ public class FeatureManager implements Features {
 
     @Override
     public String[] getAvailableFeatureNames() {
-        return this.activeProviders.keySet().toArray(new 
String[this.activeProviders.size()]);
+        return this.activeFeatures.keySet().toArray(new 
String[this.activeFeatures.size()]);
     }
 
     @Override
     public boolean isAvailable(final String featureName) {
-        return this.activeProviders.containsKey(featureName);
+        return this.activeFeatures.containsKey(featureName);
     }
 
     /**
-     * Internal class caching some provider infos like service id and ranking.
+     * Internal class caching some feature meta data like service id and 
ranking.
      */
-    private final static class FeatureProviderDescription implements 
Comparable<FeatureProviderDescription> {
+    private final static class FeatureDescription implements 
Comparable<FeatureDescription> {
 
-        public final FeatureProvider provider;
         public final int ranking;
         public final long serviceId;
         public final Feature feature;
 
-        public FeatureProviderDescription(final FeatureProvider provider,
-                final Map<String, Object> props,
-                final Feature feature) {
-            this.provider = provider;
+        public FeatureDescription(final Feature feature,
+                final Map<String, Object> props) {
             this.feature = feature;
             final Object sr = props.get(Constants.SERVICE_RANKING);
             if ( sr == null || !(sr instanceof Integer)) {
@@ -234,7 +229,7 @@ public class FeatureManager implements Features {
         }
 
         @Override
-        public int compareTo(final FeatureProviderDescription o) {
+        public int compareTo(final FeatureDescription o) {
             if ( this.ranking < o.ranking ) {
                 return 1;
             } else if (this.ranking > o.ranking ) {
@@ -246,8 +241,8 @@ public class FeatureManager implements Features {
 
         @Override
         public boolean equals(final Object obj) {
-            if ( obj instanceof FeatureProviderDescription ) {
-                return ((FeatureProviderDescription)obj).serviceId == 
this.serviceId;
+            if ( obj instanceof FeatureDescription ) {
+                return ((FeatureDescription)obj).serviceId == this.serviceId;
             }
             return false;
         }
@@ -260,10 +255,4 @@ public class FeatureManager implements Features {
             return result;
         }
     }
-
-    private final static class FeatureDescription {
-        public Feature feature;
-        public FeatureProvider provider;
-
-    }
 }

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to