FELIX-3641 :  Option to generate separate descriptor files 

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1379336 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 38aa7ca..b213968 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
@@ -46,13 +46,10 @@
 import org.apache.felix.scrplugin.helper.Validator;
 import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
 import org.apache.felix.scrplugin.om.metatype.Designate;
-import org.apache.felix.scrplugin.om.metatype.MTObject;
-import org.apache.felix.scrplugin.om.metatype.MetaData;
 import org.apache.felix.scrplugin.om.metatype.OCD;
 import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
 import org.apache.felix.scrplugin.xml.MetaTypeIO;
 import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.metatype.MetaTypeService;
 
 /**
  * The <code>SCRDescriptorGenerator</code> class does the hard work of
@@ -152,10 +149,6 @@
         this.scanner = new ClassScanner(logger, iLog, project, aProcessor);
         final List<ClassDescription> scannedDescriptions = scanner.scanSources();
 
-        // setup metadata
-        final MetaData metaData = new MetaData();
-        metaData.setLocalization(MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype");
-
         final List<ComponentContainer> processedContainers = new ArrayList<ComponentContainer>();
         for (final ClassDescription desc : scannedDescriptions) {
             this.logger.debug("Processing component class " + desc.getSource());
@@ -166,7 +159,7 @@
                              " Check the annotations and merge the definitions to a single definition.",
                                 desc.getSource());
             } else {
-                final ComponentContainer container = this.createComponent(desc, metaData, iLog);
+                final ComponentContainer container = this.createComponent(desc, iLog);
                 if (container.getComponentDescription().getSpecVersion() != null) {
                     if ( specVersion == null ) {
                         specVersion = container.getComponentDescription().getSpecVersion();
@@ -275,7 +268,7 @@
         // create result and generate files
         final Result result = new Result();
 
-        result.setMetatypeFiles(MetaTypeIO.generateDescriptors(metaData, this.options, this.logger));
+        result.setMetatypeFiles(MetaTypeIO.generateDescriptors(module, this.options, this.logger));
         result.setScrFiles(ComponentDescriptorIO.generateDescriptorFiles(module, this.options, logger));
 
         return result;
@@ -285,7 +278,6 @@
      * Create the SCR objects based on the descriptions
      */
     private ComponentContainer createComponent(final ClassDescription desc,
-                    final MetaData metaData,
                     final IssueLog iLog) {
         final ComponentDescription componentDesc = desc.getDescription(ComponentDescription.class);
 
@@ -294,12 +286,14 @@
             componentDesc.setSpecVersion(SpecVersion.VERSION_1_2);
         }
 
+        final ComponentContainer container = new ComponentContainer(desc, componentDesc);
+
         // Create metatype (if required)
         final OCD ocd;
         if ( !componentDesc.isAbstract() && componentDesc.isCreateMetatype() ) {
             // OCD
             ocd = new OCD();
-            metaData.addOCD( ocd );
+            container.setOCD( ocd );
             ocd.setId( componentDesc.getName() );
             if ( componentDesc.getLabel() != null ) {
                 ocd.setName( componentDesc.getLabel() );
@@ -314,7 +308,7 @@
 
             // Designate
             final Designate designate = new Designate();
-            metaData.addDesignate( designate );
+            container.setDesignate( designate );
             designate.setPid( componentDesc.getName() );
 
             // Factory pid
@@ -326,16 +320,10 @@
                         + " should not set metatype factory pid.", desc.getSource() );
                 }
             }
-            // MTObject
-            final MTObject mtobject = new MTObject();
-            designate.setObject( mtobject );
-            mtobject.setOcdref( componentDesc.getName() );
         } else {
             ocd = null;
         }
 
