You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2015/07/28 00:01:59 UTC

svn commit: r1692966 [2/3] - in /felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds: src/org/apache/felix/scr/impl/ src/org/apache/felix/scr/impl/config/ src/org/apache/felix/scr/impl/helper/ src/org/apache/felix/scr/impl/m...

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java Mon Jul 27 22:01:59 2015
@@ -26,11 +26,11 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.apache.felix.scr.impl.manager.ComponentContextImpl;
@@ -50,7 +50,8 @@ public class FieldHandler
         serviceObjects,
         serviceType,
         map,
-        tuple
+        tuple,
+        ignore
     }
 
     /** The reference metadata. */
@@ -274,6 +275,15 @@ public class FieldHandler
         final Class<?> referenceType = ClassUtils.getClassFromComponentClassLoader(
                 this.componentClass, metadata.getInterface(), logger);
 
+        // ignore static fields
+        if ( Modifier.isStatic(f.getModifiers()))
+        {
+            logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be static", new Object[]
+                    {metadata.getField(), this.componentClass}, null );
+        	valueType = ParamType.ignore;
+        	return f;
+        }
+
         // unary reference
         if ( !metadata.isMultiple() )
         {
@@ -301,69 +311,26 @@ public class FieldHandler
             {
                 logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}", new Object[]
                         {metadata.getField(), this.componentClass, fieldType.getName()}, null );
-                return null;
+                valueType = ParamType.ignore;
             }
 
-            // if the field is dynamic and optional it has to be volatile
-            if ( !metadata.isStatic() && metadata.isOptional() )
-            {
-                if ( !Modifier.isVolatile(f.getModifiers()) )
-                {
-                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
-                            {metadata.getField(), this.componentClass}, null );
-                    return null;
-                }
+            // if the field is dynamic, it has to be volatile (field is ignored, case logged) (112.3.8.1)
+            if ( !metadata.isStatic() && !Modifier.isVolatile(f.getModifiers()) ) {
+                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
+                        {metadata.getField(), this.componentClass}, null );
+                valueType = ParamType.ignore;
             }
 
-            // the field must not be final
+            // the field must not be final (field is ignored, case logged) (112.3.8.1)
             if ( Modifier.isFinal(f.getModifiers()) )
             {
                 logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
                         {metadata.getField(), this.componentClass}, null );
-                return null;
+                valueType = ParamType.ignore;
             }
         }
         else
         {
-            // multiple cardinality, field type must be collection or subtype
-            if ( !ClassUtils.COLLECTION_CLASS.isAssignableFrom(fieldType) )
-            {
-                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}", new Object[]
-                        {metadata.getField(), this.componentClass, fieldType.getName()}, null );
-                return null;
-            }
-
-            // if the field is dynamic with the replace strategy it has to be volatile
-            if ( !metadata.isStatic() && metadata.isReplace() )
-            {
-                if ( !Modifier.isVolatile(f.getModifiers()) )
-                {
-                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
-                            {metadata.getField(), this.componentClass}, null );
-                    return null;
-                }
-            }
-
-            // replace strategy: field must not be final
-            //                   only collection and list allowed
-            if ( metadata.isReplace()  )
-            {
-                if ( Modifier.isFinal(f.getModifiers()) )
-                {
-                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
-                            {metadata.getField(), this.componentClass}, null );
-                    return null;
-                }
-                if ( fieldType != ClassUtils.LIST_CLASS && fieldType != ClassUtils.COLLECTION_CLASS )
-                {
-                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}."+
-                    " It must be one of java.util.Collection or java.util.List.",
-                    new Object[] {metadata.getField(), this.componentClass, fieldType.getName()}, null );
-                    return null;
-
-                }
-            }
-
             if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE.equals(metadata.getFieldCollectionType()) )
             {
                 valueType = ParamType.serviceType;
@@ -384,6 +351,50 @@ public class FieldHandler
             {
                 valueType = ParamType.tuple;
             }
+
+            // multiple cardinality, field type must be collection or subtype
+            if ( !ClassUtils.COLLECTION_CLASS.isAssignableFrom(fieldType) )
+            {
+                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}", new Object[]
+                        {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                valueType = ParamType.ignore;
+            }
+
+            // additional checks for replace strategy:
+            if ( metadata.isReplace()  )
+            {
+                // if the field is dynamic wit has to be volatile (field is ignored, case logged) (112.3.8.1)
+                if ( !metadata.isStatic() && !Modifier.isVolatile(f.getModifiers()) )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
+                            {metadata.getField(), this.componentClass}, null );
+                    valueType = ParamType.ignore;
+                }
+
+                // replace strategy: field must not be final (field is ignored, case logged) (112.3.8.1)
+                //                   only collection and list allowed
+                if ( fieldType != ClassUtils.LIST_CLASS && fieldType != ClassUtils.COLLECTION_CLASS )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}."+
+                        " It must be one of java.util.Collection or java.util.List.",
+                        new Object[] {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                    valueType = ParamType.ignore;
+
+                }
+                if ( Modifier.isFinal(f.getModifiers()) )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
+                            {metadata.getField(), this.componentClass}, null );
+                    valueType = ParamType.ignore;
+                }
+            }
+        }
+        // static references only allowed for replace strategy
+        if ( metadata.isStatic() && !metadata.isReplace() )
+        {
+            logger.log( LogService.LOG_ERROR, "Update strategy for field {0} in component {1} only allowed for non static field references.", new Object[]
+                    {metadata.getField(), this.componentClass}, null );
+            valueType = ParamType.ignore;
         }
         return f;
     }
