sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1552222 - in /sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl: ExecutionContextFilter.java FeatureImpl.java FeatureManager.java ResourceAccessImpl.java ResourceDecoratorImpl.java
Date Thu, 19 Dec 2013 03:46:14 GMT
Author: cziegeler
Date: Thu Dec 19 03:46:14 2013
New Revision: 1552222

URL: http://svn.apache.org/r1552222
Log:
Implemet hiding of resource and decorating

Added:
    sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
  (with props)
    sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
  (with props)
Modified:
    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
    sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceAccessImpl.java

Modified: 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/ExecutionContextFilter.java?rev=1552222&r1=1552221&r2=1552222&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/ExecutionContextFilter.java
Thu Dec 19 03:46:14 2013
@@ -19,8 +19,9 @@
 package org.apache.sling.extensions.featureflags.impl;
 
 import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -85,7 +86,7 @@ public class ExecutionContextFilter impl
     public final class ExecutionContextInfo {
 
         public final ExecutionContext context;
-        public final Set<String> enabledFeatures = new HashSet<String>();
+        public final List<String> enabledFeatures = new ArrayList<String>();
 
         public ExecutionContextInfo(final SlingHttpServletRequest req,
                 final Feature feature) {
@@ -95,6 +96,7 @@ public class ExecutionContextFilter impl
                     enabledFeatures.add(name);
                 }
             }
+            Collections.sort(enabledFeatures);
         }
     }
 }

Modified: 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/FeatureImpl.java?rev=1552222&r1=1552221&r2=1552222&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/FeatureImpl.java
Thu Dec 19 03:46:14 2013
@@ -18,21 +18,12 @@
  */
 package org.apache.sling.extensions.featureflags.impl;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
 import org.apache.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.osgi.framework.Constants;
 
 /**
  * This service implements the feature handling.
@@ -40,157 +31,24 @@ import org.osgi.framework.Constants;
  */
 @Component
 @Service(value=Feature.class)
