Author: cziegeler
Date: Thu Dec 19 04:47:20 2013
New Revision: 1552225
URL: http://svn.apache.org/r1552225
Log:
Take II for the feature flags, separate into different contexts to avoid
duplicate evaluation
Added:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
- copied, changed from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Features.java
- copied, changed from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
(with props)
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
(with props)
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
- copied, changed from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
(with props)
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
- copied, changed from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java
Removed:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java
Modified:
sling/whiteboard/feature-flags/ (props changed)
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
Propchange: sling/whiteboard/feature-flags/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Thu Dec 19 04:47:20 2013
@@ -3,3 +3,5 @@
.classpath
.project
+
+target
Copied:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
(from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java?p2=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java&p1=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java&r1=1552224&r2=1552225&rev=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ExecutionContext.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ClientContext.java
Thu Dec 19 04:47:20 2013
@@ -18,39 +18,26 @@
*/
package org.apache.sling.extensions.featureflags;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.ResourceResolver;
+import java.util.Collection;
-public class ExecutionContext {
+import aQute.bnd.annotation.ProviderType;
- 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) {
- this.request = null;
- this.resourceResolver = resourceResolver;
- }
-
-
- private ExecutionContext(final SlingHttpServletRequest request) {
- this.request = request;
- this.resourceResolver = request.getResourceResolver();
- }
-
- public SlingHttpServletRequest getRequest() {
- return this.request;
- }
+/**
+ * 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 ClientContext {
- public ResourceResolver getResourceResolver() {
- return this.resourceResolver;
- }
+ /**
+ * Returns <code>true</code> if the feature is enabled.
+ */
+ boolean isEnabled(String featureName);
+
+ /**
+ * Returns a list of all enabled features
+ * @return The list of features, the list might be empty.
+ */
+ Collection<String> getEnabledFeatures();
}
Modified:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java?rev=1552225&r1=1552224&r2=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/FeatureProvider.java
Thu Dec 19 04:47:20 2013
@@ -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.
Copied:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Features.java
(from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Feature.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Features.java?p2=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Features.java&p1=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Feature.java&r1=1552224&r2=1552225&rev=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Feature.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/Features.java
Thu Dec 19 04:47:20 2013
@@ -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);
}
Added:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java?rev=1552225&view=auto
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
(added)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
Thu Dec 19 04:47:20 2013
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+
+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.
+ */
+@ProviderType
+public interface ProviderContext {
+
+ /**
+ * Return the associated request if available
+ * @return the request or <code>null</code>
+ */
+ SlingHttpServletRequest getRequest();
+
+ /**
+ * Return the associated resource resolver.
+ * @return the resource resolver
+ */
+ ResourceResolver getResourceResolver();
+}
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/ProviderContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java?rev=1552225&view=auto
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
(added)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
Thu Dec 19 04:47:20 2013
@@ -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;
+ }
+}
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ClientContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
(from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java?p2=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java&p1=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java&r1=1552224&r2=1552225&rev=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ExecutionContextFilter.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/CurrentClientContextFilter.java
Thu Dec 19 04:47:20 2013
@@ -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.
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
}
}
Added:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java?rev=1552225&view=auto
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
(added)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
Thu Dec 19 04:47:20 2013
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.extensions.featureflags.ProviderContext;
+
+public class FeatureContextImpl implements ProviderContext {
+
+ private final ResourceResolver resourceResolver;
+
+ private final SlingHttpServletRequest request;
+
+ public FeatureContextImpl(final ResourceResolver resourceResolver) {
+ this.request = null;
+ this.resourceResolver = resourceResolver;
+ }
+
+ 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;
+ }
+}
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java?rev=1552225&r1=1552224&r2=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
Thu Dec 19 04:47:20 2013
@@ -28,10 +28,13 @@ import org.apache.felix.scr.annotations.
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 F
}
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 ClientContext createClientContext(final ResourceResolver resolver) {
+ if ( resolver == null ) {
+ throw new IllegalArgumentException("Resolver must not be null.");
+ }
+ final ProviderContext featureContext = new
FeatureContextImpl(resolver);
+ final ClientContext ctx = this.createClientContext(featureContext);
+ return ctx;
+ }
+
@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 SlingHttpServletRequest
request) {
+ if ( request == null ) {
+ throw new IllegalArgumentException("Request must not be null.");
}
- return result;
+ 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 F
/**
* 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 F
}
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);
Copied:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
(from r1552224,
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java?p2=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java&p1=sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java&r1=1552224&r2=1552225&rev=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureImpl.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeaturesImpl.java
Thu Dec 19 04:47:20 2013
@@ -21,34 +21,43 @@ package org.apache.sling.extensions.feat
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);
+ }
}
Modified:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java?rev=1552225&r1=1552224&r2=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java
Thu Dec 19 04:47:20 2013
@@ -22,9 +22,13 @@ import org.apache.felix.scr.annotations.
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;
Modified:
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java?rev=1552225&r1=1552224&r2=1552225&view=diff
==============================================================================
---
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
(original)
+++
sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
Thu Dec 19 04:47:20 2013
@@ -26,7 +26,11 @@ import org.apache.felix.scr.annotations.
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 imple
@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);