Instances can now customize their requirement filters (both on primitive and composite components)
Remove equals method invocation form the generated bytecode (use '==' instead)
Allow dependency callbacks to invoke parent classes methods.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@581147 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 6982b32..527d195 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
@@ -19,7 +19,6 @@
package org.apache.felix.ipojo;
import java.net.URL;
-import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
@@ -113,11 +112,6 @@
* Component Type Name.
*/
protected String m_typeName = null;
-
- /**
- * Class loader to delegate loading.
- */
- private FactoryClassloader m_classLoader = null;
/**
* Component Implementation class.
@@ -303,21 +297,6 @@
instance.start();
return instance;
}
-
- /**
- * Define a class.
- * @param name : qualified name of the class
- * @param b : byte array of the class
- * @param domain : protection domain of the class
- * @return the defined class object
- * @throws Exception : an exception occur during the definition
- */
- public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
- if (m_classLoader == null) {
- m_classLoader = new FactoryClassloader();
- }
- return m_classLoader.defineClass(name, b, domain);
- }
/**
* Delete an instance.
@@ -437,20 +416,22 @@
* Load a class.
* @param className : name of the class to load
* @return the resulting Class object
+ * @throws ClassNotFoundException
* @throws ClassNotFoundException : happen when the class is not found
*/
public Class loadClass(String className) throws ClassNotFoundException {
- if (m_clazz != null && className.equals(m_componentClassName)) {
- // Used the factory classloader to load the component implementation
- // class
- if (m_classLoader == null) {
- m_classLoader = new FactoryClassloader();
- }
- try {
- return m_classLoader.defineClass(m_componentClassName, m_clazz, null);
- } catch (Exception e) {
- throw new ClassNotFoundException("[Bundle " + m_context.getBundle().getBundleId() + "] Cannot define the class : " + className, e);
- }
+ if (m_clazz != null) {
+ // Used the factory classloader to load the component implementation class
+ ClassLoader cl = new ClassLoader() {
+ public Class loadClass(String name) throws ClassNotFoundException {
+ if (name.equals(m_componentClassName)) {
+ return defineClass(name, m_clazz, 0, m_clazz.length, null);
+ } else {
+ return m_context.getBundle().loadClass(name);
+ }
+ }
+ };
+ return cl.loadClass(m_componentClassName);
}
return m_context.getBundle().loadClass(className);
}
@@ -585,7 +566,6 @@
m_tracker = null;
m_componentDesc = null;
- m_classLoader = null;
m_clazz = null;
m_state = INVALID;
}
@@ -1005,55 +985,21 @@
}
}
- /**
- * FactoryClassloader.
- */
- private class FactoryClassloader extends ClassLoader {
-
- /**
- * Map of defined classes [Name, Class Object].
- */
- private Map m_definedClasses = new HashMap();
-
- /**
- * The defineClass method.
- *
- * @param name : name of the class
- * @param b : the byte array of the class
- * @param domain : the protection domain
- * @return : the defined class.
- * @throws Exception : if a problem is detected during the loading
- */
- public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
- if (m_definedClasses.containsKey(name)) {
- return (Class) m_definedClasses.get(name);
- }
- final Class c = super.defineClass(name, b, 0, b.length, domain);
- m_definedClasses.put(name, c);
- return c;
- }
-
- /**
- * Return the URL of the asked resource.
- *
- * @param arg : the name of the resource to find.
- * @return the URL of the resource.
- * @see java.lang.ClassLoader#getResource(java.lang.String)
- */
- public URL getResource(String arg) {
- return m_context.getBundle().getResource(arg);
- }
-
- /**
- * Load the class.
- * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
- * @param name : the name of the class
- * @param resolve : should be the class resolve now ?
- * @return : the loaded class
- * @throws ClassNotFoundException : the class to load is not found
- */
- protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
- return m_context.getBundle().loadClass(name);
- }
- }
+// /**
+// * FactoryClassloader.
+// */
+// private class FactoryClassloader extends ClassLoader {
+// /**
+// * The defineClass method.
+// *
+// * @param name : name of the class
+// * @param b : the byte array of the class
+// * @param domain : the protection domain
+// * @return : the defined class.
+// * @throws Exception : if a problem is detected during the loading
+// */
+// public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+// return super.defineClass(name, b, 0, b.length, domain);
+// }
+// }
}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
index 6c756e3..aeb4c0f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
@@ -71,7 +71,7 @@
* @param event : the bundle event.
* @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
*/
- public void bundleChanged(BundleEvent event) {
+ public synchronized void bundleChanged(BundleEvent event) {
if (event.getBundle().getBundleId() == m_bundleId) {
return;
}
@@ -147,7 +147,7 @@
start(bundle, parser.getInstances());
}
- /**
+ /**
* iPOJO Starting method.
* @param bc : iPOJO bundle context.
* @throws Exception : the start method failed.
@@ -158,22 +158,20 @@
m_bundleId = bc.getBundle().getBundleId();
m_components = new Hashtable();
m_creators = new Hashtable();
-
+
// Begin by initializing core handlers
startManagementFor(bc.getBundle());
-
- synchronized (m_components) {
- synchronized (m_creators) {
- for (int i = 0; i < bc.getBundles().length; i++) {
- if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {
- startManagementFor(bc.getBundles()[i]);
- }
+
+ synchronized (this) {
+ // listen to any changes in bundles.
+ m_context.addBundleListener(this);
+ // compute already started bundles.
+ for (int i = 0; i < bc.getBundles().length; i++) {
+ if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {
+ startManagementFor(bc.getBundles()[i]);
}
}
}
-
- // listen to any changes in bundles
- m_context.addBundleListener(this);
}
/**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index 982aacc..ab1d6ab 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -389,14 +389,6 @@
}
/**
- * Is the implementation class loaded?
- * @return true if the class is loaded
- */
- private boolean isLoaded() {
- return m_clazz != null;
- }
-
- /**
* Add an instance to the created instance list.
* @param o : the instance to add
*/
@@ -462,7 +454,7 @@
*/
public Object createPojoObject() {
- if (!isLoaded()) {
+ if (m_clazz == null) {
load();
}
Object instance = null;
@@ -528,7 +520,7 @@
* @return the manipulated class
*/
public Class getClazz() {
- if (!isLoaded()) {
+ if (m_clazz == null) {
load();
}
return m_clazz;
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
index 04c5da1..c9b26bf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
@@ -75,6 +75,12 @@
m_scope = getCompositeManager().getServiceContext();
Element[] imp = metadata.getElements("requires");
+
+ // Get instance filters
+ Dictionary filtersConfiguration = null;
+ if (conf.get("requires.filters") != null) {
+ filtersConfiguration = (Dictionary) conf.get("requires.filters");
+ }
for (int i = 0; i < imp.length; i++) {
boolean optional = false;
@@ -111,6 +117,12 @@
scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
}
}
+
+ // Configure instance filter if available
+ if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
+ filter = (String) filtersConfiguration.get(id);
+ }
+
ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
m_importers.add(si);
} else { // Malformed import
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
index 56a64b9..e573d4a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
@@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
+import java.util.Properties;
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.CompositeHandler;
@@ -219,7 +220,7 @@
*/
private void checkServiceSpecification(ProvidedService ps) throws CompositionException {
try {
- Class spec = getCompositeManager().getFactory().loadClass(ps.getSpecification());
+ Class spec = m_context.getBundle().loadClass(ps.getSpecification());
Field specField = spec.getField("specification");
Object o = specField.get(null);
if (o instanceof String) {
@@ -313,7 +314,7 @@
}
// Add the required handler
try {
- ci.init(getCompositeManager(), new Element("composite", ""), null);
+ ci.init(getCompositeManager(), new Element("composite", ""), new Properties());
} catch (ConfigurationException e) {
log(Logger.ERROR, "Internal error : cannot configure the Import Handler : " + e.getMessage());
throw new CompositionException("Internal error : cannot configure the Import Handler : " + e.getMessage());
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 70540cd..ef62ef7 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
@@ -19,9 +19,10 @@
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.Callback;
+import org.apache.felix.ipojo.util.Logger;
import org.osgi.framework.ServiceReference;
/**
@@ -30,7 +31,7 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class DependencyCallback {
+public class DependencyCallback extends Callback {
/**
* Bind method (called when a service arrives).
@@ -57,16 +58,11 @@
* Callback method name.
*/
private String m_method;
-
+
/**
- * Is the callback a static callback.
+ * Service Dependency.
*/
- private Callback m_callback;
-
- /**
- * The instance manager.
- */
- private InstanceManager m_manager;
+ private Dependency m_dependency;
/**
* Constructor.
@@ -77,9 +73,10 @@
* method
*/
public DependencyCallback(Dependency dep, String method, int methodType) {
+ super(method, (String[]) null, false, dep.getDependencyHandler().getInstanceManager());
m_methodType = methodType;
+ m_dependency = dep;
m_method = method;
- m_manager = dep.getDependencyHandler().getInstanceManager();
}
@@ -93,15 +90,87 @@
/**
* Set the argument type (Empty or the class name).
- * @param arg : the type name or EMPTY
+ * @param arg : the array of argument types.
*/
public void setArgument(String[] arg) {
m_argument = arg;
- m_callback = new Callback(m_method, arg, false, m_manager);
}
- public String[] getArgument() {
- return m_argument;
+ /**
+ * Search the method object in the POJO by analyzing present method.
+ * If not found in the pojo it tests the parent classes.
+ * The name of the method and the argument type are checked.
+ */
+ protected void searchMethod() {
+ if (m_argument != null) {
+ Method[] methods = m_dependency.getDependencyHandler().getInstanceManager().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_argument.length) { // Test size to avoid useless loop
+ boolean ok = true;
+ for (int j = 0; ok && j < m_argument.length; j++) {
+ if (!m_argument[j].equals(clazzes[j].getName())) {
+ ok = false;
+ }
+ }
+ if (ok) {
+ m_methodObj = methods[i]; // It is the looked method.
+ }
+ }
+
+ }
+ }
+ }
+
+ if (m_methodObj == null) { //look at parent classes
+ Method[] methods = m_dependency.getDependencyHandler().getInstanceManager().getClazz().getMethods();
+ 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();
+ switch(clazzes.length) {
+ case 0 :
+ // Callback with no arguments.
+ m_methodObj = methods[i];
+ m_argument = new String[0];
+ break;
+ case 1 :
+ if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
+ // Callback with a service reference.
+ m_methodObj = methods[i];
+ m_argument = new String[] {ServiceReference.class.getName()};
+ break;
+ }
+ if (clazzes[0].getName().equals(m_dependency.getSpecification())) {
+ // Callback with the service object.
+ m_methodObj = methods[i];
+ m_argument = new String[] {m_dependency.getSpecification()};
+ break;
+ }
+ case 2 :
+ if (clazzes[0].getName().equals(m_dependency.getSpecification()) && clazzes[1].getName().equals(ServiceReference.class.getName())) {
+ // Callback with two arguments.
+ m_methodObj = methods[i];
+ m_argument = new String[] {m_dependency.getSpecification(), ServiceReference.class.getName()};
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ }
+ }
+
+ if (m_methodObj == null) {
+ m_dependency.getDependencyHandler().log(Logger.ERROR, "The method " + m_method + " cannot be called : method not found");
+ return;
+ } else {
+ m_methodObj.setAccessible(true);
+ }
}
/**
@@ -114,19 +183,22 @@
* @throws IllegalAccessException : The method can not be invoked
*/
protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (m_methodObj == null) {
+ searchMethod();
+ }
switch (m_argument.length) {
case 0 :
- m_callback.call(new Object[0]);
+ call(new Object[0]);
break;
case 1 :
if (m_argument[0].equals(ServiceReference.class.getName())) {
- m_callback.call(new Object[] {ref});
+ call(new Object[] {ref});
} else {
- m_callback.call(new Object[] {obj});
+ call(new Object[] {obj});
}
break;
case 2 :
- m_callback.call(new Object[] {obj, ref});
+ call(new Object[] {obj, ref});
break;
default :
break;
@@ -145,19 +217,22 @@
* @throws InvocationTargetException
*/
protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ if (m_methodObj == null) {
+ searchMethod();
+ }
switch (m_argument.length) {
case 0 :
- m_callback.call(instance, new Object[0]);
+ call(instance, new Object[0]);
break;
case 1 :
if (m_argument[0].equals(ServiceReference.class.getName())) {
- m_callback.call(instance, new Object[] {ref});
+ call(instance, new Object[] {ref});
} else {
- m_callback.call(instance, new Object[] {obj});
+ call(instance, new Object[] {obj});
}
break;
case 2 :
- m_callback.call(instance, new Object[] {obj, ref});
+ call(instance, new Object[] {obj, ref});
break;
default :
break;
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 7b7c839..95e58d7 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
@@ -146,45 +146,45 @@
for (int i = 0; i < callbacks.length; i++) {
MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
- if (mets.length == 0) {
- 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 > 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());
- }
- 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]);
- }
- 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]);
- }
- }
- } 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 (mets.length != 0) {
+ 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());
}
+ 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]);
+ }
+ 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]);
+ }
+ }
+ } 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]);
+ }
+ }
+ }
+ } else {
+ log(Logger.INFO, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
}
-
+
}
if (field != null) {
@@ -240,6 +240,12 @@
}
// END OF DEPRECATED BLOCK
+ // Get instance filters.
+ Dictionary filtersConfiguration = null;
+ if (configuration.get("requires.filters") != null) {
+ filtersConfiguration = (Dictionary) configuration.get("requires.filters");
+ }
+
for (int i = 0; i < deps.length; i++) {
// Create the dependency metadata
String field = null;
@@ -279,6 +285,11 @@
}
}
+ // Get instance filter if available
+ if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
+ filter = (String) filtersConfiguration.get(id);
+ }
+
Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy);
// Look for dependency callback :
@@ -328,15 +339,24 @@
// dep.getMetadata().getServiceSpecification().split("[.]");
// String className = "org/apache/felix/ipojo/" + segment[segment.length
// - 1] + "Nullable";
- String className = dep.getSpecification() + "Nullable";
+ final String className = dep.getSpecification() + "Nullable";
String resource = dep.getSpecification().replace('.', '/') + ".class";
URL url = getInstanceManager().getContext().getBundle().getResource(resource);
try {
- byte[] b = NullableObjectWriter.dump(url, dep.getSpecification());
+ final byte[] b = NullableObjectWriter.dump(url, dep.getSpecification());
Class c = null;
try {
- c = getInstanceManager().getFactory().defineClass(className, b, null);
+ ClassLoader cl = new ClassLoader() {
+ public Class loadClass(String name) throws ClassNotFoundException {
+ if (name.equals(className)) {
+ return defineClass(name, b, 0, b.length, null);
+ } else {
+ return getInstanceManager().getContext().getBundle().loadClass(name);
+ }
+ }
+ };
+ c = cl.loadClass(className);
} catch (Exception e) {
log(Logger.ERROR, "Cannot define the nullable class : " + e.getMessage());
e.printStackTrace();
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 4f84322..a4daa34 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
@@ -30,6 +30,11 @@
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class Callback {
+
+ /**
+ * Method object.
+ */
+ protected Method m_methodObj;
/**
* Name of the method to call.
@@ -47,11 +52,6 @@
private InstanceManager m_manager;
/**
- * Method object.
- */
- private Method m_methodObj;
-
- /**
* Argument classes.
*/
private String[] m_args;
@@ -68,32 +68,34 @@
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) {
- String arr = "";
- for (int j = 0; j < args[i].length(); j++) {
- if (args[i].charAt(j) == '[') { arr += '['; }
+ if (args != null) {
+ m_args = new String[args.length];
+ for (int i = 0; i < args.length; i++) {
+ // Primitive Array
+ if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
+ String arr = "";
+ for (int j = 0; j < args[i].length(); j++) {
+ if (args[i].charAt(j) == '[') { arr += '['; }
+ }
+ int index = args[i].indexOf('[');
+ m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
}
- int index = args[i].indexOf('[');
- m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
- }
- // Non-Primitive Array
- if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
- String arr = "";
- for (int j = 0; j < args[i].length(); j++) {
- if (args[i].charAt(j) == '[') { arr += '['; }
+ // Non-Primitive Array
+ if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
+ String arr = "";
+ for (int j = 0; j < args[i].length(); j++) {
+ if (args[i].charAt(j) == '[') { arr += '['; }
+ }
+ int index = args[i].indexOf('[');
+ m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
}
- int index = args[i].indexOf('[');
- m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
+ // Simple type
+ if (!args[i].endsWith("[]")) {
+ m_args[i] = args[i];
+ }
}
- // Simple type
- if (!args[i].endsWith("[]")) {
- m_args[i] = args[i];
- }
-
}
+
}
/**
@@ -188,7 +190,7 @@
* Search the method object in the POJO by analyzing present method.
* The name of the method and the argument type are checked.
*/
- private void searchMethod() {
+ protected void searchMethod() {
Method[] methods = m_manager.getClazz().getDeclaredMethods();
for (int i = 0; m_methodObj == null && i < methods.length; i++) {
// First check the method name
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
index 22ad2ad..51db771 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
@@ -185,17 +185,17 @@
mv.visitJumpInsn(IFNULL, l4a);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 3);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
-
Label l5a = new Label();
- mv.visitJumpInsn(IFNE, l5a);
- mv.visitLabel(l4a);
-
+ mv.visitJumpInsn(IF_ACMPEQ, l5a); // Test equality on object.
+
+ // Invoke the _set method
+ mv.visitLabel(l4a);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalType + ")V");
+
+ // End of the method
mv.visitLabel(l5a);
-
mv.visitVarInsn(ALOAD, 3);
mv.visitInsn(ARETURN);
@@ -504,17 +504,17 @@
mv.visitJumpInsn(IFNULL, l4b);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 3);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
-
+
Label l5b = new Label();
- mv.visitJumpInsn(IFNE, l5b);
+ mv.visitJumpInsn(IF_ACMPEQ, l5b); // Test equality on object.
+
mv.visitLabel(l4b);
-
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(L" + type.getInternalName() + ";)V");
+
+ // End of the getter method, return the object
mv.visitLabel(l5b);
-
mv.visitVarInsn(ALOAD, 3);
mv.visitInsn(ARETURN);