FELIX-924 configuration policy configurable
FELIX-925 activate and deactivate method names are configurable
FELIX-929 name attributes of component and reference elements are optional
FELIX-930 Add support for DS 1.1 XML schema and namespace
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@784693 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
index ee27ab5..837be55 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -25,6 +25,8 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
import org.osgi.service.component.ComponentException;
import org.osgi.service.log.LogService;
@@ -34,6 +36,22 @@
* This class holds the information associated to a component in the descriptor * */
public class ComponentMetadata
{
+ // Configuration required for component activation (since DS 1.1)
+ public static final String CONFIGURATION_POLICY_REQUIRE = "require";
+
+ // Configuration not provided to component (since DS 1.1)
+ public static final String CONFIGURATION_POLICY_IGNORE = "ignore";
+
+ // Configuration optional (default) (since DS 1.1)
+ public static final String CONFIGURATION_POLICY_OPTIONAL = "optional";
+
+ // set of valid configuration policy settings
+ private static final Set CONFIGURATION_POLICY_VALID;
+
+ // the namespace code of the namespace declaring this component, this is
+ // one of the XmlHandler.DS_VERSION_* constants
+ private final int m_namespaceCode;
+
// 112.4.3: A Globally unique component name (required)
private String m_name;
@@ -43,7 +61,7 @@
// 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
private String m_factory = null;
- // 112.4.3: Controls whether component configurations must be immediately activated after becoming
+ // 112.4.3: Controls whether component configurations must be immediately activated after becoming
// satisfied or whether activation should be delayed. (optional, default value depends
// on whether the component has a service element or not).
private Boolean m_immediate = null;
@@ -51,6 +69,15 @@
// 112.4.4 Implementation Element (required)
private String m_implementationClassName = null;
+ // 112.5.8 activate can be specified (since DS 1.1)
+ private String m_activate = null;
+
+ // 112.5.12 deactivate can be specified (since DS 1.1)
+ private String m_deactivate = null;
+
+ // 112.4.3 configuration-policy (since DS 1.1)
+ private String m_configurationPolicy = null;
+
// Associated properties (0..*)
private Dictionary m_properties = new Hashtable();
@@ -69,11 +96,25 @@
// Flag that is set once the component is verified (its properties cannot be changed)
private boolean m_validated = false;
+ static
+ {
+ CONFIGURATION_POLICY_VALID = new TreeSet();
+ CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_IGNORE );
+ CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_OPTIONAL );
+ CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_REQUIRE );
+ }
+
+
+ public ComponentMetadata( int namespaceCode )
+ {
+ this.m_namespaceCode = namespaceCode;
+ }
+
/////////////////////////////////////////// SETTERS //////////////////////////////////////
/**
* Setter for the name
- *
+ *
* @param name
*/
public void setName( String name )
@@ -88,7 +129,7 @@
/**
* Setter for the enabled property
- *
+ *
* @param enabled
*/
public void setEnabled( boolean enabled )
@@ -102,7 +143,7 @@
/**
- *
+ *
* @param factoryIdentifier
*/
public void setFactoryIdentifier( String factoryIdentifier )
@@ -117,7 +158,7 @@
/**
* Setter for the immediate property
- *
+ *
* @param immediate
*/
public void setImmediate( boolean immediate )
@@ -132,7 +173,7 @@
/**
* Sets the name of the implementation class
- *
+ *
* @param implementationClassName a class name
*/
public void setImplementationClassName( String implementationClassName )
@@ -146,6 +187,54 @@
/**
+ * Sets the configuration policy
+ *
+ * @param configurationPolicy configuration policy
+ * @since 1.2.0 (DS 1.1)
+ */
+ public void setConfigurationPolicy( String configurationPolicy )
+ {
+ if ( m_validated )
+ {
+ return;
+ }
+ m_configurationPolicy = configurationPolicy;
+ }
+
+
+ /**
+ * Sets the name of the activate method
+ *
+ * @param activate a method name
+ * @since 1.2.0 (DS 1.1)
+ */
+ public void setActivate( String activate )
+ {
+ if ( m_validated )
+ {
+ return;
+ }
+ m_activate = activate;
+ }
+
+
+ /**
+ * Sets the name of the deactivate method
+ *
+ * @param deactivate a method name
+ * @since 1.2.0 (DS 1.1)
+ */
+ public void setDeactivate( String deactivate )
+ {
+ if ( m_validated )
+ {
+ return;
+ }
+ m_deactivate = deactivate;
+ }
+
+
+ /**
* Used to add a property to the instance
*
* @param newProperty a property metadata object
@@ -201,9 +290,20 @@
/////////////////////////////////////////// GETTERS //////////////////////////////////////
/**
+ * Returns the namespace code of the namespace of the component element
+ * declaring this component. This is one of the XmlHandler.DS_VERSION_*
+ * constants.
+ */
+ public int getNamespaceCode()
+ {
+ return m_namespaceCode;
+ }
+
+
+ /**
* Returns the name of the component
- *
- * @return A string containing the name of the component
+ *
+ * @return A string containing the name of the component
*/
public String getName()
{
@@ -212,8 +312,8 @@
/**
- * Returns the value of the enabled flag
- *
+ * Returns the value of the enabled flag
+ *
* @return a boolean containing the value of the enabled flag
*/
public boolean isEnabled()
@@ -224,7 +324,7 @@
/**
* Returns the factory identifier
- *
+ *
* @return A string containing a factory identifier or null
*/
public String getFactoryIdentifier()
@@ -242,7 +342,7 @@
* element or the factory attribute is set or true otherwise. This latter
* default value deduction may be unsafe while the descriptor has not been
* completely read.
- *
+ *
* @return a boolean that defines the activation policy
*/
public boolean isImmediate()
@@ -253,7 +353,7 @@
return m_immediate.booleanValue();
}
- // deduce default from service element and factory attribute presence
+ // deduce default from service element and factory attribute presence
return m_service == null && m_factory == null;
}
@@ -270,8 +370,44 @@
/**
+ * Returns the configuration Policy
+ *
+ * @return the configuration policy
+ * @since 1.2.0 (DS 1.1)
+ */
+ public String getConfigurationPolicy()
+ {
+ return m_configurationPolicy;
+ }
+
+
+ /**
+ * Returns the name of the activate method
+ *
+ * @return the name of the activate method
+ * @since 1.2.0 (DS 1.1)
+ */
+ public String getActivate()
+ {
+ return m_activate;
+ }
+
+
+ /**
+ * Returns the name of the deactivate method
+ *
+ * @return the name of the deactivate method
+ * @since 1.2.0 (DS 1.1)
+ */
+ public String getDeactivate()
+ {
+ return m_deactivate;
+ }
+
+
+ /**
* Returns the associated ServiceMetadata
- *
+ *
* @return a ServiceMetadata object or null if the Component does not provide any service
*/
public ServiceMetadata getServiceMetadata()
@@ -292,6 +428,18 @@
/**
+ * Returns the list of property meta data.
+ * <b>Note: This method is intended for unit testing only</b>
+ *
+ * @return the list of property meta data.
+ */
+ List getPropertyMetaData()
+ {
+ return m_propertyMetaData;
+ }
+
+
+ /**
* Returns the dependency descriptors
*
* @return a Collection of dependency descriptors
@@ -327,7 +475,12 @@
// 112.10 The name of the component is required
if ( m_name == null )
{
- throw new ComponentException( "The component name has not been set" );
+ // 112.4.3 name is optional defaulting to implementation class name since DS 1.1
+ if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+ {
+ throw new ComponentException( "The component name has not been set" );
+ }
+ setName( getImplementationClassName() );
}
// 112.10 There must be one implementation element and the class atribute is required
@@ -336,6 +489,49 @@
throw validationFailure( "Implementation class name missing" );
}
+ // 112.4.3 configuration-policy (since DS 1.1)
+ if ( m_configurationPolicy == null )
+ {
+ // default if not specified or pre DS 1.1
+ m_configurationPolicy = CONFIGURATION_POLICY_OPTIONAL;
+ }
+ else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+ {
+ logger.log( LogService.LOG_WARNING, "Ignoring configuration policy, DS 1.1 or later namespace required",
+ this, null );
+ m_configurationPolicy = CONFIGURATION_POLICY_OPTIONAL;
+ }
+ else if ( !CONFIGURATION_POLICY_VALID.contains( m_configurationPolicy ) )
+ {
+ throw validationFailure( "Configuration policy must be one of " + CONFIGURATION_POLICY_VALID );
+ }
+
+ // 112.5.8 activate can be specified (since DS 1.1)
+ if ( m_activate == null )
+ {
+ // default if not specified or pre DS 1.1
+ m_activate = "activate";
+ }
+ else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+ {
+ logger.log( LogService.LOG_WARNING,
+ "Ignoring activate method declaration, DS 1.1 or later namespace required", this, null );
+ m_activate = "activate";
+ }
+
+ // 112.5.12 deactivate can be specified (since DS 1.1)
+ if ( m_deactivate == null )
+ {
+ // default if not specified or pre DS 1.1
+ m_deactivate = "deactivate";
+ }
+ else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+ {
+ logger.log( LogService.LOG_WARNING,
+ "Ignoring deactivate method declaration, DS 1.1 or later namespace required", this, null );
+ m_deactivate = "deactivate";
+ }
+
// Next check if the properties are valid (and extract property values)
Iterator propertyIterator = m_propertyMetaData.iterator();
while ( propertyIterator.hasNext() )
@@ -391,7 +587,7 @@
}
}
- // 112.4.6 The serviceFactory attribute (of a provided service) must not be true if
+ // 112.4.6 The serviceFactory attribute (of a provided service) must not be true if
// the component is a factory component or an immediate component
if ( m_service != null )
{
@@ -409,7 +605,7 @@
/**
* Returns a <code>ComponentException</code> for this compeonent with the
* given explanation for failure.
- *
+ *
* @param reason The explanation for failing to validate this component.
*/
ComponentException validationFailure( String reason )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
index 402528f..2e158a2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
@@ -18,12 +18,39 @@
*/
package org.apache.felix.scr.impl;
+import java.util.Set;
+import java.util.TreeSet;
+
/**
* Information associated to a dependency
*
*/
public class ReferenceMetadata
{
+ // constant for option single reference - 0..1
+ public static final String CARDINALITY_0_1 = "0..1";
+
+ // constant for option multiple reference - 0..n
+ public static final String CARDINALITY_0_N = "0..n";
+
+ // constant for required single reference - 1..1
+ public static final String CARDINALITY_1_1 = "1..1";
+
+ // constant for required multiple reference - 1..n
+ public static final String CARDINALITY_1_N = "1..n";
+
+ // set of valid cardinality settings
+ private static final Set CARDINALITY_VALID;
+
+ // constant for static policy
+ public static final String POLICY_STATIC = "static";
+
+ // constant for dynamic policy
+ public static final String POLICY_DYNAMIC = "dynamic";
+
+ // set of valid policy settings
+ private static final Set POLICY_VALID;
+
// Name for the reference (required)
private String m_name = null;
@@ -31,7 +58,7 @@
private String m_interface = null;
// Cardinality (optional, default="1..1")
- private String m_cardinality = "1..1";
+ private String m_cardinality = null;
// Target (optional)
private String m_target;
@@ -43,7 +70,7 @@
private String m_unbind = null;
// Policy attribute (optional, default = static)
- private String m_policy = "static";
+ private String m_policy = null;
// Flag that is set once the component is verified (its properties cannot be changed)
private boolean m_validated = false;
@@ -53,6 +80,19 @@
private boolean m_isOptional = false;
private boolean m_isMultiple = false;
+ static
+ {
+ CARDINALITY_VALID = new TreeSet();
+ CARDINALITY_VALID.add( CARDINALITY_0_1 );
+ CARDINALITY_VALID.add( CARDINALITY_0_N );
+ CARDINALITY_VALID.add( CARDINALITY_1_1 );
+ CARDINALITY_VALID.add( CARDINALITY_1_N );
+
+ POLICY_VALID = new TreeSet();
+ POLICY_VALID.add( POLICY_DYNAMIC );
+ POLICY_VALID.add( POLICY_STATIC );
+ }
+
/////////////////////////////////////////////// setters ///////////////////////////////////
@@ -103,20 +143,9 @@
m_cardinality = cardinality;
- if ( !m_cardinality.equals( "0..1" ) && !m_cardinality.equals( "0..n" ) && !m_cardinality.equals( "1..1" )
- && !m_cardinality.equals( "1..n" ) )
- {
- throw new IllegalArgumentException(
- "Cardinality should take one of the following values: 0..1, 0..n, 1..1, 1..n" );
- }
- if ( m_cardinality.equals( "0..1" ) || m_cardinality.equals( "0..n" ) )
- {
- m_isOptional = true;
- }
- if ( m_cardinality.equals( "0..n" ) || m_cardinality.equals( "1..n" ) )
- {
- m_isMultiple = true;
- }
+ // secondary properties
+ m_isOptional = CARDINALITY_0_1.equals( cardinality ) || CARDINALITY_0_N.equals( cardinality );
+ m_isMultiple = CARDINALITY_0_N.equals( cardinality ) || CARDINALITY_1_N.equals( cardinality );
}
@@ -132,16 +161,10 @@
return;
}
- if ( !m_policy.equals( "static" ) && !m_policy.equals( "dynamic" ) )
- {
- throw new IllegalArgumentException( "Policy must be either 'static' or 'dynamic'" );
- }
- if ( policy.equals( "static" ) == false )
- {
- m_isStatic = false;
- }
-
m_policy = policy;
+
+ // secondary property
+ m_isStatic = POLICY_STATIC.equals( policy );
}
@@ -330,13 +353,37 @@
{
if ( m_name == null )
{
- throw componentMetadata.validationFailure( "A name must be declared for the reference" );
+ // 112.10 name attribute is optional, defaults to interface since DS 1.1
+ if ( componentMetadata.getNamespaceCode() < XmlHandler.DS_VERSION_1_1 )
+ {
+ throw componentMetadata.validationFailure( "A name must be declared for the reference" );
+ }
+ setName( getInterface() );
}
if ( m_interface == null )
{
throw componentMetadata.validationFailure( "An interface must be declared for the reference" );
}
+
+
+ if ( m_cardinality == null )
+ {
+ setCardinality( CARDINALITY_1_1 );
+ }
+ else if ( !CARDINALITY_VALID.contains( m_cardinality ) )
+ {
+ throw componentMetadata.validationFailure( "Cardinality must be one of " + CARDINALITY_VALID );
+ }
+
+ if ( m_policy == null )
+ {
+ setPolicy( POLICY_STATIC );
+ }
+ else if ( !POLICY_VALID.contains( m_policy ) )
+ {
+ throw componentMetadata.validationFailure( "Policy must be one of " + POLICY_VALID );
+ }
}
}
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
index b144734..9b537f7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
@@ -37,8 +37,27 @@
public class XmlHandler implements KXml2SAXHandler
{
- public static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/scr/v1.0.0";
+ // Empty Namespace URI maps to DS 1.0
+ public static final String NAMESPACE_URI_EMPTY = "";
+ // Namespace URI of DS 1.0
+ public static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/scr/v1.0.0";
+
+ // Namespace URI of DS 1.1
+ public static final String NAMESPACE_URI_1_1 = "http://www.osgi.org/xmlns/scr/v1.1.0";
+
+ // namespace code for non-DS namespace
+ public static final int DS_VERSION_NONE = -1;
+
+ // namespace code for the DS 1.0 specification
+ public static final int DS_VERSION_1_0 = 0;
+
+ // namespace code for the DS 1.0 specification
+ public static final int DS_VERSION_1_1 = 1;
+
+ // mapping of namespace URI to namespace code
+ private static final Map NAMESPACE_CODE_MAP;
+
// the bundle containing the XML resource being parsed
private final Bundle m_bundle;
@@ -66,6 +85,14 @@
/** Flag for elements inside a component element */
protected boolean isComponent = false;
+ static
+ {
+ NAMESPACE_CODE_MAP = new HashMap();
+ NAMESPACE_CODE_MAP.put( NAMESPACE_URI_EMPTY, new Integer( DS_VERSION_1_0 ) );
+ NAMESPACE_CODE_MAP.put( NAMESPACE_URI, new Integer( DS_VERSION_1_0 ) );
+ NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1, new Integer( DS_VERSION_1_1 ) );
+ }
+
// creates an instance with the bundle owning the component descriptor
// file parsed by this instance
@@ -111,8 +138,10 @@
uri = NAMESPACE_URI;
}
+ // get the namespace code for the namespace uri
+ Integer namespaceCode = (Integer) NAMESPACE_CODE_MAP.get( uri );
// from now on uri points to the namespace
- if ( NAMESPACE_URI.equals( uri ) )
+ if ( namespaceCode != null )
{
try
{
@@ -123,10 +152,13 @@
this.isComponent = true;
// Create a new ComponentMetadata
- m_currentComponent = new ComponentMetadata();
+ m_currentComponent = new ComponentMetadata( namespaceCode.intValue() );
- // name attribute is mandatory
- m_currentComponent.setName( attrib.getProperty( "name" ) );
+ // name attribute is optional (since DS 1.1)
+ if ( attrib.getProperty( "name" ) != null )
+ {
+ m_currentComponent.setName( attrib.getProperty( "name" ) );
+ }
// enabled attribute is optional
if ( attrib.getProperty( "enabled" ) != null )
@@ -146,6 +178,24 @@
m_currentComponent.setFactoryIdentifier( attrib.getProperty( "factory" ) );
}
+ // configuration-policy is optional (since DS 1.1)
+ if ( attrib.getProperty( "configuration-policy" ) != null )
+ {
+ m_currentComponent.setConfigurationPolicy( attrib.getProperty( "configuration-policy" ) );
+ }
+
+ // activate attribute is optional (since DS 1.1)
+ if ( attrib.getProperty( "activate" ) != null )
+ {
+ m_currentComponent.setActivate( attrib.getProperty( "activate" ) );
+ }
+
+ // deactivate attribute is optional (since DS 1.1)
+ if ( attrib.getProperty( "deactivate" ) != null )
+ {
+ m_currentComponent.setDeactivate( attrib.getProperty( "deactivate" ) );
+ }
+
// Add this component to the list
m_components.add( m_currentComponent );
}
@@ -210,7 +260,13 @@
else if ( localName.equals( "reference" ) )
{
ReferenceMetadata ref = new ReferenceMetadata();
- ref.setName( attrib.getProperty( "name" ) );
+
+ // name attribute is optional (since DS 1.1)
+ if ( attrib.getProperty( "name" ) != null )
+ {
+ ref.setName( attrib.getProperty( "name" ) );
+ }
+
ref.setInterface( attrib.getProperty( "interface" ) );
// Cardinality
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
index 2e79705..3d2bad8 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
@@ -27,7 +27,7 @@
public class ComponentMetadataTest extends TestCase
{
- private TestLogger logger = new TestLogger();
+ private MockLogger logger = new MockLogger();
// test various combinations of component metadata with respect to
@@ -243,27 +243,230 @@
}
- public void testReference()
+ public void test_component_no_name_ds10()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+ cm1.setName( null );
+ try
+ {
+ cm1.validate( logger );
+ fail( "Expected validation failure for DS 1.0 component without name" );
+ }
+ catch ( ComponentException ce )
+ {
+ // expected
+ }
+ }
+
+
+ public void test_component_no_name_ds11()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+ cm1.setName( null );
+ cm1.validate( logger );
+ assertEquals( "Expected name to equal implementation class name", cm1.getImplementationClassName(), cm1
+ .getName() );
+ }
+
+
+ public void test_component_activate_ds10()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Activate method name", "activate", cm1.getActivate() );
+
+ final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+ cm2.setActivate( "someMethod" );
+ cm2.validate( logger );
+ assertEquals( "Activate method name", "activate", cm2.getActivate() );
+ }
+
+
+ public void test_component_activate_ds11()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Activate method name", "activate", cm1.getActivate() );
+
+ final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+ cm2.setActivate( "someMethod" );
+ cm2.validate( logger );
+ assertEquals( "Activate method name", "someMethod", cm2.getActivate() );
+ }
+
+
+ public void test_component_deactivate_ds10()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Deactivate method name", "deactivate", cm1.getDeactivate() );
+
+ final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+ cm2.setActivate( "someMethod" );
+ cm2.validate( logger );
+ assertEquals( "Deactivate method name", "deactivate", cm2.getDeactivate() );
+ }
+
+
+ public void test_component_deactivate_ds11()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Deactivate method name", "deactivate", cm1.getDeactivate() );
+
+ final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+ cm2.setDeactivate( "someMethod" );
+ cm2.validate( logger );
+ assertEquals( "Deactivate method name", "someMethod", cm2.getDeactivate() );
+ }
+
+
+ public void test_component_configuration_policy_ds10()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm1
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+ cm2.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_IGNORE );
+ cm2.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm2
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm3 = createComponentMetadata( Boolean.TRUE, null );
+ cm3.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL );
+ cm3.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm3
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm4 = createComponentMetadata( Boolean.TRUE, null );
+ cm4.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_REQUIRE );
+ cm4.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm4
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm5 = createComponentMetadata( Boolean.TRUE, null );
+ cm5.setConfigurationPolicy( "undefined" );
+ cm5.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm5
+ .getConfigurationPolicy() );
+ }
+
+
+ public void test_component_configuration_policy_ds11()
+ {
+ final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+ cm1.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm1
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+ cm2.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_IGNORE );
+ cm2.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_IGNORE, cm2
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm3 = createComponentMetadata11( Boolean.TRUE, null );
+ cm3.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL );
+ cm3.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm3
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm4 = createComponentMetadata11( Boolean.TRUE, null );
+ cm4.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_REQUIRE );
+ cm4.validate( logger );
+ assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_REQUIRE, cm4
+ .getConfigurationPolicy() );
+
+ final ComponentMetadata cm5 = createComponentMetadata11( Boolean.TRUE, null );
+ cm5.setConfigurationPolicy( "undefined" );
+ try
+ {
+ cm5.validate( logger );
+ fail( "Expected validation failure due to undefined configuration policy" );
+ }
+ catch ( ComponentException ce )
+ {
+ // expected due to undefned configuration policy
+ }
+ }
+
+
+ public void test_reference_valid()
{
// two references, should validate
final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
cm1.addDependency( createReferenceMetadata( "name1" ) );
cm1.addDependency( createReferenceMetadata( "name2" ) );
cm1.validate( logger );
+ }
- // two references, must warn
+
+ public void test_reference_duplicate_name()
+ {
+ // two references with same name, must warn
final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
cm2.addDependency( createReferenceMetadata( "name1" ) );
cm2.addDependency( createReferenceMetadata( "name1" ) );
cm2.validate( logger );
- assertTrue( "Expected warning for duplicate reference name", logger.lastMessage != null
- && logger.lastMessage.indexOf( "Detected duplicate reference name" ) >= 0 );
+ assertTrue( "Expected warning for duplicate reference name", logger
+ .messageContains( "Detected duplicate reference name" ) );
}
+ public void test_reference_no_name_ds10()
+ {
+ // un-named reference, illegal for pre DS 1.1
+ final ComponentMetadata cm3 = createComponentMetadata( Boolean.TRUE, null );
+ cm3.addDependency( createReferenceMetadata( null ) );
+ try
+ {
+ cm3.validate( logger );
+ fail( "Expect validation failure for DS 1.0 reference without name" );
+ }
+ catch ( ComponentException ce )
+ {
+ // expected
+ }
+ }
+
+
+ public void test_reference_no_name_ds11()
+ {
+ // un-named reference, illegal for DS 1.1
+ final ComponentMetadata cm4 = createComponentMetadata11( Boolean.TRUE, null );
+ final ReferenceMetadata rm4 = createReferenceMetadata( null );
+ cm4.addDependency( rm4 );
+ cm4.validate( logger );
+ assertEquals( "Reference name defaults to interface", rm4.getInterface(), rm4.getName() );
+ }
+
+
+ //---------- Helper methods
+
+ // Creates DS 1.0 Component Metadata
private ComponentMetadata createComponentMetadata( Boolean immediate, String factory )
{
- ComponentMetadata meta = new ComponentMetadata();
+ ComponentMetadata meta = new ComponentMetadata( XmlHandler.DS_VERSION_1_0 );
+ meta.setName( "place.holder" );
+ meta.setImplementationClassName( "place.holder.implementation" );
+ if ( immediate != null )
+ {
+ meta.setImmediate( immediate.booleanValue() );
+ }
+ if ( factory != null )
+ {
+ meta.setFactoryIdentifier( factory );
+ }
+ return meta;
+ }
+
+
+ // Creates DS 1.1 Component Metadata
+ private ComponentMetadata createComponentMetadata11( Boolean immediate, String factory )
+ {
+ ComponentMetadata meta = new ComponentMetadata( XmlHandler.DS_VERSION_1_1 );
meta.setName( "place.holder" );
meta.setImplementationClassName( "place.holder.implementation" );
if ( immediate != null )
@@ -297,15 +500,4 @@
meta.setInterface( "place.holder" );
return meta;
}
-
- private static class TestLogger implements Logger
- {
- String lastMessage;
-
-
- public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
- {
- lastMessage = message;
- }
- }
}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java b/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java
new file mode 100644
index 0000000..ddc18eb
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java
@@ -0,0 +1,166 @@
+/*
+ * 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.felix.scr.impl;
+
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+
+public class MockBundle implements Bundle
+{
+
+ public Enumeration findEntries( String arg0, String arg1, boolean arg2 )
+ {
+ return null;
+ }
+
+
+ public BundleContext getBundleContext()
+ {
+ return null;
+ }
+
+
+ public long getBundleId()
+ {
+ return 0;
+ }
+
+
+ public URL getEntry( String name )
+ {
+ return getClass().getClassLoader().getResource( name );
+ }
+
+
+ public Enumeration getEntryPaths( String arg0 )
+ {
+ return null;
+ }
+
+
+ public Dictionary getHeaders()
+ {
+ return null;
+ }
+
+
+ public Dictionary getHeaders( String arg0 )
+ {
+ return null;
+ }
+
+
+ public long getLastModified()
+ {
+ return 0;
+ }
+
+
+ public String getLocation()
+ {
+ return "test:mockbundle";
+ }
+
+
+ public ServiceReference[] getRegisteredServices()
+ {
+ return null;
+ }
+
+
+ public URL getResource( String arg0 )
+ {
+ return null;
+ }
+
+
+ public Enumeration getResources( String arg0 )
+ {
+ return null;
+ }
+
+
+ public ServiceReference[] getServicesInUse()
+ {
+ return null;
+ }
+
+
+ public int getState()
+ {
+ return 0;
+ }
+
+
+ public String getSymbolicName()
+ {
+ return null;
+ }
+
+
+ public boolean hasPermission( Object arg0 )
+ {
+ return false;
+ }
+
+
+ public Class loadClass( String arg0 )
+ {
+ return null;
+ }
+
+
+ public void start()
+ {
+
+ }
+
+
+ public void stop()
+ {
+
+ }
+
+
+ public void uninstall()
+ {
+
+ }
+
+
+ public void update()
+ {
+
+ }
+
+
+ public void update( InputStream arg0 )
+ {
+
+ }
+
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java b/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java
new file mode 100644
index 0000000..3bf9061
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java
@@ -0,0 +1,37 @@
+/*
+ * 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.felix.scr.impl;
+
+
+public class MockLogger implements Logger
+{
+ String lastMessage;
+
+
+ public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
+ {
+ lastMessage = message;
+ }
+
+
+ public boolean messageContains( String value )
+ {
+ return lastMessage != null && lastMessage.indexOf( value ) >= 0;
+ }
+}
\ No newline at end of file
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java
new file mode 100644
index 0000000..c823a70
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.felix.scr.impl;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.impl.parser.KXml2SAXParser;
+import org.osgi.service.component.ComponentException;
+import org.xmlpull.v1.XmlPullParserException;
+
+
+public class XmlHandlerTest extends TestCase
+{
+ private MockLogger logger;
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ logger = new MockLogger();
+ }
+
+
+ public void test_component_attributes_11() throws Exception
+ {
+ final List metadataList10 = readMetadata( "/components_activate_10.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList10.size() );
+
+ final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+ cm10.validate( logger );
+ assertEquals( "DS Version 1.0", XmlHandler.DS_VERSION_1_0, cm10.getNamespaceCode() );
+ assertEquals( "Expected Activate Method not set", "activate", cm10.getActivate() );
+ assertEquals( "Expected Deactivate Method not set", "deactivate", cm10.getDeactivate() );
+ assertEquals( "Expected Configuration Policy not set", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm10
+ .getConfigurationPolicy() );
+
+ final List metadataList11 = readMetadata( "/components_activate_11.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList11.size() );
+ final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+ cm11.validate( logger );
+ assertEquals( "DS Version 1.1", XmlHandler.DS_VERSION_1_1, cm11.getNamespaceCode() );
+ assertEquals( "Expected Activate Method set", "myactivate", cm11.getActivate() );
+ assertEquals( "Expected Deactivate Method set", "mydeactivate", cm11.getDeactivate() );
+ assertEquals( "Expected Configuration Policy set", ComponentMetadata.CONFIGURATION_POLICY_IGNORE, cm11
+ .getConfigurationPolicy() );
+ }
+
+
+ public void test_component_no_name() throws Exception
+ {
+ final List metadataList10 = readMetadata( "/components_anonymous_10.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList10.size() );
+ final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+ try
+ {
+ cm10.validate( logger );
+ fail( "Expected validation failure for component without name" );
+ }
+ catch ( ComponentException ce )
+ {
+ // expected !!
+ }
+
+ final List metadataList11 = readMetadata( "/components_anonymous_11.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList11.size() );
+ final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+ cm11.validate( logger );
+ assertEquals( "Expected name equals class", cm11.getImplementationClassName(), cm11.getName() );
+ }
+
+
+ public void test_reference_no_name() throws Exception
+ {
+ final List metadataList10 = readMetadata( "/components_anonymous_10.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList10.size() );
+ final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+ try
+ {
+ cm10.validate( logger );
+ fail( "Expected validation failure for component without name" );
+ }
+ catch ( ComponentException ce )
+ {
+ // expected !!
+ }
+
+ final List metadataList11 = readMetadata( "/components_anonymous_11.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList11.size() );
+ final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+ cm11.validate( logger );
+ assertEquals( "Expected name equals class", cm11.getImplementationClassName(), cm11.getName() );
+ }
+
+
+ public void test_all_elements_10() throws Exception
+ {
+ final List metadataList10 = readMetadata( "/components_all_elements_10.xml" );
+ assertEquals( "Component Descriptors", 1, metadataList10.size() );
+ final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+
+ // dont validate this, we test the raw reading
+
+ // ds namespace
+ assertEquals( "ds name space", XmlHandler.DS_VERSION_1_0, cm10.getNamespaceCode() );
+
+ // base component attributes
+ assertEquals( "component name", true, cm10.isEnabled() );
+ assertEquals( "component name", "components.all.name", cm10.getName() );
+ assertEquals( "component name", "components.all.factory", cm10.getFactoryIdentifier() );
+ assertEquals( "component name", true, cm10.isFactory() );
+ assertEquals( "component name", true, cm10.isImmediate() );
+
+ // ds 1.1 elements
+ assertEquals( "activate method", "myactivate", cm10.getActivate() );
+ assertEquals( "deactivate method", "mydeactivate", cm10.getDeactivate() );
+ assertEquals( "configuration policy", "ignore", cm10.getConfigurationPolicy() );
+
+ // from the implementation element
+ assertEquals( "component name", "components.all.impl", cm10.getImplementationClassName() );
+
+ // property setting
+ final PropertyMetadata prop = getPropertyMetadata( cm10, "prop" );
+ assertNotNull( "prop exists", prop );
+ assertEquals( "prop type", "Integer", prop.getType() );
+ assertEquals( "prop value", 1234, ( ( Integer ) prop.getValue() ).intValue() );
+
+ final PropertyMetadata file_property = getPropertyMetadata( cm10, "file.property" );
+ assertNotNull( "file.property exists", file_property );
+ assertEquals( "file.property type", "String", file_property.getType() );
+ assertEquals( "file.property value", "Property from File", file_property.getValue() );
+
+ // service setup
+ final ServiceMetadata sm = cm10.getServiceMetadata();
+ assertNotNull( "service", sm );
+ assertEquals( "servicefactory", true, sm.isServiceFactory() );
+ assertEquals( "1 interface", 1, sm.getProvides().length );
+ assertEquals( "service interface", "components.all.service", sm.getProvides()[0] );
+
+ // references - basic
+ final ReferenceMetadata rm = getReference( cm10, "ref.name" );
+ assertNotNull( "refeference ref.name", rm );
+ assertEquals( "ref.name name", "ref.name", rm.getName() );
+ assertEquals( "ref.name interface", "ref.service", rm.getInterface() );
+ assertEquals( "ref.name cardinality", "0..n", rm.getCardinality() );
+ assertEquals( "ref.name policy", "dynamic", rm.getPolicy() );
+ assertEquals( "ref.name target", "ref.target", rm.getTarget() );
+ assertEquals( "ref.name target prop name", "ref.name.target", rm.getTargetPropertyName() );
+ assertEquals( "ref.name bind method", "ref_bind", rm.getBind() );
+ assertEquals( "ref.name undbind method", "ref_unbind", rm.getUnbind() );
+
+ // references - cardinality side properties (isOptional, isMultiple)
+ final ReferenceMetadata rm01 = getReference( cm10, "ref.01" );
+ assertNotNull( "refeference ref.01", rm01 );
+ assertEquals( "ref.01 cardinality", "0..1", rm01.getCardinality() );
+ final ReferenceMetadata rm11 = getReference( cm10, "ref.11" );
+ assertNotNull( "refeference ref.11", rm11 );
+ assertEquals( "ref.11 cardinality", "1..1", rm11.getCardinality() );
+ final ReferenceMetadata rm0n = getReference( cm10, "ref.0n" );
+ assertNotNull( "refeference ref.0n", rm0n );
+ assertEquals( "ref.0n cardinality", "0..n", rm0n.getCardinality() );
+ final ReferenceMetadata rm1n = getReference( cm10, "ref.1n" );
+ assertNotNull( "refeference ref.1n", rm1n );
+ assertEquals( "ref.1n cardinality", "1..n", rm1n.getCardinality() );
+ }
+
+
+ //---------- helper
+
+ private List readMetadata( String filename ) throws IOException, ComponentException, XmlPullParserException,
+ Exception
+ {
+ BufferedReader in = new BufferedReader( new InputStreamReader( getClass().getResourceAsStream( filename ),
+ "UTF-8" ) );
+ final KXml2SAXParser parser = new KXml2SAXParser( in );
+
+ XmlHandler handler = new XmlHandler( new MockBundle(), logger );
+ parser.parseXML( handler );
+
+ return handler.getComponentMetadataList();
+ }
+
+
+ private ReferenceMetadata getReference( final ComponentMetadata cm, final String name )
+ {
+ List rmlist = cm.getDependencies();
+ for ( Iterator rmi = rmlist.iterator(); rmi.hasNext(); )
+ {
+ ReferenceMetadata rm = ( ReferenceMetadata ) rmi.next();
+ if ( name.equals( rm.getName() ) )
+ {
+ return rm;
+ }
+ }
+
+ // none found
+ return null;
+ }
+
+
+ private PropertyMetadata getPropertyMetadata( final ComponentMetadata cm, final String name )
+ {
+ List pmlist = cm.getPropertyMetaData();
+ for ( Iterator pmi = pmlist.iterator(); pmi.hasNext(); )
+ {
+ PropertyMetadata pm = ( PropertyMetadata ) pmi.next();
+ if ( name.equals( pm.getName() ) )
+ {
+ return pm;
+ }
+ }
+
+ // none found
+ return null;
+ }
+}
diff --git a/scr/src/test/resources/components_activate_10.xml b/scr/src/test/resources/components_activate_10.xml
new file mode 100644
index 0000000..2c754b5
--- /dev/null
+++ b/scr/src/test/resources/components_activate_10.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components>
+ <scr:component name="components.activate.10"
+ activate="myactivate" deactivate="mydeactivate"
+ configuration-policy="ignore" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <implementation class="components.activate.10" />
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_activate_11.xml b/scr/src/test/resources/components_activate_11.xml
new file mode 100644
index 0000000..b046ea6
--- /dev/null
+++ b/scr/src/test/resources/components_activate_11.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components>
+ <scr:component name="components.activate.11"
+ activate="myactivate" deactivate="mydeactivate"
+ configuration-policy="ignore" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <implementation class="components.activate.11" />
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_all_elements_10.properties b/scr/src/test/resources/components_all_elements_10.properties
new file mode 100644
index 0000000..da7d322
--- /dev/null
+++ b/scr/src/test/resources/components_all_elements_10.properties
@@ -0,0 +1,20 @@
+# 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.
+#
+# Sample properties file for the metadate load test
+
+file.property = Property from File
\ No newline at end of file
diff --git a/scr/src/test/resources/components_all_elements_10.xml b/scr/src/test/resources/components_all_elements_10.xml
new file mode 100644
index 0000000..0587053
--- /dev/null
+++ b/scr/src/test/resources/components_all_elements_10.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<!--
+
+ This file has a component descriptor with values for all elements
+ and attributes defined in the Declarative Services XML Schema for
+ the Declarative Services Specification 1.0.
+
+ The goal of this file is to test the XML parsing whether all elements
+ are read and stored in the metadata objects and fields. Semantic
+ correctness according to the specificiation is not tested.
+ -->
+
+<components>
+ <!--
+ component element with
+ * DS 1.0 namespace (sets the ds namespace code)
+ * DS 1.0 attributes
+ * DS 1.1 attributes (must be read)
+ -->
+ <scr:component
+ xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0"
+
+ enabled="true"
+ name="components.all.name"
+ factory="components.all.factory"
+ immediate="true"
+
+ activate="myactivate"
+ deactivate="mydeactivate"
+ configuration-policy="ignore"
+ >
+
+ <implementation class="components.all.impl" />
+
+ <property
+ name="prop"
+ value="1234"
+ type="Integer"
+ />
+
+ <properties
+ entry="components_all_elements_10.properties"
+ />
+
+ <service
+ servicefactory="true"
+ >
+ <provide
+ interface="components.all.service"
+ />
+ </service>
+
+ <!-- Basic reference testing reading -->
+ <reference
+ name="ref.name"
+ interface="ref.service"
+ cardinality="0..n"
+ policy="dynamic"
+ target="ref.target"
+ bind="ref_bind"
+ unbind="ref_unbind"
+ />
+
+ <!--
+ references testing the setting of secondary properties
+ isStatic, isMultiple and isOptional
+ -->
+ <reference name="ref.01" cardinality="0..1" />
+ <reference name="ref.11" cardinality="1..1" />
+ <reference name="ref.0n" cardinality="0..n" />
+ <reference name="ref.1n" cardinality="1..n" />
+ <reference name="ref.static" policy="static" />
+ <reference name="ref.dynamic" policy="dynamic" />
+
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_anonymous_10.xml b/scr/src/test/resources/components_anonymous_10.xml
new file mode 100644
index 0000000..0627e5a
--- /dev/null
+++ b/scr/src/test/resources/components_anonymous_10.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <scr:component enabled="true" immediate="true">
+ <implementation class="components.anonymous.10" />
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_anonymous_11.xml b/scr/src/test/resources/components_anonymous_11.xml
new file mode 100644
index 0000000..5254df9
--- /dev/null
+++ b/scr/src/test/resources/components_anonymous_11.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <scr:component enabled="true" immediate="true">
+ <implementation class="components.anonymous.11" />
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/reference_anonymous_10.xml b/scr/src/test/resources/reference_anonymous_10.xml
new file mode 100644
index 0000000..c1d68ea
--- /dev/null
+++ b/scr/src/test/resources/reference_anonymous_10.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+ <scr:component enabled="true" immediate="true"
+ name="reference.anonymous.10">
+ <implementation class="reference.anonymous.10" />
+ <reference interface="ref.anon" />
+ </scr:component>
+</components>
diff --git a/scr/src/test/resources/reference_anonymous_11.xml b/scr/src/test/resources/reference_anonymous_11.xml
new file mode 100644
index 0000000..11a5bf4
--- /dev/null
+++ b/scr/src/test/resources/reference_anonymous_11.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <scr:component enabled="true" immediate="true"
+ name="reference.anonymous.10">
+ <implementation class="reference.anonymous.10" />
+ <reference interface="ref.anon" />
+ </scr:component>
+</components>