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 2008/10/06 10:13:59 UTC

svn commit: r701987 - in /felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo: manipulation/ manipulation/annotations/ manipulator/ xml/parser/

Author: clement
Date: Mon Oct  6 01:13:59 2008
New Revision: 701987

URL: http://svn.apache.org/viewvc?rev=701987&view=rev
Log:
Fix the issue Felix-739.
Visible annotations on methods are now moved to iPOJO methods replacing those methods.

Modified:
    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/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/MethodCreator.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/annotations/CustomAnnotationVisitor.java
    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/xml/parser/XMLMetadataParser.java

Modified: 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?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java Mon Oct  6 01:13:59 2008
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -71,6 +72,12 @@
      * List of visited inner class owned by the implementation class.
      */
     private List m_inners = new ArrayList();
+    
+    /**
+     * <code>true</code> if the class supports annotations.
+     * This enables the analysis of the code to find and moves annotations.
+     */
+    private boolean m_supportAnnotation = false;
 
     /**
      * Check if the _cm field already exists.
@@ -150,6 +157,8 @@
      */
     public void visit(int version, int access, String name, String signature,
             String superName, String[] interfaces) {
+
+        m_supportAnnotation = version > V1_4 && version < V1_1;
         
         if (! superName.equals("java/lang/Object")) {
             m_superClass = superName.replace('/', '.');
@@ -180,18 +189,27 @@
         if (!name.equals("<clinit>")) { 
             
             if (name.equals("<init>")) {
-                m_methods.add(new MethodDescriptor("$init", desc));
+                final MethodDescriptor md = new MethodDescriptor("$init", desc);
+                m_methods.add(md);
+                if (m_supportAnnotation) {
+                    return new AnnotationCollector(md); 
+                }
             } else {
                 // Avoid constructors.
                 if (!(name.startsWith("_get") || // Avoid getter method
                         name.startsWith("_set") || // Avoid setter method
                         name.equals("_setComponentManager") || // Avoid the set method
                         name.equals("getComponentInstance"))) { // Avoid the getComponentInstance method
-                    m_methods.add(new MethodDescriptor(name, desc));
+                    final MethodDescriptor md = new MethodDescriptor(name, desc);
+                    m_methods.add(md);
+                    if (m_supportAnnotation) {
+                        return new AnnotationCollector(md); 
+                    }
                 }
             }
             
-        }
+        }        
+        
         return null;
     }
     
@@ -226,5 +244,413 @@
     public List getInnerClasses() {
         return m_inners;
     }
