Fixed an issue with adapters and extra dependencies that had callbacks. Callbacks were not always invoked correctly for each new adapter instance. This has now been fixed and while at it, I also improved the shell output of several types of dependencies.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@959632 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/Dependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/Dependency.java
index 29cbe94..df85d7f 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/Dependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/Dependency.java
@@ -109,4 +109,9 @@
     
     public boolean isPropagated();
     public Dictionary getProperties();
+    
+    /**
+     * Creates a copy of this dependency, cloning all declared state, but not the runtime state.
+     */
+    public Dependency createCopy();
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
index d0048ef..8c54524 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
@@ -22,6 +22,7 @@
 import java.util.Properties;
 
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.service.Service;
 import org.apache.felix.dm.service.ServiceStateListener;
 import org.osgi.framework.ServiceReference;
@@ -79,10 +80,15 @@
                 .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
                 .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
                 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
-                .add(dependencies)
+//                .add(dependencies)
                 .add(m_manager.createServiceDependency()
                      .setService(m_adapteeInterface, ref)
                      .setRequired(true));
+            
+            for (Object d : dependencies) {
+                service.add(((Dependency) d).createCopy());
+            }
+            
             for (int i = 0; i < m_stateListeners.size(); i ++) {
                 service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
index b298e68..830357b 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
@@ -86,8 +86,12 @@
                 .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
                 .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
                 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
-                .add(dependencies)
                 .add(getAspectDependency());
+            
+            for (Object d : dependencies) {
+                service.add(((Dependency) d).createCopy());
+            }
+
             for (int i = 0; i < m_stateListeners.size(); i ++) {
                 service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java
index 1256c77..4a8b464 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java
@@ -23,6 +23,7 @@
 import java.util.Properties;
 
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.service.Service;
 import org.apache.felix.dm.service.ServiceStateListener;
 import org.osgi.framework.Bundle;
@@ -77,13 +78,18 @@
                 .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
                 .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
                 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
-                .add(dependencies)
                 .add(m_manager.createBundleDependency()
                     .setBundle(bundle)
+                    .setStateMask(m_bundleStateMask)
                     .setPropagate(m_propagate)
                     .setCallbacks(null, "changed", null)
                     .setAutoConfig(true)
                     .setRequired(true));
+
+            for (Object d : dependencies) {
+                service.add(((Dependency) d).createCopy());
+            }
+
             for (int i = 0; i < m_stateListeners.size(); i ++) {
                 service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java
index d9acf70..dc60d78 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java
@@ -23,6 +23,7 @@
 import java.util.Properties;
 
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.resources.Resource;
 import org.apache.felix.dm.service.Service;
 import org.apache.felix.dm.service.ServiceStateListener;
@@ -75,13 +76,17 @@
                 .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
                 .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
                 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
-                .add(dependencies)
                 .add(m_manager.createResourceDependency()
                      .setResource(resource)
                      .setPropagate(m_propagate)
                      .setCallbacks(null, "changed", null)
                      .setAutoConfig(true)
-                     .setRequired(true));         
+                     .setRequired(true));
+            
+            for (Object d : dependencies) {
+                service.add(((Dependency) d).createCopy());
+            }
+
             for (int i = 0; i < m_stateListeners.size(); i ++) {
                 service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
             }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
index 8104091..2946486 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
@@ -24,6 +24,7 @@
 import java.util.List;
 
 import org.apache.felix.dm.dependencies.BundleDependency;
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
 import org.apache.felix.dm.impl.Logger;
 import org.apache.felix.dm.impl.tracker.BundleTracker;
@@ -62,6 +63,27 @@
 		m_context = context;
 		m_autoConfig = true;
 	}
+    
+    public BundleDependencyImpl(BundleDependencyImpl prototype) {
+        super(prototype);
+        m_context = prototype.m_context;
+        m_autoConfig = prototype.m_autoConfig;
+        m_stateMask = prototype.m_stateMask;
+        m_nullObject = prototype.m_nullObject;
+        m_bundleInstance = prototype.m_bundleInstance;
+        m_filter = prototype.m_filter;
+        m_bundleId = prototype.m_bundleId;
+        m_propagate = prototype.m_propagate;
+        m_callbackInstance = prototype.m_callbackInstance;
+        m_callbackAdded = prototype.m_callbackAdded;
+        m_callbackChanged = prototype.m_callbackChanged;
+        m_callbackRemoved = prototype.m_callbackRemoved;
+        m_autoConfigInstance = prototype.m_autoConfigInstance;
+    }
+    
+    public Dependency createCopy() {
+        return new BundleDependencyImpl(this);
+    }
 
     public BundleDependency setInstanceBound(boolean isInstanceBound) {
         setIsInstanceBound(isInstanceBound);
@@ -104,23 +126,26 @@
 
 	public String getName() {
         StringBuilder sb = new StringBuilder();
-        if (m_bundleInstance != null) {
-            sb.append(m_bundleInstance.getSymbolicName());
-            sb.append(' ');
-            sb.append(m_bundleInstance.getHeaders().get("Bundle-Version"));
-            sb.append(' ');
+        if ((m_stateMask & Bundle.ACTIVE) != 0) {
+            sb.append("active ");
         }
-        sb.append(Integer.toString(m_stateMask, 2));
+        if ((m_stateMask & Bundle.INSTALLED) != 0) {
+            sb.append("installed ");
+        }
+        if ((m_stateMask & Bundle.RESOLVED) != 0) {
+            sb.append("resolved ");
+        }
         if (m_filter != null) {
-            sb.append(' ');
             sb.append(m_filter.toString());
         }
+        if (m_bundleId != -1) {
+            sb.append("bundle.id=" + m_bundleId);
+        }
         return sb.toString();
 	}
 
 	public int getState() {
-		// TODO Auto-generated method stub
-		return 0;
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
 	}
 
 	public String getType() {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
index 6a3a8b0..a0791f3 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
@@ -27,6 +27,7 @@
 import java.util.Set;
 
 import org.apache.felix.dm.dependencies.ConfigurationDependency;
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.dependencies.PropertyMetaData;
 import org.apache.felix.dm.impl.InvocationUtil;
 import org.apache.felix.dm.impl.Logger;
@@ -75,6 +76,18 @@
 		m_context = context;
 	}
 	
+	public ConfigurationDependencyImpl(ConfigurationDependencyImpl prototype) {
+	    super(prototype);
+	    m_context = prototype.m_context;
+	    m_pid = prototype.m_pid;
+	    m_propagate = prototype.m_propagate;
+	    m_callback = prototype.m_callback;
+	}
+	
+	public Dependency createCopy() {
+	    return new ConfigurationDependencyImpl(this);
+	}
+	
 	public synchronized boolean isAvailable() {
 		return m_settings != null;
 	}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
index 4208145..401f970 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
@@ -11,6 +11,12 @@
     public DependencyBase(Logger logger) {
         m_logger = logger;
     }
+    
+    public DependencyBase(DependencyBase prototype) {
+        m_logger = prototype.m_logger;
+        m_isRequired = prototype.isRequired();
+        m_isInstanceBound = prototype.m_isInstanceBound;
+    }
 
     public synchronized boolean isRequired() {
         return m_isRequired;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
index 95dda61..ddefa1e 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
@@ -23,15 +23,17 @@
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.dependencies.ResourceDependency;
 import org.apache.felix.dm.impl.Logger;
+import org.apache.felix.dm.management.ServiceComponentDependency;
 import org.apache.felix.dm.resources.Resource;
 import org.apache.felix.dm.resources.ResourceHandler;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
-public class ResourceDependencyImpl extends DependencyBase implements ResourceDependency, ResourceHandler, DependencyActivation {
+public class ResourceDependencyImpl extends DependencyBase implements ResourceDependency, ResourceHandler, DependencyActivation, ServiceComponentDependency {
 	private volatile BundleContext m_context;
 	private volatile ServiceRegistration m_registration;
 //	private long m_resourceCounter;
@@ -43,7 +45,6 @@
     private boolean m_autoConfig;
     private String m_autoConfigInstance;
     protected List m_services = new ArrayList();
-	private boolean m_isRequired;
 	private String m_resourceFilter;
 	private Resource m_trackedResource;
     private boolean m_isStarted;
@@ -57,6 +58,24 @@
     	m_autoConfig = true;
     }
     
+    public ResourceDependencyImpl(ResourceDependencyImpl prototype) {
+        super(prototype);
+        m_context = prototype.m_context;
+        m_autoConfig = prototype.m_autoConfig;
+        m_callbackInstance = prototype.m_callbackInstance;
+        m_callbackAdded = prototype.m_callbackAdded;
+        m_callbackChanged = prototype.m_callbackChanged;
+        m_callbackRemoved = prototype.m_callbackRemoved;
+        m_autoConfigInstance = prototype.m_autoConfigInstance;
+        m_resourceFilter = prototype.m_resourceFilter;
+        m_trackedResource = prototype.m_trackedResource;
+        m_propagate = prototype.m_propagate;
+    }
+    
+    public Dependency createCopy() {
+        return new ResourceDependencyImpl(this);
+    }
+    
 	public synchronized boolean isAvailable() {
 		return m_resources.size() > 0;
 	}
@@ -433,4 +452,23 @@
         setIsInstanceBound(isInstanceBound);
         return this;
     }
+
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        if (m_resourceFilter != null) {
+            sb.append(m_resourceFilter);
+        }
+        if (m_trackedResource != null) {
+            sb.append(m_trackedResource.getID());
+        }
+        return sb.toString();
+    }
+
+    public int getState() {
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+    }
+
+    public String getType() {
+        return "resource";
+    }
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
index 7abcffd..163e3e3 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
@@ -29,6 +29,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.dependencies.ServiceDependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
 import org.apache.felix.dm.impl.Logger;
@@ -179,6 +180,28 @@
         m_autoConfig = true;
     }
     
+    /** Copying constructor that clones an existing instance. */
+    public ServiceDependencyImpl(ServiceDependencyImpl prototype) {
+        super(prototype);
+        m_context = prototype.m_context;
+        m_autoConfig = prototype.m_autoConfig;
+        m_trackedServiceName = prototype.m_trackedServiceName;
+        m_nullObject = prototype.m_nullObject;
+        m_trackedServiceFilter = prototype.m_trackedServiceFilter;
+        m_trackedServiceFilterUnmodified = prototype.m_trackedServiceFilterUnmodified;
+        m_trackedServiceReference = prototype.m_trackedServiceReference;
+        m_callbackInstance = prototype.m_callbackInstance;
+        m_callbackAdded = prototype.m_callbackAdded;
+        m_callbackChanged = prototype.m_callbackChanged;
+        m_callbackRemoved = prototype.m_callbackRemoved;
+        m_autoConfigInstance = prototype.m_autoConfigInstance;
+        m_defaultImplementation = prototype.m_defaultImplementation;
+    }
+    
+    public Dependency createCopy() {
+        return new ServiceDependencyImpl(this);
+    }
+    
     public synchronized boolean isAutoConfig() {
         return m_autoConfig;
     }
@@ -244,7 +267,7 @@
         }
         return service;
     }
-    
+
     // TODO lots of duplication in lookupService()
     public ServiceReference lookupServiceReference() {
         ServiceReference service = null;
@@ -348,6 +371,7 @@
                 m_isStarted = true;
                 needsStarting = true;
             }
+            else { System.out.println("ALREADY STARTED..."); } // TODO REMOVE, FOR DEBUGGING
         }
         if (needsStarting) {
             m_tracker.open();
@@ -736,10 +760,15 @@
 
     public String getName() {
         StringBuilder sb = new StringBuilder();
-        sb.append(m_trackedServiceName.getName());
-        if (m_trackedServiceFilterUnmodified != null) {
-            sb.append(' ');
-            sb.append(m_trackedServiceFilterUnmodified);
+        if (m_trackedServiceName != null) {
+            sb.append(m_trackedServiceName.getName());
+            if (m_trackedServiceFilterUnmodified != null) {
+                sb.append(' ');
+                sb.append(m_trackedServiceFilterUnmodified);
+            }
+        }
+        if (m_trackedServiceReference != null) {
+            sb.append("service.id=" + m_trackedServiceReference.getProperty(Constants.SERVICE_ID));
         }
         return sb.toString();
     }