FELIX-594: Pretty print generated xml.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@662676 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
index f940ec1..cc15f8d 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
@@ -115,6 +115,7 @@
 
         // wrapper element to generate well formed xml
         contentHandler.startElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS, new AttributesImpl());
+        IOUtils.newline(contentHandler);
 
         final Iterator i = components.getComponents().iterator();
         while ( i.hasNext() ) {
@@ -123,6 +124,7 @@
         }
         // end wrapper element
         contentHandler.endElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS);
+        IOUtils.newline(contentHandler);
         contentHandler.endPrefixMapping(PREFIX);
         contentHandler.endDocument();
     }
@@ -141,7 +143,9 @@
         IOUtils.addAttribute(ai, "name", component.getName());
         IOUtils.addAttribute(ai, "factory", component.getFactory());
 
+        IOUtils.indent(contentHandler, 1);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME, ai);
+        IOUtils.newline(contentHandler);
         generateXML(component.getImplementation(), contentHandler);
         if ( component.getService() != null ) {
             generateXML(component.getService(), contentHandler);
@@ -160,7 +164,9 @@
                 generateXML(reference, contentHandler);
             }
         }
+        IOUtils.indent(contentHandler, 1);
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
@@ -173,8 +179,10 @@
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "class", implementation.getClassame());
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION, ComponentDescriptorIO.IMPLEMENTATION_QNAME, ai);
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION, ComponentDescriptorIO.IMPLEMENTATION_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
@@ -187,6 +195,7 @@
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "servicefactory", String.valueOf(service.isServicefactory()));
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.SERVICE, ComponentDescriptorIO.SERVICE_QNAME, ai);
         if ( service.getInterfaces() != null ) {
             final Iterator i = service.getInterfaces().iterator();
@@ -195,7 +204,9 @@
                 generateXML(interf, contentHandler);
             }
         }
+        IOUtils.indent(contentHandler, 2);
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.SERVICE, ComponentDescriptorIO.SERVICE_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
@@ -208,8 +219,10 @@
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "interface", interf.getInterfacename());
+        IOUtils.indent(contentHandler, 3);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME, ai);
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
@@ -237,17 +250,20 @@
                 IOUtils.addAttribute(ai, "cardinality", String.valueOf(property.getCardinality()));
             }
         }
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.PROPERTY, ComponentDescriptorIO.PROPERTY_QNAME, ai);
         if ( property.getMultiValue() != null && property.getMultiValue().length > 0 ) {
             // generate a new line first
             IOUtils.text(contentHandler, "\n");
             for(int i=0; i<property.getMultiValue().length; i++) {
-                IOUtils.text(contentHandler, "    ");
+                IOUtils.indent(contentHandler, 3);
                 IOUtils.text(contentHandler, property.getMultiValue()[i]);
-                IOUtils.text(contentHandler, "\n");
+                IOUtils.newline(contentHandler);
             }
+            IOUtils.indent(contentHandler, 2);
         }
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.PROPERTY, ComponentDescriptorIO.PROPERTY_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
@@ -266,8 +282,10 @@
         IOUtils.addAttribute(ai, "target", reference.getTarget());
         IOUtils.addAttribute(ai, "bind", reference.getBind());
         IOUtils.addAttribute(ai, "unbind", reference.getUnbind());
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, ComponentDescriptorIO.REFERENCE, ComponentDescriptorIO.REFERENCE_QNAME, ai);
         contentHandler.endElement(NAMESPACE_URI, ComponentDescriptorIO.REFERENCE, ComponentDescriptorIO.REFERENCE_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     /**
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/IOUtils.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/IOUtils.java
index c199090..0259cb7 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/IOUtils.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/IOUtils.java
@@ -18,31 +18,15 @@
  */
 package org.apache.felix.scrplugin.xml;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import java.io.*;
+import java.util.*;
 
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.*;
+import javax.xml.transform.sax.*;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
+import org.xml.sax.*;
 import org.xml.sax.helpers.AttributesImpl;
 
 /**
@@ -391,7 +375,7 @@
 
     /**
      * Helper method writing out a string.
-     * @param ch
+     * @param ch    The content handler.
      * @param text
      * @throws SAXException
      */
@@ -402,4 +386,27 @@
             ch.characters(c, 0, c.length);
         }
     }
+
+    /**
+     * Helper method to indent the xml elements.
+     * Each level is indented with four spaces.
+     * @param ch    The content handler.
+     * @param level The level of indention.
+     */
+    protected static void indent(ContentHandler ch, int level)
+    throws SAXException {
+        for(int i=0;i<level;i++) {
+            IOUtils.text(ch, "    ");
+        }
+    }
+
+    /**
+     * Helper method to create a new line.
+     * @param ch    The content handler.
+     * @throws SAXException
+     */
+    protected static void newline(ContentHandler ch)
+    throws SAXException {
+        IOUtils.text(ch, "\n");
+    }
 }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
