You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2010/07/12 14:43:43 UTC

svn commit: r963265 - in /felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm: ./ impl/ impl/dependencies/

Author: marrs
Date: Mon Jul 12 12:43:42 2010
New Revision: 963265

URL: http://svn.apache.org/viewvc?rev=963265&view=rev
Log:
Added a feature to use an external instance/method to provide properties to propagate. Implemented it for all dependencies plus the resource adapter. Other adapters still under consideration.

Modified:
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java Mon Jul 12 12:43:42 2010
@@ -161,6 +161,10 @@ public abstract class DependencyActivato
         return m_manager.createResourceAdapterService(resourceFilter, propagate, callbackInstance, callbackChanged);
     }
     
+    public Service createResourceAdapter(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
+        return m_manager.createResourceAdapterService(resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackChanged);
+    }
+    
     public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
         return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, propagate);
     }

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java Mon Jul 12 12:43:42 2010
@@ -238,6 +238,10 @@ public class DependencyManager {
         return new ResourceAdapterServiceImpl(this, resourceFilter, propagate, callbackInstance, callbackChanged);
     }
     
+    public Service createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
+        return new ResourceAdapterServiceImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackChanged);
+    }
+    
     /**
      * Creates a new bundle adapter. The adapter will be applied to any bundle that
      * matches the specified bundle state mask and filter condition. For each matching

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/ResourceDependency.java Mon Jul 12 12:43:42 2010
@@ -102,5 +102,7 @@ public interface ResourceDependency exte
      
      public ResourceDependency setPropagate(boolean propagate);
      
+     public ResourceDependency setPropagate(Object instance, String method);
+     
      public ResourceDependency setInstanceBound(boolean isInstanceBound);
 }

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java Mon Jul 12 12:43:42 2010
@@ -6,12 +6,11 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 
 public class InvocationUtil {
-    public static void invokeCallbackMethod(Object instance, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+    public static Object invokeCallbackMethod(Object instance, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
         Class currentClazz = instance.getClass();
         while (currentClazz != null) {
             try {
-                invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
-                return;
+                return invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
             }
             catch (NoSuchMethodException nsme) {
                 // ignore

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ResourceAdapterServiceImpl.java Mon Jul 12 12:43:42 2010
@@ -25,6 +25,7 @@ import java.util.Properties;
 
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ResourceDependency;
 import org.apache.felix.dm.Service;
 import org.apache.felix.dm.ServiceStateListener;
 
@@ -51,13 +52,36 @@ public class ResourceAdapterServiceImpl 
                  .setCallbacks("added", "removed"));
     }
 
+    public ResourceAdapterServiceImpl(DependencyManager dm, String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
+        super(dm.createService()); // This service will be filtered by our super class, allowing us to take control.
+        m_callbackInstance = callbackInstance;
+        m_callbackChanged = callbackChanged;
+        m_service.setImplementation(new ResourceAdapterImpl(resourceFilter, propagateCallbackInstance, propagateCallbackMethod))
+            .add(dm.createResourceDependency()
+                 .setFilter(resourceFilter)
+                 .setAutoConfig(false)
+                 .setCallbacks("added", "removed"));
+    }
+
     public class ResourceAdapterImpl extends AbstractDecorator {
         private final String m_resourceFilter;
         private final boolean m_propagate;
+        private final Object m_propagateCallbackInstance;
+        private final String m_propagateCallbackMethod;
 
         public ResourceAdapterImpl(String resourceFilter, boolean propagate) {
+            this(resourceFilter, propagate, null, null);
+        }
+
+        public ResourceAdapterImpl(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod) {
+            this(resourceFilter, true, propagateCallbackInstance, propagateCallbackMethod);
+        }
+        
+        private ResourceAdapterImpl(String resourceFilter, boolean propagate, Object propagateCallbackInstance, String propagateCallbackMethod) {
             m_resourceFilter = resourceFilter;
             m_propagate = propagate;
+            m_propagateCallbackInstance = propagateCallbackInstance;
+            m_propagateCallbackMethod = propagateCallbackMethod;
         }
 
         public Service createService(Object[] properties) {
@@ -74,18 +98,21 @@ public class ResourceAdapterServiceImpl 
             // the first dependency is always the dependency on the resource, which
             // will be replaced with a more specific dependency below
             dependencies.remove(0);
+            ResourceDependency resourceDependency = m_manager.createResourceDependency()
+                 .setResource(resource)
+                 .setPropagate(m_propagate)
+                 .setCallbacks(m_callbackInstance, null, m_callbackChanged, null)
+                 .setAutoConfig(true)
+                 .setRequired(true);
+            resourceDependency.setPropagate(m_propagate);
+            resourceDependency.setPropagate(m_propagateCallbackInstance, m_propagateCallbackMethod);
             Service service = m_manager.createService()
                 .setInterface(m_serviceInterfaces, props)
                 .setImplementation(m_serviceImpl)
                 .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(m_manager.createResourceDependency()
-                     .setResource(resource)
-                     .setPropagate(m_propagate)
-                     .setCallbacks(m_callbackInstance, null, m_callbackChanged, null)
-                     .setAutoConfig(true)
-                     .setRequired(true));
+                .add(resourceDependency);
             
             for (int i = 0; i < dependencies.size(); i++) {
                 service.add(((Dependency) dependencies.get(i)).createCopy());

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java Mon Jul 12 12:43:42 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.dm.impl.dependencies;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -27,6 +28,7 @@ import org.apache.felix.dm.BundleDepende
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
+import org.apache.felix.dm.impl.InvocationUtil;
 import org.apache.felix.dm.impl.Logger;
 import org.apache.felix.dm.impl.tracker.BundleTracker;
 import org.apache.felix.dm.impl.tracker.BundleTrackerCustomizer;
@@ -35,6 +37,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.log.LogService;
 
 public class BundleDependencyImpl extends DependencyBase implements BundleDependency, BundleTrackerCustomizer, ServiceComponentDependency {
 	private final BundleContext m_context;
@@ -43,7 +46,6 @@ public class BundleDependencyImpl extend
 	private int m_stateMask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
 	private List m_services = new ArrayList();
 	private boolean m_isAvailable;
-	
     private Object m_callbackInstance;
     private String m_callbackAdded;
     private String m_callbackChanged;
@@ -52,12 +54,13 @@ public class BundleDependencyImpl extend
 	private Bundle m_bundleInstance;
 	private Filter m_filter;
 	private long m_bundleId = -1;
-	private boolean m_propagate;
 	private String m_autoConfigInstance;
     private Object m_nullObject;
     private boolean m_autoConfigInvoked;
+    private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
 
-    
     public BundleDependencyImpl(BundleContext context, Logger logger) {
         super(logger);
 		m_context = context;
@@ -356,12 +359,6 @@ public class BundleDependencyImpl extend
         return this;
     }
     
-    public BundleDependency setPropagate(boolean propagate) {
-        ensureNotActive();
-        m_propagate = propagate;
-        return this;
-    }
-    
 	public BundleDependency setBundle(Bundle bundle) {
 		m_bundleId = bundle.getBundleId();
 		return this;
@@ -461,10 +458,42 @@ public class BundleDependencyImpl extend
         invokeRemoved(service, m_bundleInstance);
         m_bundleInstance = null;
     }
-
+    
+    public BundleDependency setPropagate(boolean propagate) {
+        ensureNotActive();
+        m_propagate = propagate;
+        return this;
+    }
+    
+    public BundleDependency setPropagate(Object instance, String method) {
+        setPropagate(instance != null && method != null);
+        m_propagateCallbackInstance = instance;
+        m_propagateCallbackMethod = method;
+        return this;
+    }
+    
     public Dictionary getProperties() {
-        // TODO Auto-generated method stub
-        return null;
+        Bundle bundle = lookupBundle();
+        if (bundle != null) {
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ Bundle.class }}, new Object[][] {{ bundle }});
+                }
+                catch (InvocationTargetException e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while invoking callback method", e.getCause());
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                return bundle.getHeaders();
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find bundle");
+        }
     }
 
     public boolean isPropagated() {

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java Mon Jul 12 12:43:42 2010
@@ -38,6 +38,7 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
+import org.osgi.service.log.LogService;
 
 /**
  * Configuration dependency that can track the availability of a (valid) configuration.
@@ -65,11 +66,13 @@ public class ConfigurationDependencyImpl
 	private ServiceRegistration m_registration;
     protected List m_services = new ArrayList();
 	private Dictionary m_settings;
-	private boolean m_propagate;
     private String m_callback;
     private boolean m_isStarted;
 	private final Set m_updateInvokedCache = new HashSet();
     private MetaTypeProviderImpl m_metaType;
+    private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
 	
 	public ConfigurationDependencyImpl(BundleContext context, Logger logger) {
 	    super(logger);
@@ -324,8 +327,35 @@ public class ConfigurationDependencyImpl
         return false;
     }
 
+    public ConfigurationDependency setPropagate(Object instance, String method) {
+        setPropagate(instance != null && method != null);
+        m_propagateCallbackInstance = instance;
+        m_propagateCallbackMethod = method;
+        return this;
+    }
+    
     public Dictionary getProperties() {
-        return getConfiguration();
+        Dictionary config = getConfiguration();
+        if (config != null) {
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ Dictionary.class }, {}}, new Object[][] {{ config }, {}});
+                }
+                catch (InvocationTargetException e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while invoking callback method", e.getCause());
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                return config;
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find configuration");
+        }
     }
     
     public BundleContext getBundleContext() {

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java Mon Jul 12 12:43:42 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.dm.impl.dependencies;
 
+import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -29,9 +30,11 @@ import org.apache.felix.dm.ResourceDepen
 import org.apache.felix.dm.ResourceHandler;
 import org.apache.felix.dm.Service;
 import org.apache.felix.dm.ServiceComponentDependency;
+import org.apache.felix.dm.impl.InvocationUtil;
 import org.apache.felix.dm.impl.Logger;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
 
 public class ResourceDependencyImpl extends DependencyBase implements ResourceDependency, ResourceHandler, DependencyActivation, ServiceComponentDependency {
 	private volatile BundleContext m_context;
@@ -51,6 +54,8 @@ public class ResourceDependencyImpl exte
     private List m_resources = new ArrayList();
     private URL m_resourceInstance;
     private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
 	
     public ResourceDependencyImpl(BundleContext context, Logger logger) {
         super(logger);
@@ -430,15 +435,36 @@ public class ResourceDependencyImpl exte
         return this;
     }
     
+    public ResourceDependency setPropagate(Object instance, String method) {
+        setPropagate(instance != null && method != null);
+        m_propagateCallbackInstance = instance;
+        m_propagateCallbackMethod = method;
+        return this;
+    }
+    
     public Dictionary getProperties() {
         URL resource = lookupResource();
         if (resource != null) {
-            Properties props = new Properties();
-            props.setProperty(ResourceHandler.HOST, resource.getHost());
-            props.setProperty(ResourceHandler.PATH, resource.getPath());
-            props.setProperty(ResourceHandler.PROTOCOL, resource.getProtocol());
-            props.setProperty(ResourceHandler.PORT, Integer.toString(resource.getPort()));
-            return props;
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ URL.class }}, new Object[][] {{ resource }});
+                }
+                catch (InvocationTargetException e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while invoking callback method", e.getCause());
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                Properties props = new Properties();
+                props.setProperty(ResourceHandler.HOST, resource.getHost());
+                props.setProperty(ResourceHandler.PATH, resource.getPath());
+                props.setProperty(ResourceHandler.PROTOCOL, resource.getProtocol());
+                props.setProperty(ResourceHandler.PORT, Integer.toString(resource.getPort()));
+                return props;
+            }
         }
         else {
             throw new IllegalStateException("cannot find resource");

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java?rev=963265&r1=963264&r2=963265&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java Mon Jul 12 12:43:42 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.dm.impl.dependencies;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Proxy;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -27,12 +28,14 @@ import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.ServiceComponentDependency;
 import org.apache.felix.dm.ServiceDependency;
 import org.apache.felix.dm.impl.DefaultNullObject;
+import org.apache.felix.dm.impl.InvocationUtil;
 import org.apache.felix.dm.impl.Logger;
 import org.apache.felix.dm.impl.tracker.ServiceTracker;
 import org.apache.felix.dm.impl.tracker.ServiceTrackerCustomizer;
@@ -40,6 +43,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
 
 /**
  * Service dependency that can track an OSGi service.
@@ -69,6 +73,9 @@ public class ServiceDependencyImpl exten
     private Object m_defaultImplementationInstance;
     private boolean m_isAvailable;
     private ServiceReference[] m_references;
+    private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
     
     private static final Comparator COMPARATOR = new Comparator() {
         public int getRank(ServiceReference ref) {
@@ -805,12 +812,51 @@ public class ServiceDependencyImpl exten
     }
 
     public Dictionary getProperties() {
-        // TODO Auto-generated method stub
-        return null;
+        ServiceReference reference = lookupServiceReference();
+        Object service = lookupService();
+        if (reference != null) {
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ ServiceReference.class, Object.class }, { ServiceReference.class }}, new Object[][] {{ reference, service }, { reference }});
+                }
+                catch (InvocationTargetException e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while invoking callback method", e.getCause());
+                }
+                catch (Exception e) {
+                    m_logger.log(LogService.LOG_WARNING, "Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                Properties props = new Properties();
+                String[] keys = reference.getPropertyKeys();
+                for (int i = 0; i < keys.length; i++) {
+                    if (!(keys[i].equals(Constants.SERVICE_ID) || keys[i].equals(Constants.SERVICE_PID))) {
+                        props.put(keys[i], reference.getProperty(keys[i]));
+                    }
+                }
+                return props;
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find service reference");
+        }
     }
 
     public boolean isPropagated() {
-        // TODO Auto-generated method stub
-        return false;
+        return m_propagate;
+    }
+    
+    public ServiceDependency setPropagate(boolean propagate) {
+        ensureNotActive();
+        m_propagate = propagate;
+        return this;
+    }
+    
+    public ServiceDependency setPropagate(Object instance, String method) {
+        setPropagate(instance != null && method != null);
+        m_propagateCallbackInstance = instance;
+        m_propagateCallbackMethod = method;
+        return this;
     }
 }