FELIX-3552 : Implement new features of DS 1.2

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1350302 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
index 1baa0fb..55c3738 100644
--- a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
+++ b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
@@ -136,4 +136,11 @@
      * @since 1.0
      */
     ConfigurationPolicy policy() default ConfigurationPolicy.OPTIONAL;
+
+    /**
+     * The configuration pid.
+     * The default value for this is the name of the component.
+     * @since 1.7
+     */
+    String configurationPid();
 }
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 6060330..42ddd91 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
@@ -206,6 +206,9 @@
                         ComponentConfigurationPolicy.OPTIONAL.name())));
         component.setSetMetatypeFactoryPid(cad.getBooleanValue("configurationFactory", false));
 
+        // Version 1.2
+        component.setConfigurationPid(cad.getStringValue("configurationPid", null));
+
         return component;
     }
 
diff --git a/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java b/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
index 2ce7c11..3dcb4f3 100644
--- a/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
+++ b/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
@@ -198,7 +198,8 @@
         component.setConfigurationPolicy(ComponentConfigurationPolicy.valueOf(cad.getEnumValue("policy",
                         ComponentConfigurationPolicy.OPTIONAL.name())));
 
-        // configuration pid (TODO)
+        // configuration pid
+        component.setConfigurationPid(cad.getStringValue("configurationPid", null));
         component.setCreatePid(cad.getBooleanValue("createPid", true));
 
         // no inheritance
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 067eff9..49e29ca 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
@@ -371,6 +371,12 @@
         comp.setFactory(componentDesc.getFactory());
         comp.setSpecVersion(componentDesc.getSpecVersion());
 
+        // configuration pid in 1.2
+        if ( componentDesc.getConfigurationPid() != null && !componentDesc.getConfigurationPid().equals(componentDesc.getName())) {
+            comp.setConfigurationPid(componentDesc.getConfigurationPid());
+            comp.setSpecVersion(SpecVersion.VERSION_1_2);
+        }
+
         // Create metatype (if required)
         final OCD ocd;
         if ( !componentDesc.isAbstract() && componentDesc.isCreateMetatype() ) {
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java
index 14c2b13..e42cb56 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java
@@ -48,6 +48,7 @@
  * <li>deactivate : null</li>
  * <li>modified : null</li>
  * <li>specVersion : null</li>
+ * <li>configuraionPid : null</li>
  * </ul>
  *
  */
@@ -104,6 +105,9 @@
     /** The spec version. */
     private SpecVersion specVersion;
 
+    /** Configuration PID (V1.2) */
+    private String configurationPid;
+
     public ComponentDescription(final ScannedAnnotation annotation) {
         super(annotation);
     }
@@ -246,16 +250,20 @@
 
     @Override
     public String toString() {
-        return "ComponentDescription [name=" + name + ", label=" + label
-                + ", description=" + description + ", enabled=" + enabled
-                + ", immediate=" + immediate + ", factory=" + factory
-                + ", isSetMetatypeFactoryPid=" + isSetMetatypeFactoryPid
-                + ", isAbstract=" + isAbstract + ", isInherit=" + isInherit
-                + ", createDs=" + createDs + ", createPid=" + createPid
-                + ", createMetatype=" + createMetatype
-                + ", configurationPolicy=" + configurationPolicy
-                + ", activate=" + activate + ", deactivate=" + deactivate
-                + ", modified=" + modified + ", specVersion=" + specVersion
-                + ", annotation=" + annotation + "]";
+        return "ComponentDescription [name=" + name + ", label=" + label + ", description=" + description
+                        + ", configurationPolicy=" + configurationPolicy + ", isAbstract=" + isAbstract + ", isInherit="
+                        + isInherit + ", createDs=" + createDs + ", createPid=" + createPid + ", createMetatype="
+                        + createMetatype + ", enabled=" + enabled + ", immediate=" + immediate + ", factory=" + factory
+                        + ", isSetMetatypeFactoryPid=" + isSetMetatypeFactoryPid + ", activate=" + activate + ", deactivate="
+                        + deactivate + ", modified=" + modified + ", specVersion=" + specVersion + ", configurationPid="
+                        + configurationPid + "]";
+    }
+
+    public String getConfigurationPid() {
+        return configurationPid;
+    }
+
+    public void setConfigurationPid(String configurationPid) {
+        this.configurationPid = configurationPid;
     }
 }