+    
+    /**
+     * This class collects annotations in a method.
+     * This class creates an {@link AnnotationDescriptor} 
+     * if an annotation is found during the visit.
+     *  @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    private final class AnnotationCollector extends EmptyVisitor {
+        /**
+         * The method descriptor of the visited method.
+         */
+        private MethodDescriptor m_method;
+        
+        /**
+         * Creates an annotation collector.
+         * @param md the method descriptor of the visited method.
+         */
+        private AnnotationCollector(MethodDescriptor md) {
+            m_method = md;
+        }
+        
+        /**
+         * Visits an annotation.
+         * This class checks the visibility. If the annotation is visible,
+         * creates the {@link AnnotationDescriptor} corresponding to this annotation
+         * to visit this annotation. This {@link AnnotationDescriptor} is added to
+         * the {@link MethodDescriptor} of the visited method.
+         * @param name the name of the annotation
+         * @param visible is the annotation visible at runtime
+         * @return the {@link AnnotationDescriptor} to visit this annotation or
+         * <code>null</code> if the annotation is not visible.
+         * @see org.objectweb.asm.commons.EmptyVisitor#visitAnnotation(java.lang.String, boolean)
+         */
+        public AnnotationVisitor visitAnnotation(String name, boolean visible) {
+            if (visible) {
+                AnnotationDescriptor ann = new AnnotationDescriptor(name, visible);
+                m_method.addAnnotation(ann);
+                return ann;
+            }
+            return null;
+        }
+    }
+    
+    /**
+     * Describes a method or constructor annotation.
+     * This allows creating a copy of the annotations found in the original class
+     * to move them on inserted method. This class implements an
+     * {@link AnnotationVisitor} in order to create the copy.
+     * This class contains a <code>visit</code> method re-injecting the
+     * annotation in the generated method.
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    public class AnnotationDescriptor implements AnnotationVisitor {
+        /**
+         * The name of the annotation.
+         */
+        private String m_name;
+        /**
+         * Is the annotation visible at runtime?
+         */
+        private boolean m_visible;
+        /**
+         * The description of the annotation.
+         * This attribute is set only for nested annotations.
+         */
+        private String m_desc;
+        /**
+         * The list of 'simple' attributes.
+         */
+        private List m_simples = new ArrayList(0);
+        /**
+         * The list of attribute containing an
+         * enumeration value.
+         */
+        private List m_enums = new ArrayList(0);
+        /**
+         * The list of attribute which are
+         * annotations.
+         */
+        private List m_nested = new ArrayList(0);
+        /**
+         * The list of attribute which are
+         * arrays. 
+         */
+        private List m_arrays = new ArrayList(0);
+        
+        
+        /**
+         * Creates an annotation descriptor.
+         * This constructor is used for 'root' annotations.
+         * @param name the name of the  annotation
+         * @param visible the visibility of the annotation at runtime
+         */
+        public AnnotationDescriptor(String name, boolean visible) {
+            m_name = name;
+            m_visible = visible;
+        }
+        
+        /**
+         * Creates an annotation descriptor.
+         * This constructor is used for nested annotations.
+         * @param name the name of the  annotation
+         * @param desc the descriptor of the annotation
+         */
+        public AnnotationDescriptor(String name, String desc) {
+            m_name = name;
+            m_visible = true;
+            m_desc = desc;
+        }
+
+
+        /**
+         * Visits a simple attribute.
+         * @param arg0 the attribute name
+         * @param arg1 the attribute value
+         * @see org.objectweb.asm.AnnotationVisitor#visit(java.lang.String, java.lang.Object)
+         */
+        public void visit(String arg0, Object arg1) {
+            m_simples.add(new SimpleAttribute(arg0, arg1));
+        }
+
+
+        /**
+         * Visits a nested annotation.
+         * @param arg0 the attribute name
+         * @param arg1 the annotation descriptor
+         * @return the annotation visitor parsing the nested annotation
+         * @see org.objectweb.asm.AnnotationVisitor#visitAnnotation(java.lang.String, java.lang.String)
+         */
+        public AnnotationVisitor visitAnnotation(String arg0, String arg1) {
+            AnnotationDescriptor ad = new AnnotationDescriptor(arg0, arg1);
+            m_nested.add(ad);
+            return ad;
+        }
+
+
+        /**
+         * Visits an array attribute.
+         * @param arg0 the name of the attribute
+         * @return the annotation visitor parsing the content of the array,
+         * uses a specific {@link ArrayAttribute} to parse this array
+         * @see org.objectweb.asm.AnnotationVisitor#visitArray(java.lang.String)
+         */
+        public AnnotationVisitor visitArray(String arg0) {
+            ArrayAttribute aa = new ArrayAttribute(arg0);
+            m_arrays.add(aa);
+            return aa;
+        }
+
+
+        /**
+         * End of the visit.
+         * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
+         */
+        public void visitEnd() { }
+
+
+        /**
+         * Visits an enumeration attribute.
+         * @param arg0 the attribute name
+         * @param arg1 the enumeration descriptor
+         * @param arg2 the attribute value
+         * @see org.objectweb.asm.AnnotationVisitor#visitEnum(java.lang.String, java.lang.String, java.lang.String)
+         */
+        public void visitEnum(String arg0, String arg1, String arg2) {
+            m_enums.add(new EnumAttribute(arg0, arg1, arg2));
+        }
+        
+        /**
+         * Methods allowing to recreate the visited (stored) annotation
+         * into the destination method.
+         * This method recreate the annotations itself and any other 
+         * attributes.
+         * @param mv the method visitor visiting the destination method.
+         */
+        public void visit(MethodVisitor mv) {
+            AnnotationVisitor av = mv.visitAnnotation(m_name, m_visible);
+            for (int i = 0; i < m_simples.size(); i++) {
+                ((SimpleAttribute) m_simples.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_enums.size(); i++) {
+                ((EnumAttribute) m_enums.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_nested.size(); i++) {
+                ((AnnotationDescriptor) m_nested.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_arrays.size(); i++) {
+                ((ArrayAttribute) m_arrays.get(i)).visit(av);
+            }
+            av.visitEnd();
+        }
+        
+        /**
+         * Method allowing to recreate the visited (stored) annotation
+         * into the destination annotation. This method is used only
+         * for nested annotation.
+         * @param mv the annotation visitor to populate with the stored
+         * annotation
+         */
+        public void visit(AnnotationVisitor mv) {
+            AnnotationVisitor av = mv.visitAnnotation(m_name, m_desc);
+            for (int i = 0; i < m_simples.size(); i++) {
+                ((SimpleAttribute) m_simples.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_enums.size(); i++) {
+                ((EnumAttribute) m_enums.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_nested.size(); i++) {
+                ((AnnotationDescriptor) m_nested.get(i)).visit(av);
+            }
+            for (int i = 0; i < m_arrays.size(); i++) {
+                ((ArrayAttribute) m_arrays.get(i)).visit(av);
+            }
+            av.visitEnd();
+        }
+        
+        
+    }
+    
+    /**
+     * Describes an array attribute.
+     * This class is able to visit an annotation array attribute, and to
+     * recreate this array on another annotation.
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    public class ArrayAttribute implements AnnotationVisitor {
+        /**
+         * The name of the attribute.
+         */
+        private String m_name;
+        /**
+         * The content of the parsed array.
+         */
+        private List m_content = new ArrayList();
+        
+        /**
+         * Creates an array attribute.
+         * @param name the name of the attribute.
+         */
+        public ArrayAttribute(String name) {
+            m_name = name;
+        }
+
+        /**
+         * Visits the content of the array. This method is called for 
+         * simple values. 
+         * @param arg0 <code>null</code>
+         * @param arg1 the value
+         * @see org.objectweb.asm.AnnotationVisitor#visit(java.lang.String, java.lang.Object)
+         */
+        public void visit(String arg0, Object arg1) {
+            m_content.add(arg1);
+        }
+
+        /**
+         * Visits the content of the array. This method is called for 
+         * nested annotations (annotations contained in the array). 
+         * @param arg0 <code>null</code>
+         * @param arg1 the annotation descriptor
+         * @return an {@link AnnotationDescriptor} which creates a copy of
+         * the contained annotation.
+         * @see org.objectweb.asm.AnnotationVisitor#visitAnnotation(String, String)
+         */
+        public AnnotationVisitor visitAnnotation(String arg0, String arg1) {
+            AnnotationDescriptor ad = new AnnotationDescriptor(null, arg1);
+            m_content.add(ad);
+            return ad;
+        }
+
+        /**
+         * Visits the content of the array. This method is called for 
+         * nested arrays (arrays contained in the array). 
+         * @param arg0 <code>null</code>
+         * @return an {@link ArrayDescriptor} which creates a copy of
+         * the contained array.
+         * @see org.objectweb.asm.AnnotationVisitor#visitArray(String)
+         */
+        public AnnotationVisitor visitArray(String arg0) {
+            ArrayAttribute aa = new ArrayAttribute(null);
+            m_content.add(aa);
+            return aa;
+        }
+
+        /**
+         * End of the array attribute visit.
+         * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
+         */
+        public void visitEnd() {  }
+
+        /**
+         * Visits the content of the array. This method is called for 
+         * enumeration values. 
+         * @param arg0 <code>null</code>
+         * @param arg1 the enumeration descriptor
+         * @param arg2 the value
+         * @see org.objectweb.asm.AnnotationVisitor#visitEnum(String, String, String)
+         */
+        public void visitEnum(String arg0, String arg1, String arg2) {
+            EnumAttribute ea = new EnumAttribute(null, arg1, arg2);
+            m_content.add(ea);
+        }
+        
+        /**
+         * Recreates the visited array attribute. This method
+         * handle the generation of the object embedded in the
+         * array.
+         * @param av the annotation visitor on which the array attribute
+         * needs to be injected.
+         */
+        public void visit(AnnotationVisitor av) {
+            AnnotationVisitor content = av.visitArray(m_name);
+            for (int i = 0; i < m_content.size(); i++) {
+                Object component = m_content.get(i);
+                if (component instanceof AnnotationDescriptor) {
+                    ((AnnotationDescriptor) component).visit(content);
+                } else if (component instanceof EnumAttribute) {
+                    ((EnumAttribute) component).visit(content);
+                } else if (component instanceof ArrayAttribute) {
+                    ((ArrayAttribute) component).visit(content);
+                } else { // Simple
+                    content.visit(null, component);
+                }
+            }
+            content.visitEnd();
+        }
+                
+    }
+    
+    /**
+     * Describes a simple attribute.
+     * This class is able to visit an annotation simple attribute, and to
+     * recreate this attribute on another annotation.
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    public final class SimpleAttribute {
+        /**
+         * The name of the attribute.
+         */
+        private String m_name;
+        /**
+         * The value of the attribute.
+         */
+        private Object m_value;
+        
+        /**
+         * Creates a simple attribute.
+         * @param name the name of the attribute
+         * @param object the value of the attribute
+         */
+        private SimpleAttribute(String name, Object object) {
+            m_name = name;
+            m_value = object;
+        }
+        
+        /**
+         * Recreates the attribute on the given annotation.
+         * @param visitor the visitor on which the attribute needs
+         * to be injected.
+         */
+        public void visit(AnnotationVisitor visitor) {
+            visitor.visit(m_name, m_value);
+        }
+    }
+    
+    /**
+     * Describes an attribute. The value of this attribute is an enumerated
+     * value.
+     * This class is able to visit an annotation enumeration attribute, and to
+     * recreate this attribute on another annotation.
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    public final class EnumAttribute {
+        /**
+         * The name of the attribute.
+         */
+        private String m_name;
+        /**
+         * The descriptor of the enumeration.
+         */
+        private String m_desc;
+        /**
+         * The value of the attribute.
+         */
+        private String m_value;
+        
+        /**
+         * Creates a enumeration attribute.
+         * @param name the name of the attribute.
+         * @param desc the descriptor of the {@link Enum}
+         * @param value the enumerated value
+         */
+        private EnumAttribute(String name, String desc, String value) {
+            m_name = name;
+            m_value = value;
+            m_desc = desc;
+        }
+        
+        /**
+         * Recreates the attribute on the given annotation.
+         * @param visitor the visitor on which the attribute needs
+         * to be injected.
+         */
+        public void visit(AnnotationVisitor visitor) {
+            visitor.visitEnum(m_name, m_desc, m_value);
+        }
+        
+    }
+
 
 }

