FELIX-1010 : Use qdox to get annotations and create fake annotations.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@762830 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Component.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Component.java
index d90ad53..da93572 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Component.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Component.java
@@ -34,7 +34,7 @@
  * </p>
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 public @interface Component {
 
     /**
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Properties.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Properties.java
index 632ab0d..faac843 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Properties.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Properties.java
@@ -24,7 +24,7 @@
  * Allows to define multiple {@link Property} annotations for one type.
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface Properties {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Property.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Property.java
index 8b5926d..4b90e6b 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Property.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Property.java
@@ -33,7 +33,7 @@
  * OSGi Service Platform Service Compendium Specification for more information.
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface Property {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/PropertyOption.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/PropertyOption.java
index 0f902ff..2d4b4a1 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/PropertyOption.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/PropertyOption.java
@@ -24,7 +24,7 @@
  * Defines a {@link Property} option.
  */
 @Target(ElementType.ANNOTATION_TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface PropertyOption {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Reference.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Reference.java
index 2d24350..9d1ec6e 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Reference.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Reference.java
@@ -33,7 +33,7 @@
  * Service Platform Service Compendium Specification for more information.
  */
 @Target( { ElementType.TYPE, ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface Reference {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/References.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/References.java
index 0208d55..e2d3079 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/References.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/References.java
@@ -24,7 +24,7 @@
  * Allows to define multiple {@link Reference} annotations for one type.
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface References {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Service.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Service.java
index a241c18..226c64e 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Service.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Service.java
@@ -30,7 +30,7 @@
  * information.
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface Service {
 
diff --git a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Services.java b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Services.java
index 69b792d..e00f689 100644
--- a/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Services.java
+++ b/scrplugin-annotations/src/main/java/org/apache/felix/scrplugin/annotations/Services.java
@@ -24,7 +24,7 @@
  * Allows to define multiple {@link Service} annotations for one type.
  */
 @Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
+@Retention(RetentionPolicy.SOURCE)
 @Documented
 public @interface Services {
 
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptorManager.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptorManager.java
index f4e940f..aeefe9b 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptorManager.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptorManager.java
@@ -41,6 +41,7 @@
 import org.codehaus.plexus.util.*;
 
 import com.thoughtworks.qdox.JavaDocBuilder;
+import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaSource;
 
 /**
@@ -392,11 +393,12 @@
             this.log.debug("Searching description for: " + className);
             int index = 0;
             while ( result == null && index < this.sources.length) {
-                if ( this.sources[index].getClasses()[0].getFullyQualifiedName().equals(className) ) {
+                final JavaClass javaClass = this.sources[index].getClasses()[0];
+                if ( javaClass.getFullyQualifiedName().equals(className) ) {
                     try {
                         // check for java annotation descriptions - fallback to QDox if none found
                         Class clazz = this.classloader.loadClass(className);
-                        if (this.processAnnotations && getAnnotationTagProviderManager().hasScrPluginAnnotation(clazz)) {
+                        if (this.processAnnotations && getAnnotationTagProviderManager().hasScrPluginAnnotation(javaClass)) {
                             this.log.debug("Found java annotation description for: " + className);
                             result = new AnnotationJavaClassDescription(clazz, this.sources[index], this);
                         } else if ( this.parseJavadocs ) {
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java
index 5bc342c..a74d16d 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java
@@ -20,14 +20,9 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
 
-import org.apache.felix.scrplugin.tags.JavaClassDescription;
-import org.apache.felix.scrplugin.tags.JavaClassDescriptorManager;
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.tags.*;
 import org.apache.felix.scrplugin.tags.qdox.QDoxJavaClassDescription;
 import org.apache.maven.plugin.MojoExecutionException;
 
@@ -62,6 +57,14 @@
                 }
             }
         }
+        for(com.thoughtworks.qdox.model.Annotation annotation : this.javaClass.getAnnotations()) {
+            List<JavaTag> tags = manager.getAnnotationTagProviderManager().getTags(annotation, this);
+            for (JavaTag tag : tags) {
+                if (tag.getName().equals(name)) {
+                    return tag;
+                }
+            }
+        }
         return null;
     }
 
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java
index 9bbdaa5..7bfd24f 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java
@@ -41,4 +41,14 @@
      */
     List<JavaTag> getTags(Annotation pAnnotation, AnnotationJavaClassDescription description, JavaField field);
 
+    /**
+     * Maps a annotation to one or many {@link JavaTag} implementations.
+     * @param pAnnotation Java annotation
+     * @param description Annotations-based java class description
+     * @param field Reference to field (set on field-level annotations, null on
+     *            other annotations)
+     * @return List of tag implementations. Return empty list if this provider
+     *         cannot map the annotation to any tag instance.
+     */
+    List<JavaTag> getTags(com.thoughtworks.qdox.model.Annotation pAnnotation, AnnotationJavaClassDescription description, JavaField field);
 }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
index cc553a8..0083367 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
@@ -27,6 +27,8 @@
 import org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider;
 import org.apache.maven.plugin.MojoFailureException;
 
+import com.thoughtworks.qdox.model.JavaClass;
+
 /**
  * Supports mapping of built-in and custom java anntoations to {@link JavaTag}
  * implementations.
@@ -77,7 +79,7 @@
 
     /**
      * Converts a java annotation to {@link JavaTag} if a mapping can be found.
-     * 
+     *
      * @param annotation Java annotation
      * @param description Description
      * @return Tag declaration or null if no mapping found
@@ -88,7 +90,18 @@
 
     /**
      * Converts a java annotation to {@link JavaTag} if a mapping can be found.
-     * 
+     *
+     * @param annotation Java annotation
+     * @param description Description
+     * @return Tag declaration or null if no mapping found
+     */
+    public List<JavaTag> getTags(com.thoughtworks.qdox.model.Annotation annotation, AnnotationJavaClassDescription description) {
+        return getTags(annotation, description, null);
+    }
+
+    /**
+     * Converts a java annotation to {@link JavaTag} if a mapping can be found.
+     *
      * @param annotation Java annotation
      * @param description Description
      * @param field Field
@@ -105,6 +118,24 @@
     }
 
     /**
+     * Converts a java annotation to {@link JavaTag} if a mapping can be found.
+     *
+     * @param annotation Java annotation
+     * @param description Description
+     * @param field Field
+     * @return Tag declaration or null if no mapping found
+     */
+    public List<JavaTag> getTags(com.thoughtworks.qdox.model.Annotation annotation, AnnotationJavaClassDescription description, JavaField field) {
+        List<JavaTag> tags = new ArrayList<JavaTag>();
+
+        for (AnnotationTagProvider provider : this.annotationTagProviders) {
+            tags.addAll(provider.getTags(annotation, description, field));
+        }
+
+        return tags;
+    }
+
+    /**
      * Checks if the given class has any SCR plugin java annotations defined.
      * @param pClass Class
      * @return true if SCR plugin java annotation found
@@ -118,4 +149,17 @@
         return false;
     }
 
+    /**
+     * Checks if the given class has any SCR plugin java annotations defined.
+     * @param pClass Class
+     * @return true if SCR plugin java annotation found
+     */
+    public boolean hasScrPluginAnnotation(JavaClass pClass) {
+        for (com.thoughtworks.qdox.model.Annotation annotation : pClass.getAnnotations()) {
+            if (getTags(annotation, null).size() > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/ComponentTag.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/ComponentTag.java
index 510956e..6352043 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/ComponentTag.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/ComponentTag.java
@@ -25,6 +25,8 @@
 import org.apache.felix.scrplugin.annotations.Component;
 import org.apache.felix.scrplugin.tags.JavaClassDescription;
 
+import com.thoughtworks.qdox.model.Annotation;
+
 /**
  * Description of a java tag for components.
  */
@@ -41,6 +43,64 @@
         this.annotation = annotation;
     }
 
+    /**
+     * @param annotation Annotation
+     * @param desc Description
+     */
+    public ComponentTag(final Annotation annotation, JavaClassDescription desc) {
+        super(desc, null);
+        this.annotation = new Component() {
+
+            public boolean componentAbstract() {
+                return Util.getValue(annotation, "componentAbstract", false);
+            }
+
+            public boolean createPid() {
+                return Util.getValue(annotation, "createPid", true);
+            }
+
+            public String description() {
+                return Util.getValue(annotation, "description", "");
+            }
+
+            public boolean ds() {
+                return Util.getValue(annotation, "ds", true);
+            }
+
+            public boolean enabled() {
+                return Util.getValue(annotation, "enabled", true);
+            }
+
+            public String factory() {
+                return Util.getValue(annotation, "factory", "");
+            }
+
+            public boolean immediate() {
+                return Util.getValue(annotation, "immediate", false);
+            }
+
+            public boolean inherit() {
+                return Util.getValue(annotation, "inherit", true);
+            }
+
+            public String label() {
+                return Util.getValue(annotation, "label", "");
+            }
+
+            public boolean metatype() {
+                return Util.getValue(annotation, "metatype", false);
+            }
+
+            public String name() {
+                return Util.getValue(annotation, "name", "");
+            }
+
+            public Class<? extends java.lang.annotation.Annotation> annotationType() {
+                return null;
+            }
+        };
+    }
+
     @Override
     public String getName() {
         return Constants.COMPONENT;
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/DefaultAnnotationTagProvider.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/DefaultAnnotationTagProvider.java
index 203bcc8..9023e60 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/DefaultAnnotationTagProvider.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/DefaultAnnotationTagProvider.java
@@ -22,13 +22,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.felix.scrplugin.annotations.Component;
-import org.apache.felix.scrplugin.annotations.Properties;
-import org.apache.felix.scrplugin.annotations.Property;
-import org.apache.felix.scrplugin.annotations.Reference;
-import org.apache.felix.scrplugin.annotations.References;
-import org.apache.felix.scrplugin.annotations.Service;
-import org.apache.felix.scrplugin.annotations.Services;
+import org.apache.felix.scrplugin.annotations.*;
 import org.apache.felix.scrplugin.tags.JavaField;
 import org.apache.felix.scrplugin.tags.JavaTag;
 import org.apache.felix.scrplugin.tags.annotation.AnnotationJavaClassDescription;
@@ -75,4 +69,40 @@
         return tags;
     }
 
+    /**
+     * @see org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider#getTags(java.lang.annotation.Annotation, org.apache.felix.scrplugin.tags.annotation.AnnotationJavaClassDescription, org.apache.felix.scrplugin.tags.JavaField)
+     */
+    public List<JavaTag> getTags(com.thoughtworks.qdox.model.Annotation annotation,
+                                 AnnotationJavaClassDescription description, JavaField field) {
+        List<JavaTag> tags = new ArrayList<JavaTag>();
+
+        // check for single annotations
+        if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Component.class.getName())) {
+            tags.add(new ComponentTag(annotation, description));
+        } else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Property.class.getName())) {
+            //tags.add(new PropertyTag(annotation, description));
+        } else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Service.class.getName())) {
+            //tags.add(new ServiceTag(annotation, description));
+        } else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Reference.class.getName())) {
+            //tags.add(new ReferenceTag(annotation, description, field));
+        }
+
+        // check for multi-annotations
+        else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Properties.class.getName())) {
+            //for (Property property : ((Properties) annotation).value()) {
+            //    tags.add(new PropertyTag(property, description));
+            //}
+        } else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(Services.class.getName())) {
+            //for (Service service : ((Services) annotation).value()) {
+            //    tags.add(new ServiceTag(service, description));
+            //}
+        } else if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(References.class.getName())) {
+            //for (Reference reference : ((References) annotation).value()) {
+            //    tags.add(new ReferenceTag(reference, description, field));
+            //}
+        }
+
+        return tags;
+    }
+
 }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java
new file mode 100644
index 0000000..7cc3239
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java
@@ -0,0 +1,48 @@
+/*
+ * 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.scrplugin.tags.annotation.defaulttag;
+
+import com.thoughtworks.qdox.model.Annotation;
+
+public abstract class Util {
+
+    public static boolean getValue(Annotation annotation, String name, boolean defaultValue) {
+        final Object obj = annotation.getNamedParameter(name);
+        if ( obj != null ) {
+            if ( obj instanceof String ) {
+                return Boolean.valueOf((String)obj);
+            } else if ( obj instanceof Boolean ) {
+                return (Boolean)obj;
+            }
+            return Boolean.valueOf(obj.toString());
+        }
+        return defaultValue;
+    }
+
+    public static String getValue(Annotation annotation, String name, String defaultValue) {
+        final Object obj = annotation.getNamedParameter(name);
+        if ( obj != null ) {
+            if ( obj instanceof String ) {
+                return (String)obj;
+            }
+            return obj.toString();
+        }
+        return defaultValue;
+    }
+}