factoring out some common methods

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@884649 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/AbstractDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/AbstractDependency.java
new file mode 100644
index 0000000..7492abc
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/AbstractDependency.java
@@ -0,0 +1,79 @@
+package org.apache.felix.dependencymanager.dependencies;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.felix.dependencymanager.Dependency;
+import org.apache.felix.dependencymanager.impl.Logger;
+
+public abstract class AbstractDependency implements Dependency {
+    private boolean m_isRequired;
+    protected final Logger m_logger;
+
+    public AbstractDependency(Logger logger) {
+        m_logger = logger;
+    }
+
+    public synchronized boolean isRequired() {
+        return m_isRequired;
+    }
+    
+    protected synchronized void setIsRequired(boolean isRequired) {
+        m_isRequired = isRequired;
+    }
+    
+    protected void invokeCallbackMethod(Object[] instances, String methodName, Class[][] signatures, Object[][] parameters) {
+        for (int i = 0; i < instances.length; i++) {
+            try {
+                invokeCallbackMethod(instances[i], methodName, signatures, parameters);
+            }
+            catch (NoSuchMethodException e) {
+                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
+            }
+        }
+    }
+
+    protected void invokeCallbackMethod(Object instance, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException {
+        Class currentClazz = instance.getClass();
+        boolean done = false;
+        while (!done && currentClazz != null) {
+            done = invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
+            if (!done) {
+                currentClazz = currentClazz.getSuperclass();
+            }
+        }
+        if (!done && currentClazz == null) {
+            throw new NoSuchMethodException(methodName);
+        }
+    }
+
+    protected boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
+        Method m = null;
+        for (int i = 0; i < signatures.length; i++) {
+            Class[] signature = signatures[i];
+            try {
+                m = clazz.getDeclaredMethod(name, signature);
+                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
+                    m.setAccessible(true);
+                    try {
+                        m.invoke(object, parameters[i]);
+                    }
+                    catch (InvocationTargetException e) {
+                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
+                    }
+                    // we did find and invoke the method, so we return true
+                    return true;
+                }
+            }
+            catch (NoSuchMethodException e) {
+                // ignore this and keep looking
+            }
+            catch (Exception e) {
+                // could not even try to invoke the method
+                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
+            }
+        }
+        return false;
+    }
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/BundleDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/BundleDependency.java
index 24edcb1..88cf970 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/BundleDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/BundleDependency.java
@@ -18,9 +18,6 @@
  */
 package org.apache.felix.dependencymanager.dependencies;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.Dictionary;
 
 import org.apache.felix.dependencymanager.Dependency;
