You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by no...@apache.org on 2011/02/17 15:44:50 UTC

svn commit: r1071628 - in /aries/trunk/blueprint: blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ blueprint-core/src/main/java/org/apache/aries/blueprint/ blueprint-core/src/main/java/org/apache/aries/blueprint/container/ blueprint...

Author: not
Date: Thu Feb 17 14:44:49 2011
New Revision: 1071628

URL: http://svn.apache.org/viewvc?rev=1071628&view=rev
Log:
ARIES-577 Add support for ext:default on a reference element so if the availability is optional you
can wire to a default implementation if no service is present, making everything simple to write
optional services where you want a default implementation that can be overridden.

Added:
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java   (with props)
    aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd   (with props)
    aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java   (with props)
Modified:
    aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java
    aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml
    aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestReferences.java
    aries/trunk/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml

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=1071628&r1=1071627&r2=1071628&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 Feb 17 14:44:49 2011
@@ -210,13 +210,11 @@ public class CmNamespaceHandler implemen
         if (defaultsRef != null) {
             metadata.addProperty("defaultProperties", createRef(context, defaultsRef));
         }
-        String ignoreMissingLocations = element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE)
-                ? element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE) : null;
+        String ignoreMissingLocations = extractIgnoreMissingLocations(element);
         if (ignoreMissingLocations != null) {
             metadata.addProperty("ignoreMissingLocations", createValue(context, ignoreMissingLocations));
         }
-        String systemProperties = element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE)
-                ? element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE) : null;
+        String systemProperties = extractSystemPropertiesAttribute(element);
         if (systemProperties == null) {
             systemProperties = ExtNamespaceHandler.SYSTEM_PROPERTIES_NEVER;
         }
@@ -242,7 +240,11 @@ public class CmNamespaceHandler implemen
                         Metadata props = parseDefaultProperties(context, metadata, e);
                         metadata.addProperty("defaultProperties", props);
                     }
-                } else if (ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE.equals(e.getNamespaceURI())) {
+                } else if (ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_0.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, ExtNamespaceHandler.LOCATION_ELEMENT)) {
+                        locations.add(getTextValue(e));
+                    }
+                } else if (ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_1.equals(e.getNamespaceURI())) {
                     if (nodeNameEquals(e, ExtNamespaceHandler.LOCATION_ELEMENT)) {
                         locations.add(getTextValue(e));
                     }
@@ -258,6 +260,27 @@ public class CmNamespaceHandler implemen
         return metadata;
     }
 
