You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2010/06/03 15:19:22 UTC

svn commit: r950985 - in /incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint: ./ container/ mutable/ reflect/

Author: gnodet
Date: Thu Jun  3 13:19:22 2010
New Revision: 950985

URL: http://svn.apache.org/viewvc?rev=950985&view=rev
Log:
ARIES-330: Support for specifiying the runtime class on service references instead of class names

Modified:
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedServiceReferenceMetadata.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableServiceReferenceMetadata.java
    incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ServiceReferenceMetadataImpl.java

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedServiceReferenceMetadata.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedServiceReferenceMetadata.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedServiceReferenceMetadata.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedServiceReferenceMetadata.java Thu Jun  3 13:19:22 2010
@@ -31,4 +31,6 @@ public interface ExtendedServiceReferenc
 
     int getProxyMethod();
 
+    Class getRuntimeInterface();
+
 }

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java Thu Jun  3 13:19:22 2010
@@ -42,6 +42,7 @@ import net.sf.cglib.proxy.Enhancer;
 
 import org.apache.aries.blueprint.BlueprintConstants;
 import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ExtendedReferenceListMetadata;
 import org.apache.aries.blueprint.ExtendedServiceReferenceMetadata;
 import org.apache.aries.blueprint.di.AbstractRecipe;
 import org.apache.aries.blueprint.di.CollectionRecipe;