Modified: 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?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java Mon Oct  6 01:13:59 2008
@@ -20,6 +20,7 @@
 
 import java.util.Set;
 
+import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
@@ -65,6 +66,26 @@
         m_superDetected = false;
         m_fields = fields;
     }
+    
+    /**
+     * Visits an annotation.
+     * If the annotation is visible, the annotation is removed. In fact
+     * the annotation was already moved to the method replacing this one.
+     * If the annotation is not visible, this annotation is kept on this method.
+     * @param name the name of the annotation
+     * @param visible the annotation visibility
+     * @return the <code>null</code> if the annotation is visible, otherwise returns
+     * {@link GeneratorAdapter#visitAnnotation(String, boolean)}
+     * @see org.objectweb.asm.MethodAdapter#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String name, boolean visible) {
+        // Annotations are moved to the injected constructor.
+        if (visible) {
+            return null;
+        } else {
+            return super.visitAnnotation(name, visible);
+        }
+    }
 
 
     /** 

Modified: 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?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java Mon Oct  6 01:13:59 2008
@@ -96,7 +96,7 @@
             ClassReader cr0 = new ClassReader(is2);
             ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);
             //CheckClassAdapter ch = new CheckClassAdapter(cw0);
-            MethodCreator preprocess = new MethodCreator(cw0, m_fields);
+            MethodCreator preprocess = new MethodCreator(cw0, m_fields, m_methods);
             cr0.accept(preprocess, ClassReader.SKIP_FRAMES);
             is2.close();
             finalWriter = cw0;

Modified: 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?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java Mon Oct  6 01:13:59 2008
@@ -20,6 +20,7 @@
 
 import java.util.Set;
 
+import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.commons.GeneratorAdapter;
@@ -78,5 +79,25 @@
         }
         super.visitFieldInsn(opcode, owner, name, desc);
     }
+    
+    /**
+     * Visits an annotation.
+     * If the annotation is visible, the annotation is removed. In fact
+     * the annotation was already moved to the method replacing this one.
+     * If the annotation is not visible, this annotation is kept on this method.
+     * @param name the name of the annotation
+     * @param visible the annotation visibility
+     * @return the <code>null</code> if the annotation is visible, otherwise returns
+     * {@link GeneratorAdapter#visitAnnotation(String, boolean)}
+     * @see org.objectweb.asm.MethodAdapter#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String name, boolean visible) {
+        // Annotations are moved to the injected constructor.
+        if (visible) {
+            return null;
+        } else {
+            return super.visitAnnotation(name, visible);
+        }
+    }
 
 }

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java Mon Oct  6 01:13:59 2008
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.felix.ipojo.manipulation.ClassChecker.AnnotationDescriptor;
 import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
@@ -112,19 +113,28 @@
      * This set contains field name generate from method id.
      */
     private List m_methodFlags = new ArrayList(); 
