Add a service.pid inside factories.
Add a new kind of requirement callback (Service Object, Service Reference)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@580366 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 7504220..6982b32 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -848,6 +848,7 @@
         props.put("component.class", m_componentClassName);
        
         props.put("factory.name", m_factoryName);
+        props.put(Constants.SERVICE_PID, m_factoryName); // Service PID is required for the integration in the configuration admin.
         if (m_typeName != null) {
             props.put("component.type", m_typeName);
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
index fe5f033..70540cd 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -49,9 +49,9 @@
     private int m_methodType;
     
     /**
-     * Argument of the callback.
+     * Arguments of the callback.
      */
-    private String m_argument;
+    private String[] m_argument;
 
     /**
      * Callback method name.
@@ -71,7 +71,7 @@
     /**
      * Constructor.
      * 
-     * @param dep : the dependency attached to this depednency callback
+     * @param dep : the dependency attached to this dependency callback
      * @param method : the method to call
      * @param methodType : is the method to call a bind method or an unbind
      * method
@@ -95,32 +95,16 @@
      * Set the argument type (Empty or the class name).
      * @param arg : the type name or EMPTY
      */
-    public void setArgument(String arg) {
+    public void setArgument(String[] arg) {
         m_argument = arg;
-        if ("EMPTY".equals(arg)) {
-            m_callback = new Callback(m_method, new String[0], false, m_manager);
-        } else {
-            m_callback = new Callback(m_method, new String[] {arg}, false, m_manager);
-        }
-        
+        m_callback = new Callback(m_method, arg, false, m_manager);        
     }
     
-    public String getArgument() {
+    public String[] getArgument() {
         return m_argument;
     }
 
     /**
-     * Call the callback method.
-     * 
-     * @throws NoSuchMethodException : Method is not found in the class
-     * @throws InvocationTargetException : The method is not static
-     * @throws IllegalAccessException : The method can not be invoked
-     */
-    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        m_callback.call();
-    }
-
-    /**
      * Call the callback method with a service reference.
      * 
      * @param ref : the service reference to send to the method
@@ -130,14 +114,22 @@
      * @throws IllegalAccessException : The method can not be invoked
      */
     protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if ("EMPTY".equals(m_argument)) {
-            m_callback.call(new Object[] {});
-        } else {
-            if (m_argument.equals(ServiceReference.class.getName())) {
-                m_callback.call(new Object[] {ref});
-            } else {
-                m_callback.call(new Object[] {obj});
-            }
+        switch (m_argument.length) {
+            case 0 :
+                m_callback.call(new Object[0]);
+                break;
+            case 1 : 
+                if (m_argument[0].equals(ServiceReference.class.getName())) {
+                    m_callback.call(new Object[] {ref});
+                } else {
+                    m_callback.call(new Object[] {obj});
+                }
+                break;
+            case 2 :
+                m_callback.call(new Object[] {obj, ref});
+                break;
+            default : 
+                break;
         }
     }
 
@@ -153,28 +145,22 @@
      * @throws InvocationTargetException
      */
     protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if ("EMPTY".equals(m_argument)) {
-            m_callback.call(instance, new Object[] {});
-            return;
+        switch (m_argument.length) {
+            case 0 :
+                m_callback.call(instance, new Object[0]);
+                break;
+            case 1 : 
+                if (m_argument[0].equals(ServiceReference.class.getName())) {
+                    m_callback.call(instance, new Object[] {ref});
+                } else {
+                    m_callback.call(instance, new Object[] {obj});
+                }
+                break;
+            case 2 :
+                m_callback.call(instance, new Object[] {obj, ref});
+                break;
+            default : 
+                break;
         }
-        if (m_argument.equals(ServiceReference.class.getName())) {
-            m_callback.call(instance, new Object[] {ref});
-        } else {
-            m_callback.call(instance, new Object[] {obj});
-        }
-    }
-
-    /**
-     * Call the callback on the given instance with the given argument.
-     * 
-     * @param instance : the instance on which call the callback
-     * @param o : the service object to send to the callback
-     * @throws NoSuchMethodException : the method is not found
-     * @throws IllegalAccessException : the method could not be called
-     * @throws InvocationTargetException : an error happens in the called method
-     * @throws InvocationTargetException
-     */
-    protected void callOnInstance(Object instance, Object o) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        m_callback.call(instance, new Object[] {o});
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 206734f..7b7c839 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -147,17 +147,15 @@
         for (int i = 0; i < callbacks.length; i++) {
             MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
             if (mets.length == 0) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation");
+                log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation");
                 throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation", getInstanceManager().getFactory().getName());
             }
-            if (mets[0].getMethodArguments().length > 1) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument");
-                throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument", getInstanceManager().getFactory().getName());
+            if (mets[0].getMethodArguments().length > 2) {
+                log(Logger.ERROR, "A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 or 2 arguments");
+                throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 or 2 arguments", getInstanceManager().getFactory().getName());
             }
-            if (mets[0].getMethodArguments().length == 0) {
-                callbacks[i].setArgument("EMPTY");
-            } else {
-                callbacks[i].setArgument(mets[0].getMethodArguments()[0]);
+            callbacks[i].setArgument(mets[0].getMethodArguments());
+            if (mets[0].getMethodArguments().length == 1) {
                 if (!mets[0].getMethodArguments()[0].equals(ServiceReference.class.getName())) {
                     if (dep.getSpecification() == null) {
                         dep.setSpecification(mets[0].getMethodArguments()[0]);
@@ -168,13 +166,31 @@
                         dep.setSpecification(mets[0].getMethodArguments()[0]);
                     }
                 }
+            } else if (mets[0].getMethodArguments().length == 2) {
+                // Check that the second arguments is a service reference
+                if (!mets[0].getMethodArguments()[1].equals(ServiceReference.class.getName())) {
+                    String message = "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second arguments";
+                    log(Logger.ERROR, message);
+                    throw new ConfigurationException(message, getInstanceManager().getFactory().getName());
+                }
+                if (dep.getSpecification() == null) {
+                    dep.setSpecification(mets[0].getMethodArguments()[0]);
+                } else {
+                    if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
+                        log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification()
+                                + "] are not the same");
+                        dep.setSpecification(mets[0].getMethodArguments()[0]);
+                    }
+                }
+                
             }
+            
         }
 
         if (field != null) {
             FieldMetadata fm = manipulation.getField(field);
             if (fm == null) {
-                getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A requirement field " + field + " does not exist in the implementation class");
+                log(Logger.ERROR, "A requirement field " + field + " does not exist in the implementation class");
                 throw new ConfigurationException("Requirement Callback : A requirement field " + field + " does not exist in the implementation class", getInstanceManager().getFactory().getName());
             }
             String type = fm.getFieldType();
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
index b90e6b6..4f84322 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -186,7 +186,7 @@
     
     /**
      * Search the method object in the POJO by analyzing present method.
-     * The name of the maethod and the argument type are checked.
+     * The name of the method and the argument type are checked.
      */
     private void searchMethod() {
         Method[] methods = m_manager.getClazz().getDeclaredMethods();
@@ -249,26 +249,7 @@
      * @throws IllegalAccessException : The method can not be invoked
      */
     public Object call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if (m_methodObj == null) {
-            searchMethod();
-        }
-
-        if (m_isStatic) {
-            return m_methodObj.invoke(null, new Object[] {});
-        } else {
-            // Two cases :
-            // - if instances already exists : call on each instances
-            // - if no instance exists : create an instance
-            if (m_manager.getPojoObjects().length == 0) {
-                return m_methodObj.invoke(m_manager.getPojoObject(), new Object[] {});
-            } else {
-                Object r = null;
-                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
-                    r = m_methodObj.invoke(m_manager.getPojoObjects()[i], new Object[] {});
-                }
-                return r;
-            }
-        }
+        return call(new Object[0]);
     }
 
     /**
@@ -277,14 +258,11 @@
      * @param instance : instance on which call the callback
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the method was not found
-     * @throws IllegalAccessException : the method cannont be called
+     * @throws IllegalAccessException : the method cannot be called
      * @throws InvocationTargetException : an error happens in the method
      */
     public Object call(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        if (m_methodObj == null) {
-            searchMethod();
-        }
-        return m_methodObj.invoke(instance, new Object[] {});
+        return call(instance, new Object[0]);
     }
 
     /**
@@ -328,7 +306,7 @@
      * @param arg : the argument array
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the callback method is not found
-     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws IllegalAccessException : the callback method cannot be called
      * @throws InvocationTargetException : an error occurs inside the called
      * method
      */