felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r1691760 [1/2] - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/ main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/integration/ test/java/org/apache/felix/scr/integration/components/deadlock/ test/res...
Date Sat, 18 Jul 2015 18:12:45 GMT
Author: djencks
Date: Sat Jul 18 18:12:45 2015
New Revision: 1691760

URL: http://svn.apache.org/r1691760
Log:
FELIX-4964 Activate a component at most once from a service event

Added:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java
      - copied, changed from r1691622, felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java
      - copied, changed from r1691622, felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java
Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTrackerCustomizer.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/LocateTest.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java
    felix/trunk/scr/src/test/resources/integration_test_locate.xml

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java?rev=1691760&r1=1691759&r2=1691760&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java Sat Jul 18 18:12:45 2015
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.scr.impl;
 
-
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -28,8 +27,11 @@ import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -39,23 +41,29 @@ import org.apache.felix.scr.impl.config.
 import org.apache.felix.scr.impl.helper.Logger;
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
 import org.apache.felix.scr.impl.manager.DependencyManager;
+import org.apache.felix.scr.impl.manager.ExtendedServiceEvent;
+import org.apache.felix.scr.impl.manager.ExtendedServiceListener;
+import org.apache.felix.scr.impl.manager.ExtendedServiceListenerContext;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.XmlHandler;
 import org.apache.felix.scr.impl.parser.KXml2SAXParser;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentException;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
 
-
 /**
  * The BundleComponentActivator is helper class to load and unload Components of
  * a single bundle. It will read information from the metadata.xml file
  * descriptors and create the corresponding managers.
  */