-        final ComponentContainer container = new ComponentContainer(desc, componentDesc);
-
         ClassDescription current = desc;
         boolean inherit;
         do {
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 b016a82..cf524dc 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
@@ -26,6 +26,8 @@
 import org.apache.felix.scrplugin.description.PropertyDescription;
 import org.apache.felix.scrplugin.description.ReferenceDescription;
 import org.apache.felix.scrplugin.description.ServiceDescription;
+import org.apache.felix.scrplugin.om.metatype.Designate;
+import org.apache.felix.scrplugin.om.metatype.OCD;
 
 
 /**
@@ -54,6 +56,12 @@
     /** All properties. */
     private final Map<String, PropertyDescription> allProperties = new LinkedHashMap<String, PropertyDescription>();
 
+    /** Metatype: OCD. */
+    private OCD ocd;
+
+    /** Metatype: Designate. */
+    private Designate designate;
+
     /**
      * Create a new component container
      * @param classDescription     Class description
@@ -123,4 +131,20 @@
                         + ", serviceDescription=" + serviceDescription + ", allReferences=" + allReferences + ", allProperties="
                         + allProperties + "]";
     }
+
+    public OCD getOCD() {
+        return ocd;
+    }
+
+    public void setOCD(final OCD ocd) {
+        this.ocd = ocd;
+    }
+
+    public Designate getDesignate() {
+        return designate;
+    }
+
+    public void setDesignate(final Designate designate) {
+        this.designate = designate;
+    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/Designate.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/Designate.java
index 6354505..b2d86c4 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/Designate.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/Designate.java
@@ -24,8 +24,6 @@
 
     protected String factoryPid;
 
-    protected MTObject object;
-
     public String getPid() {
         return this.pid;
     }
@@ -41,12 +39,4 @@
     public void setFactoryPid(String pid) {
         this.factoryPid = pid;
     }
-
-    public MTObject getObject() {
-        return this.object;
-    }
-
-    public void setObject(MTObject object) {
-        this.object = object;
-    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MTObject.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MTObject.java
deleted file mode 100644
index 7d99b39..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MTObject.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.om.metatype;
-
-public class MTObject {
-
-    protected String ocdref;
-
-    public String getOcdref() {
-        return this.ocdref;
-    }
-
-    public void setOcdref(String ocdref) {
-        this.ocdref = ocdref;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MetaData.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MetaData.java
deleted file mode 100644
index 33841cd..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/metatype/MetaData.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.om.metatype;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class MetaData {
-
-    protected String localization;
-
-    protected List<OCD> ocds = new ArrayList<OCD>();
-
-    protected List<Designate> designates = new ArrayList<Designate>();
-
-    public String getLocalization() {
-        return this.localization;
-    }
-
-    public void setLocalization(String localization) {
-        this.localization = localization;
-    }
-
-    public List<OCD> getOCDs() {
-        return this.ocds;
-    }
-
-    public List<Designate> getDesignates() {
-        return this.designates;
-    }
-
-    public void addOCD(OCD ocd) {
-        this.ocds.add(ocd);
-    }
-
-    public void addDesignate(Designate d) {
-        this.designates.add(d);
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
index b4d2d10..9d788ac 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
@@ -27,12 +27,13 @@
 import org.apache.felix.scrplugin.Log;
 import org.apache.felix.scrplugin.Options;
 import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.apache.felix.scrplugin.helper.ComponentContainer;
+import org.apache.felix.scrplugin.helper.DescriptionContainer;
 import org.apache.felix.scrplugin.helper.StringUtils;
 import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
 import org.apache.felix.scrplugin.om.metatype.Designate;
-import org.apache.felix.scrplugin.om.metatype.MTObject;
-import org.apache.felix.scrplugin.om.metatype.MetaData;
 import org.apache.felix.scrplugin.om.metatype.OCD;
+import org.osgi.service.metatype.MetaTypeService;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
@@ -70,30 +71,42 @@
     private static final String OPTION_ELEMENT = "Option";
     private static final String OPTION_ELEMENT_QNAME = OPTION_ELEMENT;
 
-    public static List<String> generateDescriptors(final MetaData metaData, final Options options, final Log logger)
+    public static List<String> generateDescriptors(final DescriptionContainer module,
+                    final Options options,
+                    final Log logger)
     throws SCRDescriptorException {
+        int metatypeCount = 0;
+        for(final ComponentContainer component : module.getComponents()) {
+            if ( component.getOCD() != null ) {
+                metatypeCount++;
+            }
+        }
         // write meta type info if there is a file name
         if (!StringUtils.isEmpty(options.getMetaTypeName())) {
-            final String path = "OSGI-INF" + File.separator + "metatype" + File.separator + options.getMetaTypeName();
-            final File mtFile = new File(options.getOutputDirectory(), path);
-            final int size = metaData.getOCDs().size() + metaData.getDesignates().size();
-            if (size > 0) {
-                logger.info("Generating " + size + " MetaType Descriptors to " + mtFile);
+            final File parentDir = new File(options.getOutputDirectory(), "OSGI-INF");
+            final File mtDir = new File(parentDir, "metatype");
+
+            final File mtFile = new File(mtDir, options.getMetaTypeName());
+
+            if (metatypeCount > 0) {
+                logger.info("Generating " + metatypeCount + " MetaType Descriptors to " + mtFile);
                 mtFile.getParentFile().mkdirs();
-                MetaTypeIO.write(metaData, mtFile);
-                return Collections.singletonList(path.replace(File.separatorChar, '/'));
+                MetaTypeIO.write(module, mtFile);
+                return Collections.singletonList(parentDir.getName() + '/' + mtDir.getName() + '/' + mtFile.getName());
             }
             if (mtFile.exists()) {
                 mtFile.delete();
             }
 
         } else {
-            logger.info("Meta type file name is not set: meta type info is not written.");
+            if ( metatypeCount > 0 ) {
+                logger.info("Meta type file name is not set: meta type info is not written.");
+            }
         }
         return null;
     }
 
-    private static void write(final MetaData metaData, final File file)
+    private static void write(final DescriptionContainer metaData, final File file)
     throws SCRDescriptorException {
         try {
             generateXML(metaData, IOUtils.getSerializer(file));
@@ -109,22 +122,22 @@
      * @param contentHandler
      * @throws SAXException
      */
-    private static void generateXML(final MetaData metaData, final ContentHandler contentHandler)
+    private static void generateXML(final DescriptionContainer metaData, final ContentHandler contentHandler)
     throws SAXException {
         contentHandler.startDocument();
         contentHandler.startPrefixMapping(PREFIX, NAMESPACE_URI);
 
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "localization", metaData.getLocalization());
+        IOUtils.addAttribute(ai, "localization", MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype");
 
         contentHandler.startElement(NAMESPACE_URI, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
         IOUtils.newline(contentHandler);
 
-        for(final OCD ocd : metaData.getOCDs()) {
-            generateXML(ocd, contentHandler);
-        }
-        for(final Designate d : metaData.getDesignates()) {
-            generateXML(d, contentHandler);
+        for(final ComponentContainer comp : metaData.getComponents()) {
+            if ( comp.getOCD() != null ) {
+                generateXML(comp.getOCD(), contentHandler);
+                generateXML(comp.getDesignate(), contentHandler);
+            }
         }
 
         // end wrapper element
@@ -199,7 +212,7 @@
         IOUtils.newline(contentHandler);
     }
 
-    private static void generateXML(Designate designate, ContentHandler contentHandler)
+    private static void generateXML(final Designate designate, final ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "pid", designate.getPid());
@@ -208,17 +221,17 @@
         contentHandler.startElement(INNER_NAMESPACE_URI, DESIGNATE_ELEMENT, DESIGNATE_ELEMENT_QNAME, ai);
         IOUtils.newline(contentHandler);
 
-        generateXML(designate.getObject(), contentHandler);
+        generateObjectXML(designate, contentHandler);
 
         IOUtils.indent(contentHandler, 1);
         contentHandler.endElement(INNER_NAMESPACE_URI, DESIGNATE_ELEMENT, DESIGNATE_ELEMENT_QNAME);
         IOUtils.newline(contentHandler);
     }
 
-    private static void generateXML(MTObject obj, ContentHandler contentHandler)
+    private static void generateObjectXML(final Designate obj, final ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "ocdref", obj.getOcdref());
+        IOUtils.addAttribute(ai, "ocdref", obj.getPid());
         IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(INNER_NAMESPACE_URI, OBJECT_ELEMENT, OBJECT_ELEMENT_QNAME, ai);
         contentHandler.endElement(INNER_NAMESPACE_URI, OBJECT_ELEMENT, OBJECT_ELEMENT_QNAME);