You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2018/01/25 13:04:45 UTC

svn commit: r1822200 - in /aries/trunk/blueprint: blueprint-bundle/ blueprint-cm/ blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ blueprint-cm/src/main/resources/OSGI-INF/blueprint/ blueprint-cm/src/main/resources/org/apache/aries/...

Author: gnodet
Date: Thu Jan 25 13:04:45 2018
New Revision: 1822200

URL: http://svn.apache.org/viewvc?rev=1822200&view=rev
Log:
[ARIES-1668] Support null values inside property-placeholders

Added:
    aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.4.0.xsd
Modified:
    aries/trunk/blueprint/blueprint-bundle/pom.xml
    aries/trunk/blueprint/blueprint-cm/pom.xml
    aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
    aries/trunk/blueprint/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
    aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd
    aries/trunk/blueprint/itests/blueprint-itests/pom.xml
    aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/CmPropertyPlaceholderTest.java
    aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/Foo.java
    aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/FooInterface.java
    aries/trunk/blueprint/itests/blueprint-itests/src/test/resources/CmPropertyPlaceholderTest.xml

Modified: aries/trunk/blueprint/blueprint-bundle/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-bundle/pom.xml?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-bundle/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-bundle/pom.xml Thu Jan 25 13:04:45 2018
@@ -128,7 +128,7 @@
         <dependency>
             <groupId>org.apache.aries.blueprint</groupId>
             <artifactId>org.apache.aries.blueprint.cm</artifactId>
-            <version>1.1.1-SNAPSHOT</version>
+            <version>1.2.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

Modified: aries/trunk/blueprint/blueprint-cm/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/pom.xml?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-cm/pom.xml Thu Jan 25 13:04:45 2018
@@ -31,7 +31,7 @@
     <groupId>org.apache.aries.blueprint</groupId>
     <artifactId>org.apache.aries.blueprint.cm</artifactId>
     <packaging>bundle</packaging>
-    <version>1.1.1-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
     <name>Apache Aries Blueprint CM</name>
     <description>
         This bundle contains the ConfigAdmin namespace for blueprint.
@@ -66,7 +66,7 @@
             <id>dev</id>
             <properties>
                 <blueprint.api.version>1.0.1</blueprint.api.version>
-                <blueprint.core.version>1.8.4-SNAPSHOT</blueprint.core.version>
+                <blueprint.core.version>1.9.0-SNAPSHOT</blueprint.core.version>
                 <blueprint.parser.version>1.4.0</blueprint.parser.version>
             </properties>
         </profile>

Modified: aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java Thu Jan 25 13:04:45 2018
@@ -19,13 +19,7 @@
 package org.apache.aries.blueprint.compendium.cm;
 
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.aries.blueprint.ComponentDefinitionRegistry;
 import org.apache.aries.blueprint.NamespaceHandler;
@@ -84,12 +78,14 @@ public class CmNamespaceHandler implemen
     public static final String BLUEPRINT_CM_NAMESPACE_1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0";
     public static final String BLUEPRINT_CM_NAMESPACE_1_2 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0";
     public static final String BLUEPRINT_CM_NAMESPACE_1_3 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0";
+    public static final String BLUEPRINT_CM_NAMESPACE_1_4 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_0 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_2 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_3 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.3.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_4 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.4.0";
     public static final String BLUEPRINT_EXT_NAMESPACE_V1_5 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.5.0";
+    public static final String BLUEPRINT_EXT_NAMESPACE_V1_6 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0";
 
     public static final String PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
     public static final String MANAGED_PROPERTIES_ELEMENT = "managed-properties";
@@ -109,6 +105,7 @@ public class CmNamespaceHandler implemen
     public static final String PERSISTENT_ID_ATTRIBUTE = "persistent-id";
     public static final String PLACEHOLDER_PREFIX_ATTRIBUTE = "placeholder-prefix";
     public static final String PLACEHOLDER_SUFFIX_ATTRIBUTE = "placeholder-suffix";
+    public static final String PLACEHOLDER_NULL_VALUE_ATTRIBUTE = "null-value";
     public static final String DEFAULTS_REF_ATTRIBUTE = "defaults-ref";
     public static final String UPDATE_STRATEGY_ATTRIBUTE = "update-strategy";
     public static final String UPDATE_METHOD_ATTRIBUTE = "update-method";
