FELIX-3550 : Reimplement the SCR Generator

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1354340 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
index 33193d6..19a5086 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
@@ -113,6 +113,8 @@
      * @throws SCRDescriptorFailureException
      */
     public Result execute() throws SCRDescriptorException, SCRDescriptorFailureException {
+
+        this.logger.debug("Starting SCR Descriptor Generator....");
         if (this.project == null) {
             throw new SCRDescriptorFailureException("Project has not been set!");
         }
@@ -120,8 +122,14 @@
             // use default options
             this.options = new Options();
         }
+        if (this.options.getOutputDirectory() == null) {
+            throw new SCRDescriptorFailureException("Output directory has not been set!");
+        }
 
-        this.logger.debug("Starting SCRDescriptorMojo....");
+        this.logger.debug("..using output directory: " + this.options.getOutputDirectory());
+        this.logger.debug("..using scr name: " + this.options.getSCRName());
+        this.logger.debug("..using metatype name: " + this.options.getMetaTypeName());
+        this.logger.debug("..strict mode: " + this.options.isStrictMode());
         this.logger.debug("..generating accessors: " + this.options.isGenerateAccessors());
 
         // check speck version configuration
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java
index fb8ba92..b63a112 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java
@@ -44,16 +44,9 @@
 public class AnnotationProcessorManager implements AnnotationProcessor {
 
     /**
-     * Allows to define additional implementations of the interface
-     * {@linkAnnotationProcessor}
-     * that provide mappings from custom annotations to descriptions.
-     */
-    private final Map<String, AnnotationProcessor> processors = new HashMap<String, AnnotationProcessor>();
-
-    /**
      * Ordered list of processors
      */
-    private final List<AnnotationProcessor> cachedProcessors = new ArrayList<AnnotationProcessor>();
+    private final List<AnnotationProcessor> processors = new ArrayList<AnnotationProcessor>();
 
     /**
      * Create annotation processor manager.
@@ -63,28 +56,34 @@
             final ClassLoader classLoader )
     throws SCRDescriptorFailureException {
         // search for providers
+        final Map<String, AnnotationProcessor> processorMap = new HashMap<String, AnnotationProcessor>();
+
         final Iterator<AnnotationProcessor> serviceIter = ServiceRegistry.lookupProviders(AnnotationProcessor.class, classLoader);
         while ( serviceIter.hasNext() ) {
-            final AnnotationProcessor provider = serviceIter.next();
-            this.addProvider(provider);
+            final AnnotationProcessor processor = serviceIter.next();
+            // check if this processor is already loaded
+            final String key = processor.getClass().getName();
+            if ( !processorMap.containsKey(key) ) {
+                processorMap.put(key, processor);
+            }
         }
 
-        // create ordered list
-        for(final AnnotationProcessor pro : this.processors.values() ) {
-            this.cachedProcessors.add(pro);
+        // create ordered list sorted by ranking
+        for(final AnnotationProcessor pro : processorMap.values() ) {
+            this.processors.add(pro);
         }
-        Collections.sort(this.cachedProcessors, new Comparator<AnnotationProcessor>() {
+        Collections.sort(this.processors, new Comparator<AnnotationProcessor>() {
 
             public int compare(AnnotationProcessor o1, AnnotationProcessor o2) {
                 return Integer.valueOf(o1.getRanking()).compareTo(Integer.valueOf(o2.getRanking()));
             }
         });
-        if ( this.cachedProcessors.size() == 0 ) {
+        if ( this.processors.size() == 0 ) {
             throw new SCRDescriptorFailureException("No annotation processors found in classpath.");
         }
-        log.debug("Using annotation processors: ");
-        for(final AnnotationProcessor pro : this.cachedProcessors) {
-            log.debug("- " + pro.getName() + " - " + pro.getRanking());
+        log.debug("..using annotation processors: ");
+        for(final AnnotationProcessor pro : this.processors) {
+            log.debug("  - " + pro.getName() + " - " + pro.getRanking());
         }
     }
 
@@ -94,7 +93,8 @@
     public void process(final ScannedClass scannedClass,
             final ClassDescription describedClass)
     throws SCRDescriptorException, SCRDescriptorFailureException {
-        for(final AnnotationProcessor ap : this.cachedProcessors) {
+        // forward do all processors
+        for(final AnnotationProcessor ap : this.processors) {
             ap.process(scannedClass, describedClass);
         }
     }
@@ -112,15 +112,4 @@
     public String getName() {
         return "Annotation Processor Manager";
     }
-
-    /**
-     * Add a processor (if not already available)
-     */
-    private void addProvider(final AnnotationProcessor processor) {
-        // check if this processor is already loaded
-        final String key = processor.getClass().getName();
-        if ( !this.processors.containsKey(key) ) {
-            this.processors.put(key, processor);
-        }
-    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java
index e57a5d0..f643b77 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java
@@ -78,4 +78,11 @@
     public void setServiceDescription(ServiceDescription serviceDescription) {
         this.serviceDescription = serviceDescription;
     }
+
+    @Override
+    public String toString() {
+        return "ComponentContainer [classDescription=" + classDescription + ", componentDescription=" + componentDescription
+                        + ", serviceDescription=" + serviceDescription + ", allReferences=" + allReferences + ", allProperties="
+                        + allProperties + "]";
+    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java
index cbd2dec..9b94282 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java
@@ -59,4 +59,9 @@
     public void addComponent(ComponentContainer component) {
         this.components.add(component);
     }
+
+    @Override
+    public String toString() {
+        return "DescriptionContainer [options=" + options + ", components=" + components + "]";
+    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
index 1677b77..d32db43 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
@@ -173,10 +173,7 @@
         IOUtils.newline(contentHandler);
 
         for (final ComponentContainer component : module.getComponents()) {
-            final SpecVersion oldVersion = component.getComponentDescription().getSpecVersion();
-            component.getComponentDescription().setSpecVersion(module.getOptions().getSpecVersion());
-            generateXML(namespace, component, contentHandler);
-            component.getComponentDescription().setSpecVersion(oldVersion);
+            generateXML(namespace, module, component, contentHandler);
         }
 
         // end wrapper element
@@ -193,7 +190,10 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(final String namespace, final ComponentContainer container, final ContentHandler contentHandler)
+    protected static void generateXML(final String namespace,
+                    final DescriptionContainer module,
+                    final ComponentContainer container,
+                    final ContentHandler contentHandler)
     throws SAXException {
         final ComponentDescription component = container.getComponentDescription();
 
@@ -204,7 +204,7 @@
         IOUtils.addAttribute(ai, COMPONENT_ATTR_FACTORY, component.getFactory());
 
         // attributes new in 1.1
-        if (component.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+        if (module.getOptions().getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
             if ( component.getConfigurationPolicy() != ComponentConfigurationPolicy.OPTIONAL ) {
                 IOUtils.addAttribute(ai, COMPONENT_ATTR_POLICY, component.getConfigurationPolicy().name().toLowerCase());
             }
@@ -213,7 +213,7 @@
             IOUtils.addAttribute(ai, COMPONENT_ATTR_MODIFIED, component.getModified());
         }
         // attributes new in 1.2
-        if ( component.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_2.ordinal() ) {
+        if ( module.getOptions().getSpecVersion().ordinal() >= SpecVersion.VERSION_1_2.ordinal() ) {
             if ( component.getConfigurationPid() != null && !component.getConfigurationPid().equals(component.getName())) {
                 IOUtils.addAttribute(ai, COMPONENT_ATTR_CONFIGURATION_PID, component.getConfigurationPid());
             }
@@ -230,7 +230,7 @@
         }
 
         for (final ReferenceDescription reference : container.getReferences().values()) {
-            generateReferenceXML(component, reference, contentHandler);
+            generateReferenceXML(component, module, reference, contentHandler);
         }
 
         IOUtils.indent(contentHandler, 1);
@@ -337,6 +337,7 @@
      * @throws SAXException
      */
     protected static void generateReferenceXML(final ComponentDescription component,
+                    final DescriptionContainer module,
                     final ReferenceDescription reference,
                     final ContentHandler contentHandler)
     throws SAXException {
@@ -350,12 +351,12 @@
         IOUtils.addAttribute(ai, "unbind", reference.getUnbind());
 
         // attributes new in 1.1-felix (FELIX-1893)
-        if (component.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1_FELIX.ordinal() ) {
+        if (module.getOptions().getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1_FELIX.ordinal() ) {
             IOUtils.addAttribute(ai, "updated", reference.getUpdated());
         }
 
         // attributes new in 1.2
-        if (component.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_2.ordinal() ) {
+        if (module.getOptions().getSpecVersion().ordinal() >= SpecVersion.VERSION_1_2.ordinal() ) {
             if ( reference.getPolicyOption() != ReferencePolicyOption.RELUCTANT ) {
                 IOUtils.addAttribute(ai, "policy-option", reference.getPolicyOption().name().toLowerCase());
             }