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-testing-osgi-mock.git


The following commit(s) were added to refs/heads/master by this push:
     new 51838fe  SLING-11860 OsgiServiceUtil may invoke the wrong method (#26)
51838fe is described below

commit 51838fe3b1dea7f534be8cbc9728e47485538c2b
Author: Eric Norman <[email protected]>
AuthorDate: Wed May 10 11:56:01 2023 -0700

    SLING-11860 OsgiServiceUtil may invoke the wrong method (#26)
---
 .../sling/testing/mock/osgi/OsgiServiceUtil.java   | 290 +++++++++++----------
 .../OsgiServiceUtilActivateDeactivateTest.java     |  14 +
 .../mock/osgi/OsgiServiceUtilBindUnbindTest.java   |  14 +
 .../activatedeactivate/Service9.java               |  53 ++++
 .../activatedeactivate/Service9Super1.java         |  67 +++++
 5 files changed, 306 insertions(+), 132 deletions(-)

diff --git 
a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java 
b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index 80460e8..d76549a 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -36,6 +36,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
@@ -135,6 +136,35 @@ final class OsgiServiceUtil {
                 + " found in class " + targetClass.getName());
     }
 
+    /**
+     * SLING-11860 - find the nearest match.  First find any match in the 
class itself.
+     *     If none is found, then walk up the ancestor super classes to look 
for a match
+     *
+     * @param targetClass the class to start from
+     * @param fn the function to find and invoke the method, returns true if 
handled
+     * @return true if the method was found and invoked, false otherwise
+     */
+    private static boolean findAndInvokeNearestMethod(Class<?> targetClass, 
Predicate<Class<?>> fn) {
+        boolean found = false;
+        do {
+            found = fn.test(targetClass);
+
+            if (!found) {
+                // not found? check super classes
+                Class<?> superClass = targetClass.getSuperclass();
+                if (superClass != null && superClass != Object.class) {
+                    // make the superClass the next candidate
+                    targetClass = superClass;
+                } else {
+                    // stop walking up
+                    targetClass = null;
+                }
+            }
+        } while (!found && targetClass != null);
+
+        return found;
+    }
+
     /**
      * Invokes a lifecycle method (activation, deactivation or modified) with 
variable method arguments.
      * @param target Target object
@@ -149,92 +179,95 @@ final class OsgiServiceUtil {
             String methodName, boolean allowIntegerArgument,
             MockComponentContext componentContext, Map<String,Object> 
properties) {
 
-        // 1. componentContext
-        Method method = getMethod(targetClass, methodName, new Class<?>[] { 
ComponentContext.class });
-        if (method != null) {
-            invokeMethod(target, method, new Object[] { componentContext });
-            return true;
-        }
-
-        // 2. bundleContext
-        method = getMethod(targetClass, methodName, new Class<?>[] { 
BundleContext.class });
-        if (method != null) {
-            invokeMethod(target, method, new Object[] { 
componentContext.getBundleContext() });
-            return true;
-        }
-
-        // 3. map
-        method = getMethod(targetClass, methodName, new Class<?>[] { Map.class 
});
-        if (method != null) {
-            invokeMethod(target, method, new Object[] { 
componentContext.getPropertiesAsMap() });
-            return true;
-        }
+        return findAndInvokeNearestMethod(targetClass, candidateClass -> {
+            // 1. componentContext
+            Method method = getMethod(candidateClass, methodName, new 
Class<?>[] { ComponentContext.class });
+            if (method != null) {
+                invokeMethod(target, method, new Object[] { componentContext 
});
+                return true;
+            }
 
-        // 4. Component property type (annotation lass)
-        method = getMethod(targetClass, methodName, new Class<?>[] { 
Annotation.class });
-        if (method != null) {
-            invokeMethod(target, method, new Object[] { 
Annotations.toObject(method.getParameterTypes()[0],
-                    componentContext.getPropertiesAsMap(),
-                    componentContext.getBundleContext().getBundle(), false) });
-            return true;
-        }
+            // 2. bundleContext
+            method = getMethod(candidateClass, methodName, new Class<?>[] { 
BundleContext.class });
+            if (method != null) {
+                invokeMethod(target, method, new Object[] { 
componentContext.getBundleContext() });
+                return true;
+            }
 
-        // 5. int (deactivation only)
-        if (allowIntegerArgument) {
-            method = getMethod(targetClass, methodName, new Class<?>[] { 
int.class });
+            // 3. map
+            method = getMethod(candidateClass, methodName, new Class<?>[] { 
Map.class });
             if (method != null) {
-                invokeMethod(target, method, new Object[] { 0 });
+                invokeMethod(target, method, new Object[] { 
componentContext.getPropertiesAsMap() });
                 return true;
             }
-        }
 
-        // 6. Integer (deactivation only)
-        if (allowIntegerArgument) {
-            method = getMethod(targetClass, methodName, new Class<?>[] { 
Integer.class });
+            // 4. Component property type (annotation lass)
+            method = getMethod(candidateClass, methodName, new Class<?>[] { 
Annotation.class });
             if (method != null) {
-                invokeMethod(target, method, new Object[] { 0 });
+                invokeMethod(target, method, new Object[] { 
Annotations.toObject(method.getParameterTypes()[0],
+                        componentContext.getPropertiesAsMap(),
+                        componentContext.getBundleContext().getBundle(), 
false) });
                 return true;
             }
-        }
 
-        // 7. mixed arguments
-        Class<?>[] mixedArgsAllowed = allowIntegerArgument ?
-                new Class<?>[] { ComponentContext.class, BundleContext.class, 
Map.class, Annotation.class, int.class, Integer.class }
-                : new Class<?>[] { ComponentContext.class, 
BundleContext.class, Map.class, Annotation.class };
-        method = getMethodWithAnyCombinationArgs(targetClass, methodName, 
mixedArgsAllowed);
-        if (method != null) {
-            Object[] args = new Object[method.getParameterTypes().length];
-            for (int i=0; i<args.length; i++) {
-                if (method.getParameterTypes()[i] == ComponentContext.class) {
-                    args[i] = componentContext;
-                }
-                else if (method.getParameterTypes()[i] == BundleContext.class) 
{
-                    args[i] = componentContext.getBundleContext();
+            // 5. int (deactivation only)
+            if (allowIntegerArgument) {
+                method = getMethod(candidateClass, methodName, new Class<?>[] 
{ int.class });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { 0 });
+                    return true;
                 }
-                else if (method.getParameterTypes()[i] == Map.class) {
-                    args[i] = componentContext.getPropertiesAsMap();
-                }
-                else if (method.getParameterTypes()[i].isAnnotation()) {
-                    args[i] = 
Annotations.toObject(method.getParameterTypes()[i],
-                            componentContext.getPropertiesAsMap(),
-                            componentContext.getBundleContext().getBundle(), 
false);
+            }
+
+            // 6. Integer (deactivation only)
+            if (allowIntegerArgument) {
+                method = getMethod(candidateClass, methodName, new Class<?>[] 
{ Integer.class });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { 0 });
+                    return true;
                 }
-                else if (method.getParameterTypes()[i] == int.class || 
method.getParameterTypes()[i] == Integer.class) {
-                    args[i] = 0;
+            }
+
+            // 7. mixed arguments
+            Class<?>[] mixedArgsAllowed = allowIntegerArgument ?
+                    new Class<?>[] { ComponentContext.class, 
BundleContext.class, Map.class, Annotation.class, int.class, Integer.class }
+                    : new Class<?>[] { ComponentContext.class, 
BundleContext.class, Map.class, Annotation.class };
+            method = getMethodWithAnyCombinationArgs(candidateClass, 
methodName, mixedArgsAllowed);
+            if (method != null) {
+                Object[] args = new Object[method.getParameterTypes().length];
+                for (int i=0; i<args.length; i++) {
+                    if (method.getParameterTypes()[i] == 
ComponentContext.class) {
+                        args[i] = componentContext;
+                    }
+                    else if (method.getParameterTypes()[i] == 
BundleContext.class) {
+                        args[i] = componentContext.getBundleContext();
+                    }
+                    else if (method.getParameterTypes()[i] == Map.class) {
+                        args[i] = componentContext.getPropertiesAsMap();
+                    }
+                    else if (method.getParameterTypes()[i].isAnnotation()) {
+                        args[i] = 
Annotations.toObject(method.getParameterTypes()[i],
+                                componentContext.getPropertiesAsMap(),
+                                
componentContext.getBundleContext().getBundle(), false);
+                    }
+                    else if (method.getParameterTypes()[i] == int.class || 
method.getParameterTypes()[i] == Integer.class) {
+                        args[i] = 0;
+                    }
                 }
+                invokeMethod(target, method, args);
+                return true;
             }
-            invokeMethod(target, method, args);
-            return true;
-        }
 
-        // 8. noargs
-        method = getMethod(targetClass, methodName, new Class<?>[0]);
-        if (method != null) {
-            invokeMethod(target, method, new Object[0]);
-            return true;
-        }
+            // 8. noargs
+            method = getMethod(candidateClass, methodName, new Class<?>[0]);
+            if (method != null) {
+                invokeMethod(target, method, new Object[0]);
+                return true;
+            }
 
-        return false;
+            // no match found
+            return false;
+        });
     }
 
     private static Method getMethod(Class clazz, String methodName, Class<?>[] 
types) {
@@ -254,11 +287,6 @@ final class OsgiServiceUtil {
                 }
             }
         }
-        // not found? check super classes
-        Class<?> superClass = clazz.getSuperclass();
-        if (superClass != null && superClass != Object.class) {
-            return getMethod(superClass, methodName, types);
-        }
         return null;
     }
 
@@ -278,11 +306,7 @@ final class OsgiServiceUtil {
                 }
             }
         }
-        // not found? check super classes
-        Class<?> superClass = clazz.getSuperclass();
-        if (superClass != null && superClass != Object.class) {
-            return getMethodWithAssignableTypes(superClass, methodName, types);
-        }
+
         return null;
     }
 
@@ -323,11 +347,7 @@ final class OsgiServiceUtil {
                 }
             }
         }
-        // not found? check super classes
-        Class<?> superClass = clazz.getSuperclass();
-        if (superClass != null && superClass != Object.class) {
-            return getMethodWithAnyCombinationArgs(superClass, methodName, 
types);
-        }
+
         return null;
     }
 
@@ -666,60 +686,66 @@ final class OsgiServiceUtil {
 
         if (StringUtils.isNotEmpty(methodName) && serviceInfo != null) {
 
-            // 1. ServiceReference
-            Method method = getMethod(targetClass, methodName, new Class<?>[] 
{ ServiceReference.class });
-            if (method != null) {
-                invokeMethod(target, method, new Object[] { 
serviceInfo.getServiceReference() });
-                return;
-            }
+            boolean found = findAndInvokeNearestMethod(targetClass, 
candidateClass -> {
+                // 1. ServiceReference
+                Method method = getMethod(candidateClass, methodName, new 
Class<?>[] { ServiceReference.class });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { 
serviceInfo.getServiceReference() });
+                    return true;
+                }
 
-            // 2. ComponentServiceObjects
-            method = getMethod(targetClass, methodName, new Class<?>[] { 
ComponentServiceObjects.class });
-            if (method != null) {
-                invokeMethod(target, method, new Object[] { serviceInfo });
-                return;
-            }
+                // 2. ComponentServiceObjects
+                method = getMethod(candidateClass, methodName, new Class<?>[] 
{ ComponentServiceObjects.class });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { serviceInfo });
+                    return true;
+                }
 
-            // 3. assignable from service instance
-            Class<?> interfaceType = reference.getInterfaceTypeAsClass();
-            method = getMethodWithAssignableTypes(targetClass, methodName, new 
Class<?>[] { interfaceType });
-            if (method != null) {
-                invokeMethod(target, method, new Object[] { 
serviceInfo.getService() });
-                return;
-            }
+                // 3. assignable from service instance
+                Class<?> interfaceType = reference.getInterfaceTypeAsClass();
+                method = getMethodWithAssignableTypes(candidateClass, 
methodName, new Class<?>[] { interfaceType });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { 
serviceInfo.getService() });
+                    return true;
+                }
 
-            // 4. Map
-            method = getMethod(targetClass, methodName, new Class<?>[] { 
Map.class });
-            if (method != null) {
-                invokeMethod(target, method, new Object[] { 
serviceInfo.getServiceConfig() });
-                return;
-            }
+                // 4. Map
+                method = getMethod(candidateClass, methodName, new Class<?>[] 
{ Map.class });
+                if (method != null) {
+                    invokeMethod(target, method, new Object[] { 
serviceInfo.getServiceConfig() });
+                    return true;
+                }
 
-            // 5. mixed arguments
-            Class<?>[] mixedArgsAllowed = new Class<?>[] { 
ServiceReference.class, ComponentServiceObjects.class, interfaceType, Map.class 
};
-            method = getMethodWithAnyCombinationArgs(targetClass, methodName, 
mixedArgsAllowed);
-            if (method != null) {
-                Object[] args = new Object[method.getParameterTypes().length];
-                for (int i=0; i<args.length; i++) {
-                    if (method.getParameterTypes()[i] == 
ServiceReference.class) {
-                        args[i] = serviceInfo.getServiceReference();
-                    }
-                    else if (method.getParameterTypes()[i] == 
ComponentServiceObjects.class) {
-                        args[i] = serviceInfo;
-                    }
-                    else if 
(method.getParameterTypes()[i].isAssignableFrom(interfaceType)) {
-                        args[i] = serviceInfo.getService();
-                    }
-                    else if (method.getParameterTypes()[i] == Map.class) {
-                        args[i] = serviceInfo.getServiceConfig();
+                // 5. mixed arguments
+                Class<?>[] mixedArgsAllowed = new Class<?>[] { 
ServiceReference.class, ComponentServiceObjects.class, interfaceType, Map.class 
};
+                method = getMethodWithAnyCombinationArgs(candidateClass, 
methodName, mixedArgsAllowed);
+                if (method != null) {
+                    Object[] args = new 
Object[method.getParameterTypes().length];
+                    for (int i=0; i<args.length; i++) {
+                        if (method.getParameterTypes()[i] == 
ServiceReference.class) {
+                            args[i] = serviceInfo.getServiceReference();
+                        }
+                        else if (method.getParameterTypes()[i] == 
ComponentServiceObjects.class) {
+                            args[i] = serviceInfo;
+                        }
+                        else if 
(method.getParameterTypes()[i].isAssignableFrom(interfaceType)) {
+                            args[i] = serviceInfo.getService();
+                        }
+                        else if (method.getParameterTypes()[i] == Map.class) {
+                            args[i] = serviceInfo.getServiceConfig();
+                        }
                     }
+                    invokeMethod(target, method, args);
+                    return true;
                 }
-                invokeMethod(target, method, args);
-                return;
-            }
 
-            throw new RuntimeException((bind ? "Bind" : "Unbind") + " method 
with name " + methodName + " not found "
-                    + "for reference '" + reference.getName() + "' for class " 
+  targetClass.getName());
+                return false;
+            });
+
+            if (!found) {
+                throw new RuntimeException((bind ? "Bind" : "Unbind") + " 
method with name " + methodName + " not found "
+                        + "for reference '" + reference.getName() + "' for 
class " +  targetClass.getName());
+            }
         }
 
         // OSGi declarative services 1.3 supports modifying the field directly
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java
index ca2e762..e1aed2c 100644
--- 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java
@@ -41,6 +41,7 @@ import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeacti
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.Service6Constructor;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.Service7;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.Service7Constructor;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.Service9;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.ServiceReferenceInConstructor;
 import org.junit.Assert;
 import org.junit.Test;
@@ -242,4 +243,17 @@ public class OsgiServiceUtilActivateDeactivateTest {
             assertTrue("Expected exception message matching regex:\n" + regex 
+ "\nbut got:\n" + e.getMessage(), e.getMessage().matches(regex));
         }
     }
+
+    /**
+     * SLING-11860 verify OsgiServiceUtil#activateDeactivate invokes the 
correct activate and deactivate methods
+     */
+    @Test 
+    public void testService9ActivateDeactivate() {
+        Service9 service = MockOsgi.activateInjectServices(Service9.class, 
bundleContext, map);
+        assertEquals(Service9.class, service.getActivateFromClass());
+
+        MockOsgi.deactivate(service, bundleContext, map);
+        assertEquals(Service9.class, service.getDeactivateFromClass());
+    }
+
 }
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java
index dacb3ff..7a4dc7d 100644
--- 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate.Service9;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.bindunbind.Service1;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.bindunbind.Service2;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.bindunbind.Service3;
@@ -166,4 +167,17 @@ public class OsgiServiceUtilBindUnbindTest {
         assertItems(actualFiltered, expected);
     }
 
