Tomás Dias Almeida created SLING-10030:
------------------------------------------
Summary: 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
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)