+    
+    /**
+     * The list of methods visited during the previous analysis.
+     * This list allows getting annotations to move to generated
+     * method.
+     */
+    private List m_visitedMethods = new ArrayList();
 
     /**
      * Constructor.
      * @param arg0 : class visitor.
      * @param fields : fields map detected during the previous class analysis.
+     * @param methods : the list of the detected method during the previous class analysis.
      */
-    public MethodCreator(ClassVisitor arg0, Map fields) {
+    public MethodCreator(ClassVisitor arg0, Map fields, List methods) {
         super(arg0);
         m_fields = fields.keySet();
+        m_visitedMethods = methods;
     }
 
     /**
-     * Vist method.
+     * Visit method.
      * This method store the current class name.
      * Moreover the POJO interface is added to the list of implemented interface.
      * Then the Instance manager field is added.
@@ -161,16 +171,16 @@
         if (name.equals("<clinit>") || name.equals("class$")) { return super.visitMethod(access, name, desc, signature, exceptions); }
         // The constructor is manipulated separately
         if (name.equals("<init>")) {
-            
+            MethodDescriptor md = getMethodDescriptor("$init", desc);
             // 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;
 
             Type[] args = Type.getArgumentTypes(desc);
             if (args.length == 0) {
-                generateEmptyConstructor(access, signature, exceptions);
+                generateEmptyConstructor(access, signature, exceptions, md.getAnnotations());
             } else if (args.length == 1 && args[0].getClassName().equals("org.osgi.framework.BundleContext")) {
-                generateBCConstructor(access, signature, exceptions);
+                generateBCConstructor(access, signature, exceptions, md.getAnnotations());
             } else {
                 // Do nothing, the constructor does not match.
                 return cv.visitMethod(access, name, desc, signature, exceptions);
@@ -188,9 +198,8 @@
 
         if ((access & ACC_STATIC) == ACC_STATIC) { return super.visitMethod(access, name, desc, signature, exceptions); }
 
-        
-        generateMethodHeader(access, name, desc, signature, exceptions);
-        
+        MethodDescriptor md = getMethodDescriptor(name, desc);
+        generateMethodHeader(access, name, desc, signature, exceptions, md.getAnnotations());
         
         String id = generateMethodFlag(name, desc);
         if (! m_methodFlags.contains(id)) {
@@ -204,6 +213,24 @@
     }
     
     /**
+     * Gets the method descriptor for the specified name and descriptor.
+     * The method descriptor is looked inside the 
+     * {@link MethodCreator#m_visitedMethods}
+     * @param name the name of the method
+     * @param desc the descriptor of the method
+     * @return the method descriptor or <code>null</code> if not found.
+     */
+    private MethodDescriptor getMethodDescriptor(String name, String desc) {
+        for (int i = 0; i < m_visitedMethods.size(); i++) {
+            MethodDescriptor md = (MethodDescriptor) m_visitedMethods.get(i);
+            if (md.getName().equals(name) && md.getDescriptor().equals(desc)) {
+                return md;
+            }
+        }
+        return null;
+    }
+    
+    /**
      * Visit a Field.
      * This field access is replaced by an invocation to the getter method or to the setter method.
      * (except for static field).
@@ -252,14 +279,26 @@
      * @param access : access flag
      * @param signature : method signature
      * @param exceptions : declared exception
+     * @param annotations : the annotations to move to this constructor.
      */
-    private void generateEmptyConstructor(int access, String signature, String[] exceptions) {
+    private void generateEmptyConstructor(int access, String signature, String[] exceptions, List annotations) {
         MethodVisitor mv = cv.visitMethod(access, "<init>", "()V", signature, exceptions);
         mv.visitCode();
         mv.visitVarInsn(ALOAD, 0);
         mv.visitInsn(ACONST_NULL);
         mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;)V");
         mv.visitInsn(RETURN);
+   
+        // Move annotations
+        if (annotations != null) {
+            for (int i = 0; i < annotations.size(); i++) {
+                AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i);
+                ad.visit(mv);
+                System.out.println("Inject annotation : " + ad);
+            }
+        }
+        
+        
         mv.visitMaxs(0, 0);
         mv.visitEnd();
     }