+
+    /**
+     * SLING-11860 verify OsgiServiceUtil#invokeBindUnbindMethod invokes the 
correct bind and unbind methods
+     */
+    @Test 
+    public void testService9BindUnbind() {
+        Service9 service9 = registerInjectService(new Service9());
+        assertEquals(Service9.class, service9.getBindSvc1FromClass());
+
+        reg1a.unregister();
+        assertEquals(Service9.class, service9.getUnbindSvc1FromClass());
+    }
+
 }
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9.java
new file mode 100644
index 0000000..b7ad364
--- /dev/null
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9.java
@@ -0,0 +1,53 @@
+/*
+ * 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.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate;
+
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+
+/**
+ * SLING-11860 - subclass to provide more specific 
activate/deactivate/bind/unbind methods
+ */
+@Component(service = ServiceInterface1.class)
+public class Service9 extends Service9Super1 {
+
+    @Activate
+    protected void activate(ServiceConfig config) {
+        activateFromClass = Service9.class;
+    }
+
+    @Deactivate
+    protected void deactivate(ServiceConfig config) {
+        deactivateFromClass = Service9.class;
+    }
+
+    @Reference(policy = ReferencePolicy.DYNAMIC, cardinality = 
ReferenceCardinality.OPTIONAL)
+    protected void bindServiceInterface1(ServiceInterface1 svc1, 
ServiceReference<ServiceInterface1> svc1Ref) {
+        bindSvc1FromClass = Service9.class;
+    }
+
+    protected void unbindServiceInterface1(ServiceInterface1 svc1, 
ServiceReference<ServiceInterface1> svc1Ref) {
+        unbindSvc1FromClass = Service9.class;
+    }
+
+}
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9Super1.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9Super1.java
new file mode 100644
index 0000000..662fbcc
--- /dev/null
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/activatedeactivate/Service9Super1.java
@@ -0,0 +1,67 @@
+/*
+ * 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.testing.mock.osgi.testsvc.osgiserviceutil.activatedeactivate;
+
+import java.util.Map;
+
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
+
+/**
+ * SLING-11860 - Superclass that provides generic 
activate/deactivate/bind/unbind methods
+ */
+public abstract class Service9Super1 implements ServiceInterface1 {
+
+    protected Class<?> activateFromClass = null;
+    protected Class<?> deactivateFromClass = null;
+    protected Class<?> bindSvc1FromClass = null;
+    protected Class<?> unbindSvc1FromClass = null;
+
+    protected void activate(Map<String, Object> props) {
+        activateFromClass = Service9Super1.class;
+    }
+
+    protected void deactivate(Map<String, Object> props) {
+        deactivateFromClass = Service9Super1.class;
+    }
+
+    protected void bindServiceInterface1(ServiceInterface1 svc1) {
+        bindSvc1FromClass = Service9Super1.class;
+    }
+
+    protected void unbindServiceInterface1(ServiceInterface1 svc1) {
+        unbindSvc1FromClass = Service9Super1.class;
+    }
+
+    public Class<?> getActivateFromClass() {
+        return activateFromClass;
+    }
+
+    public Class<?> getDeactivateFromClass() {
+        return deactivateFromClass;
+    }
+
+    public Class<?> getBindSvc1FromClass() {
+        return bindSvc1FromClass;
+    }
+
+    public Class<?> getUnbindSvc1FromClass() {
+        return unbindSvc1FromClass;
+    }
+
+}

Reply via email to