You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2011/10/05 16:03:34 UTC

svn commit: r1179231 - in /felix/trunk/ipojo/core: ./ src/main/java/org/apache/felix/ipojo/ src/main/java/org/apache/felix/ipojo/handlers/dependency/

Author: clement
Date: Wed Oct  5 14:03:33 2011
New Revision: 1179231

URL: http://svn.apache.org/viewvc?rev=1179231&view=rev
Log:
Fixed https://issues.apache.org/jira/browse/FELIX-3144

The MethodInterceptors receive a Member instead of a Method. The received object can be either a Method or a Constructor.

Modified:
    felix/trunk/ipojo/core/pom.xml
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java

Modified: felix/trunk/ipojo/core/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/pom.xml?rev=1179231&r1=1179230&r2=1179231&view=diff
==============================================================================
--- felix/trunk/ipojo/core/pom.xml (original)
+++ felix/trunk/ipojo/core/pom.xml Wed Oct  5 14:03:33 2011
@@ -30,7 +30,10 @@
   <version>1.9.0-SNAPSHOT</version>
 
   <properties>
-    <ipojo.package.version>1.8.0</ipojo.package.version>
+    <!--
+        * 1.8.1 : change in the MethodInterceptor interface (FELIX-3144)
+     -->
+    <ipojo.package.version>1.8.1</ipojo.package.version>
   </properties>
 
   <description>

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?rev=1179231&r1=1179230&r2=1179231&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Wed Oct  5 14:03:33 2011
@@ -21,6 +21,7 @@ package org.apache.felix.ipojo;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
@@ -1090,7 +1091,7 @@ public class InstanceManager implements 
             return;
         }
         MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
-        Method method = getMethodById(methodId);
+        Member method = getMethodById(methodId);
         // In case of a constructor, the method is null, and the list is null too.
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].onEntry(pojo, method, args); // Outside a synchronized block.
@@ -1113,7 +1114,7 @@ public class InstanceManager implements 
             return;
         }
         MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
-        Method method = getMethodById(methodId);
+        Member method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].onExit(pojo, method, result);
         }
@@ -1137,7 +1138,7 @@ public class InstanceManager implements 
             return;
         }
         MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
-        Method method = getMethodById(methodId);
+        Member method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].onError(pojo, method, error);
         }
@@ -1153,10 +1154,12 @@ public class InstanceManager implements 
      * @param methodId the method id
      * @return the method object or <code>null</code> if the method cannot be found.
      */
