FELIX-3169 :  Add support for new PASSWORD attribute type of Metatype service 

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1438410 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Property.java b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
index 0b51db8..2b0b7c9 100644
--- a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
+++ b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
@@ -18,7 +18,11 @@
  */
 package org.apache.felix.scr.annotations;
 
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * The <code>Property</code> annotation defines properties which are made
@@ -130,6 +134,14 @@
     short[] shortValue() default {};
 
     /**
+     * The password value(s) of the property.
+     * This attribute should not be used in combination with any of the other
+     * value attributes or the type attribute.
+     * @since 1.8.0
+     */
+    String[] passwordValue() default {};
+
+    /**
      * Defines the cardinality of the property and its collection type. If the
      * cardinality is negative, the property is expected to be stored in a
      * {@link java.util.Vector} (primitive types such as boolean are boxed in
diff --git a/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java b/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
index 3ae7c9c..f97d8af 100644
--- a/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
+++ b/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
@@ -331,7 +331,7 @@
 
     private static final String[] PROPERTY_VALUE_PROCESSING = new String[] { "String", "value", "String", "classValue", "Long",
             "longValue", "Double", "doubleValue", "Float", "floatValue", "Integer", "intValue", "Byte", "byteValue", "Char",
-            "charValue", "Boolean", "boolValue", "Short", "shortValue" };
+            "charValue", "Boolean", "boolValue", "Short", "shortValue", "Password", "passwordValue" };
 
     /**
      * Create properties descriptions
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java
index 5aca421..f9a0093 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java
@@ -29,7 +29,8 @@
     Char,
     Character,
     Boolean,
-    Short;
+    Short,
+    Passwort;
 
     public static PropertyType from(final Class<?> javaClass) {
         if ( javaClass.getName().equals(Long.class.getName())) {
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 4d5dcbe..208bb79 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
@@ -50,7 +50,8 @@
  */
 public class MetaTypeIO {
 
-    private static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/metatype/v1.0.0";
+    private static final String NAMESPACE_URI_10 = "http://www.osgi.org/xmlns/metatype/v1.0.0";
+    private static final String NAMESPACE_URI_12 = "http://www.osgi.org/xmlns/metatype/v1.2.0";
 
     private static final String INNER_NAMESPACE_URI = "";
 
@@ -124,6 +125,25 @@
     }
 
     /**
+     * Detect correct version to use.
+     * If password type is used, we have to use v1.2
+     */
+    private static String detectMetatypeVersion(final DescriptionContainer container) {
+        for(final ComponentContainer comp : container.getComponents()) {
+            if ( comp.getMetatypeContainer() != null ) {
+                final Iterator<MetatypeAttributeDefinition> i = comp.getMetatypeContainer().getProperties().iterator();
+                while ( i.hasNext() ) {
+                    final MetatypeAttributeDefinition ad = i.next();
+                    if ( ad.getType().equalsIgnoreCase("password") ) {
+                        return NAMESPACE_URI_12;
+                    }
+                }
+            }
+        }
+        return NAMESPACE_URI_10;
+    }
+
+    /**
      * Generate the xml top level element and start streaming
      * the meta data.
      * @param metaData
@@ -131,17 +151,19 @@
      * @throws SAXException
      */
     private static void write(final DescriptionContainer metaData, final List<ComponentContainer> components, final File file)
-            throws SCRDescriptorException {
+    throws SCRDescriptorException {
+        final String namespace = detectMetatypeVersion(metaData);
+
         try {
             final ContentHandler contentHandler = IOUtils.getSerializer(file);
 
             contentHandler.startDocument();
-            contentHandler.startPrefixMapping(PREFIX, NAMESPACE_URI);
+            contentHandler.startPrefixMapping(PREFIX, namespace);
 
             final AttributesImpl ai = new AttributesImpl();
             IOUtils.addAttribute(ai, "localization", MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype");
 
-            contentHandler.startElement(NAMESPACE_URI, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
+            contentHandler.startElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
             IOUtils.newline(contentHandler);
 
             for(final ComponentContainer comp : metaData.getComponents()) {
@@ -152,7 +174,7 @@
             }
 
             // end wrapper element
-            contentHandler.endElement(NAMESPACE_URI, METADATA_ELEMENT, METADATA_ELEMENT_QNAME);
+            contentHandler.endElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME);
             IOUtils.newline(contentHandler);
             contentHandler.endPrefixMapping(PREFIX);
             contentHandler.endDocument();