@@ -271,8 +310,9 @@
      * @param access : access flag
      * @param signature : method signature
      * @param exceptions : declared exception
+     * @param annotations : the annotations to move to this constructor.
      */
-    private void generateBCConstructor(int access, String signature, String[] exceptions) {
+    private void generateBCConstructor(int access, String signature, String[] exceptions, List annotations) {
         MethodVisitor mv = cv.visitMethod(access, "<init>", "(Lorg/osgi/framework/BundleContext;)V", signature, exceptions);
         mv.visitCode();
         Label l0 = new Label();
@@ -282,6 +322,15 @@
         mv.visitVarInsn(ALOAD, 1);
         mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;Lorg/osgi/framework/BundleContext;)V");
         mv.visitInsn(RETURN);
+        
+        // Move annotations
+        if (annotations != null) {
+            for (int i = 0; i < annotations.size(); i++) {
+                AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i);
+                ad.visit(mv);
+            }
+        }
+        
         mv.visitMaxs(0, 0);
         mv.visitEnd();
     }
@@ -295,8 +344,9 @@
      * @param desc : method descriptor.
      * @param signature : method signature.
      * @param exceptions : declared exceptions.
+     * @param annotations : the annotations to move to this method.
      */
-    private void generateMethodHeader(int access, String name, String desc, String signature, String[] exceptions) {
+    private void generateMethodHeader(int access, String name, String desc, String signature, String[] exceptions, List annotations) {
         GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc); 
         
         mv.visitCode();
@@ -385,6 +435,15 @@
             mv.visitVarInsn(returnType.getOpcode(ILOAD), result);
         }
         mv.visitInsn(returnType.getOpcode(IRETURN));