-public class BundleComponentActivator implements Logger
+public class BundleComponentActivator implements Logger, ExtendedServiceListenerContext<ExtendedServiceEvent>
 {
     // global component registration
     private final ComponentRegistry m_componentRegistry;
@@ -82,10 +90,149 @@ public class BundleComponentActivator im
     // the configuration
     private final ScrConfiguration m_configuration;
 
+    private final Map<String, ListenerInfo> listenerMap = new HashMap<String, ListenerInfo>();
+
+    private static class ListenerInfo implements ServiceListener
+    {
+        private Map<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> filterMap = new HashMap<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>>();
+
+        public void serviceChanged(ServiceEvent event)
+        {
+            ServiceReference<?> ref = event.getServiceReference();
+            ExtendedServiceEvent extEvent = null;
+            ExtendedServiceEvent endMatchEvent = null;
+            Map<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> filterMap;
+            synchronized (this)
+            {
+                filterMap = this.filterMap;
+            }
+            for (Map.Entry<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> entry : filterMap.entrySet())
+            {
+                Filter filter = entry.getKey();
+                if (filter == null || filter.match(ref))
+                {
+                    if (extEvent == null)
+                    {
+                        extEvent = new ExtendedServiceEvent(event);
+                    }
+                    for (ExtendedServiceListener<ExtendedServiceEvent> forwardTo : entry.getValue())
+                    {
+                        forwardTo.serviceChanged(extEvent);
+                    }
+                }
+                else if (event.getType() == ServiceEvent.MODIFIED)
+                {
+                    if (endMatchEvent == null)
+                    {
+                        endMatchEvent = new ExtendedServiceEvent(
+                            ServiceEvent.MODIFIED_ENDMATCH, ref);
+                    }
+                    for (ExtendedServiceListener<ExtendedServiceEvent> forwardTo : entry.getValue())
+                    {
+                        forwardTo.serviceChanged(endMatchEvent);
+                    }
+                }
+            }
+            if (extEvent != null)
+            {
+                extEvent.activateManagers();
+            }
+            if (endMatchEvent != null)
+            {
+                endMatchEvent.activateManagers();
+            }
+        }
+
+        public synchronized void add(Filter filter,
+            ExtendedServiceListener<ExtendedServiceEvent> listener)
+        {
+            filterMap = new HashMap<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>>(
+                filterMap);
+            List<ExtendedServiceListener<ExtendedServiceEvent>> listeners = filterMap.get(filter);
+            if (listeners == null)
+            {
+                listeners = Collections.<ExtendedServiceListener<ExtendedServiceEvent>> singletonList(listener);
+            }
+            else
+            {
+                listeners = new ArrayList<ExtendedServiceListener<ExtendedServiceEvent>>(
+                    listeners);
+                listeners.add(listener);
+            }
+            filterMap.put(filter, listeners);
+        }
+
+        public synchronized boolean remove(Filter filter,
+            ExtendedServiceListener<ExtendedServiceEvent> listener)
+        {
+            List<ExtendedServiceListener<ExtendedServiceEvent>> listeners = filterMap.get(filter);
+            if (listeners != null)
+            {
+                filterMap = new HashMap<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>>(
+                    filterMap);
+                listeners = new ArrayList<ExtendedServiceListener<ExtendedServiceEvent>>(
+                    listeners);
+                listeners.remove(listener);
+                if (listeners.isEmpty())
+                {
+                    filterMap.remove(filter);
+                }
+                else
+                {
+                    filterMap.put(filter, listeners);
+                }
+            }
+            return filterMap.isEmpty();
+        }
+    }
+
+    public void addServiceListener(String classNameFilter, Filter eventFilter,
+        ExtendedServiceListener<ExtendedServiceEvent> listener)
+    {
+        ListenerInfo listenerInfo;
+        synchronized (listenerMap)
+        {
+            log(LogService.LOG_DEBUG, "classNameFilter: " + classNameFilter
+                + " event filter: " + eventFilter, null, null, null);
+            listenerInfo = listenerMap.get(classNameFilter);
+            if (listenerInfo == null)
+            {
+                listenerInfo = new ListenerInfo();
+                listenerMap.put(classNameFilter, listenerInfo);
+                try
+                {
+                    m_context.addServiceListener(listenerInfo, classNameFilter);
+                }
+                catch (InvalidSyntaxException e)
+                {
+                    throw (IllegalArgumentException) new IllegalArgumentException(
+                        "invalid class name filter").initCause(e);
+                }
+            }
+        }
+        listenerInfo.add(eventFilter, listener);
+    }
+
+    public void removeServiceListener(String className, Filter filter,
+        ExtendedServiceListener<ExtendedServiceEvent> listener)
+    {
+        synchronized (listenerMap)
+        {
+            ListenerInfo listenerInfo = listenerMap.get(className);
+            if (listenerInfo != null)
+            {
+                if (listenerInfo.remove(filter, listener))
+                {
+                    listenerMap.remove(className);
+                    m_context.removeServiceListener(listenerInfo);
+                }
+            }
+        }
+    }
 
     /**
      * Called upon starting of the bundle. This method invokes initialize() which
-     * parses the metadata and creates the instance managers
+     * parses the metadata and creates the holders
      *
      * @param componentRegistry The <code>ComponentRegistry</code> used to
      *      register components with to ensure uniqueness of component names
@@ -94,8 +241,7 @@ public class BundleComponentActivator im
      *
      * @throws ComponentException if any error occurrs initializing this class
      */
-    BundleComponentActivator( ComponentRegistry componentRegistry,
-        ComponentActorThread componentActor, BundleContext context, ScrConfiguration configuration ) throws ComponentException
+    BundleComponentActivator(ComponentRegistry componentRegistry, ComponentActorThread componentActor, BundleContext context, ScrConfiguration configuration) throws ComponentException
     {
         // keep the parameters for later
         m_componentRegistry = componentRegistry;
@@ -104,24 +250,26 @@ public class BundleComponentActivator im
         m_bundle = context.getBundle();
 
         // have the LogService handy (if available)
-        m_logService = new ServiceTracker<LogService, LogService>( context, Activator.LOGSERVICE_CLASS, null );
+        m_logService = new ServiceTracker<LogService, LogService>(context,
+            Activator.LOGSERVICE_CLASS, null);
         m_logService.open();
         m_configuration = configuration;
 
-        log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] active",
-                new Object[] {m_bundle.getBundleId()}, null, null, null );
+        log(LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] active",
+            new Object[] { m_bundle.getBundleId() }, null, null, null);
 
         // Get the Metadata-Location value from the manifest
-        String descriptorLocations = ( String ) m_bundle.getHeaders().get( "Service-Component" );
-        if ( descriptorLocations == null )
+        String descriptorLocations = (String) m_bundle.getHeaders().get(
+            "Service-Component");
+        if (descriptorLocations == null)
         {
-            throw new ComponentException( "Service-Component entry not found in the manifest" );
+            throw new ComponentException(
+                "Service-Component entry not found in the manifest");
         }
 
-        initialize( descriptorLocations );
+        initialize(descriptorLocations);
     }
 
-
     /**
      * Gets the MetaData location, parses the meta data and requests the processing
      * of binder instances
@@ -131,37 +279,38 @@ public class BundleComponentActivator im
      *
      * @throws IllegalStateException If the bundle has already been uninstalled.
      */
-    private void initialize( String descriptorLocations )
+    private void initialize(String descriptorLocations)
     {
-        log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] descriptor locations {1}",
-                new Object[] {m_bundle.getBundleId(), descriptorLocations}, null, null, null );
+        log(LogService.LOG_DEBUG,
+            "BundleComponentActivator : Bundle [{0}] descriptor locations {1}",
+            new Object[] { m_bundle.getBundleId(), descriptorLocations }, null, null,
+            null);
 
         // 112.4.1: The value of the the header is a comma separated list of XML entries within the Bundle