@@ -130,6 +127,20 @@ public class CmNamespaceHandler implemen
     private static final String MANAGED_OBJECT_MANAGER_NAME = "org.apache.aries.managedObjectManager";
     
     private static final Logger LOGGER = LoggerFactory.getLogger(CmNamespaceHandler.class);
+    private static final Set<String> EXT_URIS = Collections.unmodifiableSet(new LinkedHashSet<String>(Arrays.asList(
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_0,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_1,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_2,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_3,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_4,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_5,
+                                                    BLUEPRINT_EXT_NAMESPACE_V1_6)));
+    private static final Set<String> CM_URIS = Collections.unmodifiableSet(new LinkedHashSet<String>(Arrays.asList(
+                                                    BLUEPRINT_CM_NAMESPACE_1_0,
+                                                    BLUEPRINT_CM_NAMESPACE_1_1,
+                                                    BLUEPRINT_CM_NAMESPACE_1_2,
+                                                    BLUEPRINT_CM_NAMESPACE_1_3,
+                                                    BLUEPRINT_CM_NAMESPACE_1_4)));
 
     // This property is static but it should be ok since there will be only a single instance
     // of this class for the bundle
@@ -154,15 +165,10 @@ public class CmNamespaceHandler implemen
     }
 
     public URL getSchemaLocation(String namespace) {
-        if (BLUEPRINT_CM_NAMESPACE_1_3.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.3.0.xsd");
-        } else if (BLUEPRINT_CM_NAMESPACE_1_2.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.2.0.xsd");
-        } else if (BLUEPRINT_CM_NAMESPACE_1_1.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.1.0.xsd");
-        } else if (BLUEPRINT_CM_NAMESPACE_1_0.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.0.0.xsd");
-        } else if (namespace.startsWith("http://aries.apache.org/blueprint/xmlns/blueprint-ext")) {
+        if (isCmNamespace(namespace)) {
+            String v = namespace.substring("http://aries.apache.org/blueprint/xmlns/blueprint-cm/v".length());
+            return getClass().getResource("blueprint-cm-" + v + ".xsd");
+        } else if (isExtNamespace(namespace)) {
             try {
                 Class<?> extNsHandlerClazz;
                 Bundle extBundle = FrameworkUtil.getBundle(PlaceholdersUtils.class);
@@ -271,6 +277,12 @@ public class CmNamespaceHandler implemen
                                     ? element.getAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
                                     : "}";
         metadata.addProperty("placeholderSuffix", createValue(context, suffix));
+        String nullValue = element.hasAttribute(PLACEHOLDER_NULL_VALUE_ATTRIBUTE)
+                ? element.getAttribute(PLACEHOLDER_NULL_VALUE_ATTRIBUTE)
+                : null;
+        if (nullValue != null) {
+            metadata.addProperty("nullValue", createValue(context, nullValue));
+        }
         String defaultsRef = element.hasAttribute(DEFAULTS_REF_ATTRIBUTE) ? element.getAttribute(DEFAULTS_REF_ATTRIBUTE) : null;
         if (defaultsRef != null) {
             metadata.addProperty("defaultProperties", createRef(context, defaultsRef));
@@ -321,40 +333,21 @@ public class CmNamespaceHandler implemen
     }
 
     private String extractSystemPropertiesAttribute(Element element) {
-      String systemProperties = null;
-      
-      if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_3, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_3, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_4, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_4, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_5, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_5, SYSTEM_PROPERTIES_ATTRIBUTE);
+      for (String uri : EXT_URIS) {
+          if (element.hasAttributeNS(uri, SYSTEM_PROPERTIES_ATTRIBUTE)) {
+              return element.getAttributeNS(uri, SYSTEM_PROPERTIES_ATTRIBUTE);
+          }
       }
-      return systemProperties;
+      return null;
     }
 
     private String extractIgnoreMissingLocations(Element element) {
-      String ignoreMissingLocations = null;
-      if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_3, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_3, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_4, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_4, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_5, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_5, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      }
-      return ignoreMissingLocations;
+        for (String uri : EXT_URIS) {
+            if (element.hasAttributeNS(uri, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
+                return element.getAttributeNS(uri, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
+            }
+        }
+        return null;
     }
 
     private Metadata parseDefaultProperties(ParserContext context, MutableBeanMetadata enclosingComponent, Element element) {
@@ -624,18 +617,11 @@ public class CmNamespaceHandler implemen
     }
 
     public static boolean isCmNamespace(String uri) {
-        return BLUEPRINT_CM_NAMESPACE_1_0.equals(uri)
-                || BLUEPRINT_CM_NAMESPACE_1_1.equals(uri)
-                || BLUEPRINT_CM_NAMESPACE_1_2.equals(uri)
-                || BLUEPRINT_CM_NAMESPACE_1_3.equals(uri);
+        return CM_URIS.contains(uri);
     }
 
     public static boolean isExtNamespace(String uri) {
-        return BLUEPRINT_EXT_NAMESPACE_V1_0.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_1.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_2.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_3.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_4.equals(uri);
+        return EXT_URIS.contains(uri);
     }
 
     public String getId(ParserContext context, Element element) {

Modified: aries/trunk/blueprint/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml (original)
+++ aries/trunk/blueprint/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml Thu Jan 25 13:04:45 2018
@@ -53,5 +53,13 @@
             <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0"/>
         </service-properties>
     </service>
-    
+    <service ref="CmNamespaceHandler">
+        <interfaces>
+            <value>org.apache.aries.blueprint.NamespaceHandler</value>
+        </interfaces>
+        <service-properties>
+            <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0"/>
+        </service-properties>
+    </service>
+
 </blueprint>

Added: aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.4.0.xsd
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.4.0.xsd?rev=1822200&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.4.0.xsd (added)
+++ aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.4.0.xsd Thu Jan 25 13:04:45 2018
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    /*
+    * $Revision$
+    *
+    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+    *
+    * Licensed 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.
+    */
+    -->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0"
+            xmlns:ext100="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+            xmlns:ext110="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0"
+            xmlns:ext120="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
+            xmlns:ext130="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.3.0"
+            xmlns:ext140="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.4.0"
+            xmlns:ext150="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.5.0"
+            xmlns:ext160="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0"
+            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            version="1.0.0">
+
+    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.3.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.4.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.5.0" />
+    <xsd:import namespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0" />
+
+    <!-- property placeholder -->
+
+    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
+
+    <xsd:complexType name="TpropertyPlaceholder">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <!-- nested properties declaration -->
+                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
+                    <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                        <xsd:element ref="ext100:location" />
+                        <xsd:element ref="ext110:location" />
+                        <xsd:element ref="ext120:location" />
+                        <xsd:element ref="ext130:location" />
+                        <xsd:element ref="ext140:location" />
+                        <xsd:element ref="ext150:location" />
+                        <xsd:element ref="ext160:location" />
+                    </xsd:choice>
+                </xsd:sequence>
+
+                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
+                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
+                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
+                <xsd:attribute name="null-value" type="xsd:string" use="optional"/>
+                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+                <xsd:attribute name="update-strategy" type="TplaceholderUpdateStrategyType" use="optional" default="none"/>
+                <xsd:attributeGroup ref="extAttributes" />
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TplaceholderUpdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="reload"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!-- #### is this the correct type here?  This is defining placeholder properties,
+         so should this be a restricted set of value types or should this be expanded to
+         all of the elements you can inject into a bean property? -->
+    <xsd:complexType name="TdefaultProperties">
+        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+            <xsd:element name="property" type="bp:Tproperty"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:attributeGroup name="extAttributes">
+        <xsd:attribute ref="ext100:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext110:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext120:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext130:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext140:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext150:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext160:ignore-missing-locations" use="optional" />
+        <xsd:attribute ref="ext100:system-properties" use="optional" />
+        <xsd:attribute ref="ext110:system-properties" use="optional" />
+        <xsd:attribute ref="ext120:system-properties" use="optional" />
+        <xsd:attribute ref="ext130:system-properties" use="optional" />
+        <xsd:attribute ref="ext140:system-properties" use="optional" />
+        <xsd:attribute ref="ext150:system-properties" use="optional" />
+        <xsd:attribute ref="ext160:system-properties" use="optional" />
+    </xsd:attributeGroup>
+
+    <!--  managed-properties  -->
+
+    <xsd:element name="managed-properties" type="TmanagedProperties"/>
+
+    <xsd:complexType name="TmanagedProperties">
+        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
+        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TupdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="component-managed"/>
+            <xsd:enumeration value="container-managed"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!--  managed-service-factory -->
+
+    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
+
+    <xsd:complexType name="TmanagedServiceFactory">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <xsd:group ref="bp:GbaseServiceElements"/>
+                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
+                </xsd:sequence>
+                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
+                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
+                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
+                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
+                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
+                <xsd:anyAttribute namespace="##other" processContents="strict"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="TmanagedComponent">
+        <xsd:group ref="bp:GbeanElements"/>
+        <xsd:attribute name="class" type="bp:Tclass"/>
+        <xsd:attribute name="init-method" type="bp:Tmethod"/>
+        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-ref" type="bp:Tidref"/>
+        <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+
+
+    <!-- cm-properties -->
+
+    <xsd:element name="cm-properties" type="TcmProperties"/>
+
+    <xsd:complexType name="TcmProperties">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+                <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+</xsd:schema>

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java Thu Jan 25 13:04:45 2018
@@ -71,6 +71,7 @@ public abstract class AbstractPropertyPl
 
     private String placeholderPrefix = "${";
     private String placeholderSuffix = "}";
+    private String nullValue = null;
     private Pattern pattern;
 
     private LinkedList<String> processingStack = new LinkedList<String>();
@@ -93,6 +94,14 @@ public abstract class AbstractPropertyPl
         this.placeholderSuffix = placeholderSuffix;
     }
 
+    public String getNullValue() {
+        return nullValue;
+    }
+
+    public void setNullValue(String nullValue) {
+        this.nullValue = nullValue;
+    }
+
     public void process(ComponentDefinitionRegistry registry) throws ComponentDefinitionException {
         try {
              blueprintBundle = (Bundle) ((PassThroughMetadata)registry.getComponentDefinition("blueprintBundle")).getObject();
@@ -446,6 +455,9 @@ public abstract class AbstractPropertyPl
                 matcher.reset(str);
             }
         }
+        if (nullValue != null && nullValue.equals(str)) {
+            return null;
+        }
         return str;
     }
 

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java Thu Jan 25 13:04:45 2018
@@ -88,6 +88,7 @@ public class ExtNamespaceHandler impleme
     public static final String ID_ATTRIBUTE = "id";
     public static final String PLACEHOLDER_PREFIX_ATTRIBUTE = "placeholder-prefix";
     public static final String PLACEHOLDER_SUFFIX_ATTRIBUTE = "placeholder-suffix";
+    public static final String PLACEHOLDER_NULL_VALUE_ATTRIBUTE = "null-value";
     public static final String DEFAULTS_REF_ATTRIBUTE = "defaults-ref";
     public static final String IGNORE_MISSING_LOCATIONS_ATTRIBUTE = "ignore-missing-locations";
     public static final String EVALUATOR_ATTRIBUTE = "evaluator";
@@ -378,6 +379,12 @@ public class ExtNamespaceHandler impleme
                                     ? element.getAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
                                     : "}";
         metadata.addProperty("placeholderSuffix", createValue(context, suffix));
+        String nullValue = element.hasAttribute(PLACEHOLDER_NULL_VALUE_ATTRIBUTE)
+                                    ? element.getAttribute(PLACEHOLDER_NULL_VALUE_ATTRIBUTE)
+                                    : null;
+        if (nullValue != null) {
+            metadata.addProperty("nullValue", createValue(context, nullValue));
+        }
         String defaultsRef = element.hasAttribute(DEFAULTS_REF_ATTRIBUTE) ? element.getAttribute(DEFAULTS_REF_ATTRIBUTE) : null;
         if (defaultsRef != null) {
             metadata.addProperty("defaultProperties", createRef(context, defaultsRef));

Modified: aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd Thu Jan 25 13:04:45 2018
@@ -39,6 +39,7 @@
                 </xsd:sequence>
                 <xsd:attribute default="${" name="placeholder-prefix" type="xsd:string" use="optional"/>
                 <xsd:attribute default="}" name="placeholder-suffix" type="xsd:string" use="optional"/>
+                <xsd:attribute name="null-value" type="xsd:string" use="optional"/>
                 <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
                 <xsd:attribute default="false" name="ignore-missing-locations" type="xsd:boolean" use="optional"/>
                 <xsd:attribute default="fallback" name="system-properties" use="optional">

Modified: aries/trunk/blueprint/itests/blueprint-itests/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/pom.xml?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/pom.xml (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/pom.xml Thu Jan 25 13:04:45 2018
@@ -133,7 +133,7 @@
         <dependency>
             <groupId>org.apache.aries.blueprint</groupId>
             <artifactId>org.apache.aries.blueprint.cm</artifactId>
-            <version>1.1.1-SNAPSHOT</version>
+            <version>1.2.0-SNAPSHOT</version>
             <type>bundle</type>
             <scope>compile</scope>
             <exclusions>

Modified: aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/CmPropertyPlaceholderTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/CmPropertyPlaceholderTest.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/CmPropertyPlaceholderTest.java (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/CmPropertyPlaceholderTest.java Thu Jan 25 13:04:45 2018
@@ -39,6 +39,8 @@ import org.osgi.service.cm.Configuration
 import org.osgi.service.cm.ConfigurationAdmin;
 
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.*;
 import static org.ops4j.pax.exam.CoreOptions.keepCaches;
 import static org.ops4j.pax.exam.CoreOptions.streamBundle;
@@ -85,6 +87,7 @@ public class CmPropertyPlaceholderTest e
         FooInterface foo = (FooInterface)context().getService(sr);
         assertNotNull(foo);
         assertThat(foo.getB(), equalTo("42"));
+        assertThat(foo.getC(), nullValue());
 
         Configuration cf = ca.getConfiguration("blueprint-sample-properties.pid", null);
         Hashtable<String,String> props = new Hashtable<String,String>();

Modified: aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/Foo.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/Foo.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/Foo.java (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/Foo.java Thu Jan 25 13:04:45 2018
@@ -28,6 +28,7 @@ public class Foo implements FooInterface
 
     private int a;
     private String b;
+    private Long c;
     private Properties props;
 
     public int getA() {
@@ -47,6 +48,14 @@ public class Foo implements FooInterface
         b = i;
     }
 
+    public Long getC() {
+        return c;
+    }
+
+    public void setC(Long c) {
+        this.c = c;
+    }
+
     public Properties getProps() {
         return props;
     }

Modified: aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/FooInterface.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/FooInterface.java?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/FooInterface.java (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/cm/service/FooInterface.java Thu Jan 25 13:04:45 2018
@@ -24,6 +24,8 @@ public interface FooInterface {
 
     String getB();
 
+    Long getC();
+
     Properties getProps();
 
 }

Modified: aries/trunk/blueprint/itests/blueprint-itests/src/test/resources/CmPropertyPlaceholderTest.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/src/test/resources/CmPropertyPlaceholderTest.xml?rev=1822200&r1=1822199&r2=1822200&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/src/test/resources/CmPropertyPlaceholderTest.xml (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/src/test/resources/CmPropertyPlaceholderTest.xml Thu Jan 25 13:04:45 2018
@@ -15,20 +15,23 @@
         License.
     -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0">
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0">
 
-    <cm:property-placeholder id="myProps" persistent-id="blueprint-sample-properties.pid" update-strategy="reload">
+    <cm:property-placeholder id="myProps" persistent-id="blueprint-sample-properties.pid" update-strategy="reload"
+                             null-value="#{null}">
         <cm:default-properties>
-            <cm:property name="pb" value="42" />
+            <cm:property name="pb" value="42"/>
+            <cm:property name="pc" value="#{null}"/>
         </cm:default-properties>
     </cm:property-placeholder>
 
     <bean id="foo" class="org.apache.aries.blueprint.itests.cm.service.Foo">
-        <property name="b" value="${pb}" />
+        <property name="b" value="${pb}"/>
+        <property name="c" value="${pc}"/>
     </bean>
     <service id="myService" interface="org.apache.aries.blueprint.itests.cm.service.FooInterface" ref="foo">
         <service-properties>
-            <entry key="key" value="foo5" />
+            <entry key="key" value="foo5"/>
         </service-properties>
     </service>