-    private Method getMethodById(String methodId) {
+    private Member getMethodById(String methodId) {
         // Not necessary synchronized as recomputing the methodID will give the same Method twice.
-        Method method = (Method) m_methods.get(methodId);
-        if (method == null  && m_clazz != null) {
+        Member member = (Member) m_methods.get(methodId);
+        if (member == null  && m_clazz != null) {
+
+            // First try on methods.
             Method[] mets = m_clazz.getDeclaredMethods();
             for (int i = 0; i < mets.length; i++) {
                 // Check if the method was not already computed. If not, compute the Id and check.
@@ -1166,16 +1169,25 @@ public class InstanceManager implements 
                     return mets[i];
                 }
             }
-            // If not found, it is a constructor, return null in this case.
+
+            // If not found, it is a constructor, return the constructor object in this case.
             if (methodId.startsWith(MethodMetadata.CONSTRUCTOR_PREFIX)) {
-                // Constructor.
-                return null;
+                Constructor[] constructors = m_clazz.getDeclaredConstructors();
+                for (int i = 0; i < constructors.length; i++) {
+                    // Check if the constructor was not already computed. If not, compute the Id and check.
+                    if (!m_methods.containsValue(constructors[i]) && (MethodMetadata.computeMethodId(constructors[i]).equals(methodId))) {
+                        // Store the new methodId
+                        m_methods.put(methodId, constructors[i]);
+                        return constructors[i];
+                    }
+                }
             }
+
             // Cannot happen
-            m_logger.log(Logger.ERROR, "A methodID cannot be associated with a method from the POJO class: " + methodId);
+            m_logger.log(Logger.INFO, "A methodID cannot be associated with a method from the POJO class: " + methodId);
             return null;
         } else {
-            return method;
+            return member;
         }
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java?rev=1179231&r1=1179230&r2=1179231&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java Wed Oct  5 14:03:33 2011
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -18,21 +18,26 @@
  */
 package org.apache.felix.ipojo;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 
 /**
 * Method interceptor.
 * A class implementing this interface is able to be notified of method invocations (
 * i.e. entries, exits, and errors).
-* The listener needs to be register on the instance manager with the 
+* The listener needs to be register on the instance manager with the
 * {@link InstanceManager#register(org.apache.felix.ipojo.parser.MethodMetadata, MethodInterceptor)}
-* method. 
-* Events are sent before the method entry (onEntry), after the method returns (onExit), 
-* when an error is thrown by the method (onError), and before the after either a returns or an error (onFinally)
+* method.
+* Events are sent before the method entry (onEntry), after the method returns (onExit),
+* when an error is thrown by the method (onError), and before the after either a returns or an error (onFinally).
+*
+* Instead of a {@link Method} object, the callbacks received a {@link Member} object which can be either a {@link Method}
+* or a {@link Constructor}.
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
 public interface MethodInterceptor {
-    
+
     /**
      * This method is called when a thread enters in a method.
      * The given argument array is created from the method argument.
@@ -40,36 +45,36 @@ public interface MethodInterceptor {
      * @param method the invoked method.
      * @param args the arguments array.
      */
-    void onEntry(Object pojo, Method method, Object[] args);
+    void onEntry(Object pojo, Member method, Object[] args);
 
     /**
      * This method is called when the execution exits a method :
      * before a <code>return</code>.
-     * If the given returned object is <code>null</code>, either the method is 
+     * If the given returned object is <code>null</code>, either the method is
      * <code>void</code>, or it returns <code>null</code>.
      * This method must not modify the returned object.
      * @param pojo the pojo on which the method exits.
      * @param method the exiting method.
      * @param returnedObj the the returned object (boxed for primitive type)
      */
-    void onExit(Object pojo, Method method, Object returnedObj);
-    
+    void onExit(Object pojo, Member method, Object returnedObj);
+
     /**
-     * This method is called when the execution throws an exception in the given 
+     * This method is called when the execution throws an exception in the given
      * method.
      * @param pojo the pojo on which the method was accessed.
      * @param method the invoked method.
      * @param throwable the thrown exception
      */
-    void onError(Object pojo, Method method, Throwable throwable);
-    
+    void onError(Object pojo, Member method, Throwable throwable);
+
     /**
-     * This method is called when the execution of a method is going to terminate : 
+     * This method is called when the execution of a method is going to terminate :
      * just before to throw an exception or before to return.
      * (onError or onExit was already called).
      * @param pojo the pojo on which the method was accessed.
      * @param method the invoked method.
      */
-    void onFinally(Object pojo, Method method);
+    void onFinally(Object pojo, Member method);
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java?rev=1179231&r1=1179230&r2=1179231&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java Wed Oct  5 14:03:33 2011
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.ipojo;
 
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 
 import org.apache.felix.ipojo.parser.PojoMetadata;
@@ -34,7 +35,7 @@ import org.apache.felix.ipojo.util.Logge
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
 public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor,
-	ConstructorInjector {
+    ConstructorInjector {
 
     /**
      * The "Primitive" Handler type (value).
@@ -52,10 +53,10 @@ public abstract class PrimitiveHandler e
      */
     private ComponentFactory m_factory;
 
-	/**
-	 * Instance Logger used by the handler.
-	 */
-	private Logger m_instanceLogger;
+    /**
+     * Instance Logger used by the handler.
+     */
+    private Logger m_instanceLogger;
 
     /**
      * Attaches the current handler to the given instance.
@@ -83,9 +84,9 @@ public abstract class PrimitiveHandler e
      * @see org.apache.felix.ipojo.Handler#getLogger()
      */
     public Logger getLogger() {
-    	if (m_instanceLogger == null) {
-    		return m_factory.getLogger();
-    	}
+        if (m_instanceLogger == null) {
+            return m_factory.getLogger();
+        }
         return m_instanceLogger;
     }
 
@@ -167,7 +168,7 @@ public abstract class PrimitiveHandler e
      * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
      */
     public Object getConstructorParameter(int index) {
-    	return null;
+        return null;
     }
 
     /**
@@ -182,7 +183,7 @@ public abstract class PrimitiveHandler e
      * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
      */
     public Class getConstructorParameterType(int index) {
-    	return null;
+        return null;
     }
 
     /**
@@ -193,7 +194,7 @@ public abstract class PrimitiveHandler e
      * @param args the arguments array.
      * @see MethodInterceptor#onEntry(Object, Method, Object[])
      */
-    public void onEntry(Object pojo, Method method, Object[] args) {
+    public void onEntry(Object pojo, Member method, Object[] args) {
         // Nothing to do in the default implementation
     }
 
@@ -209,7 +210,7 @@ public abstract class PrimitiveHandler e
      * @param returnedObj the returned object (boxed for primitive type)
      * @see MethodInterceptor#onExit(Object, Method, Object)
      */
-    public void onExit(Object pojo, Method method, Object returnedObj) {
+    public void onExit(Object pojo, Member method, Object returnedObj) {
         // Nothing to do in the default implementation
     }
 
@@ -223,7 +224,7 @@ public abstract class PrimitiveHandler e
      * @param throwable the thrown exception
      * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
      */
-    public void onError(Object pojo, Method method, Throwable throwable) {
+    public void onError(Object pojo, Member method, Throwable throwable) {
         // Nothing to do in the default implementation
     }
 
@@ -237,7 +238,7 @@ public abstract class PrimitiveHandler e
      * @param pojo the pojo on which the method was accessed.
      * @param method the invoked method.
      */
-    public void onFinally(Object pojo, Method method) {
+    public void onFinally(Object pojo, Member method) {
         // Nothing to do in the default implementation
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=1179231&r1=1179230&r2=1179231&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Wed Oct  5 14:03:33 2011
@@ -22,6 +22,7 @@ import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
@@ -50,7 +51,7 @@ import org.osgi.framework.ServiceReferen
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor,
-	ConstructorInjector {
+    ConstructorInjector {
 
     /**
      * Reference on the Dependency Handler.
@@ -213,9 +214,9 @@ public class Dependency extends Dependen
 
 
     protected void addConstructorInjection(int index) throws ConfigurationException {
-    	m_index = index;
-    	m_usage = new ServiceUsage();
-    	m_handler.getInstanceManager().register(index, this);
+        m_index = index;
+        m_usage = new ServiceUsage();
+        m_handler.getInstanceManager().register(index, this);
     }
 
     /**
@@ -268,7 +269,7 @@ public class Dependency extends Dependen
         // This may happen during refresh.
         // So we just return.
         if (refs == null) {
-        	return;
+            return;
         }
 
         // Call bind callback.
@@ -358,9 +359,9 @@ public class Dependency extends Dependen
     }
 
     private Object createNullableObject() {
-    	 // To load the proxy we use the POJO class loader. Indeed, this classloader imports iPOJO (so can access to Nullable) and has
+         // To load the proxy we use the POJO class loader. Indeed, this classloader imports iPOJO (so can access to Nullable) and has
         // access to the service specification.
-    	try {
+        try {
             ClassLoader cl = new NullableClassLoader(
                     getHandler().getInstanceManager().getClazz().getClassLoader(),
                     getSpecification().getClassLoader());
@@ -391,7 +392,7 @@ public class Dependency extends Dependen
             if (m_di == null) {
                 // If nullable are supported, create the nullable object.
                 if (m_supportNullable) {
-                	createNullableObject();
+                    createNullableObject();
                 }
             } else {
                 // Create the default-implementation object.
@@ -414,20 +415,20 @@ public class Dependency extends Dependen
             if (isAggregate()) {
                 m_proxyObject = new ServiceCollection(this);
             } else {
-            	// Can we really proxy ? We can proxy only interfaces.
-            	if (getSpecification().isInterface()) {
-	                String type = getHandler().getInstanceManager().getContext().getProperty(DependencyHandler.PROXY_TYPE_PROPERTY);
-	                if (type == null || type.equals(DependencyHandler.SMART_PROXY)) {
-	                    SmartProxyFactory proxyFactory = new SmartProxyFactory(this.getClass().getClassLoader());
-	                    m_proxyObject = proxyFactory.getProxy(getSpecification(), this);
-	                } else {
-	                    DynamicProxyFactory proxyFactory = new DynamicProxyFactory();
-	                    m_proxyObject = proxyFactory.getProxy(getSpecification());
-	                }
-            	} else {
-            		m_handler.warn("Cannot create a proxy for a service dependency which is not an interface " +
-            				"- disabling proxy for " + getId());
-            	}
+                // Can we really proxy ? We can proxy only interfaces.
+                if (getSpecification().isInterface()) {
+                    String type = getHandler().getInstanceManager().getContext().getProperty(DependencyHandler.PROXY_TYPE_PROPERTY);
+                    if (type == null || type.equals(DependencyHandler.SMART_PROXY)) {
+                        SmartProxyFactory proxyFactory = new SmartProxyFactory(this.getClass().getClassLoader());
+                        m_proxyObject = proxyFactory.getProxy(getSpecification(), this);
+                    } else {
+                        DynamicProxyFactory proxyFactory = new DynamicProxyFactory();
+                        m_proxyObject = proxyFactory.getProxy(getSpecification());
+                    }
+                } else {
+                    m_handler.warn("Cannot create a proxy for a service dependency which is not an interface " +
+                            "- disabling proxy for " + getId());
+                }
             }
         }
 
@@ -737,7 +738,7 @@ public class Dependency extends Dependen
      * @param args : arguments
      * @see org.apache.felix.ipojo.MethodInterceptor#onEntry(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
      */
-    public void onEntry(Object pojo, Method method, Object[] args) {
+    public void onEntry(Object pojo, Member method, Object[] args) {
         if (m_usage != null) {
             Usage usage = (Usage) m_usage.get();
             usage.incComponentStack(); // Increment the number of component access.
@@ -756,7 +757,7 @@ public class Dependency extends Dependen
      * @param throwable : thrown error
      * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
      */
-    public void onError(Object pojo, Method method, Throwable throwable) {
+    public void onError(Object pojo, Member method, Throwable throwable) {
         // Nothing to do  : wait onFinally
     }
 
@@ -767,7 +768,7 @@ public class Dependency extends Dependen
      * @param returnedObj : returned object (null for void method)
      * @see org.apache.felix.ipojo.MethodInterceptor#onExit(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
      */
-    public void onExit(Object pojo, Method method, Object returnedObj) {
+    public void onExit(Object pojo, Member method, Object returnedObj) {
         // Nothing to do  : wait onFinally
     }
 
@@ -777,7 +778,7 @@ public class Dependency extends Dependen
      * @param method : Method object.
      * @see org.apache.felix.ipojo.MethodInterceptor#onFinally(java.lang.Object, java.lang.reflect.Method)
      */
-    public void onFinally(Object pojo, Method method) {
+    public void onFinally(Object pojo, Member method) {
         if (m_usage != null) {
             Usage usage = (Usage) m_usage.get();
             usage.decComponentStack();
@@ -891,10 +892,10 @@ public class Dependency extends Dependen
          */
         protected Class getProxyClass(Class clazz) {
             byte[] clz = ProxyGenerator.dumpProxy(clazz); // Generate the proxy.
-        	// Turn around the VM changes (FELIX-2716) about java.* classes.
+            // Turn around the VM changes (FELIX-2716) about java.* classes.
             String cn = clazz.getName();
             if (cn.startsWith("java.")) {
-            	cn = "$" + cn;
+                cn = "$" + cn;
             }
             return defineClass(cn + "$$Proxy", clz, 0, clz.length);
         }
@@ -1015,52 +1016,52 @@ public class Dependency extends Dependen
 
     }
 
-	/**
-	 * Gets the constructor parameter.
-	 * @return the index of the constructor parameter,
-	 * or <code>-1</code> if not set.
-	 */
-	public int getConstructorParameterIndex() {
-		return m_index;
-	}
-
-	/**
-	 * Gets the object to inject in the constructor parameter.
-	 * @param index the index of the parameter
-	 * @return the created proxy object
-	 * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
-	 */
-	public Object getConstructorParameter(int index) {
-		if (m_index == index  && m_proxyObject != null) {
-			return m_proxyObject;
-		}
-		return null;
-	}
-
-	/**
-	 * Gets the type of the constructor parameter.
-	 * @param index the parameter index
-	 * @return the class of the object. For scalar dependency, it's the
-	 * specification, for aggregate it depends of the container object:
-	 * {@link List} or {@link Set}.
-	 * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
-	 */
-	public Class getConstructorParameterType(int index) {
-		if (m_index == index  && m_proxyObject != null) {
-			if (isAggregate()) {
-				switch (m_type) {
-				case DependencyHandler.LIST: return List.class;
-				case DependencyHandler.SET : return Set.class;
-				//TODO We should also manage the Collection type.
-				default: return null; // Should never happen, it was checked before.
-				}
-			} else {
-				return getSpecification();
-			}
-		} else {
-			return null;
-		}
-	}
+    /**
+     * Gets the constructor parameter.
+     * @return the index of the constructor parameter,
+     * or <code>-1</code> if not set.
+     */
+    public int getConstructorParameterIndex() {
+        return m_index;
+    }
+
+    /**
+     * Gets the object to inject in the constructor parameter.
+     * @param index the index of the parameter
+     * @return the created proxy object
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
+     */
+    public Object getConstructorParameter(int index) {
+        if (m_index == index  && m_proxyObject != null) {
+            return m_proxyObject;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the type of the constructor parameter.
+     * @param index the parameter index
+     * @return the class of the object. For scalar dependency, it's the
+     * specification, for aggregate it depends of the container object:
+     * {@link List} or {@link Set}.
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
+     */
+    public Class getConstructorParameterType(int index) {
+        if (m_index == index  && m_proxyObject != null) {
+            if (isAggregate()) {
+                switch (m_type) {
+                case DependencyHandler.LIST: return List.class;
+                case DependencyHandler.SET : return Set.class;
+                //TODO We should also manage the Collection type.
+                default: return null; // Should never happen, it was checked before.
+                }
+            } else {
+                return getSpecification();
+            }
+        } else {
+            return null;
+        }
+    }