You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2019/02/07 16:31:51 UTC

svn commit: r1853148 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager: AbstractPrototypeRefPair.java MultiplePrototypeRefPair.java SinglePrototypeRefPair.java SingleRefPair.java

Author: tjwatson
Date: Thu Feb  7 16:31:51 2019
New Revision: 1853148

URL: http://svn.apache.org/viewvc?rev=1853148&view=rev
Log:
FELIX-6050 - Use common code for PrototypRefPair

Add an AbstractPrototypeRefPair to allow the Single
and Multiple implementations to share common code

Added:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java
      - copied, changed from r1853035, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java

Copied: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java (from r1853035, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java)
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java?p2=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java&p1=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java&r1=1853035&r2=1853148&rev=1853148&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java Thu Feb  7 16:31:51 2019
@@ -20,10 +20,9 @@
 
 package org.apache.felix.scr.impl.manager;
 
-import java.util.Iterator;
+import java.util.Collection;
+import java.util.Map;
 import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -32,42 +31,36 @@ import org.osgi.service.log.LogService;
 /**
  * @version $Rev$ $Date$
  */
-public class MultiplePrototypeRefPair<S, T> extends RefPair<S, T>
+public abstract class AbstractPrototypeRefPair<S, T> extends RefPair<S, T>
 {
-    private final ConcurrentMap<ComponentContextImpl<S>, T> instances = new ConcurrentHashMap<>();
-
-    public MultiplePrototypeRefPair( ServiceReference<T> ref )
+    public AbstractPrototypeRefPair( ServiceReference<T> ref )
     {
         super(ref);
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key)
-    {
-        return instances.get( key );
-    }
+    public abstract T getServiceObject(ComponentContextImpl<S> key);
 
     @Override
-    public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject)
-    {
-        return instances.putIfAbsent( key, serviceObject ) == null;
-    }
+    public abstract boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject);
+
+    protected abstract T remove(ComponentContextImpl<S> key);
+
+    protected abstract Collection<Entry<ComponentContextImpl<S>, T>> clearEntries();
 
     @Override
-    public T ungetServiceObject(ComponentContextImpl<S> key)
+    public final T ungetServiceObject(ComponentContextImpl<S> key)
     {
-    	if ( key == null )
-    	{
-			final Iterator<Entry<ComponentContextImpl<S>, T>> iter = instances.entrySet().iterator();
-			while ( iter.hasNext() ) 
-			{
-				Entry<ComponentContextImpl<S>, T> e = iter.next();
-				doUngetService( e.getKey(), e.getValue() );
-   			} 
-    		instances.clear();
-    		return null ;
-    	}
-        T service = instances.remove( key );
+        if ( key == null )
+        {
+            Collection<Map.Entry<ComponentContextImpl<S>,T>> keys = clearEntries();
+            for (Map.Entry<ComponentContextImpl<S>,T> e : keys)
+            {
+                doUngetService( e.getKey(), e.getValue() );
+            }
+            return null ;
+        }
+        T service = remove( key );
         if(service != null) {
         	doUngetService( key, service );
         }
@@ -75,18 +68,15 @@ public class MultiplePrototypeRefPair<S,
     }
 
     @Override