+    private String extractSystemPropertiesAttribute(Element element) {
+      String systemProperties = null;
+      
+      if (element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_0, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE)) {
+        systemProperties =  element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_0, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE);
+      } else if (element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_1, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE)) {
+        systemProperties =  element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_1, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE);
+      }
+      return systemProperties;
+    }
+
+    private String extractIgnoreMissingLocations(Element element) {
+      String ignoreMissingLocations = null;
+      if (element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_0, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
+        ignoreMissingLocations = element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_0, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
+      } else if (element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_1, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
+        ignoreMissingLocations = element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE_V1_1, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
+      }
+      return ignoreMissingLocations;
+    }
+
     private Metadata parseDefaultProperties(ParserContext context, MutableBeanMetadata enclosingComponent, Element element) {
         MutableMapMetadata props = context.createMetadata(MutableMapMetadata.class);
         NodeList nl = element.getChildNodes();

Added: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java?rev=1071628&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java (added)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java Thu Feb 17 14:44:49 2011
@@ -0,0 +1,26 @@
+/*
+ * 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.aries.blueprint;
+
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+
+public interface ExtendedReferenceMetadata extends ReferenceMetadata 
+{
+    public String getDefaultBean();
+}
\ No newline at end of file

Propchange: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java Thu Feb 17 14:44:49 2011
@@ -24,6 +24,7 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 
 import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ExtendedReferenceMetadata;
 import org.apache.aries.blueprint.di.Recipe;
 import org.apache.aries.blueprint.di.CollectionRecipe;
 import org.osgi.framework.ServiceReference;
@@ -55,6 +56,7 @@ public class ReferenceRecipe extends Abs
 
     private volatile ServiceReference trackedServiceReference;
     private volatile Object trackedService;
+    private Object defaultBean;
     private final Object monitor = new Object();
 
     public ReferenceRecipe(String name,
@@ -168,21 +170,44 @@ public class ReferenceRecipe extends Abs
                 blueprintContainer.getEventDispatcher().blueprintEvent(new BlueprintEvent(BlueprintEvent.WAITING, blueprintContainer.getBundleContext().getBundle(), blueprintContainer.getExtenderBundle(), new String[] { getOsgiFilter() }));
                 monitor.wait(metadata.getTimeout());
             }
+            Object result = null;
             if (trackedServiceReference == null) {
                 if (isStarted()) {
+                  boolean failed = true;
+                  if (metadata.getAvailability() == ReferenceMetadata.AVAILABILITY_OPTIONAL && 
+                      metadata instanceof ExtendedReferenceMetadata) {
+                     if (defaultBean == null) {
+                         String defaultBeanId = ((ExtendedReferenceMetadata)metadata).getDefaultBean();
+                         if (defaultBeanId != null) {
+                           defaultBean = blueprintContainer.getComponentInstance(defaultBeanId);
+                           failed = false;
+                         }
+                     } else {
+                         failed = false;
+                     }
+                     result = defaultBean;
+                  } 
+                  
+                  if (failed) {
                     LOGGER.info("Timeout expired when waiting for OSGi service {}", getOsgiFilter());
                     throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", getOsgiFilter());
+                  }
                 } else {
                     throw new ServiceUnavailableException("The Blueprint container is being or has been destroyed", getOsgiFilter());
                 }
+            } else {
+            
+              if (trackedService == null) {
+                  trackedService = blueprintContainer.getService(trackedServiceReference);
+              }
+              
+              if (trackedService == null) {
+                  throw new IllegalStateException("getService() returned null for " + trackedServiceReference);
+              }
+              
+              result = trackedService;
             }
-            if (trackedService == null) {
-                trackedService = blueprintContainer.getService(trackedServiceReference);
-            }
-            if (trackedService == null) {
-                throw new IllegalStateException("getService() returned null for " + trackedServiceReference);
-            }
-            return trackedService;
+            return result;
         }
     }
 

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/ExtNamespaceHandler.java Thu Feb 17 14:44:49 2011
@@ -33,6 +33,7 @@ import org.apache.aries.blueprint.mutabl
 import org.apache.aries.blueprint.mutable.MutableIdRefMetadata;
 import org.apache.aries.blueprint.mutable.MutableMapMetadata;
 import org.apache.aries.blueprint.mutable.MutableRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
 import org.apache.aries.blueprint.mutable.MutableServiceReferenceMetadata;
 import org.apache.aries.blueprint.mutable.MutableValueMetadata;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
@@ -44,6 +45,7 @@ import org.osgi.service.blueprint.reflec
 import org.osgi.service.blueprint.reflect.Metadata;
 import org.osgi.service.blueprint.reflect.RefMetadata;
 import org.osgi.service.blueprint.reflect.ReferenceListMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
 import org.osgi.service.blueprint.reflect.ValueMetadata;
 import org.slf4j.Logger;
@@ -64,7 +66,8 @@ import org.w3c.dom.NodeList;
 public class ExtNamespaceHandler implements org.apache.aries.blueprint.NamespaceHandler {
 
     public static final String BLUEPRINT_NAMESPACE = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
-    public static final String BLUEPRINT_EXT_NAMESPACE = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.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 PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
     public static final String DEFAULT_PROPERTIES_ELEMENT = "default-properties";
@@ -92,13 +95,21 @@ public class ExtNamespaceHandler impleme
     public static final String ROLE_PROCESSOR = "processor";
     
     public static final String FIELD_INJECTION_ATTRIBUTE = "field-injection";
+    
+    public static final String DEFAULT_REFERENCE_BEAN = "default";
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ExtNamespaceHandler.class);
 
     private int idCounter;
 
     public URL getSchemaLocation(String namespace) {
-        return getClass().getResource("blueprint-ext.xsd");
+        if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(namespace)) {
+          return getClass().getResource("blueprint-ext.xsd");
+        } else if (BLUEPRINT_EXT_NAMESPACE_V1_1.equals(namespace)) {
+          return getClass().getResource("blueprint-ext-1.1.xsd");
+        } else {
+          return null;
+        }
     }
 
     public Set<Class> getManagedClasses() {
@@ -123,11 +134,29 @@ public class ExtNamespaceHandler impleme
             return decorateRole(node, component, context);
         } else if (node instanceof Attr && nodeNameEquals(node, FIELD_INJECTION_ATTRIBUTE)) {
             return decorateFieldInjection(node, component, context);
+        } else if (node instanceof Attr && nodeNameEquals(node, DEFAULT_REFERENCE_BEAN)) {
+            return decorateDefaultBean(node, component, context);
         } else {
             throw new ComponentDefinitionException("Unsupported node: " + node.getNodeName());
         }
     }
     
+    private ComponentMetadata decorateDefaultBean(Node node,
+        ComponentMetadata component, ParserContext context) 
+    {
+        if (!(component instanceof ReferenceMetadata)) {
+            throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <reference> element");
+        }
+      
+        if (!(component instanceof MutableReferenceMetadata)) {
+            throw new ComponentDefinitionException("Expected an instanceof MutableReferenceMetadata");
+        }
+        
+        String value = ((Attr) node).getValue();
+        ((MutableReferenceMetadata) component).setDefaultBean(value);
+        return component;
+    }
+
     private ComponentMetadata decorateFieldInjection(Node node, ComponentMetadata component, ParserContext context) {
         if (!(component instanceof BeanMetadata)) {
             throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <bean> element");
@@ -225,7 +254,7 @@ public class ExtNamespaceHandler impleme
             Node node = nl.item(i);
             if (node instanceof Element) {
                 Element e = (Element) node;
-                if (BLUEPRINT_EXT_NAMESPACE.equals(e.getNamespaceURI())) {
+                if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(e.getNamespaceURI())) {
                     if (nodeNameEquals(e, DEFAULT_PROPERTIES_ELEMENT)) {
                         if (defaultsRef != null) {
                             throw new ComponentDefinitionException("Only one of " + DEFAULTS_REF_ATTRIBUTE + " attribute or " + DEFAULT_PROPERTIES_ELEMENT + " element is allowed");
@@ -254,7 +283,7 @@ public class ExtNamespaceHandler impleme
             Node node = nl.item(i);
             if (node instanceof Element) {
                 Element e = (Element) node;
-                if (BLUEPRINT_EXT_NAMESPACE.equals(e.getNamespaceURI())) {
+                if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(e.getNamespaceURI())) {
                     if (nodeNameEquals(e, PROPERTY_ELEMENT)) {
                         BeanProperty prop = context.parseElement(BeanProperty.class, enclosingComponent, e);
                         props.addEntry(createValue(context, prop.getName(), String.class.getName()), prop.getValue());

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java Thu Feb 17 14:44:49 2011
@@ -18,15 +18,17 @@
  */
 package org.apache.aries.blueprint.mutable;
 
-import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.apache.aries.blueprint.ExtendedReferenceMetadata;
 
 /**
  * A mutable version of the <code>ReferenceMetadata</code> that allows modifications.
  *
  * @version $Rev$, $Date$
  */
-public interface MutableReferenceMetadata extends ReferenceMetadata, MutableServiceReferenceMetadata {
+public interface MutableReferenceMetadata extends ExtendedReferenceMetadata, MutableServiceReferenceMetadata {
 
     void setTimeout(long timeout);
 
+    void setDefaultBean(String value);
+
 }
\ No newline at end of file

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java Thu Feb 17 14:44:49 2011
@@ -29,6 +29,7 @@ import org.osgi.service.blueprint.reflec
 public class ReferenceMetadataImpl extends ServiceReferenceMetadataImpl implements MutableReferenceMetadata {
 
     private long timeout;
+    private String defaultBeanId;
 
     public ReferenceMetadataImpl() {
     }
@@ -46,6 +47,14 @@ public class ReferenceMetadataImpl exten
         this.timeout = timeout;
     }
 
+    public void setDefaultBean(String defaultBeanId) {
+      this.defaultBeanId = defaultBeanId;
+    }
+
+    public String getDefaultBean() {
+      return defaultBeanId;
+    }
+
     @Override
     public String toString() {
         return "ReferenceMetadata[" +

Modified: aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml Thu Feb 17 14:44:49 2011
@@ -21,7 +21,12 @@
 
     <service interface="org.apache.aries.blueprint.NamespaceHandler">
         <service-properties>
-            <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"/>
+            <entry key="osgi.service.blueprint.namespace">
+              <array>
+                <value>http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0</value>
+                <value>http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0</value>
+              </array>
+            </entry>
         </service-properties>
         <bean class="org.apache.aries.blueprint.ext.ExtNamespaceHandler"/>
     </service>

Added: aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd?rev=1071628&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd (added)
+++ aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd Thu Feb 17 14:44:49 2011
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+    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.
+
+-->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0" version="1.0.0">
+
+    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.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 maxOccurs="1" minOccurs="0" name="default-properties" type="TdefaultProperties"/>
+                    <xsd:element maxOccurs="unbounded" minOccurs="0" name="location" type="xsd:string"/>
+                </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="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">
+                    <xsd:simpleType>
+                        <xsd:restriction base="xsd:NMTOKEN">
+                            <xsd:enumeration value="never"/>
+                            <xsd:enumeration value="fallback"/>
+                            <xsd:enumeration value="override"/>
+                        </xsd:restriction>
+                    </xsd:simpleType>
+                </xsd:attribute>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="TdefaultProperties">
+        <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+            <xsd:element name="property" type="bp:Tproperty"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <!-- proxy method -->
+
+    <xsd:attribute default="default" name="proxy-method">
+        <xsd:simpleType>
+            <xsd:restriction>
+                <xsd:simpleType>
+                    <xsd:list>
+                        <xsd:simpleType>
+                            <xsd:restriction base="xsd:NMTOKEN">
+                                <xsd:enumeration value="default"/>
+                                <xsd:enumeration value="classes"/>
+                                <xsd:enumeration value="greedy"/>
+                            </xsd:restriction>
+                        </xsd:simpleType>
+                    </xsd:list>
+                </xsd:simpleType>
+                <xsd:minLength value="1"/>
+            </xsd:restriction>
+        </xsd:simpleType>
+    </xsd:attribute>
+
+    <!-- role -->
+
+    <xsd:attribute name="role">
+        <xsd:simpleType>
+            <xsd:restriction>
+                <xsd:simpleType>
+                    <xsd:list>
+                        <xsd:simpleType>
+                            <xsd:restriction base="xsd:NMTOKEN">
+                                <xsd:enumeration value="processor"/>
+                            </xsd:restriction>
+                        </xsd:simpleType>
+                    </xsd:list>
+                </xsd:simpleType>
+            </xsd:restriction>
+        </xsd:simpleType>
+    </xsd:attribute>
+
+    <!-- CM property placeholder extenstion -->
+
+    <xsd:element name="location" type="xsd:string"/>
+    <xsd:attribute default="false" name="ignore-missing-locations" type="xsd:boolean"/>
+    <xsd:attribute default="fallback" name="system-properties">
+        <xsd:simpleType>
+            <xsd:restriction base="xsd:NMTOKEN">
+                <xsd:enumeration value="never"/>
+                <xsd:enumeration value="fallback"/>
+                <xsd:enumeration value="override"/>
+            </xsd:restriction>
+        </xsd:simpleType>
+    </xsd:attribute>
+    
+    <xsd:attribute default="false" name="field-injection" type="xsd:boolean"/>
+
+    <!-- Default reference bean -->
+    <xsd:attribute name="default" type="bp:Tidref"/>
+    
+</xsd:schema>

Propchange: aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/blueprint-ext-1.1.xsd
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestReferences.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestReferences.java?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestReferences.java (original)
+++ aries/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/TestReferences.java Thu Feb 17 14:44:49 2011
@@ -31,7 +31,10 @@ import java.util.Hashtable;
 import java.util.List;
 
 import org.apache.aries.blueprint.sample.BindingListener;
+import org.apache.aries.blueprint.sample.DefaultRunnable;
 import org.apache.aries.blueprint.sample.InterfaceA;
+import org.apache.aries.unittest.mocks.MethodCall;
+import org.apache.aries.unittest.mocks.Skeleton;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.Option;
@@ -124,6 +127,34 @@ public class TestReferences extends Abst
         assertEquals("Hello world!", a.hello("world"));
 
     }
+    
+    @Test
+    public void testDefaultReference() throws Exception {
+      BlueprintContainer blueprintContainer = getBlueprintContainerForBundle("org.apache.aries.blueprint.sample");
+      assertNotNull(blueprintContainer);
+
+      Runnable refRunnable = (Runnable) blueprintContainer.getComponentInstance("refWithDefault");
+      DefaultRunnable defaultRunnable = (DefaultRunnable) blueprintContainer.getComponentInstance("defaultRunnable");
+      refRunnable.run();
+      
+      assertEquals("The default runnable was not called", 1, defaultRunnable.getCount());
+      
+      Runnable mockService = Skeleton.newMock(Runnable.class);
+      
+      ServiceRegistration reg = bundleContext.registerService(Runnable.class.getName(), mockService, null);
+      
+      refRunnable.run();
+      
+      assertEquals("The default runnable was called when a service was bound", 1, defaultRunnable.getCount());
+      
+      Skeleton.getSkeleton(mockService).assertCalled(new MethodCall(Runnable.class, "run"));
+      
+      reg.unregister();
+      
+      refRunnable.run();
+      
+      assertEquals("The default runnable was not called", 2, defaultRunnable.getCount());
+    }
 
     @org.ops4j.pax.exam.junit.Configuration
     public static Option[] configuration() {
@@ -146,6 +177,7 @@ public class TestReferences extends Abst
             mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
             mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.sample"),
             mavenBundle("org.osgi", "org.osgi.compendium"),
+            mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit"),
 
 //            org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
 

Added: aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java?rev=1071628&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java (added)
+++ aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java Thu Feb 17 14:44:49 2011
@@ -0,0 +1,35 @@
+/*
+ * 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.aries.blueprint.sample;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class DefaultRunnable implements Runnable 
+{
+  private static AtomicInteger count = new AtomicInteger();
+  public void run() 
+  {
+    count.incrementAndGet();
+  }
+  
+  public int getCount()
+  {
+    return count.get();
+  }
+}
\ No newline at end of file

Propchange: aries/trunk/blueprint/blueprint-sample/src/main/java/org/apache/aries/blueprint/sample/DefaultRunnable.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml?rev=1071628&r1=1071627&r2=1071628&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml (original)
+++ aries/trunk/blueprint/blueprint-sample/src/main/resources/OSGI-INF/blueprint/config.xml Thu Feb 17 14:44:49 2011
@@ -16,7 +16,7 @@
 	-->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
 	xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
-	xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+	xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0"
 	default-availability="optional">
 
 	<type-converters>
@@ -110,6 +110,9 @@
 		<reference-listener bind-method="bind"
 			unbind-method="unbind" ref="bindingListener" />
 	</reference>
+	
+	<reference id="refWithDefault" interface="java.lang.Runnable" ext:default="defaultRunnable" timeout="100" availability="optional"/>
+	<bean id="defaultRunnable" class="org.apache.aries.blueprint.sample.DefaultRunnable"/>
 
 	<bean id="bindingListener" class="org.apache.aries.blueprint.sample.BindingListener" />