You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2007/06/24 17:11:35 UTC

svn commit: r550247 [1/3] - in /felix/trunk/ipojo/manipulator: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/java/org/apache/felix/ipojo/ src/main/java/org/apache/felix/ipojo/mani...

Author: clement
Date: Sun Jun 24 08:11:33 2007
New Revision: 550247

URL: http://svn.apache.org/viewvc?view=rev&rev=550247
Log:
Add the new manipulator project (Felix-311)

Added:
    felix/trunk/ipojo/manipulator/   (with props)
    felix/trunk/ipojo/manipulator/pom.xml
    felix/trunk/ipojo/manipulator/src/
    felix/trunk/ipojo/manipulator/src/main/
    felix/trunk/ipojo/manipulator/src/main/java/
    felix/trunk/ipojo/manipulator/src/main/java/org/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/QuotedTokenizer.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/ParseException.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/AdviceAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/Method.java
    felix/trunk/ipojo/manipulator/src/main/java/org/objectweb/asm/commons/TableSwitchGenerator.java

Propchange: felix/trunk/ipojo/manipulator/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Jun 24 08:11:33 2007
@@ -0,0 +1,17 @@
+classes
+target
+*.log
+*.ipr
+*.iws
+*.iml
+lib
+bundle
+dist
+.project
+.classpath
+bin
+build
+.settings
+.wtpmodules
+.deployables
+