-    public void ungetServiceObjects(BundleContext bundleContext) {
+    public final void ungetServiceObjects(BundleContext bundleContext) {
         ungetServiceObject(null);
     }
 
     @Override
-    public String toString()
-    {
-        return "[MultiplePrototypeRefPair: ref: [" + getRef() + "] has service: [" + !instances.isEmpty() + "]]";
-    }
+    public abstract String toString();
 
     @Override
-    public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
+    public final boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
     {
         final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
@@ -105,7 +95,8 @@ public class MultiplePrototypeRefPair<S,
         return true;
     }
 
-	private void doUngetService(ComponentContextImpl<S> key, final T service) {
+	@SuppressWarnings("unchecked")
+    private void doUngetService(ComponentContextImpl<S> key, final T service) {
 		try 
 		{
 			key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService( service );

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java?rev=1853148&r1=1853147&r2=1853148&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java Thu Feb  7 16:31:51 2019
@@ -20,19 +20,18 @@
 
 package org.apache.felix.scr.impl.manager;
 
-import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogService;
 
 /**
  * @version $Rev$ $Date$
  */
-public class MultiplePrototypeRefPair<S, T> extends RefPair<S, T>
+public class MultiplePrototypeRefPair<S, T> extends AbstractPrototypeRefPair<S, T>
 {
     private final ConcurrentMap<ComponentContextImpl<S>, T> instances = new ConcurrentHashMap<>();
 
@@ -42,77 +41,30 @@ public class MultiplePrototypeRefPair<S,
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key)
+    public String toString()
     {
-        return instances.get( key );
+        return "[MultiplePrototypeRefPair: ref: [" + getRef() + "] has service: [" + !instances.isEmpty() + "]]";
     }
 
     @Override
-    public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject)
-    {
-        return instances.putIfAbsent( key, serviceObject ) == null;
+    public T getServiceObject(ComponentContextImpl<S> key) {
+        return instances.get(key);
     }
 
     @Override
-    public T ungetServiceObject(ComponentContextImpl<S> key)
-    {
-    	if ( key == null )
-    	{
-			final Iterator<Entry<ComponentContextImpl<S>, T>> iter = instances.entrySet().iterator();
-			while ( iter.hasNext() ) 
-			{
-				Entry<ComponentContextImpl<S>, T> e = iter.next();
-				doUngetService( e.getKey(), e.getValue() );
-   			} 
-    		instances.clear();
-    		return null ;
-    	}
-        T service = instances.remove( key );
-        if(service != null) {
-        	doUngetService( key, service );
-        }
-		return service;
+    public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject) {
+        return instances.putIfAbsent(key, serviceObject) == null;
     }
 
     @Override
-    public void ungetServiceObjects(BundleContext bundleContext) {
-        ungetServiceObject(null);
+    protected T remove(ComponentContextImpl<S> key) {
+        return instances.remove(key);
     }
 
     @Override
-    public String toString()
-    {
-        return "[MultiplePrototypeRefPair: ref: [" + getRef() + "] has service: [" + !instances.isEmpty() + "]]";
+    protected Collection<Entry<ComponentContextImpl<S>, T>> clearEntries() {
+        Collection<Entry<ComponentContextImpl<S>, T>> result = new ArrayList<>(instances.entrySet());
+        instances.clear();
+        return result;
     }
-
-    @Override
-    public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
-    {
-        final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
-        if ( service == null )
-        {
-            setFailed();
-            key.getLogger().log(
-                 LogService.LOG_WARNING,
-                 "Could not get service from serviceobjects for ref {0}", null, getRef() );
-            return false;
-        }
-        if (!setServiceObject(key, service))
-        {
-            // Another thread got the service before, so unget our
-        	doUngetService( key, service );
-        }
-        return true;
-    }
-
-	private void doUngetService(ComponentContextImpl<S> key, final T service) {
-		try 
-		{
-			key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService( service );
-		}
-		catch ( final IllegalStateException ise )
-		{
-			// ignore
-		}
-	}
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java?rev=1853148&r1=1853147&r2=1853148&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java Thu Feb  7 16:31:51 2019
@@ -20,26 +20,21 @@
 
 package org.apache.felix.scr.impl.manager;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogService;
 
 /**
  * @version $Rev$ $Date$
  */
-public class SinglePrototypeRefPair<S, T> extends RefPair<S, T>
+public class SinglePrototypeRefPair<S, T> extends AbstractPrototypeRefPair<S, T>
 {
-    class SingleKeyService {
-        final ComponentContextImpl<S> key;
-        final T serviceObject;
-        SingleKeyService(ComponentContextImpl<S> key, T serviceObject) {
-            this.key = key;
-            this.serviceObject = serviceObject;
-        }
-    }
-    protected AtomicReference<SingleKeyService> serviceObjectRef = new AtomicReference<>();
+    private final AtomicReference<SimpleImmutableEntry<ComponentContextImpl<S>, T>> instance = new AtomicReference<>();
 
     public SinglePrototypeRefPair( ServiceReference<T> ref )
     {
@@ -47,71 +42,42 @@ public class SinglePrototypeRefPair<S, T
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key)
+    public String toString()
     {
-        SingleKeyService service = serviceObjectRef.get();
-        return service == null ? null : service.serviceObject;
+        return "[SinglePrototypeRefPair: ref: [" + getRef() + "] service: [" + getServiceObject(null) + "]]";
     }
 
     @Override
-    public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject)
-    {
-        return serviceObjectRef.compareAndSet(null, new SingleKeyService(key, serviceObject ));
+    public T getServiceObject(ComponentContextImpl<S> key) {
+        return internalGetServiceObject(key, false);
     }
 
     @Override
-    public T ungetServiceObject(ComponentContextImpl<S> key)
-    {
-        SingleKeyService service = serviceObjectRef.getAndSet(null);
-        if (service != null) {
-            if (key == null) {
-                key = service.key;
-            }
-            doUngetService(key, service.serviceObject);
-            return service.serviceObject;
-        }
-		return null;
+    public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject) {
+        return instance.compareAndSet(null, new SimpleImmutableEntry<>(key, serviceObject));
     }
 
     @Override
-    public void ungetServiceObjects(BundleContext bundleContext) {
-        ungetServiceObject(null);
+    protected T remove(ComponentContextImpl<S> key) {
+        return internalGetServiceObject(key, true);
     }
 
-    @Override
-    public String toString()
-    {
-        return "[SinglePrototypeRefPair: ref: [" + getRef() + "] service: [" + getServiceObject(null) + "]]";
+    private T internalGetServiceObject(ComponentContextImpl<S> key, boolean remove) {
+        SimpleImmutableEntry<ComponentContextImpl<S>, T> entry = instance.get();
+        if (entry == null) {
+            return null;
+        }
+        T result = key == null || entry.getKey().equals(key) ? entry.getValue() : null;
+        if (remove && result != null) {
+            instance.compareAndSet(entry, null);
+        }
+        return result;
     }
 
     @Override
-    public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
-    {
-    	final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
-        if ( service == null )
-        {
-            setFailed();
-            key.getLogger().log(
-                 LogService.LOG_WARNING,
-                 "Could not get service from serviceobjects for ref {0}", null, getRef() );
-            return false;
-        }
-        if (!setServiceObject(key, service))
-        {
-            // Another thread got the service before, so unget our
-        	doUngetService( key, service );
-        }
-        return true;
+    protected Collection<Entry<ComponentContextImpl<S>, T>> clearEntries() {
+        Map.Entry<ComponentContextImpl<S>, T> entry = instance.getAndSet(null);
+        return entry == null ? Collections.<Entry<ComponentContextImpl<S>, T>>emptyList() : Collections.singleton(entry);
     }
 
-	private void doUngetService(ComponentContextImpl<S> key, final T service) {
-		try 
-		{
-			key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService( service );
-		}
-		catch ( final IllegalStateException ise )
-		{
-			// ignore
-		}
-	}
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java?rev=1853148&r1=1853147&r2=1853148&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java Thu Feb  7 16:31:51 2019
@@ -31,7 +31,7 @@ import org.osgi.service.log.LogService;
  */
 public class SingleRefPair<S, T> extends RefPair<S, T>
 {
-    protected AtomicReference<T> serviceObjectRef = new AtomicReference<>();
+    private final AtomicReference<T> serviceObjectRef = new AtomicReference<>();
 
     public SingleRefPair( ServiceReference<T> ref )
     {