+        
+        // Move annotations
+        if (annotations != null) {
+            for (int i = 0; i < annotations.size(); i++) {
+                AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i);
+                ad.visit(mv);
+                System.out.println("Inject annotation : " + ad);
+            }
+        }
 
         mv.visitMaxs(0, 0);
         mv.visitEnd();

Modified: 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?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java Mon Oct  6 01:13:59 2008
@@ -18,6 +18,10 @@
  */
 package org.apache.felix.ipojo.manipulation;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulation.ClassChecker.AnnotationDescriptor;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.objectweb.asm.Type;
@@ -42,6 +46,18 @@
      * Argument types.
      */
     private String[] m_arguments;
+    
+    /**
+     * The descriptor of the method.
+     */
+    private String m_desc;
+    
+    
+    /**
+     * The list of {@link AnnotationDescriptor} attached to this
+     * method. 
+     */
+    private List m_annotations;
 
     /**
      * Constructor.
@@ -50,6 +66,7 @@
      */
     public MethodDescriptor(String name, String desc) {
         m_name = name;
+        m_desc = desc;
         Type ret = Type.getReturnType(desc);
         Type[] args = Type.getArgumentTypes(desc);
 
@@ -59,6 +76,25 @@
             m_arguments[i] = getType(args[i]);
         }
     }
