Added patch (FELIX-103) that checks to see if the component class was
already instrumented.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@426410 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
new file mode 100644
index 0000000..e8880f9
--- /dev/null
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
@@ -0,0 +1,116 @@
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.HashMap;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class ClassChecker implements ClassVisitor, Opcodes {
+
+ /**
+ * True if the class is already manipulated.
+ */
+ private boolean isAlreadyManipulated = false;
+
+ /**
+ * Interfaces implemented by the component.
+ */
+ private String[] m_itfs = new String[0];
+
+ /**
+ * Field hashmap [field name, type] discovered in the component class.
+ */
+ private HashMap m_fields = new HashMap();
+
+ /** Check if the _cm field already exists.
+ * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+ */
+ public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
+
+ if (access == ACC_PRIVATE && name.equals("_cm") && desc.equals("Lorg/apache/felix/ipojo/ComponentManager;")) {
+ isAlreadyManipulated = true;
+ }
+
+ Type type = Type.getType(desc);
+ if (type.getSort() == Type.ARRAY) {
+ if (type.getInternalName().startsWith("L")) {
+ String internalType = type.getInternalName().substring(1);
+ String nameType = internalType.replace('/', '.');
+ m_fields.put(name, nameType + "[]");
+ }
+ else {
+ String nameType = type.getClassName().substring(0, type.getClassName().length() - 2);
+ m_fields.put(name, nameType);
+ }
+ } else {
+ m_fields.put(name, type.getClassName());
+ }
+
+ return null;
+ }
+
+ public boolean isalreadyManipulated() { return isAlreadyManipulated; }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+ */
+ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ //Store the interfaces :
+ m_itfs = interfaces;
+ }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+ */
+ public void visitSource(String arg0, String arg1) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void visitOuterClass(String arg0, String arg1, String arg2) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+ */
+ public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { return null; }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+ */
+ public void visitAttribute(Attribute arg0) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)
+ */
+ public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+ */
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return null; }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitEnd()
+ */
+ public void visitEnd() { }
+
+ /**
+ * @return the interfaces implemented by the component class.
+ */
+ public String[] getInterfaces() {
+ return m_itfs;
+ }
+
+ /**
+ * @return the field hashmap [field_name, type]
+ */
+ public HashMap getFields() {
+ return m_fields;
+ }
+
+}
diff --git a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index e001d4d..34f55cc 100644
--- a/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/org.apache.felix.ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -79,23 +79,38 @@
//if (url == null) { throw new ClassNotFoundException(name); }
IPojoPluginConfiguration.getLogger().log(Level.INFO, "Manipulate the class file : " + clazz.getAbsolutePath());
- InputStream is = url.openStream();
+ InputStream is1 = url.openStream();
+
+
+ // First check if the class is already manipulated :
+ ClassReader ckReader = new ClassReader(is1);
+ ClassChecker ck = new ClassChecker();
+ ckReader.accept(ck, true);
+ is1.close();
+
+ m_fields = ck.getFields();
+ m_interfaces = new String[ck.getInterfaces().length];
+ for (int i = 0; i < m_interfaces.length; i++) {
+ m_interfaces[i] = ck.getInterfaces()[i].replace('/', '.');
+ }
+
+ if(!ck.isalreadyManipulated()) {
- //Manipulation ->
- // Add the _setComponentManager method
- // Instrument all fields
- ClassReader cr0 = new ClassReader(is);
- ClassWriter cw0 = new ClassWriter(true);
- PreprocessClassAdapter preprocess = new PreprocessClassAdapter(cw0);
- cr0.accept(preprocess, false);
- is.close();
+ //Manipulation ->
+ // Add the _setComponentManager method
+ // Instrument all fields
+ InputStream is2 = url.openStream();
+ ClassReader cr0 = new ClassReader(is2);
+ ClassWriter cw0 = new ClassWriter(true);
+ PreprocessClassAdapter preprocess = new PreprocessClassAdapter(cw0);
+ cr0.accept(preprocess, false);
+ is2.close();
- File file = null;
- try {
- file = new File(url.getFile());
+ File file = null;
+ try {
+ file = new File(url.getFile());
-
- //file.createNewFile();
+ //file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos.write(cw0.toByteArray());
@@ -104,10 +119,6 @@
IPojoPluginConfiguration.getLogger().log(Level.INFO, "Put the file " + file.getAbsolutePath() + " in the jar file");
} catch (Exception e) { System.err.println("Problem to write the adapted class on the file system " + " [ "+ file.getAbsolutePath() +" ] " + e.getMessage()); }
- m_fields = preprocess.getFields();
- m_interfaces = new String[preprocess.getInterfaces().length];
- for (int i = 0; i < m_interfaces.length; i++) {
- m_interfaces[i] = preprocess.getInterfaces()[i].replace('/', '.');
}
}
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 454d618..bb569e1 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
@@ -48,17 +48,6 @@
private String m_owner;
/**
- * Interfaces implemented by the component.
- */
- private String[] m_itfs = new String[0];
-
- /**
- * Field hashmap [field name, type] discovered in the component class.
- */
- private HashMap m_fields = new HashMap();
-
-
- /**
* Constructor.
* @param cv : Class visitor
*/
@@ -95,9 +84,6 @@
// Create the _cmSetter(ComponentManager cm) method
createComponentManagerSetter();
- //Store the interfaces :
- m_itfs = interfaces;
-
super.visit(version, access, name, signature, superName, interfaces);
}
@@ -177,15 +163,6 @@
FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
if (type.getSort() == Type.ARRAY) {
- if (type.getInternalName().startsWith("L")) {
- String internalType = type.getInternalName().substring(1);
- String nameType = internalType.replace('/', '.');
- m_fields.put(name, nameType + "[]");
- }
- else {
- String nameType = type.getClassName().substring(0, type.getClassName().length() - 2);
- m_fields.put(name, nameType);
- }
String gDesc = "()" + desc;
createArrayGetter(name, gDesc, type);
@@ -196,8 +173,6 @@
}
else {
- // Store information on the fields
- m_fields.put(name, type.getClassName());
// Generate the getter method
String gDesc = "()" + desc;
@@ -485,19 +460,5 @@
mv.visitMaxs(0, 0);
mv.visitEnd();
}
-
- /**
- * @return the interfaces implemented by the component class.
- */
- public String[] getInterfaces() {
- return m_itfs;
- }
-
- /**
- * @return the field hashmap [field_name, type]
- */
- public HashMap getFields() {
- return m_fields;
- }
}