Patched code to remove use of a static component manager to support
component factories (FELIX-99).
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@425681 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
index 42955e2..454d618 100644
--- a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessClassAdapter.java
@@ -31,10 +31,10 @@
/**
* Manipulate the class.
- * - Add a static component manager field (_cm) ok
- * - Create getter and setter for each fields ok
- * - Store information about field ok
- * - Store information about implemented interfaces ok
+ * - Add a component manager field (_cm)
+ * - Create getter and setter for each fields
+ * - Store information about field
+ * - Store information about implemented interfaces
* - Change GETFIELD and PUTFIELD to called the getter and setter method
* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
*
@@ -89,8 +89,9 @@
m_owner = name;
// Insert _cm field
- super.visitField(ACC_PRIVATE + ACC_STATIC, "_cm", ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;", null, null);
-
+ FieldVisitor fv = super.visitField(ACC_PRIVATE, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;", null, null);
+ fv.visitEnd();
+
// Create the _cmSetter(ComponentManager cm) method
createComponentManagerSetter();
@@ -99,6 +100,7 @@
super.visit(version, access, name, signature, superName, interfaces);
}
+
/** visit method method :-).
* @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
@@ -115,28 +117,39 @@
final String desc,
final String signature,
final String[] exceptions) {
- MethodVisitor mv = cv.visitMethod(access,
- name,
- desc,
- signature,
- exceptions);
+ // The method is a constructor, adapt the constructor to add a ComponentManager argument
+ if(name.equals("<init>")) {
+ // 1) change the constructor descriptor (add a component manager arg as first argument)
+ String new_desc = desc.substring(1);
+ new_desc = "(Lorg/apache/felix/ipojo/ComponentManager;"+new_desc;
+
+ // Insert the new constructor
+ MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "<init>", new_desc, null, null);
- if (mv == null) { return null; }
- else { return new PreprocessCodeAdapter(mv, m_owner); }
+ if (mv == null) { return null; }
+ else {return new ConstructorCodeAdapter(mv, m_owner); }
+
+ }
+ else {
+ MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
+ if (mv == null) { return null; }
+ else {return new PreprocessCodeAdapter(mv, m_owner); }
+ }
}
/**
* Create the setter method for the _cm field.
- * The generated method must be called only one time.
*/
- private void createComponentManagerSetter() {
- MethodVisitor mv = super.visitMethod(ACC_PRIVATE + ACC_STATIC, "setComponentManager", "(" + ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;)V", null, null);
-
+ private void createComponentManagerSetter() {
+ MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_setComponentManager", "(Lorg/apache/felix/ipojo/ComponentManager;)V", null, null);
+
mv.visitVarInsn(ALOAD, 0);
- mv.visitFieldInsn(PUTSTATIC, m_owner, "_cm", ManipulationProperty.IPOJO_INTERNAL_DESCRIPTOR + "ComponentManager;");
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitFieldInsn(PUTFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+
mv.visitInsn(RETURN);
-
+
mv.visitMaxs(0, 0);
mv.visitEnd();
}
@@ -174,7 +187,6 @@
m_fields.put(name, nameType);
}
- // TODO : Getter & SETTER on array :
String gDesc = "()" + desc;
createArrayGetter(name, gDesc, type);
@@ -212,7 +224,8 @@
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, m_owner, name, internalType);
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
@@ -244,8 +257,9 @@
//mv.visitFieldInsn(GETFIELD, m_owner, name, "["+type.getInternalName()+";");
mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);
mv.visitVarInsn(ASTORE, 1);
-
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -318,7 +332,8 @@
mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
mv.visitVarInsn(ASTORE, 2);
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -357,7 +372,8 @@
mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");
mv.visitVarInsn(ASTORE, 1);
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -437,7 +453,8 @@
Label l2 = new Label();
mv.visitLabel(l2);
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
@@ -452,7 +469,8 @@
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, m_owner, name, "L" + type.getInternalName() + ";");
- mv.visitFieldInsn(GETSTATIC, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/ComponentManager;");
mv.visitLdcInsn(name);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/ComponentManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java
index c547242..bea6444 100644
--- a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/PreprocessCodeAdapter.java
@@ -65,7 +65,6 @@
return;
} else
if (opcode == PUTFIELD) {
- // replaces PUTFIELD f by INVOKESPECIAL _setf
IPojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate a PUTFIELD on : " + name);
String sDesc = "(" + desc + ")V";
visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
@@ -74,5 +73,6 @@
}
super.visitFieldInsn(opcode, owner, name, desc);
}
+
}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
index f513b47..8a0c4d8 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
@@ -18,7 +18,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.logging.Level;
import org.apache.felix.ipojo.metadata.Element;
@@ -305,23 +304,17 @@
* @return a new instance
*/
public Object createInstance() {
+
if (!isLoaded()) { load(); }
Object instance = null;
try {
-
- Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> call setComponentManager");
- // Invoke the static method setComponentManager on the manipulated class
- Method method = m_clazz.getDeclaredMethod("setComponentManager", new Class[] {this.getClass()});
- method.setAccessible(true);
- method.invoke(null, new Object[] {this});
-
Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> Try to find the constructor");
// Try to find if there is a constructor with a bundle context as parameter :
try {
- Constructor constructor = m_clazz.getConstructor(new Class[] {BundleContext.class});
+ Constructor constructor = m_clazz.getConstructor(new Class[] {ComponentManager.class, BundleContext.class});
constructor.setAccessible(true);
- instance = constructor.newInstance(new Object[] {m_factory.getBundleContext()});
+ instance = constructor.newInstance(new Object[] {this, m_factory.getBundleContext()});
}
catch (NoSuchMethodException e) {
Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> No constructor with a bundle context");
@@ -329,7 +322,11 @@
// Create an instance if no instance are already created with <init>()BundleContext
Activator.getLogger().log(Level.INFO, "[" + m_metadata.getClassName() + "] createInstance -> Try to create the object with an empty constructor");
- if (instance == null) { instance = m_clazz.newInstance(); }
+ if (instance == null) {
+ Constructor constructor = m_clazz.getConstructor(new Class[] {ComponentManager.class});
+ constructor.setAccessible(true);
+ instance = constructor.newInstance(new Object[] {this});
+ }
} catch (InstantiationException e) {
Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> The Component Instance cannot be instancied : " + e.getMessage());
@@ -340,14 +337,11 @@
} catch (SecurityException e) {
Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
e.printStackTrace();
- } catch (IllegalArgumentException e) {
- Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (illegal argument) : " + e.getMessage());
- e.printStackTrace();
} catch (InvocationTargetException e) {
- Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (illegal target) : " + e.getMessage());
+ Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getMessage());
e.printStackTrace();
} catch (NoSuchMethodException e) {
- Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the setComponentManager method (method not found) : " + e.getMessage());
+ Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
e.printStackTrace();
}
@@ -499,4 +493,4 @@
// ======================= end Handlers Management =====================
-}
+}
\ No newline at end of file
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index eb8c332..62b6cff 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -24,6 +24,8 @@
import org.apache.felix.ipojo.ComponentManager;
import org.apache.felix.ipojo.Handler;
import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.handlers.providedservice.Property;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
import org.apache.felix.ipojo.metadata.Element;
import org.osgi.framework.BundleContext;
@@ -140,7 +142,17 @@
* @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
*/
public void setterCallback(String fieldName, Object value) {
- // Nothing to do
+ // Verify that the field name correspond to a configurable property
+ for (int i = 0; i < m_configurableProperties.length; i++) {
+ ConfigurableProperty cp = m_configurableProperties[i];
+ if (cp.getName().equals(fieldName)) {
+ // Check if the value has change
+ if (cp.getValue() == null || !cp.getValue().equals(value)) {
+ cp.setValue(value); // Change the value
+ }
+ }
+ }
+ //Else do nothing
}
/**
@@ -193,7 +205,7 @@
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_configurableProperties[i].setValue(value); // Change the value
+ //m_configurableProperties[i].setValue(value); // Useless, the setterCallback will call the setValue
m_manager.setterCallback(m_configurableProperties[i].getField(), value); // says that the value has change
}
find = true;
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 1546a3d..6361bd7 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -195,11 +195,10 @@
}
if (type != null) {
- if (type.endsWith("[]")) {
- // TODO array property
- Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] An array property was found in the class [Not implemented yet] : " + prop.getMetadata().getField());
- return false;
- }
+// if (type.endsWith("[]")) {
+// Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] An array property was found in the class [Not implemented yet] : " + prop.getMetadata().getField());
+// return false;
+// }
if (prop.getMetadata().getType() == null) { prop.getMetadata().setType(type); }