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;