index 7e84dac..7ed81e7 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
@@ -25,11 +25,7 @@
 
 import javax.xml.transform.TransformerException;
 
-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.om.metatype.*;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -95,6 +91,7 @@
         IOUtils.addAttribute(ai, "localization", metaData.getLocalization());
 
         contentHandler.startElement(NAMESPACE_URI, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
+        IOUtils.newline(contentHandler);
 
         final Iterator i = metaData.getDescriptors().iterator();
         while ( i.hasNext() ) {
@@ -107,6 +104,7 @@
         }
         // end wrapper element
         contentHandler.endElement(NAMESPACE_URI, METADATA_ELEMENT, METADATA_ELEMENT_QNAME);
+        IOUtils.newline(contentHandler);
         contentHandler.endPrefixMapping(PREFIX);
         contentHandler.endDocument();
     }
@@ -117,15 +115,21 @@
         IOUtils.addAttribute(ai, "id", ocd.getId());
         IOUtils.addAttribute(ai, "name", ocd.getName());
         IOUtils.addAttribute(ai, "description", ocd.getDescription());
+        IOUtils.indent(contentHandler, 1);
         contentHandler.startElement(NAMESPACE_URI, OCD_ELEMENT, OCD_ELEMENT_QNAME, ai);
 
-        final Iterator i = ocd.getProperties().iterator();
-        while ( i.hasNext() ) {
-            final AttributeDefinition ad = (AttributeDefinition) i.next();
-            generateXML(ad, contentHandler);
+        if ( ocd.getProperties().size() > 0 ) {
+            IOUtils.newline(contentHandler);
+            final Iterator i = ocd.getProperties().iterator();
+            while ( i.hasNext() ) {
+                final AttributeDefinition ad = (AttributeDefinition) i.next();
+                generateXML(ad, contentHandler);
+            }
+            IOUtils.indent(contentHandler, 1);
         }
 
         contentHandler.endElement(NAMESPACE_URI, OCD_ELEMENT, OCD_ELEMENT_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     protected static void generateXML(AttributeDefinition ad, ContentHandler contentHandler)
@@ -148,38 +152,50 @@
         IOUtils.addAttribute(ai, "name", ad.getName());
         IOUtils.addAttribute(ai, "description", ad.getDescription());
         IOUtils.addAttribute(ai, "cardinality", ad.getCardinality());
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, AD_ELEMENT, AD_ELEMENT_QNAME, ai);
 
-        if (ad.getOptions() != null) {
+        if (ad.getOptions() != null && ad.getOptions().size() > 0) {
+            IOUtils.newline(contentHandler);
             for (Iterator oi=ad.getOptions().entrySet().iterator(); oi.hasNext(); ) {
                 final Map.Entry entry = (Map.Entry) oi.next();
                 ai.clear();
                 IOUtils.addAttribute(ai, "value", String.valueOf(entry.getKey()));
                 IOUtils.addAttribute(ai, "label", String.valueOf(entry.getValue()));
+                IOUtils.indent(contentHandler, 3);
                 contentHandler.startElement(NAMESPACE_URI, OPTION_ELEMENT, OPTION_ELEMENT_QNAME, ai);
                 contentHandler.endElement(NAMESPACE_URI, OPTION_ELEMENT, OPTION_ELEMENT_QNAME);
+                IOUtils.newline(contentHandler);
             }
+            IOUtils.indent(contentHandler, 2);
         }
 
         contentHandler.endElement(NAMESPACE_URI, AD_ELEMENT, AD_ELEMENT_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     protected static void generateXML(Designate designate, ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "pid", designate.getPid());
+        IOUtils.indent(contentHandler, 1);
         contentHandler.startElement(NAMESPACE_URI, DESIGNATE_ELEMENT, DESIGNATE_ELEMENT_QNAME, ai);
+        IOUtils.newline(contentHandler);
 
         generateXML(designate.getObject(), contentHandler);
 
+        IOUtils.indent(contentHandler, 1);
         contentHandler.endElement(NAMESPACE_URI, DESIGNATE_ELEMENT, DESIGNATE_ELEMENT_QNAME);
+        IOUtils.newline(contentHandler);
     }
 
     protected static void generateXML(MTObject obj, ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "ocdref", obj.getOcdref());
+        IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(NAMESPACE_URI, OBJECT_ELEMENT, OBJECT_ELEMENT_QNAME, ai);
         contentHandler.endElement(NAMESPACE_URI, OBJECT_ELEMENT, OBJECT_ELEMENT_QNAME);
+        IOUtils.newline(contentHandler);
     }
 }