-@Reference(name="featureProvider",
-           cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
-           policy=ReferencePolicy.DYNAMIC,
-           referenceInterface=FeatureProvider.class)
 public class FeatureImpl implements Feature {
 
-    private final Map<String, List<FeatureProviderDescription>> providers = new
HashMap<String, List<FeatureProviderDescription>>();
-
-    private Map<String, FeatureProviderDescription> activeProviders = new HashMap<String,
FeatureProviderDescription>();
-
-    /**
-     * Bind a new feature provider
-     */
-    protected void bindFeatureProvider(final FeatureProvider provider, final Map<String,
Object> props) {
-        final String[] features = provider.getFeatureNames();
-        if ( features != null && features.length > 0 ) {
-            final FeatureProviderDescription info = new FeatureProviderDescription(provider,
props);
-            synchronized ( this.providers ) {
-                boolean changed = false;
-                for(final String n : features) {
-                    if ( n != null ) {
-                        final String name = n.trim();
-                        if ( name.length() > 0 ) {
-                            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();
-                }
-            }
-        }
-    }
-
-    /**
-     * Unbind a feature provider
-     */
-    protected void unbindFeatureProvider(final FeatureProvider provider, final Map<String,
Object> props) {
-        final String[] features = provider.getFeatureNames();
-        if ( features != null && features.length > 0 ) {
-            final FeatureProviderDescription info = new FeatureProviderDescription(provider,
props);
-            synchronized ( this.providers ) {
-                boolean changed = false;
-                for(final String n : features) {
-                    if ( n != null ) {
-                        final String name = n.trim();
-                        if ( name.length() > 0 ) {
-                            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();
-                }
-            }
-        }
-    }
-
-    private void calculateActiveProviders() {
-        final Map<String, FeatureProviderDescription> activeMap = new HashMap<String,
FeatureImpl.FeatureProviderDescription>();
-        for(final Map.Entry<String, List<FeatureProviderDescription>> entry :
this.providers.entrySet()) {
-            activeMap.put(entry.getKey(), entry.getValue().get(0));
-        }
-        this.activeProviders = activeMap;
-    }
+    @Reference
+    private FeatureManager manager;
 
     @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);
-        }
-        return result;
+        return this.manager.isEnabled(featureName, context);
     }
 
     @Override
     public String[] getFeatureNames() {
-        return this.activeProviders.keySet().toArray(new String[this.activeProviders.size()]);
+        return this.manager.getFeatureNames();
     }
 
     @Override
     public boolean isAvailable(final String featureName) {
-        return this.activeProviders.containsKey(featureName);
-    }
-
-
-    /**
-     * Internal class caching some provider infos like service id and ranking.
-     */
-    private final static class FeatureProviderDescription implements Comparable<FeatureProviderDescription>
{
-
-        public FeatureProvider provider;
-        public final int ranking;
-        public final long serviceId;
-
-        public FeatureProviderDescription(final FeatureProvider provider, final Map<String,
Object> props) {
-            this.provider = provider;
-            final Object sr = props.get(Constants.SERVICE_RANKING);
-            if ( sr == null || !(sr instanceof Integer)) {
-                this.ranking = 0;
-            } else {
-                this.ranking = (Integer)sr;
-            }
-            this.serviceId = (Long)props.get(Constants.SERVICE_ID);
-        }
-
-        @Override
-        public int compareTo(final FeatureProviderDescription o) {
-            if ( this.ranking < o.ranking ) {
-                return 1;
-            } else if (this.ranking > o.ranking ) {
-                return -1;
-            }
-            // If ranks are equal, then sort by service id in descending order.
-            return (this.serviceId < o.serviceId) ? -1 : 1;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if ( obj instanceof FeatureProviderDescription ) {
-                return ((FeatureProviderDescription)obj).serviceId == this.serviceId;
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + (int) (serviceId ^ (serviceId >>> 32));
-            return result;
-        }
-
-        public FeatureProvider getProvider() {
-            return provider;
-        }
+        // TODO Auto-generated method stub
+        return this.manager.isAvailable(featureName);
     }
 }

Added: 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=1552222&view=auto
==============================================================================
--- sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
(added)
+++ sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
Thu Dec 19 03:46:14 2013
@@ -0,0 +1,220 @@
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.extensions.featureflags.ExecutionContext;
+import org.apache.sling.extensions.featureflags.Feature;
+import org.apache.sling.extensions.featureflags.FeatureProvider;
+import org.osgi.framework.Constants;
+
+/**
+ * This service implements the feature handling.
+ * It keeps track of all {@link FeatureProvider} services.
+ */
+@Component
+@Reference(name="featureProvider",
+           cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
+           policy=ReferencePolicy.DYNAMIC,
+           referenceInterface=FeatureProvider.class)
+public class FeatureManager implements Feature {
+
+    private final Map<String, List<FeatureProviderDescription>> providers = new
HashMap<String, List<FeatureProviderDescription>>();
+
+    private Map<String, FeatureProviderDescription> activeProviders = new HashMap<String,
FeatureProviderDescription>();
+
+    /**
+     * Bind a new feature provider
+     */
+    protected void bindFeatureProvider(final FeatureProvider provider, final Map<String,
Object> props) {
+        final String[] features = provider.getFeatureNames();
+        if ( features != null && features.length > 0 ) {
+            final FeatureProviderDescription info = new FeatureProviderDescription(provider,
props);
+            synchronized ( this.providers ) {
+                boolean changed = false;
+                for(final String n : features) {
+                    if ( n != null ) {
+                        final String name = n.trim();
+                        if ( name.length() > 0 ) {
+                            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();
+                }
+            }
+        }
+    }
+
+    /**
+     * Unbind a feature provider
+     */
+    protected void unbindFeatureProvider(final FeatureProvider provider, final Map<String,
Object> props) {
+        final String[] features = provider.getFeatureNames();
+        if ( features != null && features.length > 0 ) {
+            final FeatureProviderDescription info = new FeatureProviderDescription(provider,
props);
+            synchronized ( this.providers ) {
+                boolean changed = false;
+                for(final String n : features) {
+                    if ( n != null ) {
+                        final String name = n.trim();
+                        if ( name.length() > 0 ) {
+                            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();
+                }
+            }
+        }
+    }
+
+    private void calculateActiveProviders() {
+        final Map<String, FeatureProviderDescription> activeMap = new HashMap<String,
FeatureManager.FeatureProviderDescription>();
+        for(final Map.Entry<String, List<FeatureProviderDescription>> entry :
this.providers.entrySet()) {
+            activeMap.put(entry.getKey(), entry.getValue().get(0));
+        }
+        this.activeProviders = activeMap;
+    }
+
+    @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);
+        }
+        return result;
+    }
+
+    @Override
+    public String[] getFeatureNames() {
+        return this.activeProviders.keySet().toArray(new String[this.activeProviders.size()]);
+    }
+
+    @Override
+    public boolean isAvailable(final String featureName) {
+        return this.activeProviders.containsKey(featureName);
+    }
+
+    /**
+     * Checks whether a resource should be hidden for a feature.
+     * This check is only executed if {@link #isEnabled(String, ExecutionContext)}
+     * 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();
+            return prod.hideResource(featureName, resource);
+        }
+        return false;
+    }
+
+    /**
+     * Internal class caching some provider infos like service id and ranking.
+     */
+    private final static class FeatureProviderDescription implements Comparable<FeatureProviderDescription>
{
+
+        public FeatureProvider provider;
+        public final int ranking;
+        public final long serviceId;
+
+        public FeatureProviderDescription(final FeatureProvider provider, final Map<String,
Object> props) {
+            this.provider = provider;
+            final Object sr = props.get(Constants.SERVICE_RANKING);
+            if ( sr == null || !(sr instanceof Integer)) {
+                this.ranking = 0;
+            } else {
+                this.ranking = (Integer)sr;
+            }
+            this.serviceId = (Long)props.get(Constants.SERVICE_ID);
+        }
+
+        @Override
+        public int compareTo(final FeatureProviderDescription o) {
+            if ( this.ranking < o.ranking ) {
+                return 1;
+            } else if (this.ranking > o.ranking ) {
+                return -1;
+            }
+            // If ranks are equal, then sort by service id in descending order.
+            return (this.serviceId < o.serviceId) ? -1 : 1;
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if ( obj instanceof FeatureProviderDescription ) {
+                return ((FeatureProviderDescription)obj).serviceId == this.serviceId;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + (int) (serviceId ^ (serviceId >>> 32));
+            return result;
+        }
+
+        public FeatureProvider getProvider() {
+            return provider;
+        }
+    }
+
+    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 Map<String, String> mapping = prod.getResourceTypeMapping(featureName);
+            if ( mapping != null ) {
+                return mapping.get(resourceType);
+            }
+        }
+        return null;
+    }
+}

Propchange: sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/FeatureManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

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

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=1552222&r1=1552221&r2=1552222&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 03:46:14 2013
@@ -22,7 +22,6 @@ 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.Feature;
 import org.apache.sling.resourceaccesssecurity.AllowingResourceAccessGate;
 import org.apache.sling.resourceaccesssecurity.ResourceAccessGate;
 
@@ -33,7 +32,7 @@ public class ResourceAccessImpl
     implements ResourceAccessGate {
 
     @Reference
-    private Feature feature;
+    private FeatureManager manager;
 
     @Override
     public GateResult canRead(final Resource resource) {
@@ -42,8 +41,10 @@ public class ResourceAccessImpl
         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)
-                available = false;
-                break;
+                available = !manager.hideResource(name, resource);
+                if ( !available) {
+                    break;
+                }
             }
         }
         return (available ? GateResult.DONTCARE : GateResult.DENIED);

Added: 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=1552222&view=auto
==============================================================================
--- sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
(added)
+++ sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
Thu Dec 19 03:46:14 2013
@@ -0,0 +1,68 @@
+/*
+ * 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 javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceDecorator;
+import org.apache.sling.api.resource.ResourceWrapper;
+
+@Component
+@Service(value=ResourceDecorator.class)
+public class ResourceDecoratorImpl implements ResourceDecorator {
+
+    @Reference
+    private FeatureManager manager;
+
+    @Override
+    public Resource decorate(final Resource resource) {
+        final ExecutionContextFilter.ExecutionContextInfo info = ExecutionContextFilter.getCurrentExecutionContextInfo();
+        if ( info != null ) {
+            for(final String name : info.enabledFeatures) {
+
+                final String resourceType = resource.getResourceType();
+                final String overwriteType = manager.getResourceType(name, resourceType);
+                if ( overwriteType != null ) {
+                    return new ResourceWrapper(resource) {
+
+                        @Override
+                        public String getResourceType() {
+                            return overwriteType;
+                        }
+
+                        @Override
+                        public String getResourceSuperType() {
+                            return resourceType;
+                        }
+                    };
+                }
+            }
+        }
+        return resource;
+    }
+
+    @Override
+    public Resource decorate(final Resource resource, final HttpServletRequest request) {
+        return this.decorate(resource);
+    }
+}

Propchange: sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/feature-flags/src/main/java/org/apache/sling/extensions/featureflags/impl/ResourceDecoratorImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

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



Mime
View raw message