-        StringTokenizer st = new StringTokenizer( descriptorLocations, ", " );
+        StringTokenizer st = new StringTokenizer(descriptorLocations, ", ");
 
-        while ( st.hasMoreTokens() )
+        while (st.hasMoreTokens())
         {
             String descriptorLocation = st.nextToken();
 
-            URL[] descriptorURLs = findDescriptors( m_bundle, descriptorLocation );
-            if ( descriptorURLs.length == 0 )
+            URL[] descriptorURLs = findDescriptors(m_bundle, descriptorLocation);
+            if (descriptorURLs.length == 0)
             {
                 // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
                 // fragments, SCR must log an error message with the Log Service, if present, and continue.
-                log( LogService.LOG_ERROR, "Component descriptor entry ''{0}'' not found", new Object[]
-                    { descriptorLocation }, null, null, null );
+                log(LogService.LOG_ERROR, "Component descriptor entry ''{0}'' not found",
+                    new Object[] { descriptorLocation }, null, null, null);
                 continue;
             }
 
             // load from the descriptors
-            for ( URL descriptorURL : descriptorURLs )
+            for (URL descriptorURL : descriptorURLs)
             {
-                loadDescriptor( descriptorURL );
+                loadDescriptor(descriptorURL);
             }
         }
     }
 
-
     /**
      * Called outside the constructor so that the m_managers field is completely initialized.
      * A component might possibly start a thread to enable other components, which could access m_managers
@@ -169,21 +318,27 @@ public class BundleComponentActivator im
     void initialEnable()
     {
         //enable all the enabled components
-        for ( ComponentHolder<?> componentHolder : m_managers )
+        for (ComponentHolder<?> componentHolder : m_managers)
         {
-            log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] May enable component holder {1}",
-                    new Object[] {m_bundle.getBundleId(), componentHolder.getComponentMetadata().getName()}, null, null, null );
-
-            if ( componentHolder.getComponentMetadata().isEnabled() )
-            {
-                log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] Enabling component holder {1}",
-                        new Object[] {m_bundle.getBundleId(), componentHolder.getComponentMetadata().getName()}, null, null, null );
+            log(LogService.LOG_DEBUG,
+                "BundleComponentActivator : Bundle [{0}] May enable component holder {1}",
+                new Object[] { m_bundle.getBundleId(),
+                        componentHolder.getComponentMetadata().getName() }, null, null,
+                null);
+
+            if (componentHolder.getComponentMetadata().isEnabled())
+            {
+                log(LogService.LOG_DEBUG,
+                    "BundleComponentActivator : Bundle [{0}] Enabling component holder {1}",
+                    new Object[] { m_bundle.getBundleId(),
+                            componentHolder.getComponentMetadata().getName() }, null,
+                    null, null);
 
                 try
                 {
-                    componentHolder.enableComponents( false );
+                    componentHolder.enableComponents(false);
                 }
-                catch ( Throwable t )
+                catch (Throwable t)
                 {
                     // caught on unhandled RuntimeException or Error
                     // (e.g. ClassDefNotFoundError)
@@ -191,26 +346,30 @@ public class BundleComponentActivator im
                     // make sure the component is properly disabled, just in case
                     try
                     {
-                        componentHolder.disableComponents( false );
+                        componentHolder.disableComponents(false);
                     }
-                    catch ( Throwable ignore )
+                    catch (Throwable ignore)
                     {
                     }
 
-                    log( LogService.LOG_ERROR,
+                    log(LogService.LOG_ERROR,
                         "BundleComponentActivator : Bundle [{0}] Unexpected failure enabling component holder {1}",
-                        new Object[] { m_bundle.getBundleId(), componentHolder.getComponentMetadata().getName() }, null, null, t );
+                        new Object[] { m_bundle.getBundleId(),
+                                componentHolder.getComponentMetadata().getName() }, null,
+                        null, t);
                 }
             }
             else
             {
-                log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] Will not enable component holder {1}",
-                        new Object[] {m_bundle.getBundleId(), componentHolder.getComponentMetadata().getName()}, null, null, null );
+                log(LogService.LOG_DEBUG,
+                    "BundleComponentActivator : Bundle [{0}] Will not enable component holder {1}",
+                    new Object[] { m_bundle.getBundleId(),
+                            componentHolder.getComponentMetadata().getName() }, null,
+                    null, null);
             }
         }
     }
 
-
     /**
      * Finds component descriptors based on descriptor location.
      *
@@ -218,21 +377,22 @@ public class BundleComponentActivator im
      * @param descriptorLocation descriptor location
      * @return array of descriptors or empty array if none found
      */
