FELIX-303 Applied the patch, fixed indenting, converted the logging message from INFO to DEBUG because callback can be absent by design, so normally you probably don't want to see these messages at all.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@814298 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
index 79bd738..18c736e 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
@@ -352,14 +352,9 @@
     }
     
     public void invokeAdded(ServiceReference reference, Object serviceInstance) {
-        Object callbackInstance = getCallbackInstance();
-        if ((callbackInstance != null) && (m_callbackAdded != null)) {
-            try {
-                invokeCallbackMethod(callbackInstance, m_callbackAdded, reference, serviceInstance);
-            }
-            catch (NoSuchMethodException e) {
-                m_logger.log(Logger.LOG_ERROR, "Could not invoke method " + m_callbackAdded + " on " + callbackInstance + ".", e);
-            }
+        Object[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackAdded != null)) {
+                invokeCallbackMethod(callbackInstances, m_callbackAdded, reference, serviceInstance);
         }
     }
 
@@ -374,17 +369,12 @@
     }
 
     public void invokeChanged(ServiceReference reference, Object serviceInstance) {
-        Object callbackInstance = getCallbackInstance();
-        if ((callbackInstance != null) && (m_callbackChanged != null)) {
-            try {
+        Object[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackChanged != null)) {
                 if (m_reference == null) {
                     Thread.dumpStack();
                 }
-                invokeCallbackMethod(callbackInstance, m_callbackChanged, reference, serviceInstance);
-            }
-            catch (NoSuchMethodException e) {
-                m_logger.log(Logger.LOG_ERROR, "Could not invoke method " + m_callbackChanged + " on " + callbackInstance + ".", e);
-            }
+                invokeCallbackMethod(callbackInstances, m_callbackChanged, reference, serviceInstance);
         }
     }
 
@@ -407,17 +397,12 @@
     }
     
     public void invokeRemoved(ServiceReference reference, Object serviceInstance) {
-        Object callbackInstance = getCallbackInstance();
-        if ((callbackInstance != null) && (m_callbackRemoved != null)) {
-            try {
+        Object[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackRemoved != null)) {
                 if (m_reference == null) {
                     Thread.dumpStack();
                 }
-                invokeCallbackMethod(callbackInstance, m_callbackRemoved, reference, serviceInstance);
-            }
-            catch (NoSuchMethodException e) {
-                m_logger.log(Logger.LOG_ERROR, "Could not invoke method " + m_callbackRemoved + " on " + callbackInstance + ".", e);
-            }
+                invokeCallbackMethod(callbackInstances, m_callbackRemoved, reference, serviceInstance);
         }
     }
     
@@ -437,14 +422,28 @@
         return false;
     }
     
-    private synchronized Object getCallbackInstance() {
-        Object callbackInstance = m_callbackInstance;
-        if (callbackInstance == null) {
-            callbackInstance = m_service.getService();
+    private synchronized Object[] getCallbackInstances() {
+        Object[] callbackInstances = ((ServiceImpl) m_service).getCompositionInstances();
+        if (m_callbackInstance == null) {
+            return callbackInstances;
         }
-        return callbackInstance;
+        Object[] res = new Object[callbackInstances.length + 1];
+        res[0] = m_callbackInstance; //this could also be extended to an array...?
+        System.arraycopy(callbackInstances, 0, res, 1, callbackInstances.length);
+        return res;
     }
-    
+
+    private void invokeCallbackMethod(Object[] instances, String methodName, ServiceReference reference, Object service) {
+        for (int i = 0; i < instances.length; i++) {
+            try {
+                invokeCallbackMethod(instances[i], methodName, reference, service);
+            }
+            catch (NoSuchMethodException e) {
+                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
+            }
+        }
+    }
+
     private void invokeCallbackMethod(Object instance, String methodName, ServiceReference reference, Object service) throws NoSuchMethodException {
         Class currentClazz = instance.getClass();
         boolean done = false;
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
index 3b8204d..f5f4c90 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
@@ -733,29 +733,7 @@
      * @param instanceName the name of the instance to fill in, or <code>null</code> if not used
      */
     private void configureImplementation(Class clazz, Object instance, String instanceName) {
-    	Object[] instances = null;
-    	if (m_compositionManagerGetMethod != null) {
-			if (m_compositionManager != null) {
-    			m_compositionManagerInstance = m_compositionManager;
-    		}
-    		else {
-    			m_compositionManagerInstance = m_serviceInstance;
-    		}
-    		if (m_compositionManagerInstance != null) {
-	    		try {
-					Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
-            		m.setAccessible(true);
-					instances = (Object[]) m.invoke(m_compositionManagerInstance, null);
-				}
-	    		catch (Exception e) {
-                    m_logger.log(Logger.LOG_ERROR, "Could not obtain instances from the composition manager.", e);
-                    return;
-				}
-    		}
-    	}
-    	else {
-    		instances = new Object[] { m_serviceInstance };
-    	}
+    	Object[] instances = getCompositionInstances();
     	if (instances != null) {
 	    	for (int i = 0; i < instances.length; i++) {
 	    		Object serviceInstance = instances[i];
@@ -783,6 +761,33 @@
     	}
     }
     
+    public Object[] getCompositionInstances() {
+      Object[] instances = null;
+      if (m_compositionManagerGetMethod != null) {
+	if (m_compositionManager != null) {
+	  m_compositionManagerInstance = m_compositionManager;
+	}
+	else {
+	  m_compositionManagerInstance = m_serviceInstance;
+	}
+	if (m_compositionManagerInstance != null) {
+	  try {
+	    Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
+	    m.setAccessible(true);
+	    instances = (Object[]) m.invoke(m_compositionManagerInstance, null);
+	  }
+	  catch (Exception e) {
+	    m_logger.log(Logger.LOG_ERROR, "Could not obtain instances from the composition manager.", e);
+	    instances = new Object[] { m_serviceInstance };
+	  }
+	}
+      }
+      else {
+	instances = new Object[] { m_serviceInstance };
+      }
+      return instances;
+    }
+
     private void configureImplementation(Class clazz, Object instance) {
         configureImplementation(clazz, instance, null);
     }