This is an automated email from the ASF dual-hosted git repository.

enorman pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-accessmanager.git


The following commit(s) were added to refs/heads/master by this push:
     new c2d5995  SLING-7831 support injecting custom/alternate PostResponse 
implementations for the servlets in the usermanager and accessmanager bundles
c2d5995 is described below

commit c2d5995ed48ae20bfd86bef22f44c786b758b44a
Author: Eric Norman <[email protected]>
AuthorDate: Sun Aug 19 13:38:40 2018 -0700

    SLING-7831 support injecting custom/alternate PostResponse
    implementations for the servlets in the usermanager and accessmanager
    bundles
---
 pom.xml                                            |   3 +
 .../post/AbstractAccessPostServlet.java            | 166 ++++++++++++++++++++-
 .../accessmanager/post/AbstractGetAclServlet.java  |   6 -
 .../accessmanager/post/DeleteAcesServlet.java      |  33 +++-
 .../accessmanager/post/ModifyAceServlet.java       |  32 +++-
 .../accessmanager/post/package-info.java           |   2 +-
 6 files changed, 221 insertions(+), 21 deletions(-)

diff --git a/pom.xml b/pom.xml
index d0cdb61..8da4c32 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,9 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
+                        <Embed-Dependency>
+                            
org.apache.sling.servlets.post;inline="org/apache/sling/servlets/post/impl/helper/MediaRangeList*"
+                        </Embed-Dependency>
                     </instructions>
                 </configuration>
             </plugin>
diff --git 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessPostServlet.java
 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessPostServlet.java
index 0044688..2887921 100644
--- 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessPostServlet.java
+++ 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessPostServlet.java
@@ -18,7 +18,9 @@ package org.apache.sling.jcr.jackrabbit.accessmanager.post;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -34,13 +36,17 @@ import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.servlets.post.HtmlResponse;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
 import org.apache.sling.api.wrappers.SlingRequestPaths;
 import org.apache.sling.servlets.post.AbstractPostResponse;
+import org.apache.sling.servlets.post.HtmlResponse;
+import org.apache.sling.servlets.post.JSONResponse;
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.PostResponseCreator;
 import org.apache.sling.servlets.post.SlingPostConstants;
-import org.apache.sling.servlets.post.JSONResponse;
+import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
+import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,6 +61,13 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
      */
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    /** Sorted list of post response creator holders. */
+    private final List<PostResponseCreatorHolder> postResponseCreators = new 
ArrayList<>();
+
+    /** Cached array of post response creators used during request processing. 
*/
+    private PostResponseCreator[] cachedPostResponseCreators = new 
PostResponseCreator[0];
+
+
        /* (non-Javadoc)
         * @see 
org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache.sling.api.SlingHttpServletRequest,
 org.apache.sling.api.SlingHttpServletResponse)
         */
@@ -63,7 +76,7 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
                        SlingHttpServletResponse httpResponse) throws 