@@ -452,7 +463,7 @@ public class FieldHandler
         {
             case serviceType : obj = refPair.getServiceObject(key); break;
             case serviceReference : obj = refPair.getRef(); break;
-            case serviceObjects : obj = ((ComponentServiceObjectsHelper)key.getComponentServiceObjectsHelper()).getServiceObjects(refPair.getRef()); break;
+            case serviceObjects : obj = key.getComponentServiceObjectsHelper().getServiceObjects(refPair.getRef()); break;
             case map : obj = new ReadOnlyDictionary<String, Object>( refPair.getRef() ); break;
             case tuple : final Object tupleKey = new ReadOnlyDictionary<String, Object>( refPair.getRef() );
                          final Object tupleValue = refPair.getServiceObject(key);
@@ -466,14 +477,17 @@ public class FieldHandler
     private boolean initField(final Object componentInstance,
             final SimpleLogger logger )
     {
+    	if ( valueType == ParamType.ignore )
+    	{
+    		return true;
+    	}
         try
         {
-            if ( metadata.isMultiple()
-                 && !metadata.isStatic() )
+            if ( metadata.isMultiple() )
             {
                 if ( metadata.isReplace()  )
                 {
-                    this.setFieldValue(componentInstance, Collections.emptyList());
+                    this.setFieldValue(componentInstance, new CopyOnWriteArrayList<Object>());
                 }
                 else
                 {
@@ -488,22 +502,42 @@ public class FieldHandler
                         {
                             logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
                                     {metadata.getField(), this.componentClass}, null );
-                            return false;
+                            valueType = ParamType.ignore;
+                            return true;
                         }
                         if ( fieldType != ClassUtils.LIST_CLASS && fieldType != ClassUtils.COLLECTION_CLASS )
                         {
                             logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}."+
-                            " It must be one of java.util.Collection or java.util.List.",
+                                " It must be one of java.util.Collection or java.util.List.",
                                 new Object[] {metadata.getField(), this.componentClass, fieldType.getName()}, null );
-                            return false;
+                            valueType = ParamType.ignore;
+                            return true;
+                        }
+                        if ( fieldType == ClassUtils.LIST_CLASS )
+                        {
+                        	this.setFieldValue(componentInstance, new CopyOnWriteArrayList<Object>());
+                        }
+                        else
+                        {
+                        	this.setFieldValue(componentInstance, new CopyOnWriteArraySet<Object>());
                         }
-                        this.setFieldValue(componentInstance, new CopyOnWriteArraySet<Object>());
                     }
                 }
             }
+            else
+            {
+            	// only optional field need initialization
+            	if ( metadata.isOptional() )
+            	{
+	            	// null the field if optional and unary
+	            	this.setFieldValue(componentInstance, null);
+	            }
+            }
         }
         catch ( final InvocationTargetException ite)
         {
+            valueType = ParamType.ignore;
+
             logger.log( LogService.LOG_ERROR, "Field {0} in component {1} can't be initialized.",
                     new Object[] {metadata.getField(), this.componentClass}, ite );
             return false;
@@ -534,7 +568,8 @@ public class FieldHandler
         if ( !this.metadata.isMultiple() )
         {
             // unary references
-            // unbind needs only be done, if reference is dynamic and optional
+
+        	// unbind needs only be done, if reference is dynamic and optional
             if ( mType == METHOD_TYPE.UNBIND )
             {
                 if ( this.metadata.isOptional() && !this.metadata.isStatic() )
@@ -547,19 +582,21 @@ public class FieldHandler
                 }
                 this.boundValues.remove(refPair);
             }
-            // updated needs only be done, if reference is dynamic and optional
-            // and the value type is map or tuple
+            // updated needs only be done, if the value type is map or tuple
+            // If it's a dynamic reference, the value can be updated
+            // for a static reference we need a reactivation
             else if ( mType == METHOD_TYPE.UPDATED )
             {
-                if ( this.metadata.isOptional() && !this.metadata.isStatic() )
-                {
-                    if ( this.valueType == ParamType.map || this.valueType == ParamType.tuple )
-                    {
-                        final Object obj = getValue(key, refPair);
-                        this.setFieldValue(componentInstance, obj);
-                        this.boundValues.put(refPair, obj);
-                    }
-                }
+            	if ( this.valueType == ParamType.map || this.valueType == ParamType.tuple )
+            	{
+            		if ( this.metadata.isStatic() )
+            		{
+            			return MethodResult.REACTIVATE;
+            		}
+                    final Object obj = getValue(key, refPair);
+                    this.setFieldValue(componentInstance, obj);
+                    this.boundValues.put(refPair, obj);
+            	}
             }
             // bind needs always be done
             else
@@ -607,26 +644,32 @@ public class FieldHandler
                     }
                 }
             }