\ No newline at end of file
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
index 0d31dce..bd1d24e 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
@@ -81,6 +81,9 @@
     /** The class description. */
     private final ClassDescription classDescription;
 
+    /** Configuration PID (V1.2) */
+    private String configurationPid;
+
     /**
      * Constructor from java source.
      */
@@ -249,6 +252,12 @@
 
         // if the service is abstract, we do not validate everything
         if (!this.isAbstract) {
+            // if configuration pid is set and different from name, we need 1.2
+            if ( this.configurationPid != null && !this.configurationPid.equals(this.name)
+                 && context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
+                this.logError(context.getIssueLog(), "Different configuration pid requires "
+                                + SpecVersion.VERSION_1_2.getName() + " or higher.");
+            }
             // ensure non-abstract, public class
             if (!Modifier.isPublic(context.getClassDescription().getDescribedClass().getModifiers())) {
                 this.logError(context.getIssueLog(), "Class must be public: "
@@ -503,14 +512,18 @@
 
     @Override
     public String toString() {
-        return "Component " + this.name + " (" + "enabled=" + (enabled == null ? "<notset>" : enabled) + ", immediate="
-                        + (immediate == null ? "<notset>" : immediate) + ", abstract=" + isAbstract + ", isDS=" + isDs
-                        + (factory != null ? ", factory=" + factory : "")
-                        + (configurationPolicy != null ? ", configurationPolicy=" + configurationPolicy : "")
-                        + (activate != null ? ", activate=" + activate : "")
-                        + (deactivate != null ? ", deactivate=" + deactivate : "")
-                        + (modified != null ? ", modified=" + modified : "") + ", specVersion=" + specVersion
-                        + ", service=" + service + ", properties=" + properties
-                        + ", references=" + references + ")";
+        return "Component [name=" + name + ", enabled=" + enabled + ", immediate=" + immediate + ", factory=" + factory
+                        + ", properties=" + properties + ", service=" + service + ", references=" + references + ", isAbstract="
+                        + isAbstract + ", isDs=" + isDs + ", configurationPolicy=" + configurationPolicy + ", activate="
+                        + activate + ", deactivate=" + deactivate + ", modified=" + modified + ", specVersion=" + specVersion
+                        + ", classDescription=" + classDescription + ", configurationPid=" + configurationPid + "]";
+    }
+
+    public String getConfigurationPid() {
+        return configurationPid;
+    }
+
+    public void setConfigurationPid(String configurationPid) {
+        this.configurationPid = configurationPid;
     }
 }
\ No newline at end of file
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 37bc803..9371e03 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
@@ -101,6 +101,9 @@
     /** Component: The modified attribute. */
     private static final String COMPONENT_ATTR_MODIFIED = "modified";
 
+    /** Component: The configuration pid attribute. */
+    private static final String COMPONENT_ATTR_CONFIGURATION_PID = "configuration-pid";
+
     private static final String IMPLEMENTATION = "implementation";
 
     private static final String IMPLEMENTATION_QNAME = IMPLEMENTATION;
@@ -160,7 +163,8 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Components components, ContentHandler contentHandler) throws SAXException {
+    protected static void generateXML(final Components components,
+                    final ContentHandler contentHandler) throws SAXException {
         // detect namespace to use
         final String namespace = components.getSpecVersion().getNamespaceUrl();
 
@@ -173,7 +177,10 @@
 
         for (final Component component : components.getComponents()) {
             if (component.isDs()) {
+                final SpecVersion oldVersion = component.getSpecVersion();
+                component.setSpecVersion(components.getSpecVersion());
                 generateXML(namespace, component, contentHandler);
+                component.setSpecVersion(oldVersion);
             }
         }
         // end wrapper element
@@ -207,7 +214,12 @@
             IOUtils.addAttribute(ai, COMPONENT_ATTR_DEACTIVATE, component.getDeactivate());
             IOUtils.addAttribute(ai, COMPONENT_ATTR_MODIFIED, component.getModified());
         }
-
+        // attributes new in 1.2
+        if ( component.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());
+            }
+        }
         IOUtils.indent(contentHandler, 1);
         contentHandler.startElement(namespace, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME, ai);
         IOUtils.newline(contentHandler);