@@ -123,8 +124,9 @@ public abstract class AbstractServiceRef
         ServiceReferenceMetadata metadata) {
       
       String typeName = metadata.getInterface();
-      
-      if (typeName == null) {
+      Class typeClass = metadata instanceof ExtendedServiceReferenceMetadata
+                                ? ((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface() : null;
+      if (typeName == null && typeClass == null) {
         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
           public ClassLoader run() {
             return new BundleDelegatingClassLoader(blueprintContainer.getBundleContext().getBundle(),
@@ -134,11 +136,15 @@ public abstract class AbstractServiceRef
       }
       
       final ClassLoader interfaceClassLoader;
-      try {
-        Bundle clientBundle = blueprintContainer.getBundleContext().getBundle();
-        interfaceClassLoader = clientBundle.loadClass(typeName).getClassLoader();
-      } catch (ClassNotFoundException cnfe) {
-        throw new ComponentDefinitionException("Unable to load class " + typeName + " from recipe " + this, cnfe);
+      if (typeClass != null) {
+          interfaceClassLoader = typeClass.getClassLoader();
+      } else {
+        try {
+          Bundle clientBundle = blueprintContainer.getBundleContext().getBundle();
+          interfaceClassLoader = clientBundle.loadClass(typeName).getClassLoader();
+        } catch (ClassNotFoundException cnfe) {
+          throw new ComponentDefinitionException("Unable to load class " + typeName + " from recipe " + this, cnfe);
+        }
       }
       
       return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@@ -248,7 +254,9 @@ public abstract class AbstractServiceRef
                 List<Listener> listeners = (List<Listener>) listenersRecipe.create();
                 for (Listener listener : listeners) {
                     List<Class> cl = new ArrayList<Class>();
-                    if (metadata.getInterface() != null) {
+                    if (metadata instanceof ExtendedServiceReferenceMetadata && ((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface() != null) {
+                        cl.add(((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface());
+                    } else if (metadata.getInterface() != null) {
                         cl.addAll(loadAllClasses(Collections.singletonList(metadata.getInterface())));
                     } else {
                         cl.add(Object.class);
@@ -289,11 +297,11 @@ public abstract class AbstractServiceRef
     }
 
 
-    protected Object createProxy(final Callable<Object> dispatcher, Iterable<String> interfaces) throws Exception {
+    protected Object createProxy(final Callable<Object> dispatcher, Set<Class> interfaces) throws Exception {
         if (!interfaces.iterator().hasNext()) {
             return new Object();
         } else {
-            return getProxyFactory().createProxy(proxyClassLoader, toClassArray(loadAllClasses(interfaces)), dispatcher);
+            return getProxyFactory().createProxy(proxyClassLoader, toClassArray(interfaces), dispatcher);
         }
     }
 
@@ -303,9 +311,16 @@ public abstract class AbstractServiceRef
             if (metadata instanceof ExtendedServiceReferenceMetadata) {
                 proxyClass = (((ExtendedServiceReferenceMetadata) metadata).getProxyMethod() & ExtendedServiceReferenceMetadata.PROXY_METHOD_CLASSES) != 0;
             }
-            List<Class> classes = loadAllClasses(Collections.singletonList(this.metadata.getInterface()));
             if (!proxyClass) {
-                for (Class cl : classes) {
+                Set<Class> interfaces = new HashSet<Class>();
+                if (metadata.getInterface() != null) {
+                    interfaces.add(loadClass(metadata.getInterface()));
+                }
+                if (metadata instanceof ExtendedReferenceListMetadata
+                            && ((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface() != null) {
+                        interfaces.add(((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface());
+                    }
+                for (Class cl : interfaces) {
                     if (!cl.isInterface()) {
                         throw new ComponentDefinitionException("A class " + cl.getName() + " was found in the interfaces list, but class proxying is not allowed by default. The ext:proxy-method='classes' attribute needs to be added to this service reference.");
                     }
@@ -562,6 +577,9 @@ public abstract class AbstractServiceRef
         }
         // Handle interfaces
         String interfaceName = metadata.getInterface();
+        if (metadata instanceof ExtendedServiceReferenceMetadata && ((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface() != null) {
+            interfaceName = ((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface().getName();
+        }
         if (interfaceName != null && interfaceName.length() > 0) {
             members.add("(" + Constants.OBJECTCLASS + "=" + interfaceName + ")");
         }
@@ -586,7 +604,7 @@ public abstract class AbstractServiceRef
     }
 
     private static Class[] getInterfaces(Class[] classes) {
-        List<Class> interfaces = new ArrayList<Class>();
+        Set<Class> interfaces = new HashSet<Class>();
         for (Class clazz : classes) {
             if (clazz.isInterface()) {
                 interfaces.add(clazz);
@@ -595,7 +613,7 @@ public abstract class AbstractServiceRef
         return toClassArray(interfaces);
     }
 
-    private static Class[] toClassArray(List<Class> classes) {
+    private static Class[] toClassArray(Set<Class> classes) {
         return classes.toArray(new Class [classes.size()]);
     }
 

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java Thu Jun  3 13:19:22 2010
@@ -18,18 +18,12 @@
  */
 package org.apache.aries.blueprint.container;
 
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.RandomAccess;
+import java.util.*;
 import java.util.concurrent.Callable;
 
 import org.apache.aries.blueprint.ExtendedBlueprintContainer;
 import org.apache.aries.blueprint.ExtendedReferenceListMetadata;
+import org.apache.aries.blueprint.ExtendedServiceReferenceMetadata;
 import org.apache.aries.blueprint.di.Recipe;
 import org.apache.aries.blueprint.di.CollectionRecipe;
 import org.apache.aries.blueprint.utils.DynamicCollection;
@@ -117,14 +111,18 @@ public class ReferenceListRecipe extends
                     }
                 } else {
                     dispatcher = new ServiceDispatcher(reference);
-                    List<String> interfaces = new ArrayList<String>();
+                    Set<Class> interfaces = new HashSet<Class>();
                     if (metadata.getInterface() != null) {
-                        interfaces.add(metadata.getInterface());
+                        interfaces.add(loadClass(metadata.getInterface()));
                     }
                     if (metadata instanceof ExtendedReferenceListMetadata) {
+                        if (((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface() != null) {
+                            interfaces.add(((ExtendedServiceReferenceMetadata) metadata).getRuntimeInterface());
+                        }
                         boolean greedy = (((ExtendedReferenceListMetadata) metadata).getProxyMethod() & ExtendedReferenceListMetadata.PROXY_METHOD_GREEDY) != 0;
                         if (greedy) {
-                            interfaces = Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS));
+                            List<String> ifs = Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS));
+                            interfaces.addAll(loadAllClasses(ifs));
                         }
                     }
                     dispatcher.proxy = createProxy(dispatcher, interfaces);

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java Thu Jun  3 13:19:22 2010
@@ -19,11 +19,14 @@
 package org.apache.aries.blueprint.container;
 
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Set;
 import java.util.concurrent.Callable;
 
 import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ExtendedServiceReferenceMetadata;
 import org.apache.aries.blueprint.di.Recipe;
 import org.apache.aries.blueprint.di.CollectionRecipe;
 import org.osgi.framework.ServiceReference;
@@ -75,10 +78,14 @@ public class ReferenceRecipe extends Abs
                 }
             }
             // Create the proxy
-            List<String> interfaces = new ArrayList<String>();
+            Set<Class> interfaces = new HashSet<Class>();
             if (this.metadata.getInterface() != null) {
-                interfaces.add(this.metadata.getInterface());
+                interfaces.add(loadClass(this.metadata.getInterface()));
             }
+            if (this.metadata instanceof ExtendedServiceReferenceMetadata && ((ExtendedServiceReferenceMetadata) this.metadata).getRuntimeInterface() != null) {
+                interfaces.add(((ExtendedServiceReferenceMetadata) this.metadata).getRuntimeInterface());
+            }
+
             proxy = createProxy(new ServiceDispatcher(), interfaces);
 
             // Add partially created proxy to the context

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableServiceReferenceMetadata.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableServiceReferenceMetadata.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableServiceReferenceMetadata.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableServiceReferenceMetadata.java Thu Jun  3 13:19:22 2010
@@ -46,4 +46,6 @@ public interface MutableServiceReference
     void setProxyMethod(int proxyMethod);
 
     void setFilter(String filter);
+
+    void setRuntimeInterface(Class clazz);
 }

Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ServiceReferenceMetadataImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ServiceReferenceMetadataImpl.java?rev=950985&r1=950984&r2=950985&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ServiceReferenceMetadataImpl.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ServiceReferenceMetadataImpl.java Thu Jun  3 13:19:22 2010
@@ -40,6 +40,7 @@ public abstract class ServiceReferenceMe
     protected String filter;
     protected Collection<ReferenceListener> referenceListeners;
     protected int proxyMethod;
+    protected Class runtimeInterface;
 
     public ServiceReferenceMetadataImpl() {
     }
@@ -126,4 +127,11 @@ public abstract class ServiceReferenceMe
         this.proxyMethod = proxyMethod;
     }
 
+    public Class getRuntimeInterface() {
+        return runtimeInterface;
+    }
+
+    public void setRuntimeInterface(Class runtimeInterface) {
+        this.runtimeInterface = runtimeInterface;
+    }
 }