You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2014/01/10 08:29:25 UTC
svn commit: r1557045 - in
/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags:
./ impl/
Author: cziegeler
Date: Fri Jan 10 07:29:24 2014
New Revision: 1557045
URL: http://svn.apache.org/r1557045
Log:
Remove FeatureProvider interface, Features are OSGi services now - rename ProviderContext to ExecutionContext
Added:
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ExecutionContext.java
- copied, changed from r1557042, sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ProviderContext.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java
- copied, changed from r1557042, sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java
Removed:
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/FeatureProvider.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ProviderContext.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java
Modified:
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
Copied: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ExecutionContext.java (from r1557042, sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ProviderContext.java)
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ExecutionContext.java?p2=sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ExecutionContext.java&p1=sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ProviderContext.java&r1=1557042&r2=1557045&rev=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ProviderContext.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ExecutionContext.java Fri Jan 10 07:29:24 2014
@@ -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
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Feature.java Fri Jan 10 07:29:24 2014
@@ -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();
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/Features.java Fri Jan 10 07:29:24 2014
@@ -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();
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceHiding.java Fri Jan 10 07:29:24 2014
@@ -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);
}
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/ResourceTypeMapping.java Fri Jan 10 07:29:24 2014
@@ -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();
}
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ClientContextImpl.java Fri Jan 10 07:29:24 2014
@@ -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.Res
*/
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 implement
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 implement
this.featureContext = featureContext;
}
- public ProviderContext getFeatureContext() {
+ public ExecutionContext getFeatureContext() {
return this.featureContext;
}
Copied: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java (from r1557042, sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java)
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java?p2=sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java&p1=sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java&r1=1557042&r2=1557045&rev=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ProviderContextImpl.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/ExecutionContextImpl.java Fri Jan 10 07:29:24 2014
@@ -20,23 +20,23 @@ package org.apache.sling.featureflags.im
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();
}
Modified: sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java?rev=1557045&r1=1557044&r2=1557045&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java (original)
+++ sling/trunk/contrib/extensions/feature-flags/src/main/java/org/apache/sling/featureflags/impl/FeatureManager.java Fri Jan 10 07:29:24 2014
@@ -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.SlingHttpSer
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 F
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 F
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 F
@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 F
@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 F
@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 F
}
@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 F
@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 F
return result;
}
}
-
- private final static class FeatureDescription {
- public Feature feature;
- public FeatureProvider provider;
-
- }
}