You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2011/12/20 10:36:22 UTC

svn commit: r1221166 - in /aries/trunk/blueprint: blueprint-core/ blueprint-core/src/main/java/org/apache/aries/blueprint/container/ blueprint-parser/src/main/java/org/apache/aries/blueprint/ blueprint-parser/src/main/java/org/apache/aries/blueprint/mu...

Author: timothyjward
Date: Tue Dec 20 09:36:22 2011
New Revision: 1221166

URL: http://svn.apache.org/viewvc?rev=1221166&view=rev
Log:
ARIES-765: Blueprint changes to support proxying of beans created by reference managers

Added:
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Voidable.java
Modified:
    aries/trunk/blueprint/blueprint-core/pom.xml
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
    aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
    aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
    aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java

Modified: aries/trunk/blueprint/blueprint-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/pom.xml?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-core/pom.xml Tue Dec 20 09:36:22 2011
@@ -94,7 +94,7 @@
 
         <blueprint.annotation.api.version>0.3</blueprint.annotation.api.version>
         <blueprint.api.version>0.3</blueprint.api.version>
-        <blueprint.parser.version>0.4</blueprint.parser.version>
+        <blueprint.parser.version>0.4.1-SNAPSHOT</blueprint.parser.version>
         <proxy.api.version>0.4</proxy.api.version>
         <proxy.impl.version>0.4</proxy.impl.version>
         <quiesce.api.version>0.3</quiesce.api.version>

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java Tue Dec 20 09:36:22 2011
@@ -31,6 +31,9 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.aries.blueprint.BeanProcessor;
 import org.apache.aries.blueprint.ComponentDefinitionRegistry;
@@ -42,6 +45,7 @@ import org.apache.aries.blueprint.proxy.
 import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
 import org.apache.aries.blueprint.utils.ReflectionUtils;
 import org.apache.aries.blueprint.utils.ReflectionUtils.PropertyDescriptor;
+import org.apache.aries.proxy.UnableToProxyException;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -60,6 +64,49 @@ import static org.apache.aries.blueprint
  */
 public class BeanRecipe extends AbstractRecipe {
 
+    public class VoidableCallable implements Callable<Object>, Voidable {
+
+        private final AtomicReference<Object> ref = new AtomicReference<Object>();
+        
+        private final Semaphore sem = new Semaphore(1);
+        
+        private final ThreadLocal<Object> deadlockDetector = new ThreadLocal<Object>();
+        
+        public void voidReference() {
+            ref.set(null);
+        }
+
+        public Object call() throws ComponentDefinitionException {
+            Object o = ref.get();
+            
+            if (o == null) {
+                if(deadlockDetector.get() != null) {
+                    deadlockDetector.remove();
+                    throw new ComponentDefinitionException("Construction cycle detected for bean " + name);
+                }
+                
+                sem.acquireUninterruptibly();
+                try {
+                    o = ref.get();
+                    if (o == null) {
+                        deadlockDetector.set(this);
+                        try {
+                            o = internalCreate2();
+                            ref.set(o);
+                        } finally {
+                            deadlockDetector.remove();
+                        }
+                    }
+                } finally {
+                  sem.release();
+                }
+            }
+            
+            return o;
+        }
+
+    }
+
     private static final Logger LOGGER = LoggerFactory.getLogger(BeanRecipe.class);
 
     private final ExtendedBlueprintContainer blueprintContainer;
@@ -701,6 +748,29 @@ public class BeanRecipe extends Abstract
         
     @Override
     protected Object internalCreate() throws ComponentDefinitionException {
+        if (factory instanceof ReferenceRecipe) {
+            ReferenceRecipe rr = (ReferenceRecipe) factory;
+            if (rr.getProxyChildBeanClasses() != null) {
+                return createProxyBean(rr);
+            }
+        } 
+        
+        return internalCreate2();
+    }
+    
+    private Object createProxyBean(ReferenceRecipe rr) {
+        try {
+            VoidableCallable vc = new VoidableCallable();
+            rr.addVoidableChild(vc);
+            return blueprintContainer.getProxyManager().createDelegatingProxy(
+                blueprintContainer.getBundleContext().getBundle(), rr.getProxyChildBeanClasses(),
+                vc, vc.call());
+        } catch (UnableToProxyException e) {
+            throw new ComponentDefinitionException(e);
+        }
+    }
+    
+    protected Object internalCreate2() throws ComponentDefinitionException {
         
         instantiateExplicitDependencies();
 

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java Tue Dec 20 09:36:22 2011
@@ -18,7 +18,11 @@
  */
 package org.apache.aries.blueprint.container;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Callable;
@@ -59,6 +63,9 @@ public class ReferenceRecipe extends Abs
     private Object defaultBean;
     private final Object monitor = new Object();
 
+    private final Collection<Class<?>> proxyChildBeanClasses;
+    private final Collection<WeakReference<Voidable>> proxiedChildren;
+    
     public ReferenceRecipe(String name,
                            ExtendedBlueprintContainer blueprintContainer,
                            ReferenceMetadata metadata,
@@ -66,6 +73,15 @@ public class ReferenceRecipe extends Abs
                            List<Recipe> explicitDependencies) {
         super(name, blueprintContainer, metadata, listenersRecipe, explicitDependencies);
         this.metadata = metadata;
+        if(metadata instanceof ExtendedReferenceMetadata) 
+            proxyChildBeanClasses = ((ExtendedReferenceMetadata) metadata).getProxyChildBeanClasses();
+        else 
+            proxyChildBeanClasses = null;
+        
+        if (proxyChildBeanClasses != null)
+            proxiedChildren = new ArrayList<WeakReference<Voidable>>();
+        else
+            proxiedChildren = null;
     }
 
     @Override
@@ -140,13 +156,15 @@ public class ReferenceRecipe extends Abs
     private void bind(ServiceReference ref) {
         LOGGER.debug("Binding reference {} to {}", getName(), ref);
         synchronized (monitor) {
-            if (trackedServiceReference != null) {
-                getBundleContextForServiceLookup().ungetService(trackedServiceReference);
-            }
+            ServiceReference oldReference = trackedServiceReference;
             trackedServiceReference = ref;
             trackedService = null;
-            monitor.notifyAll();
+            voidProxiedChildren();
             bind(trackedServiceReference, proxy);
+            if (oldReference != null) {
+                getBundleContextForServiceLookup().ungetService(oldReference);
+            }
+            monitor.notifyAll();
         }
     }
 
@@ -155,9 +173,11 @@ public class ReferenceRecipe extends Abs
         synchronized (monitor) {
             if (trackedServiceReference != null) {
                 unbind(trackedServiceReference, proxy);
-                getBundleContextForServiceLookup().ungetService(trackedServiceReference);
+                ServiceReference oldReference = trackedServiceReference;
                 trackedServiceReference = null;
                 trackedService = null;
+                voidProxiedChildren();
+                getBundleContextForServiceLookup().ungetService(oldReference);
                 monitor.notifyAll();
             }
         }
@@ -220,6 +240,34 @@ public class ReferenceRecipe extends Abs
             return trackedServiceReference;
         }
     }