-            // updated needs only be done, if reference is dynamic
-            // and the value type is map or tuple
+            // updated needs only be done, if the value type is map or tuple
             else if ( mType == METHOD_TYPE.UPDATED)
             {
-                if ( !this.metadata.isStatic()
-                     && (this.valueType == ParamType.map || this.valueType == ParamType.tuple ) )
-                {
-                    final Object obj = getValue(key, refPair);
-                    final Object oldObj = this.boundValues.put(refPair, obj);
-
-                    if ( metadata.isReplace() )
+            	if ( this.valueType == ParamType.map || this.valueType == ParamType.tuple )
+            	{
+                    if ( !this.metadata.isStatic() )
                     {
-                        this.setFieldValue(componentInstance, getReplaceCollection());
+	                    final Object obj = getValue(key, refPair);
+	                    final Object oldObj = this.boundValues.put(refPair, obj);
+
+	                    if ( metadata.isReplace() )
+	                    {
+	                        this.setFieldValue(componentInstance, getReplaceCollection());
+	                    }
+	                    else
+	                    {
+	                        @SuppressWarnings("unchecked")
+	                        final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
+	                        col.add(obj);
+	                        col.remove(oldObj);
+	                    }
                     }
                     else
                     {
-                        @SuppressWarnings("unchecked")
-                        final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
-                        col.add(obj);
-                        col.remove(oldObj);
+                    	// if it's static we need to reactivate
+                    	return MethodResult.REACTIVATE;
                     }
                 }
             }
@@ -698,7 +741,7 @@ public class FieldHandler
         // no static fields
         if ( Modifier.isStatic( mod ) )
         {
-            return false;
+            return true;
         }
 
         // accept public and protected fields
@@ -889,6 +932,11 @@ public class FieldHandler
                 final MethodResult methodCallFailureResult,
                 final SimpleLogger logger)
         {
+            if ( handler.valueType == ParamType.ignore )
+            {
+                return MethodResult.VOID;
+            }
+
             try
             {
                 return handler.state.invoke( handler,
@@ -923,8 +971,8 @@ public class FieldHandler
             }
             return true;
         }
-
     }
+
     public ReferenceMethod getBind()
     {
         return new ReferenceMethodImpl(METHOD_TYPE.BIND, this);
@@ -942,12 +990,16 @@ public class FieldHandler
 
     public InitReferenceMethod getInit()
     {
+        if ( valueType == ParamType.ignore )
+        {
+            return null;
+        }
         return new InitReferenceMethod()
         {
 
             public boolean init(final Object componentInstance, final SimpleLogger logger)
             {
-                if ( fieldExists( logger) )
+                if ( fieldExists( logger ) )
                 {
                     return initField(componentInstance, logger);
                 }

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java Mon Jul 27 22:01:59 2015
@@ -16,16 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-
 package org.apache.felix.scr.impl.helper;
 
-
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 
 /**
- * @version $Rev: 1637793 $ $Date: 2014-11-10 06:51:04 +0100 (Mon, 10 Nov 2014) $
+ * FieldMethods provides implementations for bind/unbind/updated
+ * which handle manipulation of fields.
  */
 public class FieldMethods implements ReferenceMethods
 {

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java Mon Jul 27 22:01:59 2015
@@ -34,11 +34,16 @@ public class MethodResult
 {
 
     /**
-     * Predefined instance indicating a successfull call to a void method.
+     * Predefined instance indicating a successful call to a void method.
      */
     public static final MethodResult VOID = new MethodResult(false, null);
 
     /**
+     * Predefined instance indicating to reactivate the component.
+     */
+    public static final MethodResult REACTIVATE = new MethodResult(false, null);
+
+    /**
      * The actual result from the method, which may be <code>null</code>.
      */
     private final Map<String, Object> result;

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java Mon Jul 27 22:01:59 2015
@@ -19,7 +19,6 @@
 package org.apache.felix.scr.impl.helper;
 
 import org.apache.felix.scr.impl.metadata.DSVersion;
-import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 
 
 /**
@@ -30,9 +29,9 @@ implements org.apache.felix.scr.impl.hel
 {
 
     public UnbindMethod( final String methodName,
-            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties, ReferenceMetadata.ReferenceScope referenceScope )
+            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties )
     {
-        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties, referenceScope );
+        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties );
     }
 
 

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java Mon Jul 27 22:01:59 2015
@@ -19,7 +19,6 @@
 package org.apache.felix.scr.impl.helper;
 
 import org.apache.felix.scr.impl.metadata.DSVersion;
-import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 
 
 /**
@@ -30,9 +29,9 @@ implements org.apache.felix.scr.impl.hel
 {
 
     public UpdatedMethod( final String methodName,
-            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties, ReferenceMetadata.ReferenceScope referenceScope )
+            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties )
     {
-        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties, referenceScope );
+        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties );
     }
 
 

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Mon Jul 27 22:01:59 2015
@@ -396,7 +396,7 @@ public abstract class AbstractComponentM
             enableInternal();
             if ( !async )
             {
-                activateInternal( m_trackingCount.get() );
+                activateInternal( );
             }
         }
         finally
@@ -419,7 +419,7 @@ public abstract class AbstractComponentM
                 {
                     try
                     {
-                        activateInternal( m_trackingCount.get() );
+                        activateInternal( );
                     }
                     finally
                     {
@@ -644,7 +644,7 @@ public abstract class AbstractComponentM
         log( LogService.LOG_DEBUG, "Component enabled", null );
     }
 
-    final void activateInternal( int trackingCount )
+    final void activateInternal( )
     {
         log( LogService.LOG_DEBUG, "ActivateInternal",
                 null );
@@ -993,7 +993,11 @@ public abstract class AbstractComponentM
         return true;
     }
 
-    abstract <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount );
+    /**
+     * Invoke updated method
+     * @return {@code true} if the component needs reactivation, {@code false} otherwise.
+     */
+    abstract <T> boolean invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount );
 
     abstract <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount );
 

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Mon Jul 27 22:01:59 2015
@@ -129,7 +129,7 @@ public class ComponentFactoryImpl<S> ext
         // enable
         cm.enableInternal();
         //activate immediately
-        cm.activateInternal( getTrackingCount().get() );
+        cm.activateInternal( );
 
         ComponentInstance instance;
         if ( getComponentMetadata().isPersistentFactoryComponent() ) 
@@ -300,8 +300,9 @@ public class ComponentFactoryImpl<S> ext
         return true;
     }
 
-    <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> ref, int trackingCount )
+    <T> boolean invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> ref, int trackingCount )
     {
+    	return false;
     }
 
     <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> reference, int trackingCount )

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/DependencyManager.java Mon Jul 27 22:01:59 2015
@@ -68,20 +68,17 @@ public class DependencyManager<S, T> imp
 
     private final int m_index;
 