@@ -36,15 +33,13 @@
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 
-public class BundleDependency implements Dependency, BundleTrackerCustomizer, ServiceComponentDependency {
+public class BundleDependency extends AbstractDependency implements Dependency, BundleTrackerCustomizer, ServiceComponentDependency {
 	private final BundleContext m_context;
-	private final Logger m_logger;
 	private boolean m_isStarted;
 	private BundleTracker m_tracker;
 	private int m_stateMask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
-	private boolean m_isAvailable;
-	private boolean m_isRequired;
 	private DependencyService m_service;
+	private boolean m_isAvailable;
 	
     private Object m_callbackInstance;
     private String m_callbackAdded;
@@ -54,27 +49,23 @@
 	private Bundle m_bundleInstance;
 	private Filter m_filter;
 	private long m_bundleId = -1;
-
-
-	public BundleDependency(BundleContext context, Logger logger) {
+    
+    public BundleDependency(BundleContext context, Logger logger) {
+        super(logger);
 		m_context = context;
-		m_logger = logger;
 		m_autoConfig = true;
 	}
 
-	public boolean isAvailable() {
-		return m_isAvailable;
-	}
-
-	public boolean isRequired() {
-		return m_isRequired;
-	}
-	
 	public boolean isInstanceBound() {
 		return false; // TODO for now we are never bound to the service implementation instance
 	}
 
-	public void start(DependencyService service) {
+	public synchronized boolean isAvailable() {
+        return m_isAvailable;
+    }
+
+
+    public void start(DependencyService service) {
 		synchronized (this) {
 			if (m_isStarted) {
 				throw new IllegalStateException("Dependency was already started." + getName());
@@ -169,7 +160,7 @@
 	}
 	
     private synchronized boolean makeAvailable() {
-        if (!m_isAvailable) {
+        if (!isAvailable()) {
             m_isAvailable = true;
             return true;
         }
@@ -177,8 +168,9 @@
     }
     
     private synchronized boolean makeUnavailable() {
-        if ((m_isAvailable) && (m_tracker.getTrackingCount() == 0)) {
+        if ((isAvailable()) && (m_tracker.getTrackingCount() == 0)) {
             m_isAvailable = false;
+
             return true;
         }
         return false;
@@ -188,17 +180,23 @@
         invokeAdded(m_bundleInstance);
     }
     
-    public void invokeAdded(Bundle serviceInstance) {
+    public void invokeAdded(Bundle service) {
         Object[] callbackInstances = getCallbackInstances();
         if ((callbackInstances != null) && (m_callbackAdded != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackAdded, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackAdded, 
+                new Class[][] {{Bundle.class}, {Object.class}, {}},
+                new Object[][] {{service}, {service}, {}}
+            );
         }
     }
 
-    public void invokeChanged(Bundle serviceInstance) {
+    public void invokeChanged(Bundle service) {
         Object[] callbackInstances = getCallbackInstances();
         if ((callbackInstances != null) && (m_callbackChanged != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackChanged, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackChanged, 
+                new Class[][] {{Bundle.class}, {Object.class}, {}},
+                new Object[][] {{service}, {service}, {}}
+            );
         }
     }
     
@@ -206,70 +204,16 @@
         invokeRemoved(m_bundleInstance);
     }
     
-    public void invokeRemoved(Bundle serviceInstance) {
+    public void invokeRemoved(Bundle service) {
         Object[] callbackInstances = getCallbackInstances();
         if ((callbackInstances != null) && (m_callbackRemoved != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackRemoved, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackRemoved,
+              new Class[][] {{Bundle.class}, {Object.class}, {}},
+              new Object[][] {{service}, {service}, {}}
+            );
         }
     }
     
-    private void invokeCallbackMethod(Object[] instances, String methodName, Object service) {
-        for (int i = 0; i < instances.length; i++) {
-            try {
-                invokeCallbackMethod(instances[i], methodName, 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, Object service) throws NoSuchMethodException {
-        Class currentClazz = instance.getClass();
-        boolean done = false;
-        while (!done && currentClazz != null) {
-            done = invokeMethod(instance, currentClazz, methodName,
-                new Class[][] {{Bundle.class}, {Object.class}, {}},
-                new Object[][] {{service}, {service}, {}},
-                false);
-            if (!done) {
-                currentClazz = currentClazz.getSuperclass();
-            }
-        }
-        if (!done && currentClazz == null) {
-            throw new NoSuchMethodException(methodName);
-        }
-    }
-    
-    private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
-        Method m = null;
-        for (int i = 0; i < signatures.length; i++) {
-            Class[] signature = signatures[i];
-            try {
-                m = clazz.getDeclaredMethod(name, signature);
-                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
-                    m.setAccessible(true);
-                    try {
-                        m.invoke(object, parameters[i]);
-                    }
-                    catch (InvocationTargetException e) {
-                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
-                    }
-                    // we did find and invoke the method, so we return true
-                    return true;
-                }
-            }
-            catch (NoSuchMethodException e) {
-                // ignore this and keep looking
-            }
-            catch (Exception e) {
-                // could not even try to invoke the method
-                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
-            }
-        }
-        return false;
-    }
-    
     private synchronized Object[] getCallbackInstances() {
         Object[] callbackInstances = ((ServiceImpl) m_service).getCompositionInstances();
         if (m_callbackInstance == null) {
@@ -362,7 +306,7 @@
     
     public synchronized BundleDependency setRequired(boolean required) {
         ensureNotActive();
-        m_isRequired = required;
+        setIsRequired(required);
         return this;
     }
 
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ConfigurationDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ConfigurationDependency.java
index 8806373..7cefc08 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ConfigurationDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ConfigurationDependency.java
@@ -118,7 +118,7 @@
 	public void updated(Dictionary settings) throws ConfigurationException {
 		// if non-null settings come in, we have to instantiate the service and
 		// apply these settings
-		m_service.initService(); /// <<< CHANGES THE STATE, WHEN IT SHOULD NOT (YET) DO THAT (we should not use m_serviceInstance to determine the state but use a flag var instead)
+		m_service.initService();
 		Object service = m_service.getService();
 				
 		Dictionary oldSettings = null; 
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ServiceDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ServiceDependency.java
index 18671ca..618882d 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ServiceDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dependencymanager/dependencies/ServiceDependency.java
@@ -18,9 +18,6 @@
  */
 package org.apache.felix.dependencymanager.dependencies;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -48,12 +45,10 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceDependency implements Dependency, ServiceTrackerCustomizer, ServiceComponentDependency {
-    private boolean m_isRequired;
+public class ServiceDependency extends AbstractDependency implements Dependency, ServiceTrackerCustomizer, ServiceComponentDependency {
     protected List m_services = new ArrayList();
     protected volatile ServiceTracker m_tracker;
     protected BundleContext m_context;
-    private boolean m_isAvailable;
     protected volatile Class m_trackedServiceName;
     private Object m_nullObject;
     private volatile String m_trackedServiceFilter;
@@ -67,12 +62,12 @@
     private boolean m_autoConfig;
     protected ServiceReference m_reference;
     protected Object m_serviceInstance;
-    private final Logger m_logger;
     private String m_autoConfigInstance;
     private boolean m_autoConfigInvoked;
     private Object m_defaultImplementation;
     private Object m_defaultImplementationInstance;
     private boolean m_isInstanceBound;
+    private boolean m_isAvailable;
     
     private static final Comparator COMPARATOR = new Comparator() {
         public int getRank(ServiceReference ref) {
@@ -179,23 +174,19 @@
      * @param logger the logger
      */
     public ServiceDependency(BundleContext context, Logger logger) {
+        super(logger);
         m_context = context;
-        m_logger = logger;
         m_autoConfig = true;
     }
-
-    public synchronized boolean isRequired() {
-        return m_isRequired;
-    }
-
-    public synchronized boolean isAvailable() {
-        return m_isAvailable;
-    }
     
     public synchronized boolean isAutoConfig() {
         return m_autoConfig;
     }
     
+    public synchronized boolean isAvailable() {
+        return m_isAvailable;
+    }
+
     public boolean isInstanceBound() {
         return m_isInstanceBound;
     }
@@ -414,10 +405,13 @@
         }
     }
 
-    public void invokeAdded(DependencyService dependencyService, ServiceReference reference, Object serviceInstance) {
+    public void invokeAdded(DependencyService dependencyService, ServiceReference reference, Object service) {
         Object[] callbackInstances = getCallbackInstances(dependencyService);
         if ((callbackInstances != null) && (m_callbackAdded != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackAdded, reference, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackAdded, 
+                new Class[][] {{ServiceReference.class, m_trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {m_trackedServiceName}, {Object.class}, {}, {Map.class, m_trackedServiceName}},
+                new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}}    
+            );
         }
     }
 
@@ -435,10 +429,13 @@
         }
     }
 
-    public void invokeChanged(DependencyService dependencyService, ServiceReference reference, Object serviceInstance) {
+    public void invokeChanged(DependencyService dependencyService, ServiceReference reference, Object service) {
         Object[] callbackInstances = getCallbackInstances(dependencyService);
         if ((callbackInstances != null) && (m_callbackChanged != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackChanged, reference, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackChanged, 
+                new Class[][] {{ServiceReference.class, m_trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {m_trackedServiceName}, {Object.class}, {}, {Map.class, m_trackedServiceName}},
+                new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}}    
+            );
         }
     }
 
@@ -464,15 +461,18 @@
 
     }
 
-    public void invokeRemoved(DependencyService dependencyService, ServiceReference reference, Object serviceInstance) {
+    public void invokeRemoved(DependencyService dependencyService, ServiceReference reference, Object service) {
         Object[] callbackInstances = getCallbackInstances(dependencyService);
         if ((callbackInstances != null) && (m_callbackRemoved != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackRemoved, reference, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackRemoved, 
+                new Class[][] {{ServiceReference.class, m_trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {m_trackedServiceName}, {Object.class}, {}, {Map.class, m_trackedServiceName}},
+                new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}}    
+            );
         }
     }
 
     protected synchronized boolean makeAvailable() {
-        if (!m_isAvailable) {
+        if (!isAvailable()) {
             m_isAvailable = true;
             return true;
         }
@@ -480,7 +480,7 @@
     }
     
     private synchronized boolean makeUnavailable() {
-        if ((m_isAvailable) && (m_tracker.getServiceReference() == null)) {
+        if ((isAvailable()) && (m_tracker.getServiceReference() == null)) {
             m_isAvailable = false;
             return true;
         }
@@ -495,67 +495,6 @@
             return new Object[] { m_callbackInstance };
         }
     }
-
-    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;
-        while (!done && currentClazz != null) {
-            Class trackedServiceName;
-            synchronized (this) {
-                trackedServiceName = m_trackedServiceName;
-            }
-            done = invokeMethod(instance, currentClazz, methodName,
-                new Class[][] {{ServiceReference.class, trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {trackedServiceName}, {Object.class}, {}, {Map.class, trackedServiceName}},
-                new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}},
-                false);
-            if (!done) {
-                currentClazz = currentClazz.getSuperclass();
-            }
-        }
-        if (!done && currentClazz == null) {
-            throw new NoSuchMethodException(methodName);
-        }
-    }
-
-    private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
-        Method m = null;
-        for (int i = 0; i < signatures.length; i++) {
-            Class[] signature = signatures[i];
-            try {
-                m = clazz.getDeclaredMethod(name, signature);
-                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
-                    m.setAccessible(true);
-                    try {
-                        m.invoke(object, parameters[i]);
-                    }
-                    catch (InvocationTargetException e) {
-                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
-                    }
-                    // we did find and invoke the method, so we return true
-                    return true;
-                }
-            }
-            catch (NoSuchMethodException e) {
-                // ignore this and keep looking
-            }
-            catch (Exception e) {
-                // could not even try to invoke the method
-                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
-            }
-        }
-        return false;
-    }
     
     // ----- CREATION
 
@@ -651,7 +590,7 @@
      */
     public synchronized ServiceDependency setRequired(boolean required) {
         ensureNotActive();
-        m_isRequired = required;
+        setIsRequired(required);
         return this;
     }