-    static URL[] findDescriptors( final Bundle bundle, final String descriptorLocation )
+    static URL[] findDescriptors(final Bundle bundle, final String descriptorLocation)
     {
-        if ( bundle == null || descriptorLocation == null || descriptorLocation.trim().length() == 0 )
+        if (bundle == null || descriptorLocation == null
+            || descriptorLocation.trim().length() == 0)
         {
             return new URL[0];
         }
 
         // split pattern and path
-        final int lios = descriptorLocation.lastIndexOf( "/" );
+        final int lios = descriptorLocation.lastIndexOf("/");
         final String path;
         final String filePattern;
-        if ( lios > 0 )
+        if (lios > 0)
         {
-            path = descriptorLocation.substring( 0, lios );
-            filePattern = descriptorLocation.substring( lios + 1 );
+            path = descriptorLocation.substring(0, lios);
+            filePattern = descriptorLocation.substring(lios + 1);
         }
         else
         {
@@ -241,23 +401,22 @@ public class BundleComponentActivator im
         }
 
         // find the entries
-        final Enumeration<URL> entries = bundle.findEntries( path, filePattern, false );
-        if ( entries == null || !entries.hasMoreElements() )
+        final Enumeration<URL> entries = bundle.findEntries(path, filePattern, false);
+        if (entries == null || !entries.hasMoreElements())
         {
             return new URL[0];
         }
 
         // create the result list
         List<URL> urls = new ArrayList<URL>();
-        while ( entries.hasMoreElements() )
+        while (entries.hasMoreElements())
         {
-            urls.add( entries.nextElement() );
+            urls.add(entries.nextElement());
         }
-        return urls.toArray( new URL[urls.size()] );
+        return urls.toArray(new URL[urls.size()]);
     }
 
-
-    private void loadDescriptor( final URL descriptorURL )
+    private void loadDescriptor(final URL descriptorURL)
     {
         // simple path for log messages
         final String descriptorLocation = descriptorURL.getPath();
@@ -267,117 +426,125 @@ public class BundleComponentActivator im
         {
             stream = descriptorURL.openStream();
 
-            BufferedReader in = new BufferedReader( new InputStreamReader( stream, "UTF-8" ) );
-            XmlHandler handler = new XmlHandler( m_bundle, this, getConfiguration().isFactoryEnabled(), getConfiguration().keepInstances() );
+            BufferedReader in = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
+            XmlHandler handler = new XmlHandler(m_bundle, this,
+                getConfiguration().isFactoryEnabled(), getConfiguration().keepInstances());
             KXml2SAXParser parser;
 
-            parser = new KXml2SAXParser( in );
+            parser = new KXml2SAXParser(in);
 
-            parser.parseXML( handler );
+            parser.parseXML(handler);
 
             // 112.4.2 Component descriptors may contain a single, root component element
             // or one or more component elements embedded in a larger document
-            for ( Object o : handler.getComponentMetadataList() )
+            for (Object o : handler.getComponentMetadataList())
             {
-                ComponentMetadata metadata = ( ComponentMetadata ) o;
+                ComponentMetadata metadata = (ComponentMetadata) o;
                 ComponentRegistryKey key = null;
                 try
                 {
                     // check and reserve the component name (if not null)
-                    if ( metadata.getName() != null )
+                    if (metadata.getName() != null)
                     {
-                        key = m_componentRegistry.checkComponentName( m_bundle, metadata.getName() );
+                        key = m_componentRegistry.checkComponentName(m_bundle,
+                            metadata.getName());
                     }
 
                     // validate the component metadata
-                    metadata.validate( this );
+                    metadata.validate(this);
 
                     // Request creation of the component manager
-                    ComponentHolder<?> holder = m_componentRegistry.createComponentHolder( this, metadata );
+                    ComponentHolder<?> holder = m_componentRegistry.createComponentHolder(
+                        this, metadata);
 
                     // register the component after validation
-                    m_componentRegistry.registerComponentHolder( key, holder );
-                    m_managers.add( holder );
+                    m_componentRegistry.registerComponentHolder(key, holder);
+                    m_managers.add(holder);
 
-                    log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] ComponentHolder created for {1}",
-                            new Object[] {m_bundle.getBundleId(), metadata.getName()}, null, null, null );
+                    log(LogService.LOG_DEBUG,
+                        "BundleComponentActivator : Bundle [{0}] ComponentHolder created for {1}",
+                        new Object[] { m_bundle.getBundleId(), metadata.getName() },
+                        null, null, null);
 
                 }
-                catch ( Throwable t )
+                catch (Throwable t)
                 {
                     // There is a problem with this particular component, we'll log the error
                     // and proceed to the next one
-                    log( LogService.LOG_ERROR, "Cannot register Component", metadata, null, t );
+                    log(LogService.LOG_ERROR, "Cannot register Component", metadata,
+                        null, t);
 
                     // make sure the name is not reserved any more
-                    if ( key != null )
+                    if (key != null)
                     {
-                        m_componentRegistry.unregisterComponentHolder( key );
+                        m_componentRegistry.unregisterComponentHolder(key);
                     }
                 }
             }
         }