-    private final Customizer<S, T> m_customizer;
+    private volatile Customizer<S, T> m_customizer;
 
     //only set once, but it's not clear there is enough other synchronization to get the correct object before it's used.
     private volatile ReferenceMethods m_bindMethods;
 
     //reset on filter change
-    private volatile ServiceTracker<T, RefPair<S, T>> m_tracker;
+    private volatile ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> m_tracker;
 
     // the target service filter string
     private volatile String m_target;
 
-    // the target service filter
-    private volatile Filter m_targetFilter;
-
     private volatile int m_minCardinality;
 
     /**
@@ -127,7 +124,7 @@ public class DependencyManager<S, T> imp
        m_bindMethods = bindMethods;
     }
 
-    private interface Customizer<S, T> extends ServiceTrackerCustomizer<T, RefPair<S, T>>
+    private interface Customizer<S, T> extends ServiceTrackerCustomizer<T, RefPair<S, T>, ExtendedServiceEvent>
     {
         /**
          * attempt to obtain the services from the tracked service references that will be used in inital bind calls
@@ -143,7 +140,7 @@ public class DependencyManager<S, T> imp
 
         boolean isSatisfied();
 
-        void setTracker( ServiceTracker<T, RefPair<S, T>> tracker );
+        void setTracker( ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker );
 
         void setTrackerOpened();
 
@@ -158,7 +155,7 @@ public class DependencyManager<S, T> imp
 
         private volatile Map<ServiceReference<T>, RefPair<S, T>> previousRefMap = EMPTY_REF_MAP;
 
-        public void setTracker( ServiceTracker<T, RefPair<S, T>> tracker )
+        public void setTracker( ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker )
         {
             m_tracker = tracker;
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracker reset (closed)", new Object[] {getName()}, null );
@@ -167,7 +164,7 @@ public class DependencyManager<S, T> imp
 
         public boolean isSatisfied()
         {
-            ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+            ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
             if ( tracker == null)
             {
                 return false;
@@ -175,7 +172,7 @@ public class DependencyManager<S, T> imp
             return cardinalitySatisfied( tracker.getServiceCount() );
         }
 
-        protected ServiceTracker<T, RefPair<S, T>> getTracker()
+        protected ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> getTracker()
         {
             return m_tracker;
         }
@@ -202,7 +199,7 @@ public class DependencyManager<S, T> imp
 
         protected void deactivateTracker()
         {
-            ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+            ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
             if ( tracker != null )
             {
                 tracker.deactivate();
@@ -256,21 +253,21 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             if ( cardinalityJustSatisfied( serviceCount ) )
             {
-                m_componentManager.activateInternal( trackingCount );
+                m_componentManager.activateInternal( );
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             if ( !cardinalitySatisfied( getTracker().getServiceCount() ) )
             {
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
@@ -310,7 +307,7 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
         	boolean tracked = false;
@@ -330,7 +327,7 @@ public class DependencyManager<S, T> imp
                     m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic, activating", new Object[] {getName(), trackingCount}, null );
                     tracked( trackingCount );
                     tracked = true;
-                    m_componentManager.activateInternal( trackingCount );
+                    m_componentManager.activateInternal( );
                 }
                 else
                 {
@@ -344,7 +341,7 @@ public class DependencyManager<S, T> imp
 			}
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic modified {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             if (isActive())
@@ -355,10 +352,10 @@ public class DependencyManager<S, T> imp
             tracked( trackingCount );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             boolean unbind = cardinalitySatisfied( getTracker().getServiceCount() );
             if ( unbind )
             {
@@ -415,7 +412,7 @@ public class DependencyManager<S, T> imp
         {
             if ( lastRefPair == null )
             {
-                ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+                ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
                 if (tracker == null) {
                     trackingCount.set( lastRefPairTrackingCount );
                     return Collections.emptyList();
@@ -439,7 +436,7 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
@@ -449,31 +446,44 @@ public class DependencyManager<S, T> imp
                         "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
                         {getName(), m_dependencyMetadata.getInterface()}, null );
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
-                m_componentManager.activateInternal( trackingCount );
+                //event may be null during initial operations.
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
 
             }
             else if ( isTrackerOpened() && cardinalityJustSatisfied( serviceCount ) )
             {
-                m_componentManager.activateInternal( trackingCount );
+                m_componentManager.activateInternal( );
             }
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy added {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy modified {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            boolean reactivate = false;
             if (isActive())
             {
-                m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
+            	reactivate = m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
             }
-            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
+            if ( reactivate )
+            {
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
+            }
+            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             tracked( trackingCount );
             if ( isActive() )
             {
@@ -483,7 +493,10 @@ public class DependencyManager<S, T> imp
                         {getName(), m_dependencyMetadata.getInterface()}, null );
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
                 //try to reactivate after ref is no longer tracked.
-                m_componentManager.activateInternal( trackingCount );
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
             }
             else if ( !cardinalitySatisfied( getTracker().getServiceCount() ) ) //may be called from an old tracker, so getTracker() may give a different answer
             {
@@ -501,7 +514,7 @@ public class DependencyManager<S, T> imp
         {
             int serviceCount = 0;
             AtomicInteger trackingCount = new AtomicInteger( );
-            final ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+            final ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
             SortedMap<ServiceReference<T>, RefPair<S, T>> tracked = tracker.getTracked( cardinalitySatisfied( tracker.getServiceCount() ), trackingCount );
             for (RefPair<S, T> refPair: tracked.values())
             {
@@ -530,7 +543,7 @@ public class DependencyManager<S, T> imp
 
         public Collection<RefPair<S, T>> getRefs( AtomicInteger trackingCount )
         {
-            ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+            ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
             if (tracker == null) {
                 return Collections.emptyList();
             }
@@ -549,33 +562,42 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
             if ( isTrackerOpened() && cardinalityJustSatisfied( serviceCount ) && !isActive())
             {
-                m_componentManager.activateInternal( trackingCount );
+                m_componentManager.activateInternal( );
             }
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant added {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant modified {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            boolean reactivate = false;
             Collection<RefPair<S, T>> refs = this.refs.get();
             if (isActive() && refs.contains( refPair ))
             {
-                m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
+                reactivate = m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
             }
-            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
+            if ( reactivate )
+            {
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
+            }
+            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             tracked( trackingCount );
             Collection<RefPair<S, T>> refs = this.refs.get();
             if ( isActive() && refs != null )
@@ -589,7 +611,10 @@ public class DependencyManager<S, T> imp
                     m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
 
                     // FELIX-2368: immediately try to reactivate
-                    m_componentManager.activateInternal( trackingCount );
+                    if (event != null)
+                    {
+                        event.addComponentManager(m_componentManager);
+                    }
 
                 }
             }
@@ -683,7 +708,7 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleDynamic added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             boolean tracked = false;
@@ -721,7 +746,7 @@ public class DependencyManager<S, T> imp
                 {
                     tracked( trackingCount );
                     tracked = true;
-                    m_componentManager.activateInternal( trackingCount );
+                    m_componentManager.activateInternal( );
                 }
             }
             this.trackingCount = trackingCount;
@@ -732,7 +757,7 @@ public class DependencyManager<S, T> imp
             }
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleDynamic modified {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             boolean invokeUpdated;
@@ -749,10 +774,10 @@ public class DependencyManager<S, T> imp
             tracked( trackingCount );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             boolean deactivate = false;
             boolean untracked = true;
             RefPair<S, T> oldRefPair = null;
@@ -895,7 +920,7 @@ public class DependencyManager<S, T> imp
             return refPair;
         }
 
-        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             this.trackingCount = trackingCount;
@@ -910,7 +935,10 @@ public class DependencyManager<S, T> imp
                 if ( reactivate )
                 {
                     m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
-                    m_componentManager.activateInternal( trackingCount );
+                    if (event != null)
+                    {
+                        event.addComponentManager(m_componentManager);
+                    }
                 }
                 else
                 {
@@ -919,7 +947,7 @@ public class DependencyManager<S, T> imp
             }
             else if (isTrackerOpened() && cardinalityJustSatisfied( serviceCount ) )
             {
-                m_componentManager.activateInternal( trackingCount );
+                m_componentManager.activateInternal( );
             }
             else
             {
@@ -928,27 +956,44 @@ public class DependencyManager<S, T> imp
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic added {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void modifiedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic modified {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             boolean invokeUpdated;
-            synchronized (getTracker().tracked())
+            final Object sync = getTracker().tracked();
+            synchronized (sync)
             {
                 invokeUpdated = isActive() && refPair == this.refPair;
             }
+            boolean reactivate = false;
             if ( invokeUpdated )
             {
-                m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
+                reactivate = m_componentManager.invokeUpdatedMethod( DependencyManager.this, refPair, trackingCount );
             }
             this.trackingCount = trackingCount;
-            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
+            if ( reactivate )
+            {
+                m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
+                synchronized ( sync )
+                {
+                    if (refPair == this.refPair)
+                    {
+                        this.refPair = null;
+                    }
+                }
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
+            }
+            m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic modified {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
 
-        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount )
+        public void removedService( ServiceReference<T> serviceReference, RefPair<S, T> refPair, int trackingCount, ExtendedServiceEvent event )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
-            refPair.setDeleted( true );
+            refPair.markDeleted();
             this.trackingCount = trackingCount;
             tracked( trackingCount );
             boolean reactivate;
@@ -970,7 +1015,10 @@ public class DependencyManager<S, T> imp
                         this.refPair = null;
                     }
                 }
-                m_componentManager.activateInternal( trackingCount );
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
             }
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic removed {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
         }
@@ -1006,7 +1054,7 @@ public class DependencyManager<S, T> imp
 
         public void close()
         {
-            ServiceTracker<T, RefPair<S, T>> tracker = getTracker();
+            ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = getTracker();
             if ( tracker != null )
             {
                 RefPair<S, T> ref;
@@ -1063,7 +1111,7 @@ public class DependencyManager<S, T> imp
             return isOptional();
         }
 
-        public void setTracker( ServiceTracker<T, RefPair<S, T>> tRefPairServiceTracker )
+        public void setTracker( ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tRefPairServiceTracker )
         {
         }
 
@@ -1080,15 +1128,15 @@ public class DependencyManager<S, T> imp
             return null;
         }
 
-        public void addedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount, int serviceCount )
+        public void addedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount, int serviceCount, ExtendedServiceEvent event )
         {
         }
 
-        public void modifiedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount )
+        public void modifiedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount, ExtendedServiceEvent event )
         {
         }
 
-        public void removedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount )
+        public void removedService( ServiceReference<T> tServiceReference, RefPair<S, T> service, int trackingCount, ExtendedServiceEvent event )
         {
         }
     }
@@ -1290,7 +1338,7 @@ public class DependencyManager<S, T> imp
      */
     private RefPair<S, T> getRefPair( ServiceReference<T> serviceReference )
     {
-        final ServiceTracker<T, RefPair<S, T>> tracker = m_tracker;
+        final ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = m_tracker;
         if ( tracker != null )
         {
             AtomicInteger trackingCount = new AtomicInteger( );
@@ -1617,13 +1665,14 @@ public class DependencyManager<S, T> imp
      *
      * @param componentContext instance we are calling updated on.
      * @param refPair A service reference corresponding to the service whose service
-     * @param edgeInfo EdgeInfo for the comibination of this instance and this dependency manager.
+     * @param edgeInfo EdgeInfo for the combination of this instance and this dependency manager.
+     * @return {@code true} if reactivation is required.
      */
-    void invokeUpdatedMethod( ComponentContextImpl<S> componentContext, final RefPair<S, T> refPair, int trackingCount, EdgeInfo info )
+    boolean invokeUpdatedMethod( ComponentContextImpl<S> componentContext, final RefPair<S, T> refPair, int trackingCount, EdgeInfo info )
     {
-        if ( m_dependencyMetadata.getUpdated() == null )
+        if ( m_dependencyMetadata.getUpdated() == null && m_dependencyMetadata.getField() == null )
         {
-            return;
+            return false;
         }
         // The updated method is only invoked if the implementation object is not
         // null. This is valid for both immediate and delayed components
@@ -1634,7 +1683,7 @@ public class DependencyManager<S, T> imp
                 if (info.outOfRange( trackingCount ) )
                 {
                     //ignore events after close started or we will have duplicate unbinds.
-                    return;
+                    return false;
                 }
             }
             info.waitForOpen( m_componentManager, getName(), "invokeUpdatedMethod" );
@@ -1643,15 +1692,16 @@ public class DependencyManager<S, T> imp
                 m_componentManager.log( LogService.LOG_WARNING,
                         "DependencyManager : invokeUpdatedMethod : Service not available from service registry for ServiceReference {0} for reference {1}",
                         new Object[] {refPair.getRef(), getName()}, null );
-                return;
+                return false;
 
             }
-            BindParameters bp = new BindParameters(componentContext, refPair);
-            MethodResult methodResult = m_bindMethods.getUpdated().invoke( componentContext.getImplementationObject( false ), bp, MethodResult.VOID, m_componentManager );
+            final BindParameters bp = new BindParameters(componentContext, refPair);
+            final MethodResult methodResult = m_bindMethods.getUpdated().invoke( componentContext.getImplementationObject( false ), bp, MethodResult.VOID, m_componentManager );
             if ( methodResult != null)
             {
                 m_componentManager.setServiceProperties( methodResult );
             }
+            return methodResult == MethodResult.REACTIVATE;
         }
         else
         {
@@ -1661,6 +1711,7 @@ public class DependencyManager<S, T> imp
             m_componentManager.log( LogService.LOG_DEBUG,
                     "DependencyManager : Component not set, no need to call updated method", null );
         }