+    
+    private void voidProxiedChildren() {
+        if(proxyChildBeanClasses != null) {
+            synchronized(proxiedChildren) {
+                for(Iterator<WeakReference<Voidable>> it = proxiedChildren.iterator(); it.hasNext();) {
+                    Voidable v = it.next().get();
+                    if(v == null)
+                        it.remove();
+                    else
+                      v.voidReference();
+                }
+            }
+        }
+    }
+    
+    public void addVoidableChild(Voidable v) {
+        if(proxyChildBeanClasses != null) {
+            synchronized (proxiedChildren) {
+                proxiedChildren.add(new WeakReference<Voidable>(v));
+            }
+        } else {
+            throw new IllegalStateException("Proxying of child beans is disabled for this recipe");
+        }
+    }
+    
+    public Collection<Class<?>> getProxyChildBeanClasses() {
+        return proxyChildBeanClasses;
+    }
 
     public class ServiceDispatcher implements Callable<Object> {
 

Added: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Voidable.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Voidable.java?rev=1221166&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Voidable.java (added)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Voidable.java Tue Dec 20 09:36:22 2011
@@ -0,0 +1,5 @@
+package org.apache.aries.blueprint.container;
+
+public interface Voidable {
+    public void voidReference();
+}

Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java Tue Dec 20 09:36:22 2011
@@ -18,9 +18,13 @@
  */
 package org.apache.aries.blueprint;
 
+import java.util.Collection;
+
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 
 public interface ExtendedReferenceMetadata extends ReferenceMetadata 
 {
     public String getDefaultBean();
+    
+    public Collection<Class<?>> getProxyChildBeanClasses();
 }
\ No newline at end of file

Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java Tue Dec 20 09:36:22 2011
@@ -18,6 +18,8 @@
  */
 package org.apache.aries.blueprint.mutable;
 
+import java.util.Collection;
+
 import org.apache.aries.blueprint.ExtendedReferenceMetadata;
 
 /**
@@ -30,5 +32,7 @@ public interface MutableReferenceMetadat
     void setTimeout(long timeout);
 
     void setDefaultBean(String value);
+    
+    void setProxyChildBeanClasses(Collection<Class<?>> classes);
 
 }
\ No newline at end of file

Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java?rev=1221166&r1=1221165&r2=1221166&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java Tue Dec 20 09:36:22 2011
@@ -18,6 +18,8 @@
  */
 package org.apache.aries.blueprint.reflect;
 
+import java.util.Collection;
+
 import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 
@@ -30,6 +32,7 @@ public class ReferenceMetadataImpl exten
 
     private long timeout;
     private String defaultBeanId;
+    private Collection<Class<?>> proxyChildBeanClasses;
 
     public ReferenceMetadataImpl() {
     }
@@ -69,4 +72,12 @@ public class ReferenceMetadataImpl exten
                 ", timeout=" + timeout +
                 ']';
     }
+
+    public Collection<Class<?>> getProxyChildBeanClasses() {
+        return proxyChildBeanClasses;
+    }
+
+    public void setProxyChildBeanClasses(Collection<Class<?>> c) {
+        proxyChildBeanClasses = c;
+    }
 }