Applied patch (FELIX-227) to enable callbacks for properties and service
dependencies.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@531951 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index d988294..fa474d7 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -72,9 +72,10 @@
/**
* @return the method list.
- * Modified for performance issue.
*/
- public List getMethods() { /*return m_methods;*/ return new ArrayList(); }
+ public List getMethods() {
+ return m_methods;
+ }
/**
* Manipulate the class.
@@ -83,6 +84,11 @@
* @throws Exception : throwed if the manipulation failed.
*/
public boolean preProcess(String name, File outputDirectory) throws Exception {
+
+ // Init field, itfs and methods
+ m_fields = new HashMap();
+ m_interfaces = new String[0];
+ m_methods = new ArrayList();
// gets an input stream to read the bytecode of the class
String path = outputDirectory+"/"+name.replace('.', '/') + ".class";
diff --git a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
index 7d1922d..cd1d457 100644
--- a/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
+++ b/ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
@@ -25,16 +25,24 @@
public Element getElement() {
Element method = new Element("method", "");
method.addAttribute(new Attribute("name", m_name));
- method.addAttribute(new Attribute("return", m_returnType));
- String args = "{";
- if(m_arguments.length > 0) {
+
+ // Add return
+ if(!m_returnType.equals("void")) {
+ method.addAttribute(new Attribute("return", m_returnType));
+ }
+
+ // Add arguments
+ if(m_arguments.length > 0) {
+ String args = "{";
args += m_arguments[0];
for(int i = 1; i < m_arguments.length; i++) {
args += "," + m_arguments[i];
}
+ args += "}";
+ method.addAttribute(new Attribute("arguments", args));
}
- args += "}";
- method.addAttribute(new Attribute("arguments", args));
+
+
return method;
}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 99d20d7..c36a8d6 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -81,10 +81,7 @@
/**
* Classloader to delegate loading.
*/
- private FactoryClassloader m_classLoader = null; // TODO is this
-
- // classloader really
- // useful ?
+ private FactoryClassloader m_classLoader = null;
/**
* Component Type provided by this factory. //TODO Should be keep this
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
index 5a184b4..9888082 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
@@ -23,6 +23,7 @@
import java.lang.reflect.InvocationTargetException;
import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.util.Callback;
import org.apache.felix.ipojo.util.Logger;
/**
@@ -43,34 +44,62 @@
private String m_field;
/**
+ * Method of the property.
+ */
+ private String m_method;
+
+ /**
* Value of the property.
*/
private Object m_value;
/**
+ * Type of the property.
+ */
+ private Class m_type;
+
+ /**
* Configuration Handler managing this property.
*/
private ConfigurationHandler m_handler;
/**
- * Configurable Property Constructor.
+ * Configurable Property Constructor. At least the method or the field need
+ * to be referenced.
*
- * @param name : name of the property (optional)
- * @param field : name of the field (mandatory)
- * @param value : initial value of the property (optional)
- * @param type : the type of the property
- * @param ch : configuration handler managing this configurable property
+ * @param name :
+ * name of the property (optional)
+ * @param field :
+ * name of the field
+ * @param method :
+ * method name
+ * @param value :
+ * initial value of the property (optional)
+ * @param type :
+ * the type of the property
+ * @param ch :
+ * configuration handler managing this configurable property
*/
- public ConfigurableProperty(String name, String field, String value, String type, ConfigurationHandler ch) {
+ public ConfigurableProperty(String name, String field, String method, String value, String type,
+ ConfigurationHandler ch) {
m_handler = ch;
+
+ m_field = field;
+ m_method = method;
+
if (name != null) {
m_name = name;
} else {
- m_name = field;
+ if (m_field != null) {
+ m_name = field;
+ } else {
+ m_name = method;
+ }
}
m_field = field;
+
if (value != null) {
- setValue(m_field, value, type);
+ setValue(value, type);
}
}
@@ -78,37 +107,51 @@
/**
* Set the value of the property.
*
- * @param field : name of the field attached to the property
- * @param strValue : value of the property (String)
- * @param type : type of the property
+ * @param strValue :
+ * value of the property (String)
+ * @param type :
+ * type of the property
*/
- private void setValue(String field, String strValue, String type) {
+ private void setValue(String strValue, String type) {
Object value = null;
if (type.equals("string") || type.equals("String")) {
value = new String(strValue);
+ m_type = java.lang.String.class;
}
if (type.equals("boolean")) {
value = new Boolean(strValue);
+ m_type = Boolean.TYPE;
}
if (type.equals("byte")) {
value = new Byte(strValue);
+ m_type = Byte.TYPE;
}
if (type.equals("short")) {
value = new Short(strValue);
+ m_type = Short.TYPE;
}
if (type.equals("int")) {
value = new Integer(strValue);
+ m_type = Integer.TYPE;
}
if (type.equals("long")) {
value = new Long(strValue);
+ m_type = Long.TYPE;
}
if (type.equals("float")) {
value = new Float(strValue);
+ m_type = Float.TYPE;
}
if (type.equals("double")) {
value = new Double(strValue);
+ m_type = Double.TYPE;
}
+ if (type.equals("char")) {
+ value = new Character(strValue.charAt(0));
+ m_type = Character.TYPE;
+ }
+
// Array :
if (type.endsWith("[]")) {
String internalType = type.substring(0, type.length() - 2);
@@ -120,25 +163,28 @@
// Else it is a neither a primitive type neither a String -> create
// the object by calling a constructor with a string in argument.
try {
- Class c = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
- Constructor cst = c.getConstructor(new Class[] { String.class });
+ m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
+ Constructor cst = m_type.getConstructor(new Class[] { String.class });
value = cst.newInstance(new Object[] { strValue });
} catch (ClassNotFoundException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
"Class not found exception in setValue on " + type + " : " + e.getMessage());
return;
} catch (SecurityException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security excption in setValue on " + type + " : " + e.getMessage());
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Security excption in setValue on " + type + " : " + e.getMessage());
return;
} catch (NoSuchMethodException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
"Constructor not found exeption in setValue on " + type + " : " + e.getMessage());
return;
} catch (IllegalArgumentException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + type);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Argument problem to call the constructor of the type " + type);
return;
} catch (InstantiationException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem " + type);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Instantiation problem " + type);
return;
} catch (IllegalAccessException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access " + type);
@@ -156,8 +202,10 @@
/**
* Set array value to the current property.
*
- * @param internalType : type of the property
- * @param values : new property value
+ * @param internalType :
+ * type of the property
+ * @param values :
+ * new property value
*/
private void setArrayValue(String internalType, String[] values) {
if (internalType.equals("string") || internalType.equals("String")) {
@@ -166,6 +214,7 @@
str[i] = new String(values[i]);
}
m_value = str;
+ m_type = new String[0].getClass();
return;
}
if (internalType.equals("boolean")) {
@@ -174,6 +223,7 @@
bool[i] = new Boolean(values[i]).booleanValue();
}
m_value = bool;
+ m_type = new boolean[0].getClass();
return;
}
if (internalType.equals("byte")) {
@@ -182,6 +232,7 @@
byt[i] = new Byte(values[i]).byteValue();
}
m_value = byt;
+ m_type = new byte[0].getClass();
return;
}
if (internalType.equals("short")) {
@@ -190,6 +241,7 @@
shor[i] = new Short(values[i]).shortValue();
}
m_value = shor;
+ m_type = new short[0].getClass();
return;
}
if (internalType.equals("int")) {
@@ -198,6 +250,7 @@
in[i] = new Integer(values[i]).intValue();
}
m_value = in;
+ m_type = new int[0].getClass();
return;
}
if (internalType.equals("long")) {
@@ -206,6 +259,7 @@
ll[i] = new Long(values[i]).longValue();
}
m_value = ll;
+ m_type = new long[0].getClass();
return;
}
if (internalType.equals("float")) {
@@ -214,6 +268,7 @@
fl[i] = new Float(values[i]).floatValue();
}
m_value = fl;
+ m_type = new float[0].getClass();
return;
}
if (internalType.equals("double")) {
@@ -222,6 +277,16 @@
dl[i] = new Double(values[i]).doubleValue();
}
m_value = dl;
+ m_type = new double[0].getClass();
+ return;
+ }
+ if (internalType.equals("char")) {
+ char[] dl = new char[values.length];
+ for (int i = 0; i < values.length; i++) {
+ dl[i] = values[i].toCharArray()[0];
+ }
+ m_value = dl;
+ m_type = new char[0].getClass();
return;
}
@@ -235,21 +300,29 @@
ob[i] = cst.newInstance(new Object[] { values[i].trim() });
}
m_value = ob;
+ m_type = ob.getClass();
return;
} catch (ClassNotFoundException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setValue on " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Class not found exception in setValue on " + internalType);
} catch (SecurityException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Secutiry Exception in setValue on " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Secutiry Exception in setValue on " + internalType);
} catch (NoSuchMethodException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exception in setValue on " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Constructor not found exception in setValue on " + internalType);
} catch (IllegalArgumentException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Argument problem to call the constructor of the type " + internalType);
} catch (InstantiationException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Instantiation problem " + internalType);
} catch (IllegalAccessException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Illegal Access Exception in " + internalType);
} catch (InvocationTargetException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + internalType);
+ m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+ "Invocation problem " + internalType);
}
}
@@ -261,6 +334,9 @@
return m_field;
}
+ public String getMethod() {
+ return m_method;
+ }
public Object getValue() {
return m_value;
@@ -269,9 +345,69 @@
/**
* Fix the value of the property.
*
- * @param value : the new value.
+ * @param value :
+ * the new value.
*/
public void setValue(Object value) {
m_value = value;
}
+
+ /**
+ * Invoke the method (if specified).
+ */
+ public void invoke() {
+ Callback cb = new Callback(m_method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
+ try {
+ cb.call(new Object[] { m_value });
+ } catch (NoSuchMethodException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_method + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
+ } catch (IllegalAccessException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_method + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
+ } catch (InvocationTargetException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Handler createInstance method. This method is overided to allow delayed
+ * callback invocation.
+ *
+ * @param instance :
+ * the created object
+ * @see org.apache.felix.ipojo.Handler#createInstance(java.lang.Object)
+ */
+ public void invoke(Object instance) {
+ Callback cb = new Callback(m_method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
+ try {
+ cb.call(instance, new Object[] { m_value });
+ } catch (NoSuchMethodException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_method + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
+ } catch (IllegalAccessException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_method + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
+ } catch (InvocationTargetException e) {
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
+ return;
+ }
+ }
}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 53a1904..4d02926 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.ipojo.handlers.configuration;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Properties;
@@ -28,6 +29,7 @@
import org.apache.felix.ipojo.architecture.PropertyDescription;
import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
import org.apache.felix.ipojo.util.Logger;
import org.osgi.framework.ServiceRegistration;
@@ -113,12 +115,26 @@
Element[] configurables = confs[0].getElements("Property");
for (int i = 0; i < configurables.length; i++) {
- String fieldName = configurables[i].getAttribute("field");
+ String fieldName = null;
+ String methodName = null;
+
+ if (configurables[i].containsAttribute("field")) { fieldName = configurables[i].getAttribute("field"); }
+ if (configurables[i].containsAttribute("method")) { methodName = configurables[i].getAttribute("method"); }
+
+ if (fieldName == null && methodName == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "A configurable property need to have at least a field or a method");
+ return;
+ }
+
String name = null;
if (configurables[i].containsAttribute("name")) {
name = configurables[i].getAttribute("name");
} else {
- name = fieldName;
+ if (fieldName != null) {
+ name = fieldName;
+ } else {
+ name = methodName;
+ }
}
String value = null;
if (configurables[i].containsAttribute("value")) {
@@ -136,18 +152,38 @@
// Detect the type of the property
Element manipulation = metadata.getElements("Manipulation")[0];
String type = null;
- for (int kk = 0; kk < manipulation.getElements("Field").length; kk++) {
- if (fieldName.equals(manipulation.getElements("Field")[kk].getAttribute("name"))) {
- type = manipulation.getElements("Field")[kk].getAttribute("type");
+ if (fieldName != null) {
+ for (int kk = 0; kk < manipulation.getElements("Field").length; kk++) {
+ if (fieldName.equals(manipulation.getElements("Field")[kk].getAttribute("name"))) {
+ type = manipulation.getElements("Field")[kk].getAttribute("type");
+ }
+ }
+ if (type == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR,
+ "[" + m_manager.getClassName() + "] The field " + fieldName + " does not exist in the implementation");
+ return;
+ }
+ } else {
+ for (int kk = 0; kk < manipulation.getElements("Method").length; kk++) {
+ if (methodName.equals(manipulation.getElements("Method")[kk].getAttribute("name"))) {
+ if (manipulation.getElements("Method")[kk].containsAttribute("arguments")) {
+ String[] arg = ParseUtils.parseArrays(manipulation.getElements("Method")[kk].getAttribute("arguments"));
+ if (arg.length != 1) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "A configurable property need to have a method with only one argument");
+ return;
+ }
+ type = arg[0];
+ }
+ }
+ }
+ if (type == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR,
+ "The method " + methodName + " does not exist in the implementation, or does not have one argument");
+ return;
}
}
- if (type == null) {
- m_manager.getFactory().getLogger().log(Logger.ERROR,
- "[" + m_manager.getClassName() + "] The field " + fieldName + " does not exist in the implementation");
- return;
- }
- ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, value, type, this);
+ ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, methodName, value, type, this);
if (cp.getValue() != null) {
cd.addProperty(new PropertyDescription(name, type, cp.getValue().toString()));
@@ -159,9 +195,11 @@
}
if (configurables.length > 0) {
- String[] fields = new String[m_configurableProperties.length];
+ ArrayList ff = new ArrayList();
for (int k = 0; k < m_configurableProperties.length; k++) {
- fields[k] = m_configurableProperties[k].getField();
+ if (m_configurableProperties[k].getField() != null) {
+ ff.add(m_configurableProperties[k].getField());
+ }
// Check if the instance configuration contains value for the
// current property :
@@ -175,7 +213,7 @@
}
}
}
- m_manager.register(this, fields);
+ m_manager.register(this, (String[]) ff.toArray(new String[0]));
}
}
@@ -321,12 +359,13 @@
if (m_configurableProperties[i].getName().equals(name)) {
// Check if the value has change
if (m_configurableProperties[i].getValue() == null || !m_configurableProperties[i].getValue().equals(value)) {
- m_manager.setterCallback(m_configurableProperties[i].getField(), value); // says
- // that
- // the
- // value
- // has
- // changed
+ if (m_configurableProperties[i].getField() != null) {
+ m_manager.setterCallback(m_configurableProperties[i].getField(), value); // says that the value has changed
+ }
+ if (m_configurableProperties[i].getMethod() != null) {
+ m_configurableProperties[i].setValue(value);
+ m_configurableProperties[i].invoke();
+ }
}
find = true;
// Else do nothing
@@ -349,5 +388,20 @@
m_propagated = toPropagate;
}
}
+
+ /**
+ * Handler createInstance method.
+ * This method is overided to allow delayed callback invocation.
+ * @param instance : the created object
+ * @see org.apache.felix.ipojo.Handler#createInstance(java.lang.Object)
+ */
+ public void createInstance(Object instance) {
+ for (int i = 0; i < m_configurableProperties.length; i++) {
+ if (m_configurableProperties[i].getMethod() != null) {
+ m_configurableProperties[i].invoke(instance);
+ }
+ }
+ }
+
}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
index 78059fd..4e0b298 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -70,7 +70,7 @@
/**
* Is the dependency a multiple dependency ?
*/
- private boolean m_isMultiple = false;
+ private boolean m_isAggregate = false;
/**
* Is the Dependency an optional dependency ?
@@ -125,13 +125,15 @@
* @param spec : required specification
* @param filter : LDAP filter of the dependency
* @param isOptional : is the dependency an optional dependency ?
+ * @param isAggregate : is the dependency an aggregate dependency
*/
- public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional) {
+ public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate) {
m_handler = dh;
m_field = field;
m_specification = spec;
m_isOptional = isOptional;
m_strFilter = filter;
+ m_isAggregate = isAggregate;
}
public String getField() {
@@ -149,15 +151,15 @@
}
- public boolean isMultiple() {
- return m_isMultiple;
+ public boolean isAggregate() {
+ return m_isAggregate;
}
/**
- * Set the dependency to multiple.
+ * Set the dependency to aggregate.
*/
- protected void setMultiple() {
- m_isMultiple = true;
+ protected void setAggregate() {
+ m_isAggregate = true;
}
/**
@@ -201,7 +203,7 @@
*/
public HashMap getUsedServices() {
HashMap hm = new HashMap();
- if (m_isMultiple) {
+ if (m_isAggregate) {
for (int i = 0; i < m_ref.length; i++) {
if (i < m_services.length) {
hm.put(((Object) m_services[i]).toString(), m_ref[i]);
@@ -241,7 +243,7 @@
// 1 : Test if there is any change in the reference list :
if (!m_change) {
- if (!m_isMultiple) {
+ if (!m_isAggregate) {
if (m_services.length > 0) {
return m_services[0];
}
@@ -268,7 +270,7 @@
// 3 : The service object list is populated, I return either the
// first service object, either the array.
// Return null or an empty array if no service are found.
- if (!m_isMultiple) {
+ if (!m_isAggregate) {
if (m_services.length > 0) {
return m_services[0];
} else {
@@ -309,7 +311,7 @@
} catch (Exception e) {
// There is a problem in the dependency resolving (like in stopping
// method)
- if (!m_isMultiple) {
+ if (!m_isAggregate) {
m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
"[" + m_handler.getInstanceManager().getClassName() + "] Return null, an exception was throwed in the get method", e);
return null;
@@ -371,7 +373,7 @@
addReference(ref);
if (isSatisfied()) {
m_state = RESOLVED;
- if (m_isMultiple || m_ref.length == 1) {
+ if (m_isAggregate || m_ref.length == 1) {
m_change = true;
callBindMethod(ref);
}
@@ -386,10 +388,10 @@
*/
private void departureManagement(ServiceReference ref) {
// Call unbind method
- if (!m_isMultiple && ref == m_ref[0]) {
+ if (!m_isAggregate && ref == m_ref[0]) {
callUnbindMethod(ref);
}
- if (m_isMultiple) {
+ if (m_isAggregate) {
callUnbindMethod(ref);
}
@@ -405,16 +407,16 @@
m_state = RESOLVED;
}
// Is there any change ?
- if (!m_isMultiple && index == 0) {
+ if (!m_isAggregate && index == 0) {
m_change = true;
if (m_ref.length != 0) {
callBindMethod(m_ref[0]);
}
}
- if (!m_isMultiple && index != 0) {
+ if (!m_isAggregate && index != 0) {
m_change = false;
}
- if (m_isMultiple) {
+ if (m_isAggregate) {
m_change = true;
}
@@ -431,57 +433,24 @@
if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
for (int i = 0; i < m_callbacks.length; i++) {
if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
- // Try to call the bind method with a service reference
- // inside
try {
- m_callbacks[i].call(ref);
+ m_callbacks[i].call(ref, m_handler.getInstanceManager().getContext().getService(ref));
} catch (NoSuchMethodException e) {
- // The method was not found : try without service
- // reference
- try {
- m_callbacks[i].call();
- } catch (NoSuchMethodException e1) {
- // The method was not found : try with the service
- // object
- try {
- m_callbacks[i].call(m_handler.getInstanceManager().getContext().getService(ref));
- } catch (NoSuchMethodException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Unbind method not found", e2);
- return;
- } catch (IllegalAccessException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on unbind method",
- e2);
- return;
- } catch (InvocationTargetException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the unbind method", e2);
- return;
- }
- } catch (IllegalAccessException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on unbind method", e1);
- return;
- } catch (InvocationTargetException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the unbind method", e1);
- return;
- }
-
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
} catch (IllegalAccessException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e);
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
return;
} catch (InvocationTargetException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(
Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e);
+ "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
return;
}
}
@@ -501,65 +470,29 @@
return;
}
- if (m_isMultiple) {
+ if (m_isAggregate) {
for (int i = 0; i < m_ref.length; i++) {
for (int j = 0; j < m_callbacks.length; j++) {
if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
- // Try to call the bind method with a service reference
- // inside
try {
- m_callbacks[j].callOnInstance(instance, m_ref[i]);
+ m_callbacks[j].callOnInstance(instance, m_ref[i], m_handler.getInstanceManager()
+ .getContext().getService(m_ref[i]));
} catch (NoSuchMethodException e) {
- // The method was not found : try without service
- // reference
- try {
- m_callbacks[j].callOnInstance(instance);
- } catch (NoSuchMethodException e1) {
- // The method was not found : try with the
- // service object
- try {
- m_callbacks[j].callOnInstance(instance, m_handler.getInstanceManager().getContext().getService(m_ref[i]));
- } catch (NoSuchMethodException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
- return;
- } catch (IllegalAccessException e2) {
- m_handler.getInstanceManager().getFactory().getLogger()
- .log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Illegal access on bind method", e2);
- return;
- } catch (InvocationTargetException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e2);
- return;
- }
- } catch (IllegalAccessException e1) {
- m_handler.getInstanceManager().getFactory().getLogger()
- .log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Illegal access on bind method", e1);
- return;
- } catch (InvocationTargetException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e1);
- return;
- }
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
} catch (IllegalAccessException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e);
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
return;
} catch (InvocationTargetException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(
Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method" + e);
+ "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
return;
}
}
@@ -568,59 +501,24 @@
} else {
for (int j = 0; j < m_callbacks.length; j++) {
if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
- // Try to call the bind method with a service reference
- // inside
try {
- m_callbacks[j].callOnInstance(instance, m_ref[0]);
+ m_callbacks[j].callOnInstance(instance, m_ref[0], m_handler.getInstanceManager().getContext().getService(m_ref[0]));
} catch (NoSuchMethodException e) {
- // The method was not found : try without service
- // reference
- try {
- m_callbacks[j].callOnInstance(instance);
- } catch (NoSuchMethodException e1) {
- // The method was not found : try with the service
- // object
- try {
- m_callbacks[j].callOnInstance(instance, m_handler.getInstanceManager().getContext().getService(m_ref[0]));
- } catch (NoSuchMethodException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
- return;
- } catch (IllegalAccessException e2) {
- m_handler.getInstanceManager().getFactory().getLogger()
- .log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Illegal access on bind method", e2);
- return;
- } catch (InvocationTargetException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e2);
- return;
- }
- } catch (IllegalAccessException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e1);
- return;
- } catch (InvocationTargetException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e1);
- return;
- }
-
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
} catch (IllegalAccessException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e);
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
return;
} catch (InvocationTargetException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(
Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e);
+ "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
return;
}
}
@@ -638,61 +536,24 @@
if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
for (int i = 0; i < m_callbacks.length; i++) {
if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
- // Try to call the bind method with a service reference
- // inside
try {
- m_callbacks[i].call(ref);
+ m_callbacks[i].call(ref, m_handler.getInstanceManager().getContext().getService(ref));
} catch (NoSuchMethodException e) {
- // The method was not found : try without service
- // reference
- try {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Call the Bind method");
- m_callbacks[i].call();
- } catch (NoSuchMethodException e1) {
- // The method was not found : try with the service
- // object
- try {
- m_callbacks[i].call(m_handler.getInstanceManager().getContext().getService(ref));
- } catch (NoSuchMethodException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Bind method not found", e2);
- return;
- } catch (IllegalAccessException e2) {
- m_handler.getInstanceManager().getFactory().getLogger()
- .log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Illegal access on bind method", e2);
- return;
- } catch (InvocationTargetException e2) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e2);
- return;
- }
- } catch (IllegalAccessException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e1);
- return;
- } catch (InvocationTargetException e1) {
- m_handler.getInstanceManager().getFactory().getLogger().log(
- Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e1);
- return;
- }
-
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
+ + m_handler.getInstanceManager().getClassName());
+ return;
} catch (IllegalAccessException e) {
- m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName() + "] Dependency Callback Error : Illegal access on bind method", e);
+ m_handler.getInstanceManager().getFactory().getLogger().log(
+ Logger.ERROR,
+ "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class "
+ + m_handler.getInstanceManager().getClassName());
return;
} catch (InvocationTargetException e) {
m_handler.getInstanceManager().getFactory().getLogger().log(
Logger.ERROR,
- "[" + m_handler.getInstanceManager().getClassName()
- + "] Dependency Callback Error : Invocation Target Exception in the bind method", e);
+ "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
+ + "thorws an exception : " + e.getMessage());
return;
}
}
@@ -861,5 +722,9 @@
}
return idx;
}
+
+ protected DependencyCallback[] getCallbacks() {
+ return m_callbacks;
+ }
}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
index 33a8fa6..b0777fb 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -19,10 +19,9 @@
package org.apache.felix.ipojo.handlers.dependency;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import org.apache.felix.ipojo.InstanceManager;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Callback;
import org.osgi.framework.ServiceReference;
/**
@@ -42,21 +41,27 @@
* Unbind method (called when a service disappears).
*/
public static final int UNBIND = 1;
+
/**
* Is the method a bind method or an unbind method ?
*/
private int m_methodType;
+
+ /**
+ * Argument of the callback.
+ */
+ private String m_argument;
/**
* Callback method name.
*/
- private String m_callback;
+ private String m_method;
/**
* Is the callback a static callback.
*/
- private boolean m_isStatic;
+ private Callback m_callback;
/**
* The instance manager.
@@ -70,12 +75,10 @@
* @param method : the method to call
* @param methodType : is the method to call a bind method or an unbind
* method
- * @param isStatic : is the method to call static ?
*/
- public DependencyCallback(Dependency dep, String method, int methodType, boolean isStatic) {
+ public DependencyCallback(Dependency dep, String method, int methodType) {
m_methodType = methodType;
- m_callback = method;
- m_isStatic = isStatic;
+ m_method = method;
m_manager = dep.getDependencyHandler().getInstanceManager();
}
@@ -83,6 +86,28 @@
public int getMethodType() {
return m_methodType;
}
+
+ public String getMethodName() {
+ return m_method;
+ }
+
+ /**
+ * Set the argument type (Empty or the class name).
+ * @param arg : the type name or EMPTY
+ */
+ public void setArgument(String arg) {
+ m_argument = arg;
+ if (arg.equals("EMPTY")) {
+ 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);
+ }
+
+ }
+
+ public String getArgument() {
+ return m_argument;
+ }
/**
* Call the callback method.
@@ -92,118 +117,51 @@
* @throws IllegalAccessException : The method can not be invoked
*/
protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Get the method object
- Method method = m_manager.getClazz().getDeclaredMethod(m_callback, new Class[] {});
- method.setAccessible(true);
-
- if (m_isStatic) {
- method.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) {
- m_manager.getFactory().getLogger()
- .log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
- method.invoke(m_manager.getPojoObject(), new Object[] {});
- } else {
- for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
- method.invoke(m_manager.getPojoObjects()[i], new Object[] {});
- }
- }
- }
+ m_callback.call();
}
/**
* Call the callback method with a service reference.
*
* @param ref : the service reference to send to the method
+ * @param obj : the service object
* @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(ServiceReference ref) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Get the method object
- Method method = m_manager.getClazz().getDeclaredMethod(m_callback, new Class[] { ServiceReference.class });
- method.setAccessible(true);
-
- if (m_isStatic) {
- method.invoke(null, new Object[] { ref });
+ protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (m_argument.equals("EMPTY")) {
+ m_callback.call(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) {
- m_manager.getFactory().getLogger()
- .log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
- method.invoke(m_manager.getPojoObject(), new Object[] { ref });
+ if (m_argument.equals(ServiceReference.class.getName())) {
+ m_callback.call(new Object[] {ref});
} else {
- for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
- method.invoke(m_manager.getPojoObjects()[i], new Object[] { ref });
- }
+ m_callback.call(new Object[] {obj});
}
}
}
/**
- * Call the callback method with an object.
- *
- * @param o : the object to send to the 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(Object o) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Get the method object
- Method method = m_manager.getClazz().getDeclaredMethod(m_callback, new Class[] { Object.class });
- method.setAccessible(true);
-
- if (m_isStatic) {
- method.invoke(null, new Object[] { o });
- } else {
- // Two cases :
- // - if instances already exists : call on each instances
- // - if no instance exists : create an instance
- if (m_manager.getPojoObjects().length == 0) {
- m_manager.getFactory().getLogger()
- .log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
- method.invoke(m_manager.getPojoObject(), new Object[] { o });
- } else {
- for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
- method.invoke(m_manager.getPojoObjects()[i], new Object[] { o });
- }
- }
- }
- }
-
- /**
- * Call the callback on the given instance with no parameters.
- *
- * @param instance : the instance on which call 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
- */
- protected void callOnInstance(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Method method = instance.getClass().getDeclaredMethod(m_callback, new Class[] {});
- method.setAccessible(true);
- method.invoke(instance, new Object[] {});
- }
-
- /**
* Call the callback on the given instance with the given argument.
*
* @param instance : the instance on which call the callback
* @param ref : the service reference to send to the callback
+ * @param obj : the service object
* @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, ServiceReference ref) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Method method = instance.getClass().getDeclaredMethod(m_callback, new Class[] { ServiceReference.class });
- method.setAccessible(true);
- method.invoke(instance, new Object[] { ref });
+ protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (m_argument.equals("EMPTY")) {
+ m_callback.call(instance, new Object[] {});
+ return;
+ }
+ if (m_argument.equals(ServiceReference.class.getName())) {
+ m_callback.call(instance, new Object[] {ref});
+ } else {
+ m_callback.call(instance, new Object[] {obj});
+ }
}
/**
@@ -217,8 +175,6 @@
* @throws InvocationTargetException
*/
protected void callOnInstance(Object instance, Object o) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Method method = instance.getClass().getDeclaredMethod(m_callback, new Class[] { Object.class });
- method.setAccessible(true);
- method.invoke(instance, new Object[] { o });
+ m_callback.call(instance, new Object[] {o});
}
}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 93cecdd..9a4c05d 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -26,7 +26,9 @@
import org.apache.felix.ipojo.architecture.HandlerDescription;
import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.ServiceReference;
/**
* The dependency handler manages a list of dependencies.
@@ -162,44 +164,74 @@
private boolean checkDependency(Dependency dep, Element manipulation) {
// Check the internal type of dependency
String field = dep.getField();
-
- String type = null;
- for (int i = 0; i < manipulation.getElements("Field").length; i++) {
- if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
- type = manipulation.getElements("Field")[i].getAttribute("type");
- break;
+ DependencyCallback[] callbacks = dep.getCallbacks();
+
+ for (int i = 0; i < callbacks.length; i++) {
+ for (int j = 0; j < manipulation.getElements("Method").length; j++) {
+ if (manipulation.getElements("Method")[j].getAttribute("name").equals(callbacks[i].getMethodName())) {
+ if (manipulation.getElements("Method")[j].containsAttribute("Arguments")) {
+ String[] args = ParseUtils.parseArrays(manipulation.getElements("Method")[j].getAttribute("Arguments"));
+ if (args.length != 1) {
+ getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "A dependency callback " + callbacks[i].getMethodName() + " must have 0 or 1 argument");
+ return false;
+ } else {
+ callbacks[i].setArgument(args[0]);
+ if (!args[0].equals(ServiceReference.class.getName())) {
+ if (dep.getSpecification() == null) {
+ dep.setSpecification(args[0]);
+ }
+ if (!dep.getSpecification().equals(args[0])) {
+ m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + args[0] + "] and the needed service interface ["
+ + dep.getSpecification() + "] are not the same");
+ dep.setSpecification(args[0]);
+ }
+ }
+ }
+ } else {
+ callbacks[i].setArgument("EMPTY");
+ }
+ }
}
}
-
- if (type == null) {
- m_manager.getFactory().getLogger().log(Logger.ERROR,
- "[DependencyHandler on " + m_manager.getClassName() + "] A declared dependency was not found in the class : " + dep.getField());
- return false;
- }
-
- if (type != null) {
- if (type.endsWith("[]")) {
- // Set the dependency to multiple
- dep.setMultiple();
- type = type.substring(0, type.length() - 2);
+
+ if (field != null) {
+ String type = null;
+ for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+ if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+ type = manipulation.getElements("Field")[i].getAttribute("type");
+ break;
+ }
}
- if (dep.getSpecification() == null) {
- dep.setSpecification(type);
+ if (type == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR,
+ "[DependencyHandler on " + m_manager.getClassName() + "] A declared dependency was not found in the class : " + dep.getField());
+ return false;
}
- if (!dep.getSpecification().equals(type)) {
- m_manager.getFactory().getLogger().log(
- Logger.WARNING,
- "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + type + "] and the needed service interface ["
+ if (type != null) {
+ if (type.endsWith("[]")) {
+ // Set the dependency to multiple
+ dep.setAggregate();
+ type = type.substring(0, type.length() - 2);
+ }
+
+ if (dep.getSpecification() == null) {
+ dep.setSpecification(type);
+ }
+
+ if (!dep.getSpecification().equals(type)) {
+ m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The field type [" + type + "] and the needed service interface ["
+ dep.getSpecification() + "] are not the same");
- dep.setSpecification(type);
+ dep.setSpecification(type);
+ }
+ } else {
+ m_manager.getFactory().getLogger().log(Logger.WARNING, "[DependencyHandler on " + m_manager.getClassName() + "] The declared dependency " + dep.getField() + " does not exist in the code");
}
- } else {
- m_manager.getFactory().getLogger().log(Logger.WARNING,
- "[DependencyHandler on " + m_manager.getClassName() + "] The declared dependency " + dep.getField() + " does not exist in the code");
}
- return true;
+
+ //Check that all required info are set
+ return dep.getSpecification() != null;
}
/**
@@ -218,7 +250,10 @@
Element[] deps = componentMetadata.getElements("Dependency");
for (int i = 0; i < deps.length; i++) {
// Create the dependency metadata
- String field = deps[i].getAttribute("field");
+ String field = null;
+ if (deps[i].containsAttribute("field")) {
+ field = deps[i].getAttribute("field");
+ }
String serviceSpecification = null;
if (deps[i].containsAttribute("interface")) {
serviceSpecification = deps[i].getAttribute("interface");
@@ -231,17 +266,13 @@
if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) {
optional = true;
}
-
- Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional);
- // Check the dependency :
- Element manipulation = componentMetadata.getElements("Manipulation")[0];
- if (checkDependency(dep, manipulation)) {
- addDependency(dep);
- } else {
- m_manager.getFactory().getLogger().log(Logger.ERROR,
- "[DependencyHandler on " + m_manager.getClassName() + "] The dependency on " + dep.getField() + " is not valid");
+ boolean aggregate = false;
+ if (deps[i].containsAttribute("aggregate") && deps[i].getAttribute("aggregate").equals("true")) {
+ aggregate = true;
}
+ Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate);
+
// Look for dependency callback :
for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
@@ -252,14 +283,20 @@
} else {
methodType = DependencyCallback.UNBIND;
}
- boolean isStatic = false;
- if (deps[i].getElements("Callback", "")[j].containsAttribute("isStatic")
- && deps[i].getElements("Callback", "")[j].getAttribute("isStatic").equals("true")) {
- isStatic = true;
- }
- DependencyCallback dc = new DependencyCallback(dep, method, methodType, isStatic);
+
+ DependencyCallback dc = new DependencyCallback(dep, method, methodType);
dep.addDependencyCallback(dc);
}
+
+ // Check the dependency :
+ Element manipulation = componentMetadata.getElements("Manipulation")[0];
+ if (checkDependency(dep, manipulation)) {
+ addDependency(dep);
+ } else {
+ m_manager.getFactory().getLogger().log(Logger.ERROR,
+ "[DependencyHandler on " + m_manager.getClassName() + "] The dependency on " + dep.getField() + " is not valid");
+ }
+
}
if (deps.length > 0) {
@@ -362,7 +399,7 @@
// class
for (int i = 0; i < m_dependencies.length; i++) {
Dependency dep = m_dependencies[i];
- if (dep.isOptional() && !dep.isMultiple()) {
+ if (dep.isOptional() && !dep.isAggregate()) {
createNullableClass(dep);
}
dep.start();
@@ -433,7 +470,7 @@
for (int j = 0; j < getDependencies().length; j++) {
Dependency dep = getDependencies()[j];
// Create & add the dependency description
- DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isMultiple(), dep.isOptional(), dep.getFilter(), dep.getState());
+ DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
dd.setServiceReferences(dep.getServiceReferences());
dd.setUsedServices(dep.getUsedServices());
dhd.addDependency(dd);
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
index 5385d38..7a3f4cf 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
@@ -74,11 +74,11 @@
}
m_method = method;
- m_callback = new Callback(method, isStatic, hh.getInstanceManager());
+ m_callback = new Callback(method, new String[0], isStatic, hh.getInstanceManager());
}
/**
- * Call the hook method when the transition from inital to final state is
+ * Call the callback method when the transition from inital to final state is
* detected.
*
* @throws NoSuchMethodException : Method is not found in the class
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
index 0b62ab2..0ebcd62 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -44,18 +44,129 @@
* Reference on the instance manager.
*/
private InstanceManager m_manager;
+
+ /**
+ * Method object.
+ */
+ private Method m_methodObj;
+
+ /**
+ * Argument classes.
+ */
+ private String[] m_args;
/**
- * LifecycleCallback constructor.
+ * Callback constructor.
*
* @param method : the name of the method to call
+ * @param args : argument type name
* @param isStatic : is the method a static method
* @param im : the instance manager of the component containing the method
*/
- public Callback(String method, boolean isStatic, InstanceManager im) {
+ public Callback(String method, String[] args, boolean isStatic, InstanceManager im) {
m_method = method;
m_isStatic = isStatic;
m_manager = im;
+ m_args = new String[args.length];
+ for (int i = 0; i < args.length; i++) {
+ // Primitive Array
+ if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
+ m_args[i] = "[" + getInternalPrimitiveType(args[i]);
+ }
+ // Non-Primitive Array
+ if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
+ m_args[i] = "[L" + args[i] + ";";
+ }
+ // Simple type
+ if (!args[i].endsWith("[]")) {
+ m_args[i] = args[i];
+ }
+
+ }
+ }
+
+ /**
+ * Callback constructor.
+ *
+ * @param method : the name of the method to call
+ * @param args : argument classes
+ * @param isStatic : is the method a static method
+ * @param im : the instance manager of the component containing the method
+ */
+ public Callback(String method, Class[] args, boolean isStatic, InstanceManager im) {
+ m_method = method;
+ m_isStatic = isStatic;
+ m_manager = im;
+ m_args = new String[args.length];
+ for (int i = 0; i < args.length; i++) {
+ m_args[i] = args[i].getName();
+ }
+ }
+
+ /**
+ * Get the internal notation for primitive type.
+ * @param string : Stringform of the type
+ * @return the internal notation or null if not found
+ */
+ private String getInternalPrimitiveType(String string) {
+ if (string.equalsIgnoreCase("boolean")) {
+ return "Z";
+ }
+ if (string.equalsIgnoreCase("char")) {
+ return "C";
+ }
+ if (string.equalsIgnoreCase("byte")) {
+ return "B";
+ }
+ if (string.equalsIgnoreCase("short")) {
+ return "S";
+ }
+ if (string.equalsIgnoreCase("int")) {
+ return "I";
+ }
+ if (string.equalsIgnoreCase("float")) {
+ return "F";
+ }
+ if (string.equalsIgnoreCase("long")) {
+ return "J";
+ }
+ if (string.equalsIgnoreCase("double")) {
+ return "D";
+ }
+ return null;
+ }
+
+ /**
+ * Search the method object in the POJO by analyzing present method.
+ * The name of the maethod and the argument type are checked.
+ */
+ private void searchMethod() {
+ Method[] methods = m_manager.getClazz().getDeclaredMethods();
+ for (int i = 0; m_methodObj == null && i < methods.length; i++) {
+ // First check the method name
+ if (methods[i].getName().equals(m_method)) {
+ // Check arguments
+ Class[] clazzes = methods[i].getParameterTypes();
+ if (clazzes.length == m_args.length) { // Test size to avoid useless loop
+ boolean ok = true;
+ for (int j = 0; ok && j < m_args.length; j++) {
+ if (!m_args[j].equals(clazzes[j].getName())) {
+ ok = false;
+ }
+ }
+ if (ok) {
+ m_methodObj = methods[i]; // It is the looked method.
+ }
+ }
+
+ }
+ }
+ if (m_methodObj == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " is not found in the code");
+ return;
+ } else {
+ m_methodObj.setAccessible(true);
+ }
}
/**
@@ -66,25 +177,21 @@
* @throws IllegalAccessException : The method can not be invoked
*/
public void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Call an callback method : " + m_method);
- Method method = m_manager.getClazz().getDeclaredMethod(m_method, new Class[] {});
- method.setAccessible(true);
+ if (m_methodObj == null) {
+ searchMethod();
+ }
if (m_isStatic) {
- method.invoke(null, new Object[] {});
+ 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) {
- m_manager.getFactory().getLogger()
- .log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
- method.invoke(m_manager.getPojoObject(), new Object[] {});
+ m_methodObj.invoke(m_manager.getPojoObject(), new Object[] {});
} else {
for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
- m_manager.getFactory().getLogger().log(Logger.INFO,
- "[" + m_manager.getClassName() + "] Call the callback on the instance " + m_manager.getPojoObjects()[i]);
- method.invoke(m_manager.getPojoObjects()[i], new Object[] {});
+ m_methodObj.invoke(m_manager.getPojoObjects()[i], new Object[] {});
}
}
}
@@ -99,9 +206,10 @@
* @throws InvocationTargetException : an error happens in the method
*/
public void call(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Method method = m_manager.getClazz().getDeclaredMethod(m_method, new Class[] {});
- method.setAccessible(true);
- method.invoke(instance, new Object[] {});
+ if (m_methodObj == null) {
+ searchMethod();
+ }
+ m_methodObj.invoke(instance, new Object[] {});
}
/**
@@ -114,30 +222,21 @@
* method
*/
public void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Call an callback method : " + m_method);
-
- // Build an array of call for arg :
- Class[] classes = new Class[arg.length];
- for (int i = 0; i < arg.length; i++) {
- classes[i] = arg[i].getClass();
+ if (m_methodObj == null) {
+ searchMethod();
}
-
- Method method = m_manager.getClazz().getDeclaredMethod(m_method, classes);
- method.setAccessible(true);
-
+
if (m_isStatic) {
- method.invoke(null, arg);
+ m_methodObj.invoke(null, arg);
} else {
// Two cases :
// - if instances already exists : call on each instances
// - if no instance exists : create an instance
if (m_manager.getPojoObjects().length == 0) {
- m_manager.getFactory().getLogger()
- .log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
- method.invoke(m_manager.getPojoObject(), new Object[] {});
+ m_methodObj.invoke(m_manager.getPojoObject(), arg);
} else {
for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
- method.invoke(m_manager.getPojoObjects()[i], arg);
+ m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
}
}
}
@@ -155,14 +254,10 @@
* method
*/
public void call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Build an array of call for arg :
- Class[] classes = new Class[arg.length];
- for (int i = 0; i < arg.length; i++) {
- classes[i] = arg[i].getClass();
+ if (m_methodObj == null) {
+ searchMethod();
}
-
- Method method = m_manager.getClazz().getDeclaredMethod(m_method, classes);
- method.setAccessible(true);
- method.invoke(instance, arg);
+
+ m_methodObj.invoke(instance, arg);
}
}