+        return false;
     }
 
 
@@ -1718,6 +1769,7 @@ public class DependencyManager<S, T> imp
             {
                 m_componentManager.setServiceProperties( methodResult );
             }
+            componentContext.getComponentServiceObjectsHelper().closeServiceObjects(refPair.getRef());
         }
         else
         {
@@ -1843,6 +1895,8 @@ public class DependencyManager<S, T> imp
         return minimumCardinality;
     }
 
+    private static final String OBJECTCLASS_CLAUSE = "(" + Constants.OBJECTCLASS + "=";
+    private static final String PROTOTYPE_SCOPE_CLAUSE = "(" + Constants.SERVICE_SCOPE + "=" + Constants.SCOPE_PROTOTYPE + ")";
 
     /**
      * Sets the target filter of this dependency to the new filter value. If the
@@ -1874,41 +1928,45 @@ public class DependencyManager<S, T> imp
         }
         m_target = target;
         final boolean multipleExpr = m_target != null || m_dependencyMetadata.getScope() == ReferenceScope.prototype_required;
-        final StringBuilder filterSB = new StringBuilder();
+        final boolean allExpr = m_target != null && m_dependencyMetadata.getScope() == ReferenceScope.prototype_required;
+        final StringBuilder initialReferenceFilterSB = new StringBuilder();
         if (multipleExpr )
         {
-            filterSB.append("(&");
+            initialReferenceFilterSB.append("(&");
         }
         // "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")"
-        filterSB.append('(');
-        filterSB.append(Constants.OBJECTCLASS);
-        filterSB.append('=');
-        filterSB.append(m_dependencyMetadata.getInterface());
-        filterSB.append(')');
+        String classFilterString = OBJECTCLASS_CLAUSE + m_dependencyMetadata.getInterface() + ")";
+        initialReferenceFilterSB.append(classFilterString);
 
         // if reference scope is prototype_required, we simply add
-        // service.scope=prototype to the filter
+        // (service.scope=prototype) to the filter
         if ( m_dependencyMetadata.getScope() == ReferenceScope.prototype_required )
         {
-            filterSB.append('(');
-            filterSB.append(Constants.SERVICE_SCOPE);
-            filterSB.append('=');
-            filterSB.append(Constants.SCOPE_PROTOTYPE);
-            filterSB.append(')');
+            initialReferenceFilterSB.append(PROTOTYPE_SCOPE_CLAUSE);
         }
 
         // append target
         if ( m_target != null )
         {
-            filterSB.append(m_target);
+            initialReferenceFilterSB.append(m_target);
         }
         if (multipleExpr )
         {
-            filterSB.append(')');
+            initialReferenceFilterSB.append(')');
+        }
+        String initialReferenceFilterString= initialReferenceFilterSB.toString();
+        String eventFilterString;
+        if (allExpr)
+        {
+            StringBuilder sb = new StringBuilder("(&").append(PROTOTYPE_SCOPE_CLAUSE).append(m_target).append(")");
+            eventFilterString = sb.toString();
+        }
+        else 
+        {
+            eventFilterString = m_target;
         }
-        String filterString = filterSB.toString();
 
-        final ServiceTracker<T, RefPair<S, T>> oldTracker = m_tracker;
+        final ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> oldTracker = m_tracker;
         AtomicInteger trackingCount = new AtomicInteger();
         SortedMap<ServiceReference<T>, RefPair<S, T>> refMap = unregisterServiceListener( trackingCount );
         if ( trackingCount.get() != -1 )
@@ -1919,29 +1977,34 @@ public class DependencyManager<S, T> imp
         m_componentManager.log( LogService.LOG_DEBUG, "Setting target property for dependency {0} to {1}", new Object[]
                 {getName(), target}, null );
         BundleContext bundleContext = m_componentManager.getBundleContext();
+        Filter eventFilter = null;
         if ( bundleContext != null )
         {
-            try
-            {
-                m_targetFilter = bundleContext.createFilter( filterString );
-            }
-            catch ( InvalidSyntaxException ise )
+            if ( eventFilterString != null )
             {
-                m_componentManager.log( LogService.LOG_ERROR, "Invalid syntax in target property for dependency {0} to {1}", new Object[]
-                        {getName(), target}, null );
-
-                //create a filter that will never be satisfied
-                filterString = "(component.id=-1)";
                 try
                 {
-                    m_targetFilter = bundleContext.createFilter( filterString );
+                    eventFilter = bundleContext.createFilter(eventFilterString);
                 }
-                catch ( InvalidSyntaxException e )
+                catch (InvalidSyntaxException ise)
                 {
-                    //this should not happen
-                    return;
-                }
+                    m_componentManager.log(LogService.LOG_ERROR,
+                        "Invalid syntax in target property for dependency {0} to {1}",
+                        new Object[] { getName(), target }, null);
 
+                    //create a filter that will never be satisfied
+                    eventFilterString = "(component.id=-1)";
+                    try
+                    {
+                        eventFilter = bundleContext.createFilter(eventFilterString);
+                    }
+                    catch (InvalidSyntaxException e)
+                    {
+                        //this should not happen
+                        return;
+                    }
+
+                }
             }
         }
         else
@@ -1953,9 +2016,15 @@ public class DependencyManager<S, T> imp
 
         m_customizer.setPreviousRefMap( refMap );
         boolean initialActive = oldTracker != null && oldTracker.isActive();
-        m_componentManager.log( LogService.LOG_DEBUG, "New service tracker for {0}, initial active: {1}, previous references: {2}", new Object[]
-                {getName(), initialActive, refMap}, null );
-        ServiceTracker<T, RefPair<S, T>> tracker = new ServiceTracker<T, RefPair<S, T>>( bundleContext, m_targetFilter, m_customizer, initialActive );
+        m_componentManager.log( LogService.LOG_DEBUG, "New service tracker for {0}, initial active: {1}, previous references: {2}, classFilter: {3}, eventFilter {4}, initialReferenceFilter {5}", new Object[]
+                {getName(), initialActive, refMap, classFilterString, eventFilter, initialReferenceFilterString}, null );
+        ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = new ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent>( bundleContext, 
+            m_customizer, 
+            initialActive, 
+            m_componentManager.getActivator(),
+            eventFilter,
+            classFilterString,
+            initialReferenceFilterString);
         m_customizer.setTracker( tracker );
         //set minimum cardinality
         m_minCardinality = minimumCardinality;
@@ -2018,7 +2087,7 @@ public class DependencyManager<S, T> imp
     SortedMap<ServiceReference<T>, RefPair<S, T>> unregisterServiceListener( AtomicInteger trackingCount )
     {
         SortedMap<ServiceReference<T>, RefPair<S, T>> refMap;
-        ServiceTracker<T, RefPair<S, T>> tracker = m_tracker;
+        ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = m_tracker;
         if ( tracker != null )
         {
             refMap = tracker.close( trackingCount );

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java?rev=1692966&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java Mon Jul 27 22:01:59 2015
@@ -0,0 +1,63 @@
+/*
+ * 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.felix.scr.impl.manager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+
+public class ExtendedServiceEvent extends ServiceEvent
+{
+    private List<AbstractComponentManager<?>> managers;
+
+    public ExtendedServiceEvent(ServiceEvent source)
+    {
+        super(source.getType(), source.getServiceReference());
+    }
+
+    public ExtendedServiceEvent(int type, ServiceReference ref)
+    {
+        super(type, ref);
+    }
+
+    public void addComponentManager(AbstractComponentManager<?> manager)
+    {
+        if (managers == null)
+            managers = new ArrayList<AbstractComponentManager<?>>();
+        managers.add(manager);
+    }
+
+    public List<AbstractComponentManager<?>> getManagers()
+    {
+        return managers == null ? Collections.<AbstractComponentManager<?>> emptyList()
+            : managers;
+    }
+
+    public void activateManagers()
+    {
+        for (AbstractComponentManager<?> manager : getManagers())
+        {
+            manager.activateInternal();
+        }
+    }
+
+}
\ No newline at end of file

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java?rev=1692966&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java Mon Jul 27 22:01:59 2015
@@ -0,0 +1,26 @@
+/*
+ * 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.felix.scr.impl.manager;
+
+import org.osgi.framework.ServiceEvent;
+
+public interface ExtendedServiceListener<U extends ServiceEvent>
+{
+    void serviceChanged(U event);
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java?rev=1692966&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java Mon Jul 27 22:01:59 2015
@@ -0,0 +1,32 @@
+/*
+ * 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.felix.scr.impl.manager;
+
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceEvent;
+
+public interface ExtendedServiceListenerContext<U extends ServiceEvent>
+{
+
+    void addServiceListener(String className, Filter filter,
+        ExtendedServiceListener<U> listener);
+
+    void removeServiceListener(String className, Filter filter,
+        ExtendedServiceListener<U> listener);
+}

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/RefPair.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/RefPair.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/RefPair.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/RefPair.java Mon Jul 27 22:01:59 2015
@@ -26,7 +26,7 @@ import org.osgi.framework.ServiceObjects
 import org.osgi.framework.ServiceReference;
 
 /**
- * @version $Rev: 1689302 $ $Date: 2015-07-06 03:31:39 +0200 (Mon, 06 Jul 2015) $
+ * @version $Rev: 1691603 $ $Date: 2015-07-17 18:13:58 +0200 (Fri, 17 Jul 2015) $
  */
 public abstract class RefPair<S, T>
 {
@@ -51,11 +51,11 @@ public abstract class RefPair<S, T>
     }
 
     public abstract boolean getServiceObject( ComponentContextImpl<S> key, BundleContext context, SimpleLogger logger );
