[
https://issues.apache.org/jira/browse/SLING-10030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17266884#comment-17266884
]
Tomás Dias Almeida commented on SLING-10030:
--------------------------------------------
Proposed PR:
https://github.com/apache/sling-org-apache-sling-servlets-post/pull/10
> Add an optional ranking as a property for PostOperation implementation
> -----------------------------------------------------------------------
>
> Key: SLING-10030
> URL: https://issues.apache.org/jira/browse/SLING-10030
> Project: Sling
> Issue Type: Improvement
> Affects Versions: Servlets Post 2.3.36
> Reporter: Tomás Dias Almeida
> Priority: Major
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Given the case, a PostOperation PO1 implementation is provided for a given
> operation, but it does not solve a particular need. I would like to be able
> to create another PostOperation implementation PO2 with a higher ranking and
> replace the PO1.
> h2. *Current status*
> h3. *Last wins condition*
> [org.apache.sling.servlets.post.impl.SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
> can only store one PostOperation per operation as it is stored like
>
> {code:java}
> private final Map<String, PostOperation> postOperations = new
> HashMap<>();{code}
>
> This map is filled by the binding function per order of activation
>
> {code:java}
> protected void bindPostOperation(final PostOperation operation, final
> Map<String, Object> properties) {
> final String operationName = (String)
> properties.get(PostOperation.PROP_OPERATION_NAME);
> if ( operationName != null && operation != null ) {
> synchronized (this.postOperations) {
> this.postOperations.put(operationName, operation);
> }
> }
> }{code}
>
> If two classes provide an implementation for the given operation, we run into
> a concurrency problem and the last activated component "wins" the race and
> will be used.
> h3. Incorrect map if a component is stopped
> The map is updated using an unbinding method, that relies on the axiom that
> there is only one PostOperation per operation.
>
> {code:java}
> protected void unbindPostOperation(final PostOperation operation, final
> Map<String, Object> properties) {
> final String operationName = (String)
> properties.get(PostOperation.PROP_OPERATION_NAME);
> if ( operationName != null ) {
> synchronized (this.postOperations) {
> this.postOperations.remove(operationName);
> }
> }
> }
> {code}
> And so, if we have the following scenario:
>
> # PostOperation P1 is activated for operation P
> # PostOperation P2 is activated for operation P
> #
> [SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
> stores P2 as PostOperation for P (as described above)
> # P2 is stopped for any reason
> #
> [SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
> has no PostOperation set for P, but P1 could be the right one.
> h2. Proposal
> Each PostOperation can provide an optional "operation.ranking" integer
> property.
> bindPostOperation method will store all PostOperations by order of ranking
> (higher first), PostOperations with no ranking will be added to the end by
> order of calling.
> unbindPostOperation removes the given PostOperation of the sorted list.
>
>
> If you believe that is a good idea, I can provide an implementation to
> discuss the solution.
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)