-        catch ( IOException ex )
+        catch (IOException ex)
         {
             // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
             // fragments, SCR must log an error message with the Log Service, if present, and continue.
 
-            log( LogService.LOG_ERROR, "Problem reading descriptor entry ''{0}''", new Object[]
-                { descriptorLocation }, null, null, ex );
+            log(LogService.LOG_ERROR, "Problem reading descriptor entry ''{0}''",
+                new Object[] { descriptorLocation }, null, null, ex);
         }
-        catch ( Exception ex )
+        catch (Exception ex)
         {
-            log( LogService.LOG_ERROR, "General problem with descriptor entry ''{0}''", new Object[]
-                { descriptorLocation }, null, null, ex );
+            log(LogService.LOG_ERROR, "General problem with descriptor entry ''{0}''",
+                new Object[] { descriptorLocation }, null, null, ex);
         }
         finally
         {
-            if ( stream != null )
+            if (stream != null)
             {
                 try
                 {
                     stream.close();
                 }
-                catch ( IOException ignore )
+                catch (IOException ignore)
                 {
                 }
             }
         }
     }
 
-
     /**
     * Dispose of this component activator instance and all the component
     * managers.
     */
-    void dispose( int reason )
+    void dispose(int reason)
     {
-        if ( m_active.compareAndSet( true, false ))
+        if (m_active.compareAndSet(true, false))
         {
-            log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] will destroy {1} instances", new Object[]
-                    { m_bundle.getBundleId(), m_managers.size() }, null, null, null );
+            log(LogService.LOG_DEBUG,
+                "BundleComponentActivator : Bundle [{0}] will destroy {1} instances",
+                new Object[] { m_bundle.getBundleId(), m_managers.size() }, null, null,
+                null);
 
-            for (ComponentHolder<?> holder: m_managers )
+            for (ComponentHolder<?> holder : m_managers)
             {
                 try
                 {
-                    holder.disposeComponents( reason );
+                    holder.disposeComponents(reason);
                 }
-                catch ( Exception e )
+                catch (Exception e)
                 {
-                    log( LogService.LOG_ERROR, "BundleComponentActivator : Exception invalidating", holder
-                            .getComponentMetadata(), null, e );
+                    log(LogService.LOG_ERROR,
+                        "BundleComponentActivator : Exception invalidating",
+                        holder.getComponentMetadata(), null, e);
                 }
                 finally
                 {
-                    m_componentRegistry.unregisterComponentHolder( m_bundle, holder.getComponentMetadata()
-                            .getName() );
+                    m_componentRegistry.unregisterComponentHolder(m_bundle,
+                        holder.getComponentMetadata().getName());
                 }
 
             }
 
-            log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] STOPPED", new Object[]
-                    {m_bundle.getBundleId()}, null, null, null );
+            log(LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [{0}] STOPPED",
+                new Object[] { m_bundle.getBundleId() }, null, null, null);
 
             m_logService.close();
             m_closeLatch.countDown();
@@ -388,7 +555,7 @@ public class BundleComponentActivator im
             {
                 m_closeLatch.await(m_configuration.lockTimeout(), TimeUnit.MILLISECONDS);
             }
-            catch ( InterruptedException e )
+            catch (InterruptedException e)
             {
                 //ignore interruption during concurrent shutdown.
             }
@@ -396,7 +563,6 @@ public class BundleComponentActivator im
 
     }
 
-
     /**
      * Returns <true> if this instance is active, that is if components
      * may be activated for this component. The active flag is set early
@@ -409,7 +575,6 @@ public class BundleComponentActivator im
         return m_active.get();
     }
 
-
     /**
     * Returns the BundleContext
     *
@@ -420,13 +585,11 @@ public class BundleComponentActivator im
         return m_context;
     }
 
-
     public ScrConfiguration getConfiguration()
     {
         return m_configuration;
     }
 
-
     /**
      * Implements the <code>ComponentContext.enableComponent(String)</code>
      * method by first finding the component(s) for the <code>name</code> and
@@ -436,24 +599,25 @@ public class BundleComponentActivator im
      * @param name The name of the component to enable or <code>null</code> to
      *      enable all components.
      */
-    public void enableComponent( final String name )
+    public void enableComponent(final String name)
     {
-        final List<ComponentHolder<?>> holder = getSelectedComponents( name );
-        for ( ComponentHolder<?> aHolder : holder )
+        final List<ComponentHolder<?>> holder = getSelectedComponents(name);
+        for (ComponentHolder<?> aHolder : holder)
         {
             try
             {
-                log( LogService.LOG_DEBUG, "Enabling Component", aHolder.getComponentMetadata(), null, null );
-                aHolder.enableComponents( true );
+                log(LogService.LOG_DEBUG, "Enabling Component",
+                    aHolder.getComponentMetadata(), null, null);
+                aHolder.enableComponents(true);
             }
-            catch ( Throwable t )
+            catch (Throwable t)
             {
-                log( LogService.LOG_ERROR, "Cannot enable component", aHolder.getComponentMetadata(), null, t );
+                log(LogService.LOG_ERROR, "Cannot enable component",
+                    aHolder.getComponentMetadata(), null, t);
             }
         }
     }
 
-
     /**
      * Implements the <code>ComponentContext.disableComponent(String)</code>
      * method by first finding the component(s) for the <code>name</code> and
@@ -463,24 +627,25 @@ public class BundleComponentActivator im
      * @param name The name of the component to disable or <code>null</code> to
      *      disable all components.
      */
-    public void disableComponent( final String name )
+    public void disableComponent(final String name)
     {
-        final List<ComponentHolder<?>> holder = getSelectedComponents( name );
-        for ( ComponentHolder<?> aHolder : holder )
+        final List<ComponentHolder<?>> holder = getSelectedComponents(name);
+        for (ComponentHolder<?> aHolder : holder)
         {
             try
             {
-                log( LogService.LOG_DEBUG, "Disabling Component", aHolder.getComponentMetadata(), null, null );
-                aHolder.disableComponents( true );
+                log(LogService.LOG_DEBUG, "Disabling Component",
+                    aHolder.getComponentMetadata(), null, null);
+                aHolder.disableComponents(true);
             }
-            catch ( Throwable t )
+            catch (Throwable t)
             {
-                log( LogService.LOG_ERROR, "Cannot disable component", aHolder.getComponentMetadata(), null, t );
+                log(LogService.LOG_ERROR, "Cannot disable component",
+                    aHolder.getComponentMetadata(), null, t);
             }
         }
     }
 
-
     /**
      * Returns an array of {@link ComponentHolder} instances which match the
      * <code>name</code>. If the <code>name</code> is <code>null</code> an
@@ -496,32 +661,34 @@ public class BundleComponentActivator im
      *      to the <code>name</code> parameter or <code>null</code> if no
      *      component manager with the given name is currently registered.
      */
-    private List<ComponentHolder<?>> getSelectedComponents( String name )
+    private List<ComponentHolder<?>> getSelectedComponents(String name)
     {
         // if all components are selected
-        if ( name == null )
+        if (name == null)
         {
             return m_managers;
         }
 
-        ComponentHolder<?> componentHolder = m_componentRegistry.getComponentHolder( m_bundle, name );
+        ComponentHolder<?> componentHolder = m_componentRegistry.getComponentHolder(
+            m_bundle, name);
         if (componentHolder != null)
         {
-            return Collections.<ComponentHolder<?>>singletonList( componentHolder );
+            return Collections.<ComponentHolder<?>> singletonList(componentHolder);
         }
 
         // if the component is not known
         return Collections.emptyList();
     }
 
-
     //---------- Component ID support
 
-    public long registerComponentId(AbstractComponentManager<?> componentManager) {
+    public long registerComponentId(AbstractComponentManager<?> componentManager)
+    {
         return m_componentRegistry.registerComponentId(componentManager);
     }
 
-    public void unregisterComponentId(AbstractComponentManager<?> componentManager) {
+    public void unregisterComponentId(AbstractComponentManager<?> componentManager)
+    {
         m_componentRegistry.unregisterComponentId(componentManager.getId());
     }
 
@@ -534,48 +701,50 @@ public class BundleComponentActivator im
      *
      * @param task The component task to execute
      */
-    public void schedule( Runnable task )
+    public void schedule(Runnable task)
     {
-        if ( isActive() )
+        if (isActive())
         {
             ComponentActorThread cat = m_componentActor;
-            if ( cat != null )
+            if (cat != null)
             {
-                cat.schedule( task );
+                cat.schedule(task);
             }
             else
             {
-                log( LogService.LOG_DEBUG, "Component Actor Thread not running, calling synchronously", null, null, null );
+                log(LogService.LOG_DEBUG,
+                    "Component Actor Thread not running, calling synchronously", null,
+                    null, null);
                 try
                 {
-                    synchronized ( this )
+                    synchronized (this)
                     {
                         task.run();
                     }
                 }
-                catch ( Throwable t )
+                catch (Throwable t)
                 {
-                    log( LogService.LOG_WARNING, "Unexpected problem executing task", null, null, t );
+                    log(LogService.LOG_WARNING, "Unexpected problem executing task",
+                        null, null, t);
                 }
             }
         }
         else
         {
-            log( LogService.LOG_WARNING, "BundleComponentActivator is not active; not scheduling {0}", new Object[]
-                { task }, null, null, null );
+            log(LogService.LOG_WARNING,
+                "BundleComponentActivator is not active; not scheduling {0}",
+                new Object[] { task }, null, null, null);
         }
     }
 
-
     /**
      * Returns <code>true</code> if logging for the given level is enabled.
      */
-    public boolean isLogEnabled( int level )
+    public boolean isLogEnabled(int level)
     {
         return m_configuration.getLogLevel() >= level;
     }
 
-
     /**
      * Method to actually emit the log message. If the LogService is available,
      * the message will be logged through the LogService. Otherwise the message
@@ -585,20 +754,20 @@ public class BundleComponentActivator im
      * @param pattern The <code>java.text.MessageFormat</code> message format
      *      string for preparing the message
      * @param arguments The format arguments for the <code>pattern</code>
- *      string.
+    *      string.
      * @param componentId
      * @param ex An optional <code>Throwable</code> whose stack trace is written,
      */
-    public void log( int level, String pattern, Object[] arguments, ComponentMetadata metadata, Long componentId, Throwable ex )
+    public void log(int level, String pattern, Object[] arguments,
+        ComponentMetadata metadata, Long componentId, Throwable ex)
     {
-        if ( isLogEnabled( level ) )
+        if (isLogEnabled(level))
         {
-            final String message = MessageFormat.format( pattern, arguments );
-            log( level, message, metadata, componentId, ex );
+            final String message = MessageFormat.format(pattern, arguments);
+            log(level, message, metadata, componentId, ex);
         }
     }
 
-
     /**
      * Method to actually emit the log message. If the LogService is available,
      * the message will be logged through the LogService. Otherwise the message
@@ -609,16 +778,18 @@ public class BundleComponentActivator im
      * @param componentId
      * @param ex An optional <code>Throwable</code> whose stack trace is written,
      */
-    public void log( int level, String message, ComponentMetadata metadata, Long componentId, Throwable ex )
+    public void log(int level, String message, ComponentMetadata metadata,
+        Long componentId, Throwable ex)
     {
-        if ( isLogEnabled( level ) )
+        if (isLogEnabled(level))
         {
             // prepend the metadata name to the message
-            if ( metadata != null )
+            if (metadata != null)
             {
-                if ( componentId != null )
+                if (componentId != null)
                 {
-                    message = "[" + metadata.getName() + "(" + componentId + ")] " + message;
+                    message = "[" + metadata.getName() + "(" + componentId + ")] "
+                        + message;
                 }
                 else
                 {
@@ -627,33 +798,35 @@ public class BundleComponentActivator im
             }
 
             ServiceTracker<LogService, LogService> logService = m_logService;
-            if ( logService != null )
+            if (logService != null)
             {
                 LogService logger = logService.getService();
-                if ( logger == null )
+                if (logger == null)
                 {
-                    Activator.log( level, m_bundle, message, ex );
+                    Activator.log(level, m_bundle, message, ex);
                 }
                 else
                 {
-                    logger.log( level, message, ex );
+                    logger.log(level, message, ex);
                 }
             }
             else
             {
                 // BCA has been disposed off, bundle context is probably invalid. Try to log something.
-                Activator.log( level, null, message, ex );
+                Activator.log(level, null, message, ex);
             }
         }
     }
 
-    public void missingServicePresent( ServiceReference<?> serviceReference )
+    public void missingServicePresent(ServiceReference<?> serviceReference)
     {
-        m_componentRegistry.missingServicePresent( serviceReference, m_componentActor );
+        m_componentRegistry.missingServicePresent(serviceReference, m_componentActor);
     }
 
-    public <T> void registerMissingDependency( DependencyManager<?, T> dependencyManager, ServiceReference<T> serviceReference, int trackingCount )
+    public <T> void registerMissingDependency(DependencyManager<?, T> dependencyManager,
+        ServiceReference<T> serviceReference, int trackingCount)
     {
-        m_componentRegistry.registerMissingDependency(dependencyManager, serviceReference, trackingCount );
+        m_componentRegistry.registerMissingDependency(dependencyManager,
+            serviceReference, trackingCount);
     }
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1691760&r1=1691759&r2=1691760&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Sat Jul 18 18:12:45 2015
@@ -74,14 +74,11 @@ public class DependencyManager<S, T> imp
     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,7 +253,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 )
         {
             if ( cardinalityJustSatisfied( serviceCount ) )
             {
@@ -264,11 +261,11 @@ 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 )
         {
         }
 
-        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.markDeleted();
             if ( !cardinalitySatisfied( getTracker().getServiceCount() ) )
@@ -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;
@@ -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,7 +352,7 @@ 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.markDeleted();
@@ -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,7 +446,11 @@ 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( );
+                //event may be null during initial operations.
+                if (event != null)
+                {
+                    event.addComponentManager(m_componentManager);
+                }
 
             }
             else if ( isTrackerOpened() && cardinalityJustSatisfied( serviceCount ) )
@@ -459,7 +460,7 @@ public class DependencyManager<S, T> imp
             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;
@@ -471,12 +472,15 @@ public class DependencyManager<S, T> imp
             if ( reactivate )
             {
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
-                m_componentManager.activateInternal( );
+                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.markDeleted();
@@ -489,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( );
+                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
             {
@@ -507,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())
             {
@@ -536,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();
             }
@@ -555,7 +562,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} MultipleStaticReluctant added {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
             tracked( trackingCount );
@@ -566,7 +573,7 @@ public class DependencyManager<S, T> imp
             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;
@@ -579,12 +586,15 @@ public class DependencyManager<S, T> imp
             if ( reactivate )
             {
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
-                m_componentManager.activateInternal( );
+                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.markDeleted();
@@ -601,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( );
+                    if (event != null)
+                    {
+                        event.addComponentManager(m_componentManager);
+                    }
 
                 }
             }
@@ -695,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;
@@ -744,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;
@@ -761,7 +774,7 @@ 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.markDeleted();
@@ -907,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;
@@ -922,7 +935,10 @@ public class DependencyManager<S, T> imp
                 if ( reactivate )
                 {
                     m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
-                    m_componentManager.activateInternal( );
+                    if (event != null)
+                    {
+                        event.addComponentManager(m_componentManager);
+                    }
                 }
                 else
                 {
@@ -940,7 +956,7 @@ 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;
@@ -966,12 +982,15 @@ public class DependencyManager<S, T> imp
                         this.refPair = null;
                     }
                 }
-                m_componentManager.activateInternal( );
+                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.markDeleted();
@@ -996,7 +1015,10 @@ public class DependencyManager<S, T> imp
                         this.refPair = null;
                     }
                 }
-                m_componentManager.activateInternal( );
+                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 );
         }
@@ -1032,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;
@@ -1089,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 )
         {
         }
 
@@ -1106,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 )
         {
         }
     }
@@ -1316,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( );
@@ -1873,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
@@ -1904,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 )
@@ -1949,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
+            if ( eventFilterString != null )
             {
-                m_targetFilter = bundleContext.createFilter( filterString );
-            }
-            catch ( InvalidSyntaxException ise )
-            {
-                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
@@ -1983,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;
@@ -2048,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/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java?rev=1691760&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java Sat Jul 18 18:12:45 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

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceEvent.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java (from r1691622, felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java)
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java?p2=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java&p1=felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java&r1=1691622&r2=1691760&rev=1691760&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListener.java Sat Jul 18 18:12:45 2015
@@ -16,29 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scr.integration.components.deadlock;
+package org.apache.felix.scr.impl.manager;
 
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.framework.ServiceEvent;
 
-public class Consumer
+public interface ExtendedServiceListener<U extends ServiceEvent>
 {
-    
-    private ComponentContext cc;
-    
-    protected void activate(ComponentContext cc) 
-    {
-        this.cc = cc;
-    }
-    
-    protected void setSimpleComponent(TestComponent sc)
-    {
-        sc.doIt( );       
-    }
-    
-    protected void unsetSimpleComponent(ServiceReference<TestComponent> sr)
-    {
-        
-    }    
-
+    void serviceChanged(U event);
 }

Copied: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java (from r1691622, felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java)
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java?p2=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java&p1=felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java&r1=1691622&r2=1691760&rev=1691760&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/deadlock/Consumer.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ExtendedServiceListenerContext.java Sat Jul 18 18:12:45 2015
@@ -16,29 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scr.integration.components.deadlock;
+package org.apache.felix.scr.impl.manager;
 
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceEvent;
 
-public class Consumer
+public interface ExtendedServiceListenerContext<U extends ServiceEvent>
 {
-    
-    private ComponentContext cc;
-    
-    protected void activate(ComponentContext cc) 
-    {
-        this.cc = cc;
-    }
-    
-    protected void setSimpleComponent(TestComponent sc)
-    {
-        sc.doIt( );       
-    }
-    
-    protected void unsetSimpleComponent(ServiceReference<TestComponent> sr)
-    {
-        
-    }    
 
+    void addServiceListener(String className, Filter filter,
+        ExtendedServiceListener<U> listener);
+
+    void removeServiceListener(String className, Filter filter,
+        ExtendedServiceListener<U> listener);
 }



Mime
View raw message