- 
+
     public abstract T getServiceObject(ComponentContextImpl<S> key);
 
     public abstract boolean setServiceObject( ComponentContextImpl<S> key, T serviceObject );
-    
+
     public abstract T unsetServiceObject(ComponentContextImpl<S> key);
 
     public void setFailed( )
@@ -73,10 +73,8 @@ public abstract class RefPair<S, T>
         return deleted;
     }
 
-    public void setDeleted(boolean deleted)
+    public void markDeleted()
     {
-        this.deleted = deleted;
+        this.deleted = true;
     }
-
-
 }

Modified: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1692966&r1=1692965&r2=1692966&view=diff
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java (original)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java Mon Jul 27 22:01:59 2015
@@ -176,12 +176,19 @@ public class ServiceFactoryComponentMana
         }
     }
 
-    <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount )
+    <T> boolean invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount )
     {
+    	// as all instances are treated the same == have the same updated signatures for methods/fields
+    	// we just need one result
+    	boolean reactivate = false;
         for ( ComponentContextImpl<S> cc : getComponentContexts() )
         {
-            dependencyManager.invokeUpdatedMethod( cc, refPair, trackingCount, cc.getEdgeInfo( dependencyManager ) );
+            if ( dependencyManager.invokeUpdatedMethod( cc, refPair, trackingCount, cc.getEdgeInfo( dependencyManager ) ) ) 
+            {
+            	reactivate = true;
+            }
         }
+        return reactivate;
     }
 
     <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> oldRefPair, int trackingCount )