Fix Felix-2487
If @Component is missing, the annotation processing is aborted.
This case is detected by the MetadataCollector, but the warning message is handled by Pojoization

Add tests.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@981016 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
index a35627a..1543052 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
@@ -65,6 +65,8 @@
      */
     private boolean m_containsComponentAnnotation = false;
     
+    private boolean m_ignoredBecauseOfMissingComponent = false;
+    
     /**
      * Map of [element ids, element].
      * This map is used to easily get an already created element.
@@ -101,6 +103,14 @@
         return m_containsComponentAnnotation;
     }
     
+    public boolean isIgnoredBecauseOfMissingComponent() {
+        return m_ignoredBecauseOfMissingComponent;
+    }
+    
+    public String getClassName() {
+        return m_className;
+    }
+    
     /**
      * Start visiting a class.
      * Initialize the getter/setter generator, add the _cm field, add the pojo interface.
@@ -205,6 +215,12 @@
      * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
      */
     public void visitEnd() {
+        // If m_elem (Component) is null, print a warning and ignore.
+        if (m_elem == null  && ! m_elements.isEmpty()) {
+            m_ignoredBecauseOfMissingComponent = true;
+            return;
+        }
+        
         // Recompute the tree
         Set elems = getElements().keySet();
         Iterator it = elems.iterator();
@@ -218,7 +234,6 @@
                 if (ref == null) {
                     // Add to the root
                     m_elem.addElement(current);
-                  // System.err.println("The element " + reference + " is not declared - skipping the element " + current.toXMLString());
                 } else {
                     ref.addElement(current);
                 }
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index 325cc8b..01ecfb9 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -29,6 +29,7 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -290,23 +291,26 @@
      */
     private void computeAnnotations(byte[] inC) {
         ClassReader cr = new ClassReader(inC);
-        MetadataCollector xml = new MetadataCollector();
-        cr.accept(xml, 0);
-        if (xml.isComponentType()) {
+        MetadataCollector collector = new MetadataCollector();
+        cr.accept(collector, 0);
+        
+        if (collector.isIgnoredBecauseOfMissingComponent()) {
+            warn("Annotation processing ignored in " + collector.getClassName() + " - @Component missing");
+        } else if (collector.isComponentType()) {
             boolean toskip = false;
             for (int i = 0; !toskip && i < m_metadata.size(); i++) {
                 Element meta = (Element)  m_metadata.get(i);
                 if (! meta.getName().equals("instance") // Only if its a component type definition, 
                                                                  // so skip instance declaration 
                         && meta.containsAttribute("name")
-                        && meta.getAttribute("name").equalsIgnoreCase(xml.getComponentTypeDeclaration().getAttribute("name"))) {
+                        && meta.getAttribute("name").equalsIgnoreCase(collector.getComponentTypeDeclaration().getAttribute("name"))) {
                     toskip = true;
-                    warn("The component type " + xml.getComponentTypeDeclaration().getAttribute("name") + " is overriden by the metadata file");
+                    warn("The component type " + collector.getComponentTypeDeclaration().getAttribute("name") + " is overriden by the metadata file");
                 }
             }
             if (!toskip) {
                 // if no metadata or empty one, create a new array.
-                Element elem = xml.getComponentTypeDeclaration();
+                Element elem = collector.getComponentTypeDeclaration();
                 m_metadata.add(elem);
                 
                 String name = elem.getAttribute("classname");
@@ -319,9 +323,9 @@
                 m_components.add(info);
                 
                 // Instantiate ?
-                if (xml.getInstanceDeclaration() != null) {
+                if (collector.getInstanceDeclaration() != null) {
                     warn("Declaring an empty instance of " + elem.getAttribute("classname"));
-                    m_metadata.add(xml.getInstanceDeclaration());
+                    m_metadata.add(collector.getInstanceDeclaration());
                 }
             }
         }
diff --git a/ipojo/tests/core/annotations/pom.xml b/ipojo/tests/core/annotations/pom.xml
index b3aa3da..91a1de9 100644
--- a/ipojo/tests/core/annotations/pom.xml
+++ b/ipojo/tests/core/annotations/pom.xml
@@ -102,7 +102,7 @@
               ${project.artifactId}

             </Bundle-SymbolicName>

             <Private-Package>

-              org.apache.felix.ipojo.test*

+              org.apache.felix.ipojo.test*, foo

             </Private-Package>

             <Test-Suite>

               org.apache.felix.ipojo.test.scenarios.annotations.AnnotationsTestSuite

diff --git a/ipojo/tests/core/annotations/src/main/java/foo/Foo.java b/ipojo/tests/core/annotations/src/main/java/foo/Foo.java
new file mode 100644
index 0000000..aa8d383
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/foo/Foo.java
@@ -0,0 +1,10 @@
+package foo;
+
+
+/**
+ * Creates a simple annotation to create the processing of non-matching
+ * annotations
+ */
+public @interface Foo {
+    String bar();
+}
diff --git a/ipojo/tests/core/annotations/src/main/java/foo/ipojo/IPOJOFoo.java b/ipojo/tests/core/annotations/src/main/java/foo/ipojo/IPOJOFoo.java
new file mode 100644
index 0000000..fdf9037
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/foo/ipojo/IPOJOFoo.java
@@ -0,0 +1,10 @@
+package foo.ipojo;
+
+
+/**
+ * Creates a simple annotation to create the processing of matching
+ * annotations
+ */
+public @interface IPOJOFoo {
+    String bar();
+}
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyFoo.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyFoo.java
new file mode 100644
index 0000000..9431df9
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyFoo.java
@@ -0,0 +1,8 @@
+package org.apache.felix.ipojo.test.scenarios.component;
+
+import foo.Foo;
+
+@Foo(bar="bar")
+public class OnlyFoo {
+
+}
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyiPOJOFoo.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyiPOJOFoo.java
new file mode 100644
index 0000000..6230887
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/OnlyiPOJOFoo.java
@@ -0,0 +1,8 @@
+package org.apache.felix.ipojo.test.scenarios.component;
+
+import foo.ipojo.IPOJOFoo;
+
+@IPOJOFoo(bar="bar")
+public class OnlyiPOJOFoo {
+
+}