+    
+    /**
+     * Add an annotation to the current method.
+     * @param ann annotation to add
+     */
+    public void addAnnotation(AnnotationDescriptor ann) {
+        if (m_annotations == null) {
+            m_annotations = new ArrayList();
+        }
+        m_annotations.add(ann);
+    }
+    
+    public List getAnnotations() {
+        return m_annotations;
+    }
+    
+    public String getDescriptor() {
+        return m_desc;
+    }
 
     /**
      * Compute method manipulation metadata.

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java Mon Oct  6 01:13:59 2008
@@ -31,6 +31,8 @@
  */
 public class CustomAnnotationVisitor extends EmptyVisitor implements AnnotationVisitor {
 
+    //TODO manage enum annotations.
+    
     /**
      * PArent element.
      */
@@ -96,7 +98,7 @@
     }
 
     /**
-     * Visit an 'simple' annotation attribute.
+     * Visit a 'simple' annotation attribute.
      * This method is used for primitive arrays too. 
      * @param arg0 : attribute name
      * @param arg1 : attribute value

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java Mon Oct  6 01:13:59 2008
@@ -52,8 +52,6 @@
 import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
 
-import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
-
 /**
  * Pojoization allows creating an iPOJO bundle from a "normal" bundle.  
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java?rev=701987&r1=701986&r2=701987&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java Mon Oct  6 01:13:59 2008
@@ -246,6 +246,14 @@
     }
 
 
+    /**
+     * An error occurs during the XML-Schema checking.
+     * This method propagates the error except if the error concerns
+     * no XML-Schemas are used   (<code>cvc-elt.1</code>).
+     * @param saxparseexception the checking error
+     * @throws SAXException the propagated exception
+     * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+     */
     public void error(SAXParseException saxparseexception) throws SAXException {
         if (saxparseexception.getMessage().contains("cvc-elt.1")) {
             return; // Do not throw an exception when no schema defined.
@@ -254,13 +262,27 @@
     }
 
 
+    /**
+     * A fatal error occurs during the XML-Schema checking.
+     * This method always propagates the error.
+     * @param saxparseexception the checking error
+     * @throws SAXException the propagated exception
+     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
+     */
     public void fatalError(SAXParseException saxparseexception)
             throws SAXException {
         System.err.println("Fatal error during XML-Schema parsing : " + saxparseexception);
         throw saxparseexception;
     }
 
-
+    /**
+     * A warning was detected during the XML-Schema checking.
+     * This method always propagate the warning message to
+     * {@link System#out}.
+     * @param saxparseexception the checking error
+     * @throws SAXException nothing.
+     * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
+     */
     public void warning(SAXParseException saxparseexception)
             throws SAXException {
         System.err.println("Warning : an error was detected in the metadata file : " + saxparseexception);