[ 
https://issues.apache.org/jira/browse/SLING-2575?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13478685#comment-13478685
 ] 

Chetan Mehrotra commented on SLING-2575:
----------------------------------------

Interesting discussion. Did not knew about ServiceUtil. I have also struggled 
with handling of ordered multiple references so far with Declarative Service. 
This was one area where Bleuprint's sorted dynamic reference list [1] was 
pretty useful. However we can get similar support by using 
o.a.s.commons.osgi.ServiceUtil.getComparableForServiceRanking and JDK 6 
ConcurrentSkipListMap. With this we need not require synchronized map.

@Reference(name = "AuthorizableAction",
        policy = ReferencePolicy.DYNAMIC,
        cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
        referenceInterface = AuthorizableAction.class
)
public class MultiplexingAuthorizableAction extends AbstractAuthorizableAction{
    private Map<Comparable<Object>,AuthorizableAction> actionMap =
              new ConcurrentSkipListMap<Comparable<Object>, 
AuthorizableAction>();
    ...
    private Collection<AuthorizableAction> getActions() {
        return actionMap.values(); //Sorted list
    }

    private void bindAuthorizableAction(AuthorizableAction 
action,Map<String,Object> config){
        actionMap.put(ServiceUtil.getComparableForServiceRanking(config), 
action);
    }

    private void unbindAuthorizableAction(AuthorizableAction 
action,Map<String,Object> config){
        actionMap.remove(ServiceUtil.getComparableForServiceRanking(config));
    }
}

For Alex's requirement of having a list sorted in reverse order (which is 
probably the more common usecase) we can modify the ServiceUtil to 
- Provide a Compartor implementation which does the reverse and pass that on to 
ConcurrentSkipListMap as keys
- OR Have a new ServiceUtil.getDescendingComparableForServiceRanking(config)


[1] 
http://www.eclipse.org/gemini/blueprint/documentation/reference/1.0.1.RELEASE/html/service-registry.html#service-registry:refs:collection
 
                
> Utility for tracking a multi-cardinality OSGi service reference
> ---------------------------------------------------------------
>
>                 Key: SLING-2575
>                 URL: https://issues.apache.org/jira/browse/SLING-2575
>             Project: Sling
>          Issue Type: Improvement
>          Components: Commons
>            Reporter: Alexander Klimetschek
>            Priority: Minor
>         Attachments: SLING-2575-ServiceReferences.patch
>
>
> Managing a SCR @Reference that's basically a list is very difficult when 
> compared to the simple unary, static reference. It seems a typical use case 
> is 0..n cardinality, dynamic policy and ordered by service ranking with the 
> higher ranked ones first. This supports the use case to ask a list of 
> services and have the first responding one win.
> There is the ServiceTracker [0], but its getServiceReferences() method does 
> not return the list sorted in any way, only gives your references and not the 
> typed object(s) and it's a bit cumbersome to use.
> A typical manual approach can be seen in the SlingPostServlet [1] in the 
> register*() methods. Important is to handle thread-safeness.
> [0] 
> http://www.osgi.org/javadoc/r4v42/org/osgi/util/tracker/ServiceTracker.html
> [1] 
> http://svn.apache.org/repos/asf/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to