Added: felix/trunk/ipojo/manipulator/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/pom.xml?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/pom.xml (added)
+++ felix/trunk/ipojo/manipulator/pom.xml Sun Jun 24 08:11:33 2007
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.felix</groupId>
+  <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+  <packaging>jar</packaging>
+  <version>0.7.3-incubator-SNAPSHOT</version>
+  <name>Apache Felix iPOJO Manipulator</name>
+  <dependencies>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+      <version>0.7.3-incubator-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,223 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+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;
+
+/**
+ * Check thaht a POJO is already manipulated or not.
+ * Moreover it allows to get manipulation data about this class. 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ClassChecker implements ClassVisitor, Opcodes {
+
+    /**
+     * True if the class is already manipulated.
+     */
+    private boolean m_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();
+
+    /**
+     * Method List of method descriptor discovered in the component class.
+     */
+    private List m_methods = new ArrayList()/* <MethodDesciptor> */;
+
+    /**
+     * Check if the _cm field already exists.
+     * Update the field list.
+     * @param access : access of the field
+     * @param name : name of the field
+     * @param desc : description of the field
+     * @param signature : signature of the field
+     * @param value : value of the field (for static field only)
+     * @return the field visitor
+     * @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/InstanceManager;")) {
+            m_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;
+    }
+
+    /**
+     * Check if the class was already manipulated.
+     * @return true if the class is already manipulated.
+     */
+    public boolean isalreadyManipulated() {
+        return m_isAlreadyManipulated;
+    }
+
+    /**
+     * Visit the class.
+     * Update the implemented insterface list.
+     * @param version : version of the class
+     * @param access : acess of the class
+     * @param name : name of the class
+     * @param signature : signature of the class
+     * @param superName : super class of the class
+     * @param interfaces : implemented interfaces.
+     * @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;
+    }
+
+    /**
+     * Visit sources.
+     * Do nothing
+     * @param source : the name of the source file from which the class was compiled. May be null.
+       @param debug : additional debug information to compute the correspondance between source and compiled elements of the class. May be null.
+     * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+     */
+    public void visitSource(String source, String debug) { }
+
+    /**
+     * Visit an outer class.
+     * @param owner - internal name of the enclosing class of the class.
+     * @param name - the name of the method that contains the class, or null if the class is not enclosed in a method of its enclosing class.
+     * @param desc - the descriptor of the method that contains the class, or null if the class is not enclosed in a method of its enclosing class.
+     * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String,
+     *      java.lang.String, java.lang.String)
+     */
+    public void visitOuterClass(String owner, String name, String desc) {
+    }
+
+    /**
+     * Visit an annotation.
+     * Do nothing.
+     * @param desc - the class descriptor of the annotation class.
+     * @param visible - true if the annotation is visible at runtime.
+     * @return null.
+     * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        return null;
+    }
+
+    /**
+     * Visit a non standard attribute of the class.
+     * @param attr - an attribute.
+     * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+     */
+    public void visitAttribute(Attribute attr) {
+    }
+
+    /**
+     * Visit an inner class.
+     * @param name - the internal name of an inner class (see getInternalName).
+     * @param outerName - the internal name of the class to which the inner class belongs (see getInternalName). May be null for not member classes.
+     * @param innerName - the (simple) name of the inner class inside its enclosing class. May be null for anonymous inner classes.
+     * @param access - the access flags of the inner class as originally declared in the enclosing class.
+     * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String,
+     *      java.lang.String, java.lang.String, int)
+     */
+    public void visitInnerClass(String name, String outerName, String innerName, int access) { }
+
+    /**
+     * Visit a method.
+     * Update the method list (except if it init or clinit.
+     * @param  access - the method's access flags (see Opcodes). This parameter also indicates if the method is synthetic and/or deprecated.
+     * @param name - the method's name.
+     * @param desc - the method's descriptor (see Type).
+     * @param signature - the method's signature. May be null if the method parameters, return type and exceptions do not use generic types.
+     * @param exceptions - the internal names of the method's exception classes (see getInternalName). May be null.
+     * @return nothing.
+     * @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) {
+        if (!name.equals("<init>") && !name.equals("<clinit>")) {
+            m_methods.add(new MethodDescriptor(name, desc));
+        }
+        return null;
+    }
+
+    /**
+     * End of the class visit.
+     * @see org.objectweb.asm.ClassVisitor#visitEnd()
+     */
+    public void visitEnd() { }
+
+    /**
+     * Get collected interfaces.
+     * @return the interfaces implemented by the component class.
+     */
+    public String[] getInterfaces() {
+        return m_itfs;
+    }
+
+    /**
+     * Get collected fields.
+     * @return the field hashmap [field_name, type].
+     */
+    public HashMap getFields() {
+        return m_fields;
+    }
+
+    /**
+     * Get collected methods.
+     * @return the method list of [method, signature].
+     */
+    public List getMethods() {
+        return m_methods;
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,166 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.GeneratorAdapter;
+
+/**
+ * Constructor Adapter : add a component manager argument inside a constructor.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ConstructorCodeAdapter extends GeneratorAdapter implements Opcodes {
+
+    /**
+     * The owner class of the field. 
+     * m_owner : String
+     */
+    private String m_owner;
+
+    /**
+     * Is the super call already detected ? 
+     */
+    private boolean m_superDetected;
+
+    /**
+     * ConstructorCodeAdapter constructor. 
+     * @param mv : method visitor.
+     * @param access : access level of the method.
+     * @param desc : descriptor of the constructor. 
+     * @param owner : onwer class
+     */
+    public ConstructorCodeAdapter(final MethodVisitor mv, int access,
+            String desc, final String owner) {
+        super(mv, access, "<init>", desc);
+        m_owner = owner;
+      //  m_superDetected = false;
+    }
+
+    /**
+     * Visit a method instruction.
+     * Inject the _setComponentManager invocation just of the super invocation.
+     * @param opcode : opcode
+     * @param owner : method owner class
+     * @param name : method name
+     * @param desc : method description
+     * @see org.objectweb.asm.commons.AdviceAdapter#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+        // A method call is detected, check if it is the super call :
+        if (!m_superDetected) {
+            m_superDetected = true;
+            // The first invocation is the super call
+            // 1) Visit the super constructor :
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(opcode, owner, name, desc); // Super constructor
+                                                            // invocation
+
+            // 2) Load the object and the component manager argument
+            mv.visitVarInsn(ALOAD, 0);
+            // mv.visitVarInsn(ALOAD,
+            // Type.getArgumentTypes(m_constructorDesc).length);
+            mv.visitVarInsn(ALOAD, 1); // CM is always the first argument
+            // 3) Initialize the field
+            mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setComponentManager",
+                    "(Lorg/apache/felix/ipojo/InstanceManager;)V");
+            // insertion finished
+        } else {
+            mv.visitMethodInsn(opcode, owner, name, desc);
+        }
+    }
+
+    /**
+     * Visit an instruction modifying a local variable.
+     * Increment the variable number if != 0.
+     * @param opcode : opcode of the instruction.
+     * @param var : variable number.
+     * @see org.objectweb.asm.commons.AdviceAdapter#visitVarInsn(int, int)
+     */
+    public void visitVarInsn(int opcode, int var) {
+        if (var == 0) {
+            mv.visitVarInsn(opcode, var); // ALOAD 0 (THIS)
+        } else {
+            mv.visitVarInsn(opcode, var + 1); // All other variable count
+        } 
+    }
+
+    /**
+     * Visit an increment instruction.
+     * Increment the variable number.
+     * @param var : incremented variable number.
+     * @param increment : increment.
+     * @see org.objectweb.asm.commons.LocalVariablesSorter#visitIincInsn(int, int)
+     */
+    public void visitIincInsn(int var, int increment) {
+        if (var != 0) {
+            mv.visitIincInsn(var + 1, increment);
+        } else {
+            mv.visitIincInsn(var, increment);
+        }
+    }
+
+    /**
+     * Visit local variable.
+     * @param name : name of the variable.
+     * @param desc : description of the variable.
+     * @param signature : signature of the variable.
+     * @param start : starting label.
+     * @param end : ending label.
+     * @param index : variable index.
+     * @see org.objectweb.asm.commons.LocalVariablesSorter#visitLocalVariable(java.lang.String, java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
+     */
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
+        if (index == 0) {
+            mv.visitLocalVariable(name, desc, signature, start, end, index);
+            mv.visitLocalVariable("_manager", "Lorg/apache/felix/ipojo/InstanceManager;", null, start, end, 1);
+        } else {
+            mv.visitLocalVariable(name, desc, signature, start, end, index + 1);   
+        }
+    }
+
+    /**
+     * Manage a field operation.
+     * Replace GETFIELD and PUTFILED by getter and setter invocation.
+     * 
+     * @param opcode : visited operation code
+     * @param owner : owner of the field
+     * @param name : name of the field
+     * @param desc : decriptor of the field
+     * @see org.objectweb.asm.commons.AdviceAdapter#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitFieldInsn(final int opcode, final String owner,
+            final String name, final String desc) {
+        if (owner.equals(m_owner)) {
+            if (opcode == GETFIELD) {
+                String gDesc = "()" + desc;
+                visitMethodInsn(INVOKEVIRTUAL, owner, "_get" + name, gDesc);
+                return;
+            } else if (opcode == PUTFIELD) {
+                String sDesc = "(" + desc + ")V";
+                visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
+                return;
+            }
+        }
+        super.visitFieldInsn(opcode, owner, name, desc);
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,656 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.logging.Level;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Create getter and setter for each fields .
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class FieldAdapter extends ClassAdapter implements Opcodes {
+
+    /**
+     * The owner.
+     * m_owner : String
+     */
+    private String m_owner;
+
+    /**
+     * Constructor.
+     * @param cv : Class visitor
+     */
+    public FieldAdapter(final ClassVisitor cv) {
+        super(cv);
+    }
+
+    /**
+     * The visit method. - Insert the _cm field - Create the _initialize method - Create the _cm setter method
+     * 
+     * @see org.objectweb.asm.ClassVisitor#visit(int, int, String, String, String, String[])
+     * @param version : Version
+     * @param access : Access modifier
+     * @param name : name of the visited element
+     * @param signature : signature of the visited element
+     * @param superName : superclasses (extend clause)
+     * @param interfaces : implement clause
+     */
+    public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
+        m_owner = name;
+    }
+
+    /**
+     * Visit a Field.
+     * Inject the getter and the setter method for this field.
+     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+     * @param access : acces modifier
+     * @param name : name of the field
+     * @param desc : description of the field
+     * @param signature : signature of the field
+     * @param value : value of the field
+     * @return FieldVisitor : null
+     */
+    public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
+
+        if ((access & ACC_STATIC) == 0) {
+            ManipulationProperty.getLogger().log(Level.INFO, "Manipulate the field declaration of " + name);
+            Type type = Type.getType(desc);
+
+            if (type.getSort() == Type.ARRAY) {
+                String gDesc = "()" + desc;
+                createArrayGetter(name, gDesc, type);
+
+                // Generates setter method
+                String sDesc = "(" + desc + ")V";
+                createArraySetter(name, sDesc, type);
+
+            } else {
+                // Generate the getter method
+                String gDesc = "()" + desc;
+                createSimpleGetter(name, gDesc, type);
+
+                // Generates setter method
+                String sDesc = "(" + desc + ")V";
+                createSimpleSetter(name, sDesc, type);
+            }
+
+        }
+
+        return null;
+    }
+
+    /**
+     * Create a getter method for an array.
+     * @param name : field name
+     * @param desc : method description
+     * @param type : contained type (inside the array)
+     */
+    private void createArraySetter(String name, String desc, Type type) {
+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_set" + name, desc, null, null);
+
+        String internalType = desc.substring(1);
+        internalType = internalType.substring(0, internalType.length() - 2);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitFieldInsn(PUTFIELD, m_owner, name, internalType);
+
+        Label l1 = new Label();
+        mv.visitLabel(l1);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+        Label l2 = new Label();
+        mv.visitJumpInsn(IFNE, l2);
+        mv.visitInsn(RETURN);
+        mv.visitLabel(l2);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitLdcInsn(name);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+        mv.visitInsn(RETURN);
+
+        // End
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Create a setter method for an array.
+     * @param name : field name
+     * @param desc : method description
+     * @param type : contained type (inside the array)
+     */
+    private void createArrayGetter(String name, String desc, Type type) {
+
+        String methodName = "_get" + name;
+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, methodName, desc, null, null);
+
+        String internalType = desc.substring(2);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+        Label l1 = new Label();
+        mv.visitJumpInsn(IFNE, l1);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);
+        mv.visitInsn(ARETURN);
+        mv.visitLabel(l1);
+
+        mv.visitVarInsn(ALOAD, 0);
+        // mv.visitFieldInsn(GETFIELD, m_owner, name, "["+type.getInternalName()+";");
+        mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);
+        mv.visitVarInsn(ASTORE, 1);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitLdcInsn(name);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+        mv.visitVarInsn(ASTORE, 2);
+
+        mv.visitVarInsn(ALOAD, 2);
+        mv.visitTypeInsn(CHECKCAST, internalType);
+        mv.visitVarInsn(ASTORE, 3);
+
+        Label l3a = new Label();
+        mv.visitLabel(l3a);
+
+        mv.visitVarInsn(ALOAD, 1);
+        Label l4a = new Label();
+        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.visitVarInsn(ALOAD, 0);
+        mv.visitVarInsn(ALOAD, 3);
+        mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalType + ")V");
+        mv.visitLabel(l5a);
+
+        mv.visitVarInsn(ALOAD, 3);
+        mv.visitInsn(ARETURN);
+
+        // End
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Create the getter for a field.
+     * @param name : field of the dependency
+     * @param desc : description of the getter method
+     * @param type : type to return
+     */
+    private void createSimpleGetter(String name, String desc, Type type) {
+
+        String methodName = "_get" + name;
+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, methodName, desc, null, null);
+
+        switch (type.getSort()) {
+            case Type.BOOLEAN:
+            case Type.CHAR:
+            case Type.BYTE:
+            case Type.SHORT:
+            case Type.INT:
+
+                String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+                String unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];
+
+                Label l0 = new Label();
+                mv.visitLabel(l0);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l1 = new Label();
+                mv.visitJumpInsn(IFNE, l1);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitInsn(IRETURN);
+
+                mv.visitLabel(l1);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitVarInsn(type.getOpcode(ISTORE), 1);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 2);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 2);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+                mv.visitVarInsn(ASTORE, 3);
+
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitTypeInsn(CHECKCAST, boxingType);
+                mv.visitVarInsn(ASTORE, 4);
+
+                mv.visitVarInsn(ALOAD, 4);
+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);
+                mv.visitVarInsn(type.getOpcode(ISTORE), 5);
+
+                Label l5 = new Label();
+                mv.visitLabel(l5);
+
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+                Label l6 = new Label();
+                mv.visitJumpInsn(type.getOpcode(IF_ICMPEQ), l6);
+
+                Label l7 = new Label();
+                mv.visitLabel(l7);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+                mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalName + ")V");
+                mv.visitLabel(l6);
+
+                mv.visitVarInsn(type.getOpcode(ILOAD), 5);
+                mv.visitInsn(type.getOpcode(IRETURN));
+                break;
+
+            case Type.LONG:
+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];
+
+                Label l00 = new Label();
+                mv.visitLabel(l00);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l10 = new Label();
+                mv.visitJumpInsn(IFNE, l10);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitInsn(LRETURN);
+                mv.visitLabel(l10);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitVarInsn(LSTORE, 1);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(LLOAD, 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 3); // Double Space
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+                mv.visitVarInsn(ASTORE, 4);
+
+                mv.visitVarInsn(ALOAD, 4);
+                mv.visitTypeInsn(CHECKCAST, boxingType);
+                mv.visitVarInsn(ASTORE, 5);
+
+                mv.visitVarInsn(ALOAD, 5);
+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);
+                mv.visitVarInsn(LSTORE, 6);
+
+                l5 = new Label();
+                mv.visitLabel(l5);
+
+                mv.visitVarInsn(LLOAD, 1);
+                mv.visitVarInsn(LLOAD, 6);
+                mv.visitInsn(LCMP);
+                l6 = new Label();
+                mv.visitJumpInsn(IFEQ, l6);
+
+                l7 = new Label();
+                mv.visitLabel(l7);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(LLOAD, 6);
+                mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalName + ")V");
+                mv.visitLabel(l6);
+
+                mv.visitVarInsn(LLOAD, 6);
+                mv.visitInsn(LRETURN);
+
+                break;
+
+            case Type.DOUBLE:
+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];
+
+                Label l01 = new Label();
+                mv.visitLabel(l01);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l11 = new Label();
+                mv.visitJumpInsn(IFNE, l11);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitInsn(DRETURN);
+                mv.visitLabel(l11);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitVarInsn(DSTORE, 1);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(DLOAD, 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 3); // Double Space
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+                mv.visitVarInsn(ASTORE, 4);
+
+                mv.visitVarInsn(ALOAD, 4);
+                mv.visitTypeInsn(CHECKCAST, boxingType);
+                mv.visitVarInsn(ASTORE, 5);
+
+                mv.visitVarInsn(ALOAD, 5);
+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);
+                mv.visitVarInsn(DSTORE, 6);
+
+                l5 = new Label();
+                mv.visitLabel(l5);
+
+                mv.visitVarInsn(DLOAD, 1);
+                mv.visitVarInsn(DLOAD, 6);
+                mv.visitInsn(DCMPL);
+                l6 = new Label();
+                mv.visitJumpInsn(IFEQ, l6);
+
+                l7 = new Label();
+                mv.visitLabel(l7);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(DLOAD, 6);
+                mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalName + ")V");
+                mv.visitLabel(l6);
+
+                mv.visitVarInsn(DLOAD, 6);
+                mv.visitInsn(DRETURN);
+
+                break;
+
+            case Type.FLOAT:
+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];
+
+                Label l02 = new Label();
+                mv.visitLabel(l02);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l12 = new Label();
+                mv.visitJumpInsn(IFNE, l12);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitInsn(FRETURN);
+                mv.visitLabel(l12);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);
+                mv.visitVarInsn(FSTORE, 1);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(FLOAD, 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 2); // One Space
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 2);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+                mv.visitVarInsn(ASTORE, 3);
+
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitTypeInsn(CHECKCAST, boxingType);
+                mv.visitVarInsn(ASTORE, 4);
+
+                mv.visitVarInsn(ALOAD, 4);
+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);
+                mv.visitVarInsn(FSTORE, 5);
+
+                l5 = new Label();
+                mv.visitLabel(l5);
+
+                mv.visitVarInsn(FLOAD, 1);
+                mv.visitVarInsn(FLOAD, 5);
+                mv.visitInsn(FCMPL);
+                l6 = new Label();
+                mv.visitJumpInsn(IFEQ, l6);
+
+                l7 = new Label();
+                mv.visitLabel(l7);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(FLOAD, 5);
+                mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(" + internalName + ")V");
+                mv.visitLabel(l6);
+
+                mv.visitVarInsn(FLOAD, 5);
+                mv.visitInsn(FRETURN);
+
+                break;
+
+            case Type.OBJECT:
+
+                Label l03 = new Label();
+                mv.visitLabel(l03);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l13 = new Label();
+                mv.visitJumpInsn(IFNE, l13);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");
+                mv.visitInsn(ARETURN);
+                mv.visitLabel(l13);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");
+                mv.visitVarInsn(ASTORE, 1);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
+                mv.visitVarInsn(ASTORE, 2);
+
+                mv.visitVarInsn(ALOAD, 2);
+                mv.visitTypeInsn(CHECKCAST, type.getInternalName());
+                mv.visitVarInsn(ASTORE, 3);
+
+                Label l3b = new Label();
+                mv.visitLabel(l3b);
+
+                mv.visitVarInsn(ALOAD, 1);
+                Label l4b = new Label();
+                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.visitLabel(l4b);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitMethodInsn(INVOKEVIRTUAL, m_owner, "_set" + name, "(L" + type.getInternalName() + ";)V");
+                mv.visitLabel(l5b);
+
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitInsn(ARETURN);
+
+                break;
+
+            default:
+                ManipulationProperty.getLogger().log(Level.SEVERE, "Manipulation problem in " + m_owner + " : a type is not implemented : " + type);
+                break;
+        }
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Create the setter method for one property. The name of the method is _set+name of the field
+     * 
+     * @param name :
+     *            name of the field representing a property
+     * @param desc :
+     *            description of the setter method
+     * @param type :
+     *            type of the property
+     */
+    private void createSimpleSetter(String name, String desc, Type type) {
+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_set" + name, desc, null, null);
+
+        switch (type.getSort()) {
+            case Type.BOOLEAN:
+            case Type.CHAR:
+            case Type.BYTE:
+            case Type.SHORT:
+            case Type.INT:
+            case Type.FLOAT:
+                String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);
+                Label l1 = new Label();
+                mv.visitLabel(l1);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l22 = new Label();
+                mv.visitJumpInsn(IFNE, l22);
+                mv.visitInsn(RETURN);
+                mv.visitLabel(l22);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 2);
+
+                Label l2 = new Label();
+                mv.visitLabel(l2);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 2);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+                Label l3 = new Label();
+                mv.visitLabel(l3);
+                mv.visitInsn(RETURN);
+                break;
+
+            case Type.LONG:
+            case Type.DOUBLE:
+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];
+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);
+                l1 = new Label();
+                mv.visitLabel(l1);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l23 = new Label();
+                mv.visitJumpInsn(IFNE, l23);
+                mv.visitInsn(RETURN);
+                mv.visitLabel(l23);
+
+                mv.visitTypeInsn(NEW, boxingType);
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);
+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");
+                mv.visitVarInsn(ASTORE, 3); // Double space
+
+                l2 = new Label();
+                mv.visitLabel(l2);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 3);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+                l3 = new Label();
+                mv.visitLabel(l3);
+                mv.visitInsn(RETURN);
+                break;
+
+            case Type.OBJECT:
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitFieldInsn(PUTFIELD, m_owner, name, "L" + type.getInternalName() + ";");
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");
+                Label l24 = new Label();
+                mv.visitJumpInsn(IFNE, l24);
+                mv.visitInsn(RETURN);
+                mv.visitLabel(l24);
+
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+                mv.visitLdcInsn(name);
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+                mv.visitInsn(RETURN);
+                break;
+            default:
+                ManipulationProperty.getLogger().log(Level.SEVERE, "Manipulation Error : Cannot create the setter method for the field : " + name + " (" + type + ")");
+                break;
+        }
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,84 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Store properties for the manipulation process.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ * 
+ */
+public class ManipulationProperty {
+
+    /**
+     * Manipulator logger.
+     */
+    private static Logger m_logger;
+
+    /**
+     * Default logger level.
+     */
+    private static Level m_logLevel = Level.WARNING;
+
+    /**
+     * Get the manipulator logger.
+     * @return the logger used by the manipulator.
+     */
+    public static Logger getLogger() {
+        if (m_logger == null) {
+            String name = "org.apache.felix.ipojo.manipulator";
+            m_logger = Logger.getLogger(name);
+            m_logger.setLevel(m_logLevel);
+        }
+        return m_logger;
+    }
+
+    /**
+     * iPOJO Package name.
+     */
+    protected static final String IPOJO_PACKAGE_NAME = "org.apache.felix.ipojo";
+
+    /**
+     * Activator internal package name.
+     */
+    protected static final String IPOJO_INTERNAL_PACKAGE_NAME = "org/apache/felix/ipojo/";
+
+    /**
+     * Ipojo internal package name for internal descriptor.
+     */
+    protected static final String IPOJO_INTERNAL_DESCRIPTOR = "L" + IPOJO_INTERNAL_PACKAGE_NAME;
+
+    /**
+     * Helper array for bytecode manipulation of primitive type.
+     */
+    protected static final String[][] PRIMITIVE_BOXING_INFORMATION = new String[][] { { "V", "ILLEGAL", "ILLEGAL" }, // Void type [0]
+        { "Z", "java/lang/Boolean", "booleanValue" }, // boolean [1]
+        { "C", "java/lang/Character", "charValue" }, // char [2]
+        { "B", "java/lang/Byte", "byteValue" }, // byte [3]
+        { "S", "java/lang/Short", "shortValue" }, // short [4]
+        { "I", "java/lang/Integer", "intValue" }, // int [5]
+        { "F", "java/lang/Float", "floatValue" }, // float [6]
+        { "J", "java/lang/Long", "longValue" }, // long [7]
+        { "D", "java/lang/Double", "doubleValue" } // double [8]
+    };
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,241 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * iPOJO Bytecode Manipulator.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ * 
+ */
+public class Manipulator {
+    /**
+     * Store the visited fields : [name fo the field, type of the field].
+     */
+    private HashMap m_fields = new HashMap();
+
+    /**
+     * Store the interface implemented by the class.
+     */
+    private String[] m_interfaces = new String[0];
+
+    /**
+     * Store the methods list.
+     */
+    private List m_methods = new ArrayList();
+
+    /**
+     * Manipulate the class.
+     * 
+     * @param name : The name of the class
+     * @param outputDirectory : output directory where the class if stored.
+     * @return true if the class is correctly manipulated.
+     * @throws Exception : throwed if the manipulation failed.
+     */
+    public boolean manipulate(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";
+        File clazz = new File(path);
+
+        if (!clazz.exists()) {
+            return false;
+        }
+
+        URL url = clazz.toURI().toURL();
+
+        // if (url == null) { throw new ClassNotFoundException(name); }
+        ManipulationProperty.getLogger().log(Level.INFO, "Manipulate the class file : " + clazz.getAbsolutePath());
+
+        InputStream is1 = url.openStream();
+
+        // First check if the class is already manipulated :
+        ClassReader ckReader = new ClassReader(is1);
+        ClassChecker ck = new ClassChecker();
+        ckReader.accept(ck, ClassReader.SKIP_FRAMES);
+        is1.close();
+
+        m_fields = ck.getFields();
+
+        // Get interface and remove POJO interface is presents
+        String[] its = ck.getInterfaces();
+        ArrayList l = new ArrayList();
+        for (int i = 0; i < its.length; i++) {
+            l.add(its[i]);
+        }
+        l.remove("org/apache/felix/ipojo/Pojo");
+
+        m_interfaces = new String[l.size()];
+        for (int i = 0; i < m_interfaces.length; i++) {
+            m_interfaces[i] = ((String) l.get(i)).replace('/', '.');
+        }
+
+        // Get the method list
+        // Remove iPOJO methods
+        for (int i = 0; i < ck.getMethods().size(); i++) {
+            MethodDescriptor method = (MethodDescriptor) ck.getMethods().get(i);
+            if (!(method.getName().startsWith("_get") || // Avoid getter method
+                    method.getName().startsWith("_set") || // Avoid setter method
+                    method.getName().equals("_setComponentManager") || // Avoid the set method
+                    method.getName().equals("getComponentInstance"))) { // Avoid the getComponentInstance method
+                System.err.println(" Add the method : " + method);
+                m_methods.add(method);
+            }
+        }
+
+        if (!ck.isalreadyManipulated()) {
+
+            // Manipulation ->
+            // Add the _setComponentManager method
+            // Instrument all fields
+            InputStream is2 = url.openStream();
+            ClassReader cr0 = new ClassReader(is2);
+            ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+            PojoAdapter preprocess = new PojoAdapter(cw0);
+            cr0.accept(preprocess, ClassReader.SKIP_FRAMES);
+            is2.close();
+
+            try {
+                FileOutputStream fos = new FileOutputStream(clazz);
+
+                fos.write(cw0.toByteArray());
+
+                fos.close();
+                ManipulationProperty.getLogger().log(Level.INFO, "Put the file " + clazz.getAbsolutePath() + " in the jar file");
+            } catch (Exception e) {
+                System.err.println("Problem to write the adapted class on the file system " + " [ " + clazz.getAbsolutePath() + " ] " + e.getMessage());
+            }
+        }
+        // The file is in the bundle
+        return true;
+    }
+
+    /**
+     * Manipulate the given byte array.
+     * 
+     * @param origin :
+     *            original class.
+     * @return the manipulated class.
+     * @throws IOException :
+     *             if an error occurs during the manipulation.
+     */
+    public byte[] manipulate(byte[] origin) throws IOException {
+        InputStream is1 = new ByteArrayInputStream(origin);
+
+        // First check if the class is already manipulated :
+        ClassReader ckReader = new ClassReader(is1);
+        ClassChecker ck = new ClassChecker();
+        ckReader.accept(ck, ClassReader.SKIP_FRAMES);
+        is1.close();
+
+        m_fields = ck.getFields();
+
+        // Get interface and remove POJO interface is presents
+        String[] its = ck.getInterfaces();
+        ArrayList l = new ArrayList();
+        for (int i = 0; i < its.length; i++) {
+            l.add(its[i]);
+        }
+        l.remove("org/apache/felix/ipojo/Pojo");
+
+        m_interfaces = new String[l.size()];
+        for (int i = 0; i < m_interfaces.length; i++) {
+            m_interfaces[i] = ((String) l.get(i)).replace('/', '.');
+        }
+
+        for (int i = 0; i < ck.getMethods().size(); i++) {
+            MethodDescriptor method = (MethodDescriptor) ck.getMethods().get(i);
+            if (!(method.getName().startsWith("_get") || // Avoid getter method
+                    method.getName().startsWith("_set") || // Avoid setter method
+                    method.getName().equals("_setComponentManager") || // Avoid the set method
+                    method.getName().equals("getComponentInstance"))) { // Avoid the getComponentInstance method
+                m_methods.add(method);
+            }
+        }
+
+        ClassWriter finalWriter = null;
+        if (!ck.isalreadyManipulated()) {
+            // Manipulation ->
+            // Add the _setComponentManager method
+            // Instrument all fields
+            InputStream is2 = new ByteArrayInputStream(origin);
+            ClassReader cr0 = new ClassReader(is2);
+            ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+            PojoAdapter preprocess = new PojoAdapter(cw0);
+            cr0.accept(preprocess, ClassReader.SKIP_FRAMES);
+            is2.close();
+            finalWriter = cw0;
+        }
+        // The file is in the bundle
+        return finalWriter.toByteArray();
+    }
+
+    /**
+     * Compute component type manipulation metadata.
+     * @return the manipulation metadata of the class.
+     */
+    public Element getManipulationMetadata() {
+        Element elem = new Element("Manipulation", "");
+        for (int j = 0; j < m_interfaces.length; j++) {
+            Element itf = new Element("Interface", "");
+            Attribute att = new Attribute("name", m_interfaces[j]);
+            itf.addAttribute(att);
+            elem.addElement(itf);
+        }
+        for (Iterator it = m_fields.keySet().iterator(); it.hasNext();) {
+            Element field = new Element("Field", "");
+            String name = (String) it.next();
+            String type = (String) m_fields.get(name);
+            Attribute attName = new Attribute("name", name);
+            Attribute attType = new Attribute("type", type);
+            field.addAttribute(attName);
+            field.addAttribute(attType);
+            elem.addElement(field);
+        }
+
+        for (int j = 0; j < m_methods.size(); j++) {
+            MethodDescriptor method = (MethodDescriptor) m_methods.get(j);
+            elem.addElement(method.getElement());
+        }
+
+        return elem;
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,174 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.logging.Level;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AdviceAdapter;
+
+/**
+ * Insert code calling callbacks at the entry and before the exit of a method.
+ * Moreover it replaces all GETFIELD and SETFIELD by getter and setter invocation.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class MethodCodeAdapter extends AdviceAdapter implements Opcodes {
+
+    /**
+     * The owner class of the field. m_owner : String
+     */
+    private String m_owner;
+
+    /**
+     * Name of the method.
+     */
+    private String m_name;
+
+    /**
+     * MethodCodeAdapter constructor. 
+     * @param mv : MethodVisitor
+     * @param owner : Name of the class
+     * @param access : Method acess
+     * @param name : Method name
+     * @param desc : Method descriptor
+     */
+    public MethodCodeAdapter(final MethodVisitor mv, final String owner, int access, String name, String desc) {
+        super(mv, access, name, desc);
+        m_owner = owner;
+        m_name = name;
+    }
+
+    /**
+     * Visit an instruction modifying a method (GETFIELD/PUTFIELD).
+     * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, String, String, String)
+     * @param opcode : visited operation code
+     * @param owner : owner of the field
+     * @param name : name of the field
+     * @param desc : decriptor of the field
+     */
+    public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
+        if (owner.equals(m_owner)) {
+            if (opcode == GETFIELD) {
+                ManipulationProperty.getLogger().log(Level.INFO, "Manipulate a GETFIELD on : " + name);
+                String gDesc = "()" + desc;
+                visitMethodInsn(INVOKEVIRTUAL, owner, "_get" + name, gDesc);
+                return;
+            } else if (opcode == PUTFIELD) {
+                ManipulationProperty.getLogger().log(Level.INFO, "Manipulate a PUTFIELD on : " + name);
+                String sDesc = "(" + desc + ")V";
+                visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
+                return;
+            }
+        }
+        super.visitFieldInsn(opcode, owner, name, desc);
+    }
+
+    /**
+     * Method injecting call at the entry of each method.
+     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodEnter()
+     */
+    protected void onMethodEnter() {
+        Type[] args = Type.getArgumentTypes(methodDesc);
+        String name = m_name;
+        
+        for (int i = 0; i < args.length; i++) {
+            String cn = args[i].getClassName();
+            if (cn.endsWith("[]")) {
+                cn = cn.replace("[]", "$");
+            }
+            cn = cn.replace(".", "_");
+            name += cn;
+        }
+
+        String flag = "_M" + name;
+
+        Label l0 = new Label();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");
+        Label l1 = new Label();
+        mv.visitJumpInsn(IFEQ, l1);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitLdcInsn(name);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "entryCallback", "(Ljava/lang/String;)V");
+        mv.visitLabel(l1);
+    }
+
+    /**
+     * Method injecting call at the exit of each method.
+     * @param opcode : returned opcode (ARETURN, IRETURN, ATHROW ...)
+     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodExit(int)
+     */
+    protected void onMethodExit(int opcode) {
+        Type[] args = Type.getArgumentTypes(methodDesc);
+        String name = m_name;
+       
+        for (int i = 0; i < args.length; i++) {
+            String cn = args[i].getClassName();
+            if (cn.endsWith("[]")) {
+                cn = cn.replace("[]", "$");
+            }
+            cn = cn.replace(".", "_");
+            name += cn;
+        }
+
+        String flag = "_M" + name;
+
+        int local = newLocal(Type.getType(Object.class));
+        if (opcode == RETURN) {
+            visitInsn(ACONST_NULL);
+        } else if (opcode != ARETURN && opcode != ATHROW) {
+            box(Type.getReturnType(this.methodDesc));
+        }
+        
+        mv.visitVarInsn(ASTORE, local);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");
+        Label l5 = new Label();
+        mv.visitJumpInsn(IFEQ, l5);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitLdcInsn(name);
+        mv.visitVarInsn(ALOAD, local);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "exitCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");
+
+        mv.visitLabel(l5);
+        if (opcode == ARETURN || opcode == ATHROW) {
+            mv.visitVarInsn(ALOAD, local);
+        } else if (opcode != RETURN) {
+            mv.visitVarInsn(ALOAD, local);
+            unbox(Type.getReturnType(this.methodDesc));
+        }
+    }
+
+    /**
+     * Compute mx local and max stack size.
+     * @param maxStack : new stack size.
+     * @param maxLocals : max local (do not modified, super will update it automatically).
+     * @see org.objectweb.asm.commons.LocalVariablesSorter#visitMaxs(int, int)
+     */
+    public void visitMaxs(int maxStack, int maxLocals) {
+        super.visitMaxs(maxStack + 1, maxLocals);
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,129 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
+
+/**
+ * Method Descriptor describe a method.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class MethodDescriptor {
+
+    /**
+     * Method name.
+     */
+    private String m_name;
+
+    /**
+     * Returned type.
+     */
+    private String m_returnType;
+
+    /**
+     * Argument types.
+     */
+    private String[] m_arguments;
+
+    /**
+     * Constructor.
+     * @param name : name of the method.
+     * @param desc : descriptor of the method.
+     */
+    public MethodDescriptor(String name, String desc) {
+        m_name = name;
+        Type ret = Type.getReturnType(desc);
+        Type[] args = Type.getArgumentTypes(desc);
+
+        m_returnType = getType(ret);
+        m_arguments = new String[args.length];
+        for (int i = 0; i < args.length; i++) {
+            m_arguments[i] = getType(args[i]);
+        }
+    }
+
+    /**
+     * Compute method manipulation metadata.
+     * @return the element containing metadata about this method.
+     */
+    public Element getElement() {
+        Element method = new Element("method", "");
+        method.addAttribute(new Attribute("name", m_name));
+
+        // 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));
+        }
+
+        return method;
+    }
+
+    /**
+     * Get the iPOJO internal type for the given type.
+     * @param type : type.
+     * @return the iPOJO internal type.
+     */
+    private String getType(Type type) {
+        switch (type.getSort()) {
+            case Type.ARRAY:
+                Type elemType = type.getElementType();
+                return getType(elemType) + "[]";
+            case Type.BOOLEAN:
+                return "boolean";
+            case Type.BYTE:
+                return "byte";
+            case Type.CHAR:
+                return "char";
+            case Type.DOUBLE:
+                return "double";
+            case Type.FLOAT:
+                return "float";
+            case Type.INT:
+                return "int";
+            case Type.LONG:
+                return "long";
+            case Type.OBJECT:
+                return type.getClassName();
+            case Type.SHORT:
+                return "short";
+            case Type.VOID:
+                return "void";
+            default:
+                return "unknown";
+        }
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+}

