You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2016/04/18 11:26:39 UTC

svn commit: r1739719 - in /sling/trunk/bundles: api/src/main/java/org/apache/sling/api/scripting/ scripting/core/ scripting/core/src/main/java/org/apache/sling/scripting/core/ scripting/core/src/test/java/org/apache/sling/scripting/core/

Author: kwin
Date: Mon Apr 18 09:26:39 2016
New Revision: 1739719

URL: http://svn.apache.org/viewvc?rev=1739719&view=rev
Log:
SLING-5665 always sort services being returned by SlingScriptHelper.getServices(...) descending by their service ranking

Added:
    sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java   (with props)
Modified:
    sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/SlingScriptHelper.java
    sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/package-info.java
    sling/trunk/bundles/scripting/core/pom.xml
    sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/ScriptHelper.java

Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/SlingScriptHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/SlingScriptHelper.java?rev=1739719&r1=1739718&r2=1739719&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/SlingScriptHelper.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/SlingScriptHelper.java Mon Apr 18 09:26:39 2016
@@ -322,21 +322,35 @@ public interface SlingScriptHelper {
     void forward(@Nonnull Resource resource, RequestDispatcherOptions options);
 
     /**
-     * Lookup a single service
-     *
+     * Lookup a single service.
+     * <p>
+     * If multiple such services exist, the service with the highest ranking (as specified in its Constants.SERVICE_RANKING property) is returned.
+     * If there is a tie in ranking, the service with the lowest service ID (as specified in its Constants.SERVICE_ID property); that is, the service that was registered first is returned. 
+     * </p>
+     * <p>This is equal to the semantics from 
+     * <a href="https://osgi.org/javadoc/r5/core/org/osgi/framework/BundleContext.html#getServiceReference(java.lang.Class)">
+     * BundleContext.getServiceReference(Class)</a>.</p>
      * @param serviceType The type (interface) of the service.
-     * @return The service instance, or null if the service is not available.
+     * @return The service instance, or {@code null} if no services are registered which implement the specified class.
      */
     @CheckForNull <ServiceType> ServiceType getService(@Nonnull Class<ServiceType> serviceType);
 
     /**
-     * Lookup one or several services
+     * Lookup one or several services.
+     * <p>
+     * The returned array is sorted descending by service ranking (i.e. the service with the highest ranking is returned first).
+     * If there is a tie in ranking, the service with the lowest service ID 
+     * (as specified in its Constants.SERVICE_ID property); 
+     * that is, the service that was registered first is returned first.
+     * </p>
      *
      * @param serviceType The type (interface) of the service.
      * @param filter An optional filter (LDAP-like, see OSGi spec)
-     * @return The services object or null.
+     * @return An array of services objects or {@code null}.
      * @throws InvalidServiceFilterSyntaxException If the <code>filter</code>
      *             string is not a valid OSGi service filter string.
+     *             
+     * @see <a href="https://osgi.org/javadoc/r5/core/org/osgi/framework/Filter.html">Filter class in OSGi</a>
      */
     @CheckForNull <ServiceType> ServiceType[] getServices(@Nonnull Class<ServiceType> serviceType,
             String filter);

Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/package-info.java?rev=1739719&r1=1739718&r2=1739719&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/package-info.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/scripting/package-info.java Mon Apr 18 09:26:39 2016
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("2.2.0")
+@Version("2.3.0")
 package org.apache.sling.api.scripting;
 
 import aQute.bnd.annotation.Version;

Modified: sling/trunk/bundles/scripting/core/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/pom.xml?rev=1739719&r1=1739718&r2=1739719&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/pom.xml (original)
+++ sling/trunk/bundles/scripting/core/pom.xml Mon Apr 18 09:26:39 2016
@@ -262,5 +262,19 @@
             <version>1</version>
             <scope>test</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+            <version>1.6.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/ScriptHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/ScriptHelper.java?rev=1739719&r1=1739718&r2=1739719&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/ScriptHelper.java (original)
+++ sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/ScriptHelper.java Mon Apr 18 09:26:39 2016
@@ -21,6 +21,8 @@ package org.apache.sling.scripting.core;
 import java.io.IOException;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -221,6 +223,7 @@ public class ScriptHelper implements Sli
     /**
      * @see org.apache.sling.api.scripting.SlingScriptHelper#getServices(java.lang.Class, java.lang.String)
      */
+    @SuppressWarnings("unchecked")
     public <ServiceType> ServiceType[] getServices(
             Class<ServiceType> serviceType, String filter)
     throws InvalidServiceFilterSyntaxException {
@@ -229,20 +232,24 @@ public class ScriptHelper implements Sli
                 serviceType.getName(), filter);
             ServiceType[] result = null;
             if (refs != null) {
+                // sort by service ranking (lowest first) (see ServiceReference#compareTo(Object))
+                List<ServiceReference> references = Arrays.asList(refs);
+                Collections.sort(references);
+                // get the highest ranking first
+                Collections.reverse(references);
+                
                 final List<ServiceType> objects = new ArrayList<ServiceType>();
-                for (int i = 0; i < refs.length; i++) {
-                    @SuppressWarnings("unchecked")
-                    final ServiceType service = (ServiceType) this.bundleContext.getService(refs[i]);
+                for (ServiceReference reference : references) {
+                    final ServiceType service = (ServiceType) this.bundleContext.getService(reference);
                     if (service != null) {
                         if ( this.references == null ) {
                             this.references = new ArrayList<ServiceReference>();
                         }
-                        this.references.add(refs[i]);
+                        this.references.add(reference);
                         objects.add(service);
                     }
                 }
                 if (objects.size() > 0) {
-                    @SuppressWarnings("unchecked")
                     ServiceType[] srv = (ServiceType[]) Array.newInstance(serviceType, objects.size());
                     result = objects.toArray(srv);
                 }

Added: sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java?rev=1739719&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java (added)
+++ sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java Mon Apr 18 09:26:39 2016
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.scripting.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.Constants;
+
+public class ScriptHelperTest {
+    
+    @Rule
+    public SlingContext sling = new SlingContext();
+    
+    private ScriptHelper sh;
+    private final int [] RANKINGS = { 42, 62, -12, 76, -123, 0, 7432, -21 };
+    
+    @Before
+    public void setup() {
+        sh = new ScriptHelper(sling.bundleContext(), null);
+        
+        for(int rank : RANKINGS) {
+            final Integer svc = rank;
+            final Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put(Constants.SERVICE_RANKING, rank);
+            sling.bundleContext().registerService(Integer.class.getName(), svc, props);
+        }
+    }
+    
+    private void assertHigherRankingComesFirst(Integer ...values) {
+        Integer previous = null;
+        for(Integer current : values) {
+            if(previous != null && current > previous) {
+                fail("Ranking " + current + " is higher than previous " + previous);
+            }
+            previous = current;
+        }
+    }
+    
+    @Test
+    public void testNullRefs() {
+        assertNull("Expecting null if no services found", sh.getService(ScriptHelperTest.class));
+    }
+    
+    @Test
+    public void testGetServicesOrdering() {
+        final Integer [] svc = sh.getServices(Integer.class, null);
+        assertNotNull(svc);
+        assertEquals(RANKINGS.length, svc.length);
+        assertHigherRankingComesFirst(svc);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/ScriptHelperTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain