You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2015/02/04 13:45:46 UTC

svn commit: r1657173 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/config/ main/java/org/apache/felix/scr/impl/helper/ main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/impl/helper/

Author: cziegeler
Date: Wed Feb  4 12:45:45 2015
New Revision: 1657173

URL: http://svn.apache.org/r1657173
Log:
FELIX-4769 : [RFC190/212] Implement ComponentServiceObjects

Added:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java   (with props)
Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java Wed Feb  4 12:45:45 2015
@@ -22,7 +22,6 @@ package org.apache.felix.scr.impl.config
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -38,8 +37,8 @@ import org.apache.felix.scr.impl.helper.
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
 import org.apache.felix.scr.impl.manager.ComponentFactoryImpl;
 import org.apache.felix.scr.impl.manager.PrototypeServiceFactoryComponentManager;
-import org.apache.felix.scr.impl.manager.SingleComponentManager;
 import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager;
+import org.apache.felix.scr.impl.manager.SingleComponentManager;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ServiceMetadata.Scope;
 import org.osgi.framework.Constants;
@@ -51,8 +50,8 @@ import org.osgi.util.promise.Promises;
 
 
 /**
- * The <code>ImmediateComponentHolder</code> class is a
- * {@link ComponentHolder} for automatically configured components instances 
+ * The <code>ConfigurableComponentHolder</code> class is a
+ * {@link ComponentHolder} for automatically configured components instances
  * that may or may not be configured through Config Admin.
  * <p>
  * The holder copes with three situations:
@@ -79,7 +78,7 @@ public class ConfigurableComponentHolder
      */
     private final ComponentMetadata m_componentMetadata;
 
-    /** the targeted pids corresponding to the pids specified in the config metadata, except possibly for the single 
+    /** the targeted pids corresponding to the pids specified in the config metadata, except possibly for the single
      * factory pid
      */
     private final TargetedPID[] m_targetedPids;
@@ -147,7 +146,7 @@ public class ConfigurableComponentHolder
     private Promise<Void> m_enablePromise;
     private Promise<Void> m_disablePromise = Promises.resolved(null);
 
-    private final ComponentMethods m_componentMethods;    
+    private final ComponentMethods m_componentMethods;
 
     public ConfigurableComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
     {
@@ -196,10 +195,10 @@ public class ConfigurableComponentHolder
 
         return manager;
     }
-    
-    private static class PSFLoader 
+
+    private static class PSFLoader
     {
-        static <S> AbstractComponentManager<S> newPSFComponentManager(ConfigurableComponentHolder<S> holder, ComponentMethods methods) 
+        static <S> AbstractComponentManager<S> newPSFComponentManager(ConfigurableComponentHolder<S> holder, ComponentMethods methods)
         {
             return new PrototypeServiceFactoryComponentManager<S>( holder, methods );
         }
@@ -310,7 +309,7 @@ public class ConfigurableComponentHolder
                     {
                         for (Map.Entry<String, AbstractComponentManager<S>> entry : m_components.entrySet()) {
                             scms.put(entry.getValue(), null );
-                        }	
+                        }
                         m_components.clear();
                     }
                 }
@@ -387,10 +386,10 @@ public class ConfigurableComponentHolder
                 if (m_enabled && isSatisfied()) {
                     if (m_singleComponent != null) {
                         scms.put( m_singleComponent, mergeProperties( pid.getServicePid() ) );
-                    } 
-                    else if ( m_factoryPidIndex != null) 
+                    }
+                    else if ( m_factoryPidIndex != null)
                     {
-                        for (Map.Entry<String, AbstractComponentManager<S>> entry: m_components.entrySet()) 
+                        for (Map.Entry<String, AbstractComponentManager<S>> entry: m_components.entrySet())
                         {
                             scms.put(entry.getValue(), mergeProperties( entry.getKey()));
                         }
@@ -497,7 +496,7 @@ public class ConfigurableComponentHolder
         return index;
     }
 
-    //TODO update error messages so they make sense for deleting config too. 
+    //TODO update error messages so they make sense for deleting config too.
     private void checkFactoryPidIndex(TargetedPID factoryPid) {
         int index = m_componentMetadata.getPidIndex(factoryPid);
         if (index == -1) {
@@ -545,7 +544,7 @@ public class ConfigurableComponentHolder
      * @return true if configuration optional or all pids supplied with configurations
      */
     private boolean isSatisfied() {
-        if ( m_componentMetadata.isConfigurationOptional() || m_componentMetadata.isConfigurationIgnored() ) 
+        if ( m_componentMetadata.isConfigurationOptional() || m_componentMetadata.isConfigurationIgnored() )
         {
             return true;
         }
@@ -628,7 +627,7 @@ public class ConfigurableComponentHolder
             Thread.currentThread().interrupt();
         }
     }
-    
+
     public Promise<Void> enableComponents( final boolean async )
     {
         synchronized (enableLock)
@@ -746,17 +745,18 @@ public class ConfigurableComponentHolder
 
     /**
      * Compares this {@code ImmediateComponentHolder} object to another object.
-     * 
+     *
      * <p>
-     * A ImmediateComponentHolder is considered to be <b>equal to </b> another 
-     * ImmediateComponentHolder if the component names are equal(using 
+     * A ImmediateComponentHolder is considered to be <b>equal to </b> another
+     * ImmediateComponentHolder if the component names are equal(using
      * {@code String.equals}) and they have the same bundle activator
-     * 
+     *
      * @param object The {@code ImmediateComponentHolder} object to be compared.
      * @return {@code true} if {@code object} is a
      *         {@code ImmediateComponentHolder} and is equal to this object;
      *         {@code false} otherwise.
      */
+    @Override
     public boolean equals(Object object)
     {
         if (!(object instanceof ConfigurableComponentHolder))
@@ -771,7 +771,7 @@ public class ConfigurableComponentHolder
 
     /**
      * Returns a hash code value for the object.
-     * 
+     *
      * @return An integer which is a hash code value for this object.
      */
     @Override
@@ -812,7 +812,7 @@ public class ConfigurableComponentHolder
         }
         return cms;
     }
-    
+
     List<AbstractComponentManager<S>> getDirectComponentManagers( )
     {
         List<AbstractComponentManager<S>> cms = new ArrayList<AbstractComponentManager<S>>();

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java Wed Feb  4 12:45:45 2015
@@ -125,7 +125,7 @@ implements org.apache.felix.scr.impl.hel
             suitableMethodNotAccessible = true;
         }
 
-        //case 2 ServiceObjects parameter
+        //case 2 ComponentServiceObjects parameter
         try
         {
             method = getServiceObjectsMethod( targetClass, acceptPrivate, acceptPackage, logger );
@@ -251,9 +251,9 @@ implements org.apache.felix.scr.impl.hel
                                     paramTypes.add(ParamType.serviceReference);
                                 }
                             }
-                            else if (paramType == ClassUtils.SERVICE_OBJECTS_CLASS)
+                            else if (paramType == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS)
                             {
-                                if (specialMatch && parameterClass == ClassUtils.SERVICE_OBJECTS_CLASS)
+                                if (specialMatch && parameterClass == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS)
                                 {
                                     specialMatch = false;
                                     paramTypes.add(ParamType.serviceType);
@@ -352,7 +352,7 @@ implements org.apache.felix.scr.impl.hel
         if ( m_referenceScope == ReferenceMetadata.ReferenceScope.prototype )
         {
             return getMethod(targetClass, getMethodName(),
-                new Class[] { ClassUtils.SERVICE_OBJECTS_CLASS }, acceptPrivate, acceptPackage,
+                new Class[] { ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS }, acceptPrivate, acceptPackage,
                 logger);
         }
         return null;
@@ -593,7 +593,7 @@ implements org.apache.felix.scr.impl.hel
                     break;
 
                 case serviceObjects:
-                    result[i++] = refPair.getServiceObjects();
+                    result[i++] = bp.getComponentContext().getComponentServiceObjectsHelper().getServiceObjects(refPair.getRef());
                     break;
 
                 case map:

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java Wed Feb  4 12:45:45 2015
@@ -24,8 +24,8 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.felix.scr.impl.Activator;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentServiceObjects;
 import org.osgi.service.log.LogService;
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
@@ -40,7 +40,8 @@ public class ClassUtils
     private static final Class<?> OBJECT_CLASS = Object.class;
 
     public static final Class<?> SERVICE_REFERENCE_CLASS = ServiceReference.class;
-    public static final Class<?> SERVICE_OBJECTS_CLASS;
+
+    public static final Class<?> COMPONENTS_SERVICE_OBJECTS_CLASS;
 
     public static final Class<?> MAP_CLASS = Map.class;
     public static final Class<?> MAP_ENTRY_CLASS = Map.Entry.class;
@@ -51,13 +52,13 @@ public class ClassUtils
     static {
         Class<?> serviceObjectsClass = null;
         try {
-            serviceObjectsClass = ServiceObjects.class;
+            serviceObjectsClass = ComponentServiceObjects.class;
         }
         catch (Throwable t)
         {
             //can't load class
         }
-        SERVICE_OBJECTS_CLASS = serviceObjectsClass;
+        COMPONENTS_SERVICE_OBJECTS_CLASS = serviceObjectsClass;
     }
 
     /**

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java?rev=1657173&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java Wed Feb  4 12:45:45 2015
@@ -0,0 +1,123 @@
+/*
+ * 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.helper;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentServiceObjects;
+
+
+/**
+ * Utility methods for class handling used by method and field references.
+ */
+public class ComponentServiceObjectsHelper
+{
+    private final BundleContext bundleContext;
+
+    private final Map<ServiceReference, ServiceObjects> serviceObjectsMap = new HashMap<ServiceReference, ServiceObjects>();
+
+    private final Map<ServiceObjects, List<Object>> services = new HashMap<ServiceObjects, List<Object>>();
+
+    public ComponentServiceObjectsHelper(final BundleContext bundleContext)
+    {
+        this.bundleContext = bundleContext;
+    }
+
+    public void cleanup()
+    {
+        synchronized ( this )
+        {
+            for(final Map.Entry<ServiceObjects, List<Object>> entry : services.entrySet())
+            {
+                for(final Object service : entry.getValue())
+                {
+                    entry.getKey().ungetService(service);
+                }
+            }
+            services.clear();
+            serviceObjectsMap.clear();
+        }
+    }
+
+    public ComponentServiceObjects getServiceObjects(final ServiceReference<?> ref)
+    {
+        synchronized ( this )
+        {
+            ServiceObjects<?> so = this.serviceObjectsMap.get(ref);
+            if ( so == null )
+            {
+                so = this.bundleContext.getServiceObjects(ref);
+                if ( so != null )
+                {
+                    this.serviceObjectsMap.put(ref, so);
+                }
+            }
+
+            if ( so != null )
+            {
+                List<Object> services = this.services.get(so);
+                if ( services == null )
+                {
+                    services = new ArrayList<Object>();
+                    this.services.put(so, services);
+                }
+                final ServiceObjects serviceObjects = so;
+                final List<Object> serviceList = services;
+
+                return new ComponentServiceObjects() {
+
+                    public Object getService() {
+                        final Object service = serviceObjects.getService();
+                        if ( service != null )
+                        {
+                            synchronized ( serviceList )
+                            {
+                                serviceList.add(service);
+                            }
+                        }
+                        return service;
+                    }
+
+                    public void ungetService(final Object service) {
+                        boolean remove;
+                        synchronized ( serviceList )
+                        {
+                            remove = serviceList.remove(service);
+                        }
+                        if ( remove ) {
+                            serviceObjects.ungetService(service);
+                        }
+                    }
+
+                    public ServiceReference<?> getServiceReference() {
+                        return ref;
+                    }
+                };
+            }
+        }
+        return null;
+    }
+}

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

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java Wed Feb  4 12:45:45 2015
@@ -285,7 +285,7 @@ public class FieldHandler
             {
                 valueType = ParamType.serviceReference;
             }
-            else if ( fieldType == ClassUtils.SERVICE_OBJECTS_CLASS )
+            else if ( fieldType == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS )
             {
                 valueType = ParamType.serviceObjects;
             }
@@ -452,7 +452,7 @@ public class FieldHandler
         {
             case serviceType : obj = refPair.getServiceObject(key); break;
             case serviceReference : obj = refPair.getRef(); break;
-            case serviceObjects : obj = refPair.getServiceObjects(); 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);

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Wed Feb  4 12:45:45 2015
@@ -31,7 +31,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
@@ -63,7 +62,6 @@ import org.osgi.service.component.Compon
 import org.osgi.service.log.LogService;
 import org.osgi.util.promise.Deferred;
 import org.osgi.util.promise.Promise;
-import org.osgi.util.promise.Promises;
 
 
 /**
@@ -81,7 +79,7 @@ public abstract class AbstractComponentM
         "Configuration deleted",
         "Component disabled",
         "Bundle stopped"};
-    
+
     protected final ComponentContainer<S> m_container;
 
     //true for normal spec factory instances. False for "persistent" factory instances and obsolete use of factory component with factory configurations.
@@ -99,21 +97,21 @@ public abstract class AbstractComponentM
     private final AtomicInteger m_trackingCount = new AtomicInteger( );
 
     // The ServiceRegistration is now tracked in the RegistrationManager
-    
+
     private final ReentrantLock m_stateLock;
 
     /**
-     * This latch prevents concurrent enable, disable, and reconfigure.  Since the enable and disable operations may use 
+     * This latch prevents concurrent enable, disable, and reconfigure.  Since the enable and disable operations may use
      * two threads and the initiating thread does not wait for the operation to complete, we can't use a regular lock.
      */
     private final AtomicReference< Deferred<Void>> m_enabledLatchRef = new AtomicReference<Deferred<Void>>( new Deferred<Void>() );
 
     protected volatile boolean m_internalEnabled;
-    
+
 	private volatile boolean m_satisfied;
-    
+
     protected volatile boolean m_disposed;
-    
+
     //service event tracking
     private int m_floor;
 
@@ -124,7 +122,7 @@ public abstract class AbstractComponentM
     private final Set<Integer> m_missing = new TreeSet<Integer>( );
 
     volatile boolean m_activated;
-    
+
     protected final ReentrantReadWriteLock m_activationLock = new ReentrantReadWriteLock();
 
     /**
@@ -137,7 +135,7 @@ public abstract class AbstractComponentM
     {
         this( container, componentMethods, false );
     }
-    
+
     protected AbstractComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods, boolean factoryInstance )
     {
         m_enabledLatchRef.get().resolve(null);
@@ -145,7 +143,7 @@ public abstract class AbstractComponentM
         m_container = container;
         m_componentMethods = componentMethods;
         m_componentId = -1;
-        
+
         ComponentMetadata metadata = container.getComponentMetadata();
 
         m_dependencyManagers = loadDependencyManagers( metadata );
@@ -219,7 +217,7 @@ public abstract class AbstractComponentM
             Thread.currentThread().interrupt();
         }
     }
-    
+
     final void obtainActivationReadLock( String source )
     {
         obtainLock( m_activationLock.readLock(), source);
@@ -229,7 +227,7 @@ public abstract class AbstractComponentM
     {
         m_activationLock.readLock().unlock();
     }
-    
+
     final void obtainActivationWriteLock( String source )
     {
         obtainLock( m_activationLock.writeLock(), source);
@@ -242,7 +240,7 @@ public abstract class AbstractComponentM
             m_activationLock.writeLock().unlock();
         }
     }
-    
+
     final void obtainStateLock( String source )
     {
         obtainLock( m_stateLock, source );
@@ -257,7 +255,7 @@ public abstract class AbstractComponentM
     {
         return m_stateLock.getHoldCount() > 0;
     }
-    
+
     final void dumpThreads()
     {
         try
@@ -303,7 +301,7 @@ public abstract class AbstractComponentM
     }
 
     /**
-     * We effectively maintain the set of completely processed service event tracking counts.  This method waits for all events prior 
+     * We effectively maintain the set of completely processed service event tracking counts.  This method waits for all events prior
      * to the parameter tracking count to complete, then returns.  See further documentation in EdgeInfo.
      * @param trackingCount
      */
@@ -320,7 +318,7 @@ public abstract class AbstractComponentM
                 {
                     if ( !doMissingWait())
                     {
-                        return;                        
+                        return;
                     }
                 }
                 catch ( InterruptedException e )
@@ -329,7 +327,7 @@ public abstract class AbstractComponentM
                     {
                         if ( !doMissingWait())
                         {
-                            return;                        
+                            return;
                         }
                     }
                     catch ( InterruptedException e1 )
@@ -346,7 +344,7 @@ public abstract class AbstractComponentM
             m_missingLock.unlock();
         }
     }
-    
+
     private boolean doMissingWait() throws InterruptedException
     {
         if ( !m_missingCondition.await( getLockTimeout(), TimeUnit.MILLISECONDS ))
@@ -429,6 +427,7 @@ public abstract class AbstractComponentM
                     }
                 }
 
+                @Override
                 public String toString()
                 {
                     return "Async Activate: " + getComponentMetadata().getName() + " id: " + count;
@@ -441,7 +440,7 @@ public abstract class AbstractComponentM
     /**
      * Use a CountDownLatch as a non-reentrant "lock" that can be passed between threads.
      * This lock assures that enable, disable, and reconfigure operations do not overlap.
-     * 
+     *
      * @return the latch to count down when the operation is complete (in the calling or another thread)
      * @throws InterruptedException
      */
@@ -477,7 +476,7 @@ public abstract class AbstractComponentM
             newEnabledLatch = new Deferred<Void>();
         }
         while ( !m_enabledLatchRef.compareAndSet( enabledLatch, newEnabledLatch) );
-        return newEnabledLatch;  
+        return newEnabledLatch;
     }
 
     public final Promise<Void> disable( final boolean async )
@@ -520,6 +519,7 @@ public abstract class AbstractComponentM
                     }
                 }
 
+                @Override
                 public String toString()
                 {
                     return "Async Deactivate: " + getComponentMetadata().getName() + " id: " + count;
@@ -549,7 +549,7 @@ public abstract class AbstractComponentM
     {
         deactivateInternal( reason, true, true );
     }
-    
+
     <T> void registerMissingDependency( DependencyManager<S, T> dm, ServiceReference<T> ref, int trackingCount)
     {
         BundleComponentActivator activator = getActivator();
@@ -565,7 +565,7 @@ public abstract class AbstractComponentM
     {
         return m_componentId;
     }
-    
+
     protected String getName() {
         return getComponentMetadata().getName();
     }
@@ -592,7 +592,7 @@ public abstract class AbstractComponentM
         // already disposed off component or bundle context is invalid
         return null;
     }
-    
+
     BundleContext getBundleContext()
     {
         final BundleComponentActivator activator = getActivator();
@@ -600,7 +600,7 @@ public abstract class AbstractComponentM
         {
             return activator.getBundleContext();
         }
-        return null;        
+        return null;
     }
 
 
@@ -614,7 +614,7 @@ public abstract class AbstractComponentM
     {
         return false;
     }
-    
+
     protected boolean isSatisfied()
     {
         return m_satisfied;
@@ -756,7 +756,7 @@ public abstract class AbstractComponentM
         {
             doDeactivate( reason, disable || m_factoryInstance );
         }
-        finally 
+        finally
         {
             releaseActivationReadLock( "deactivateInternal" );
         }
@@ -841,7 +841,7 @@ public abstract class AbstractComponentM
     {
         return m_componentMethods;
     }
-    
+
     protected String[] getProvidedServices()
     {
         if ( getComponentMetadata().getServiceMetadata() != null )
@@ -850,7 +850,7 @@ public abstract class AbstractComponentM
             return provides;
         }
         return null;
-        
+
     }
 
     private final RegistrationManager<ServiceRegistration<S>> registrationManager = new RegistrationManager<ServiceRegistration<S>>()
@@ -860,7 +860,7 @@ public abstract class AbstractComponentM
         ServiceRegistration<S> register(String[] services)
         {
             BundleContext bundleContext = getBundleContext();
-            if (bundleContext == null) 
+            if (bundleContext == null)
             {
                 return null;
             }
@@ -871,7 +871,7 @@ public abstract class AbstractComponentM
 								serviceProperties);
 				return serviceRegistration;
 			} catch (ServiceException e) {
-				log(LogService.LOG_ERROR, "Unexpected error registering component service with properties {0}", 
+				log(LogService.LOG_ERROR, "Unexpected error registering component service with properties {0}",
 						new Object[] {serviceProperties}, e);
 				return null;
 			}
@@ -900,7 +900,7 @@ public abstract class AbstractComponentM
         {
             dumpThreads();
         }
-        
+
     };
 
     /**
@@ -926,7 +926,7 @@ public abstract class AbstractComponentM
         }
         return true;
     }
-    
+
 
     AtomicInteger getTrackingCount()
     {
@@ -954,7 +954,7 @@ public abstract class AbstractComponentM
         }
         catch ( ClassNotFoundException e )
         {
-            log( LogService.LOG_ERROR, "Could not load implementation object class {0}", 
+            log( LogService.LOG_ERROR, "Could not load implementation object class {0}",
                     new Object[] {getComponentMetadata().getImplementationClassName()}, e );
             throw new IllegalStateException("Could not load implementation object class "
                     + getComponentMetadata().getImplementationClassName());
@@ -1013,7 +1013,7 @@ public abstract class AbstractComponentM
     }
 
 
-    final ServiceRegistration<S> getServiceRegistration() 
+    final ServiceRegistration<S> getServiceRegistration()
     {
         return registrationManager.getServiceRegistration();
     }
@@ -1056,6 +1056,7 @@ public abstract class AbstractComponentM
     }
 
 
+    @Override
     public String toString()
     {
         return "Component: " + getName() + " (" + getId() + ")";
@@ -1166,7 +1167,7 @@ public abstract class AbstractComponentM
     {
         return m_dependencyManagers;
     }
-    
+
     public List<? extends ReferenceManager<S, ?>> getReferenceManagers()
     {
     	return m_dependencyManagers;
@@ -1382,7 +1383,7 @@ public abstract class AbstractComponentM
     }
 
 	public abstract void reconfigure(Map<String, Object> configuration, boolean configurationDeleted);
-	
+
 	public abstract void getComponentManagers(List<AbstractComponentManager<S>> cms);
-    
+
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java Wed Feb  4 12:45:45 2015
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.felix.scr.component.ExtComponentContext;
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.helper.ComponentServiceObjectsHelper;
 import org.apache.felix.scr.impl.helper.ReadOnlyDictionary;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -40,19 +41,21 @@ import org.osgi.service.log.LogService;
 public class ComponentContextImpl<S> implements ExtComponentContext {
 
     private final SingleComponentManager<S> m_componentManager;
-    
+
     private final EdgeInfo[] edgeInfos;
-    
+
     private final ComponentInstance m_componentInstance = new ComponentInstanceImpl(this);
-    
+
     private final Bundle m_usingBundle;
-    
+
     private S m_implementationObject;
-    
+
     private volatile boolean m_implementationAccessible;
-    
+
     private final CountDownLatch accessibleLatch = new CountDownLatch(1);
 
+    private ComponentServiceObjectsHelper serviceObjectsHelper;
+
     public ComponentContextImpl( SingleComponentManager<S> componentManager, Bundle usingBundle )
     {
         m_componentManager = componentManager;
@@ -62,9 +65,19 @@ public class ComponentContextImpl<S> imp
         {
             edgeInfos[i] = new EdgeInfo();
         }
+        this.serviceObjectsHelper = new ComponentServiceObjectsHelper(usingBundle.getBundleContext());
     }
-    
-    
+
+    public void cleanup()
+    {
+        this.serviceObjectsHelper.cleanup();
+    }
+
+    public ComponentServiceObjectsHelper getComponentServiceObjectsHelper()
+    {
+        return this.serviceObjectsHelper;
+    }
+
     public void setImplementationObject(S implementationObject)
     {
         this.m_implementationObject = implementationObject;
@@ -79,7 +92,7 @@ public class ComponentContextImpl<S> imp
             accessibleLatch.countDown();
         }
     }
-    
+
     EdgeInfo getEdgeInfo(DependencyManager<S, ?> dm)
     {
         int index = dm.getIndex();
@@ -193,7 +206,7 @@ public class ComponentContextImpl<S> imp
     {
         getComponentManager().setServiceProperties(properties );
     }
-    
+
     //---------- ComponentInstance interface support ------------------------------
 
     S getImplementationObject( boolean requireAccessible )
@@ -227,7 +240,7 @@ public class ComponentContextImpl<S> imp
         }
         return null;
     }
-    
+
     private static class ComponentInstanceImpl<S> implements ComponentInstance
     {
         private final ComponentContextImpl<S> m_componentContext;

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Wed Feb  4 12:45:45 2015
@@ -74,7 +74,7 @@ public class SingleComponentManager<S> e
 
    /**
      * The constructor receives both the activator and the metadata
- * @param componentMethods
+     * @param componentMethods
      */
     public SingleComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods )
     {
@@ -155,6 +155,7 @@ public class SingleComponentManager<S> e
         {
             m_useCount.set( 0 );
             disposeImplementationObject( m_componentContext, reason );
+            m_componentContext.cleanup();
             m_componentContext = null;
             log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] },  null );
             clearServiceProperties();
@@ -773,7 +774,7 @@ public class SingleComponentManager<S> e
             boolean success = true;
             if ( m_componentContext == null )
             {
-                ComponentContextImpl<S> componentContext = new ComponentContextImpl<S>(this, null);
+                ComponentContextImpl<S> componentContext = new ComponentContextImpl<S>(this, this.getBundle());
                 if ( collectDependencies(componentContext))
                 {
                         log(

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java?rev=1657173&r1=1657172&r2=1657173&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java Wed Feb  4 12:45:45 2015
@@ -22,10 +22,11 @@ package org.apache.felix.scr.impl.helper
 import junit.framework.TestCase;
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.MockBundle;
 import org.apache.felix.scr.impl.config.ComponentContainer;
 import org.apache.felix.scr.impl.manager.ComponentContextImpl;
-import org.apache.felix.scr.impl.manager.SingleComponentManager;
 import org.apache.felix.scr.impl.manager.RefPair;
+import org.apache.felix.scr.impl.manager.SingleComponentManager;
 import org.apache.felix.scr.impl.manager.SingleRefPair;
 import org.apache.felix.scr.impl.manager.components.FakeService;
 import org.apache.felix.scr.impl.manager.components.T1;
@@ -36,7 +37,6 @@ import org.apache.felix.scr.impl.manager
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
-import org.apache.felix.scr.impl.metadata.XmlHandler;
 import org.easymock.EasyMock;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -51,11 +51,12 @@ public class BindMethodTest extends Test
     private BundleContext m_context;
 
 
+    @Override
     public void setUp()
     {
-        m_serviceReference = (ServiceReference) EasyMock.createNiceMock( ServiceReference.class );
-        m_serviceInstance = (FakeService) EasyMock.createNiceMock( FakeService.class );
-        m_context = ( BundleContext ) EasyMock.createNiceMock( BundleContext.class );
+        m_serviceReference = EasyMock.createNiceMock( ServiceReference.class );
+        m_serviceInstance = EasyMock.createNiceMock( FakeService.class );
+        m_context = EasyMock.createNiceMock( BundleContext.class );
 
         EasyMock.expect( m_context.getService( m_serviceReference ) ).andReturn( m_serviceInstance )
                 .anyTimes();
@@ -430,13 +431,13 @@ public class BindMethodTest extends Test
         testMethod( "suitable", new T1a(), DSVersion.DS10, "suitableT1" );
         testMethod( "suitable", new T1a(), DSVersion.DS11, "suitableT1" );
     }
-    
+
     public void test_13()
     {
         //single map param
         testMethod( "packageT1Map", new T1(), DSVersion.DS12, null);
         testMethod( "packageT1Map", new T1(), DSVersion.DS13, "packageT1Map");
-        
+
         //map, sr
         testMethod( "packageT1MapSR", new T1MapSR(), DSVersion.DS12, null);
         testMethod( "packageT1MapSR", new T1MapSR(), DSVersion.DS13, "packageT1MapSR");
@@ -451,13 +452,13 @@ public class BindMethodTest extends Test
         BindMethod bm = new BindMethod( methodName, component.getClass(),
                 FakeService.class.getName(), dsVersion, false, ReferenceMetadata.ReferenceScope.bundle );
         RefPair refPair = new SingleRefPair( m_serviceReference );
-        ComponentContextImpl<T1> cc = new ComponentContextImpl(icm, null);
+        ComponentContextImpl<T1> cc = new ComponentContextImpl(icm, new MockBundle());
         assertTrue( bm.getServiceObject( cc, refPair, m_context, icm ) );
         BindParameters bp = new BindParameters(cc, refPair);
         bm.invoke( component, bp, null, icm );
         assertEquals( expectCallPerformed, component.callPerformed );
     }
-    
+
     private ComponentContainer newContainer()
     {
         final ComponentMetadata metadata = newMetadata();
@@ -476,7 +477,7 @@ public class BindMethodTest extends Test
             public void disposed(SingleComponentManager component)
             {
             }
-            
+
         };
         return container;
     }