ServletException,
                        IOException {
         // prepare the response
-               AbstractPostResponse response = createHtmlResponse(request);
+       PostResponse response = createPostResponse(request);
         response.setReferer(request.getHeader("referer"));
 
         // calculate the paths
@@ -145,13 +158,53 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
      *   <li>the response content type is application/json
      * </ul>
      * or a {@link org.apache.sling.api.servlets.HtmlResponse} otherwise
+     * @deprecated use {@link #createPostResponse(SlingHttpServletRequest)} 
instead
      */
+       @Deprecated
     protected AbstractPostResponse createHtmlResponse(SlingHttpServletRequest 
req) {
-       if 
(JSONResponse.RESPONSE_CONTENT_TYPE.equals(req.getResponseContentType())) {
-               return new JSONResponse();
-       } else {
+       return (AbstractPostResponse)createPostResponse(req);
+    }
+       
+    /**
+     * Creates an instance of a PostResponse.
+     * @param req The request being serviced
+     * @return a {@link 
org.apache.sling.servlets.post.impl.helper.JSONResponse} if any of these 
conditions are true:
+     * <ul>
+     *   <li> the request has an <code>Accept</code> header of 
<code>application/json</code></li>
+     *   <li>the request is a JSON POST request (see SLING-1172)</li>
+     *   <li>the request has a request parameter 
<code>:accept=application/json</code></li>
+     * </ul>
+     * or a {@link org.apache.sling.api.servlets.PostResponse} otherwise
+     */
+    PostResponse createPostResponse(final SlingHttpServletRequest req) {
+        for (final PostResponseCreator creator : cachedPostResponseCreators) {
+            final PostResponse response = creator.createPostResponse(req);
+            if (response != null) {
+                return response;
+            }
+        }
+
+        //for backward compatibility, if no "accept" request param or header 
is supplied
+        // then prefer the SlingHttpServletRequest#getResponseContentType value
+        MediaRangeList mediaRangeList = null;
+        String queryParam = req.getParameter(MediaRangeList.PARAM_ACCEPT);
+        if (queryParam == null || queryParam.trim().length() == 0) {
+               String headerValue = 
req.getHeader(MediaRangeList.HEADER_ACCEPT);
+               if (headerValue == null || headerValue.trim().length() == 0) {
+                       //no param or header supplied, so try the response 
content type
+                       mediaRangeList = new 
MediaRangeList(req.getResponseContentType());
+               }
+        }
+
+        // Fall through to default behavior
+        if (mediaRangeList == null) {
+               mediaRangeList = new MediaRangeList(req);
+        }
+        if 
(JSONResponse.RESPONSE_CONTENT_TYPE.equals(mediaRangeList.prefer("text/html", 
JSONResponse.RESPONSE_CONTENT_TYPE))) {
+            return new JSONResponse();
+        } else {
             return new HtmlResponse();
-       }
+        }
     }
        
        /**
@@ -160,9 +213,24 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
         * @param request the sling http request to process
         * @param response the response
         * @param changes
+        * 
+        * @deprecated use {@link #handleOperation(SlingHttpServletRequest, 
PostResponse, List)} instead
+        */
+    @Deprecated
+       protected void handleOperation(SlingHttpServletRequest request,
+                       AbstractPostResponse response, List<Modification> 
changes) throws RepositoryException {
+               handleOperation(request, (PostResponse)response, changes);
+       }
+    
+       /**
+        * Extending Servlet should implement this operation to do the work
+        *
+        * @param request the sling http request to process
+        * @param response the response
+        * @param changes
         */
        abstract protected void handleOperation(SlingHttpServletRequest request,
-                       AbstractPostResponse response, List<Modification> 
changes) throws RepositoryException;
+                       PostResponse response, List<Modification> changes) 
throws RepositoryException;
 
 
     /**
@@ -170,8 +238,20 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
      *
      * @param ctx the post processor
      * @return the redirect location or <code>null</code>
+     * @deprecated use {@link #getRedirectUrl(HttpServletRequest, 
PostResponse)} instead
      */
+       @Deprecated
     protected String getRedirectUrl(HttpServletRequest request, 
AbstractPostResponse ctx) {
+       return getRedirectUrl(request, (PostResponse)ctx);
+    }
+    
+    /**
+     * compute redirect URL (SLING-126)
+     *
+     * @param ctx the post processor
+     * @return the redirect location or <code>null</code>
+     */
+    protected String getRedirectUrl(HttpServletRequest request, PostResponse 
ctx) {
         // redirect param has priority (but see below, magic star)
         String result = 
request.getParameter(SlingPostConstants.RP_REDIRECT_TO);
         if (result != null && ctx.getPath() != null) {
@@ -321,4 +401,74 @@ public abstract class AbstractAccessPostServlet extends 
SlingAllMethodsServlet {
                 + resourcePath);
 
     }
+
+
+    /**
+     * Bind a new post response creator
+     */
+       // NOTE: the @Reference annotation is not inherited, so subclasses will 
need to override the #bindPostResponseCreator 
+       // and #unbindPostResponseCreator methods to provide the @Reference 
annotation.     
+       //
+       // @Reference(service = PostResponseCreator.class,
+       //         cardinality = ReferenceCardinality.MULTIPLE,
+       //         policy = ReferencePolicy.DYNAMIC)
+    protected void bindPostResponseCreator(final PostResponseCreator creator, 
final Map<String, Object> properties) {
+        final PostResponseCreatorHolder nngh = new PostResponseCreatorHolder();
+        nngh.creator = creator;
+        nngh.ranking = getRanking(properties);
+
+        synchronized ( this.postResponseCreators ) {
+            int index = 0;
+            while ( index < this.postResponseCreators.size() &&
+                    nngh.ranking < 
this.postResponseCreators.get(index).ranking ) {
+                index++;
+            }
+            if ( index == this.postResponseCreators.size() ) {
+                this.postResponseCreators.add(nngh);
+            } else {
+                this.postResponseCreators.add(index, nngh);
+            }
+            this.updatePostResponseCreatorCache();
+        }
+    }
+
+    /**
+     * Unbind a post response creator
+     */
+    protected void unbindPostResponseCreator(final PostResponseCreator 
creator, final Map<String, Object> properties) {
+        synchronized ( this.postResponseCreators ) {
+            final Iterator<PostResponseCreatorHolder> i = 
this.postResponseCreators.iterator();
+            while ( i.hasNext() ) {
+                final PostResponseCreatorHolder current = i.next();
+                if ( current.creator == creator ) {
+                    i.remove();
+                }
+            }
+            this.updatePostResponseCreatorCache();
+        }
+    }
+
+    /**
+     * Update the post response creator cache
+     * This method is called by sync'ed methods, no need to add additional 
syncing.
+     */
+    private void updatePostResponseCreatorCache() {
+        final PostResponseCreator[] localCache = new 
PostResponseCreator[this.postResponseCreators.size()];
+        int index = 0;
+        for(final PostResponseCreatorHolder current : 
this.postResponseCreators) {
+            localCache[index] = current.creator;
+            index++;
+        }
+        this.cachedPostResponseCreators = localCache;
+    }
+    
+    private int getRanking(final Map<String, Object> properties) {
+        final Object val = properties.get(Constants.SERVICE_RANKING);
+        return val instanceof Integer ? (Integer)val : 0;
+    }
+    
+    private static final class PostResponseCreatorHolder {
+        public PostResponseCreator creator;
+        public int ranking;
+    }    
 }
diff --git 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
index b56adf3..9ee88f6 100644
--- 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
+++ 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
@@ -19,9 +19,7 @@ package org.apache.sling.jcr.jackrabbit.accessmanager.post;
 import java.io.IOException;
 import java.security.Principal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -31,18 +29,14 @@ import java.util.Set;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Item;
-import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.Privilege;
 import javax.json.Json;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
-import javax.json.JsonValue;
 import javax.json.stream.JsonGenerator;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
diff --git 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
index a676276..da8e3ec 100644
--- 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
+++ 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeleteAcesServlet.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.Item;
@@ -34,10 +35,14 @@ import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.jcr.base.util.AccessControlUtil;
 import org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces;
-import org.apache.sling.servlets.post.AbstractPostResponse;
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.PostResponseCreator;
 import org.apache.sling.servlets.post.SlingPostConstants;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
 
 /**
  * <p>
@@ -80,12 +85,34 @@ import org.osgi.service.component.annotations.Component;
 public class DeleteAcesServlet extends AbstractAccessPostServlet implements 
DeleteAces {
        private static final long serialVersionUID = 3784866802938282971L;
 
+    /**
+     * Overridden since the @Reference annotation is not inherited from the 
super method
+     *  
+        * @see 
org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#bindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator,
 java.util.Map)
+        */
+       @Override
+    @Reference(service = PostResponseCreator.class,
+           cardinality = ReferenceCardinality.MULTIPLE,
+           policy = ReferencePolicy.DYNAMIC)
+       protected void bindPostResponseCreator(PostResponseCreator creator, 
Map<String, Object> properties) {
+               super.bindPostResponseCreator(creator, properties);
+       }
+       
+       /* (non-Javadoc)
+        * @see 
org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator,
 java.util.Map)
+        */
+       @Override
+       protected void unbindPostResponseCreator(PostResponseCreator creator, 
Map<String, Object> properties) {
+               super.unbindPostResponseCreator(creator, properties);
+       }
+    
+       
        /* (non-Javadoc)
-        * @see 
org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest,
 org.apache.sling.api.servlets.HtmlResponse, java.util.List)
+        * @see 
org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest,
 org.apache.sling.servlets.post.PostResponse, java.util.List)
         */
        @Override
        protected void handleOperation(SlingHttpServletRequest request,
-                       AbstractPostResponse htmlResponse, List<Modification> 
changes)
+                       PostResponse htmlResponse, List<Modification> changes)
                        throws RepositoryException {
 
                Session session = 
request.getResourceResolver().adaptTo(Session.class);
diff --git 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
index 8647cf9..c11f85c 100644
--- 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
+++ 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
@@ -35,9 +35,13 @@ import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.jcr.base.util.AccessControlUtil;
 import org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce;
-import org.apache.sling.servlets.post.AbstractPostResponse;
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.PostResponseCreator;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
 
 /**
  * <p>
@@ -90,12 +94,34 @@ property= {
 public class ModifyAceServlet extends AbstractAccessPostServlet implements 
ModifyAce {
        private static final long serialVersionUID = -9182485466670280437L;
 
+    /**
+     * Overridden since the @Reference annotation is not inherited from the 
super method
+     *  
+        * @see 
org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#bindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator,
 java.util.Map)
+        */
+       @Override
+    @Reference(service = PostResponseCreator.class,
+           cardinality = ReferenceCardinality.MULTIPLE,
+           policy = ReferencePolicy.DYNAMIC)
+       protected void bindPostResponseCreator(PostResponseCreator creator, 
Map<String, Object> properties) {
+               super.bindPostResponseCreator(creator, properties);
+       }
+       
+       /* (non-Javadoc)
+        * @see 
org.apache.sling.jackrabbit.usermanager.impl.post.AbstractPostServlet#unbindPostResponseCreator(org.apache.sling.servlets.post.PostResponseCreator,
 java.util.Map)
+        */
+       @Override
+       protected void unbindPostResponseCreator(PostResponseCreator creator, 
Map<String, Object> properties) {
+               super.unbindPostResponseCreator(creator, properties);
+       }
+    
+       
        /* (non-Javadoc)
-        * @see 
org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest,
 org.apache.sling.api.servlets.HtmlResponse, java.util.List)
+        * @see 
org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest,
 org.apache.sling.servlets.post.PostResponse, java.util.List)
         */
        @Override
        protected void handleOperation(SlingHttpServletRequest request,
-                       AbstractPostResponse response, List<Modification> 
changes)
+                       PostResponse response, List<Modification> changes)
                        throws RepositoryException {
                Session session = 
request.getResourceResolver().adaptTo(Session.class);
        String resourcePath = request.getResource().getPath();
diff --git 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/package-info.java
 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/package-info.java
index 708b13c..79406f4 100644
--- 
a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/package-info.java
+++ 
b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
[email protected]("3.0.1")
[email protected]("3.1.0")
 package org.apache.sling.jcr.jackrabbit.accessmanager.post;
 
 

Reply via email to