Added: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java?view=auto&rev=550247
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java (added)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java Sun Jun 24 08:11:33 2007
@@ -0,0 +1,362 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Manipulate a POJO class.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class PojoAdapter extends ClassAdapter implements Opcodes {
+
+    /**
+     * POJO interface.
+     */
+    private final String m_pojo = "org/apache/felix/ipojo/Pojo";
+
+    /**
+     * The owner. m_owner : String
+     */
+    private String m_owner;
+
+    /**
+     * Field list.
+     */
+    private List m_fields = new ArrayList();
+
+    /**
+     * Method list.
+     */
+    private List m_methods = new ArrayList();
+
+    /**
+     * Getter/Setter methods creator.
+     */
+    FieldAdapter m_getterSetterCreator = new FieldAdapter(cv);
+
+    /**
+     * Constructor.
+     * @param arg0 : class adapter on which delegate.
+     */
+    public PojoAdapter(ClassVisitor arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Start visiting a class.
+     * Initialize the getter/setter generator, add the _cm field, add the pojo interface.
+     * @param version : class version
+     * @param access : class access
+     * @param name : class name 
+     * @param signature : class signature
+     * @param superName : class super class
+     * @param interfaces : implemented interfaces
+     * @see org.objectweb.asm.ClassAdapter#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) {
+        m_owner = name;
+        m_getterSetterCreator.visit(version, access, name, signature, superName, interfaces);
+        addCMField();
+        addPOJOInterface(version, access, name, signature, superName, interfaces);
+    }
+
+    /**
+     * Visit an annotation.
+     * @param desc : annotation descriptor.
+     * @param visible : is the annotation visible at runtime.
+     * @return the annotation visitor.
+     * @see org.objectweb.asm.ClassAdapter#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        return super.visitAnnotation(desc, visible);
+    }
+
+    /**
+     * Visit an attribute.
+     * @param attr : visited attribute
+     * @see org.objectweb.asm.ClassAdapter#visitAttribute(org.objectweb.asm.Attribute)
+     */
+    public void visitAttribute(Attribute attr) {
+        super.visitAttribute(attr);
+    }
+
+    /**
+     * Visit end.
+     * Create helper methods.
+     * @see org.objectweb.asm.ClassAdapter#visitEnd()
+     */
+    public void visitEnd() {
+        // Create the _cmSetter(ComponentManager cm) method
+        createComponentManagerSetter();
+
+        // Add the getComponentInstance
+        createGetComponentInstanceMethod();
+
+        m_methods.clear();
+        m_fields.clear();
+
+        cv.visitEnd();
+    }
+
+    /**
+     * Visit a field.
+     * Call the adapter generating getter and setter methods.
+     * @param access : field acess.
+     * @param name : field name
+     * @param desc : field descriptor
+     * @param signature : field signature
+     * @param value : field value (static field only)
+     * @return the field visitor.
+     * @see org.objectweb.asm.ClassAdapter#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) {
+        // Add the field to the list.
+        if ((access & ACC_STATIC) == 0) {
+            m_fields.add(name);
+            addFlagField(name);
+            m_getterSetterCreator.visitField(access, name, desc, signature, value);
+        }
+
+        return super.visitField(access, name, desc, signature, value);
+    }
+
+    /**
+     * Visit an inner class.
+     * @param name : class name
+     * @param outerName : outer name
+     * @param innerName : inner name
+     * @param access : class access
+     * @see org.objectweb.asm.ClassAdapter#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)
+     */
+    public void visitInnerClass(String name, String outerName, String innerName, int access) {
+        super.visitInnerClass(name, outerName, innerName, access);
+    }
+
+    /**
+     * Visit a method.
+     * Manipulate constructor and methods. Does nothing with clinit and class$
+     * @param access : method acess
+     * @param name : method name
+     * @param desc : method descriptor
+     * @param signature : method signature
+     * @param exceptions : method exceptions
+     * @return the Method Visitor.
+     * @see org.objectweb.asm.ClassAdapter#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) {
+        if (name.equals("<clinit>") || name.equals("class$")) {
+            return super.visitMethod(access, name, desc, signature, exceptions);
+        }
+        if (name.equals("<init>")) {
+            // 1) change the constructor descriptor (add a component manager arg as first argument)
+            String newDesc = desc.substring(1);
+            newDesc = "(Lorg/apache/felix/ipojo/InstanceManager;" + newDesc;
+
+            // Insert the new constructor
+            MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "<init>", newDesc, null, null);
+
+            if (mv == null) {
+                return null;
+            } else {
+                return new ConstructorCodeAdapter(mv, access, desc, m_owner);
+            }
+        } else {
+            Type[] args = Type.getArgumentTypes(desc);
+            String id = name;
+            for (int i = 0; i < args.length; i++) {
+                String cn = args[i].getClassName();
+                if (cn.endsWith("[]")) {
+                    cn = cn.replace("[]", "$");
+                }
+                cn = cn.replace(".", "_");
+                id += cn;
+            }
+
+            String flag = "_M" + id;
+            m_methods.add(id);
+
+            FieldVisitor flagField = cv.visitField(Opcodes.ACC_PRIVATE, flag, "Z", null, null);
+            if (flagField != null) {
+                flagField.visitEnd();
+            }
+
+            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+            return new MethodCodeAdapter(mv, m_owner, access, name, desc);
+        }
+    }
+
+    /**
+     * Visit an outer class.
+     * @param owner : class owner
+     * @param name : class name
+     * @param desc : class descriptor.
+     * @see org.objectweb.asm.ClassAdapter#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitOuterClass(String owner, String name, String desc) {
+        super.visitOuterClass(owner, name, desc);
+    }
+
+    /**
+     * Visit source.
+     * @param source : source
+     * @param debug : debug
+     * @see org.objectweb.asm.ClassAdapter#visitSource(java.lang.String, java.lang.String)
+     */
+    public void visitSource(String source, String debug) {
+        super.visitSource(source, debug);
+    }
+
+    /**
+     * Add the instance manager field (_cm).
+     */
+    private void addCMField() {
+        // Insert _cm field
+        FieldVisitor fv = super.visitField(ACC_PRIVATE, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;", null, null);
+        fv.visitEnd();
+    }
+
+    /**
+     * Add the POJO interface to the visited class.
+     * @param version : class version
+     * @param access : class access
+     * @param name : class name
+     * @param signature : class signature
+     * @param superName : super class
+     * @param interfaces : implemented interfaces.
+     */
+    private void addPOJOInterface(int version, int access, String name, String signature, String superName, String[] interfaces) {
+
+        // Add the POJO interface to the interface list
+        // Check that the POJO interface isnot already in the list
+        boolean found = false;
+        for (int i = 0; i < interfaces.length; i++) {
+            if (interfaces[i].equals(m_pojo)) {
+                found = true;
+            }
+        }
+        String[] itfs;
+        if (!found) {
+            itfs = new String[interfaces.length + 1];
+            for (int i = 0; i < interfaces.length; i++) {
+                itfs[i] = interfaces[i];
+            }
+            itfs[interfaces.length] = m_pojo;
+        } else {
+            itfs = interfaces;
+        }
+
+        String str = "";
+        for (int i = 0; i < itfs.length; i++) {
+            str += itfs[i] + " ";
+        }
+
+        cv.visit(version, access, name, signature, superName, itfs);
+    }
+
+    /**
+     * Create the setter method for the _cm field.
+     */
+    private void createComponentManagerSetter() {
+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_setComponentManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V", null, null);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitFieldInsn(PUTFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredFields", "()Ljava/util/Set;");
+        mv.visitVarInsn(ASTORE, 2);
+
+        for (int i = 0; i < m_fields.size(); i++) {
+            String field = (String) m_fields.get(i);
+            mv.visitVarInsn(ALOAD, 2);
+            mv.visitLdcInsn(field);
+            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");
+            Label l3 = new Label();
+            mv.visitJumpInsn(IFEQ, l3);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitInsn(ICONST_1);
+            mv.visitFieldInsn(PUTFIELD, m_owner, "_F" + field, "Z");
+            mv.visitLabel(l3);
+        }
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredMethods", "()Ljava/util/Set;");
+        mv.visitVarInsn(ASTORE, 2);
+
+        for (int i = 0; i < m_methods.size(); i++) {
+            String methodId = (String) m_methods.get(i);
+            mv.visitVarInsn(ALOAD, 2);
+            mv.visitLdcInsn(methodId);
+            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");
+            Label l3 = new Label();
+            mv.visitJumpInsn(IFEQ, l3);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitInsn(ICONST_1);
+            mv.visitFieldInsn(PUTFIELD, m_owner, "_M" + methodId, "Z");
+            mv.visitLabel(l3);
+        }
+
+        mv.visitInsn(RETURN);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Create the getComponentInstance method.
+     */
+    private void createGetComponentInstanceMethod() {
+        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getComponentInstance", "()Lorg/apache/felix/ipojo/ComponentInstance;", null, null);
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
+        mv.visitInsn(ARETURN);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Add the flag field.
+     * @param name : name of the field
+     */
+    private void addFlagField(String name) {
+        // Add the flag field
+        FieldVisitor flag = cv.visitField(Opcodes.ACC_PRIVATE, "_F" + name, "Z", null, null);
+        if (flag != null) {
+            flag.visitEnd();
+        }
+    }
+
+}