[FELIX-4506] [FELIX-4406] [FELIX-4507] Implement felix extension attribute namespace and service scope parsing. Also use extension attribute to turn persistent factory component on
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1591420 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/Component.java b/scr/src/main/java/org/apache/felix/scr/Component.java
index df21574..bca75c0 100644
--- a/scr/src/main/java/org/apache/felix/scr/Component.java
+++ b/scr/src/main/java/org/apache/felix/scr/Component.java
@@ -183,7 +183,10 @@
* the <code>service</code> element. If the component has no service
* element, this method returns <code>false</code>.
*/
+ @Deprecated
boolean isServiceFactory();
+
+ String getServiceScope();
/**
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ScrCommand.java b/scr/src/main/java/org/apache/felix/scr/impl/ScrCommand.java
index 9823ad2..92fd360 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ScrCommand.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ScrCommand.java
@@ -328,8 +328,8 @@
out.print( " " );
out.println( services[i] );
}
- out.print( "Service Type: " );
- out.println( component.isServiceFactory() ? "service factory" : "service" );
+ out.print( "Service Scope: " );
+ out.println( component.getServiceScope() );
}
Reference[] refs = component.getReferences();
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
index f35e022..b921092 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
@@ -33,6 +33,7 @@
import org.apache.felix.scr.impl.manager.SingleComponentManager;
import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager;
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.ServiceMetadata.Scope;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.log.LogService;
@@ -120,11 +121,17 @@
{
throw new IllegalArgumentException( "Cannot create component factory for " + m_componentMetadata.getName() );
}
- else if ( m_componentMetadata.getServiceMetadata() != null && m_componentMetadata.getServiceMetadata().isServiceFactory() )
+ else if ( m_componentMetadata.getServiceScope() == Scope.bundle )
{
manager = new ServiceFactoryComponentManager<S>( m_activator, this, m_componentMetadata, m_componentMethods );
}
+ else if ( m_componentMetadata.getServiceScope() == Scope.prototype )
+ {
+ manager = null;// NYI
+// manager = new ServiceFactoryComponentManager<S>( m_activator, this, m_componentMetadata, m_componentMethods );
+ }
+
else
{
//immediate or delayed
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index 1672a0a..5c1d1e9 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -51,6 +51,7 @@
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.apache.felix.scr.impl.metadata.ServiceMetadata;
+import org.apache.felix.scr.impl.metadata.ServiceMetadata.Scope;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
@@ -165,8 +166,8 @@
if ( metadata.getServiceMetadata() != null )
{
- log( LogService.LOG_DEBUG, "Component {0} Services: servicefactory={1}, services={2}", new Object[]
- { metadata.getName(), Boolean.valueOf( metadata.getServiceMetadata().isServiceFactory() ),
+ log( LogService.LOG_DEBUG, "Component {0} Services: scope={1}, services={2}", new Object[]
+ { metadata.getName(), metadata.getServiceScope(),
Arrays.asList( metadata.getServiceMetadata().getProvides() ) }, null );
}
@@ -714,8 +715,12 @@
public boolean isServiceFactory()
{
- return m_componentMetadata.getServiceMetadata() != null
- && m_componentMetadata.getServiceMetadata().isServiceFactory();
+ return m_componentMetadata.getServiceScope() == Scope.bundle;
+ }
+
+ public String getServiceScope()
+ {
+ return m_componentMetadata.getServiceScope().name();
}
public boolean isFactory()
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index 010454e..b210cdc 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -105,13 +105,12 @@
super( activator, metadata, new ComponentMethods() );
m_componentInstances = new IdentityHashMap<SingleComponentManager<S>, SingleComponentManager<S>>();
m_configuration = new Hashtable<String, Object>();
- m_nonPersistentFactory = true;
}
protected boolean verifyDependencyManagers()
{
- if (m_nonPersistentFactory)
+ if (!getComponentMetadata().isPersistentFactoryComponent())
{
return super.verifyDependencyManagers();
}
@@ -143,7 +142,7 @@
cm.activateInternal( getTrackingCount().get() );
instance = cm.getComponentInstance();
- if ( instance == null || (m_nonPersistentFactory && instance.getInstance() == null) )
+ if ( instance == null || (!getComponentMetadata().isPersistentFactoryComponent() && instance.getInstance() == null) )
{
// activation failed, clean up component manager
cm.dispose( ComponentConstants.DEACTIVATION_REASON_DISPOSED );
@@ -155,7 +154,7 @@
m_componentInstances.put( cm, cm );
}
- if ( !m_nonPersistentFactory )
+ if ( getComponentMetadata().isPersistentFactoryComponent() )
{
instance = new ModifyComponentInstance(cm);
}
@@ -543,7 +542,7 @@
*/
private SingleComponentManager<S> createComponentManager()
{
- return new SingleComponentManager<S>( getActivator(), this, getComponentMetadata(), getComponentMethods(), m_nonPersistentFactory );
+ return new SingleComponentManager<S>( getActivator(), this, getComponentMetadata(), getComponentMethods(), !getComponentMetadata().isPersistentFactoryComponent() );
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
index 7c1ec7e..5a35d8b 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
@@ -29,6 +29,7 @@
import java.util.TreeSet;
import org.apache.felix.scr.impl.helper.Logger;
+import org.apache.felix.scr.impl.metadata.ServiceMetadata.Scope;
import org.osgi.service.component.ComponentException;
import org.osgi.service.log.LogService;
@@ -111,6 +112,12 @@
// List of service references, (required services 0..*)
private List<ReferenceMetadata> m_references = new ArrayList<ReferenceMetadata>();
+
+ private boolean m_configurableServiceProperties;
+ private boolean m_persistentFactoryComponent;
+ private boolean m_deleteCallsModify;
+ private boolean m_obsoleteFactoryComponentFactory;
+ private boolean m_configureWithInterfaces;
// Flag that is set once the component is verified (its properties cannot be changed)
private boolean m_validated = false;
@@ -354,10 +361,51 @@
m_references.add( newReference );
}
+ public void setConfigurableServiceProperties( boolean configurableServiceProperties) {
+ if ( m_validated )
+ {
+ return;
+ }
+ this.m_configurableServiceProperties = configurableServiceProperties;
+ }
+
+ public void setPersistentFactoryComponent(boolean persistentFactoryComponent) {
+ if ( m_validated )
+ {
+ return;
+ }
+ this.m_persistentFactoryComponent = persistentFactoryComponent;
+ }
+
+ public void setDeleteCallsModify(boolean deleteCallsModify) {
+ if ( m_validated )
+ {
+ return;
+ }
+ this.m_deleteCallsModify = deleteCallsModify;
+ }
+
+ public void setObsoleteFactoryComponentFactory( boolean obsoleteFactoryComponentFactory) {
+ if ( m_validated )
+ {
+ return;
+ }
+ this.m_obsoleteFactoryComponentFactory = obsoleteFactoryComponentFactory;
+ }
+
+ public void setConfigureWithInterfaces(boolean configureWithInterfaces) {
+ if ( m_validated )
+ {
+ return;
+ }
+ this.m_configureWithInterfaces = configureWithInterfaces;
+ }
+
+
/////////////////////////////////////////// GETTERS //////////////////////////////////////
- /**
+ /**
* Returns the namespace code of the namespace of the component element
* declaring this component. This is one of the XmlHandler.DS_VERSION_*
* constants.
@@ -604,6 +652,15 @@
{
return m_service;
}
+
+ public Scope getServiceScope()
+ {
+ if (m_service == null)
+ {
+ return Scope.singleton;
+ }
+ return m_service.getScope();
+ }
/**
@@ -681,7 +738,27 @@
}
- /**
+ public boolean isConfigurableServiceProperties() {
+ return m_configurableServiceProperties;
+ }
+
+ public boolean isPersistentFactoryComponent() {
+ return m_persistentFactoryComponent;
+ }
+
+ public boolean isDeleteCallsModify() {
+ return m_deleteCallsModify;
+ }
+
+ public boolean isObsoleteFactoryComponentFactory() {
+ return m_obsoleteFactoryComponentFactory;
+ }
+
+ public boolean isConfigureWithInterfaces() {
+ return m_configureWithInterfaces;
+ }
+
+ /**
* Method used to verify if the semantics of this metadata are correct
*/
public void validate( Logger logger )
@@ -763,10 +840,8 @@
}
// Next check if the properties are valid (and extract property values)
- Iterator propertyIterator = m_propertyMetaData.iterator();
- while ( propertyIterator.hasNext() )
+ for ( PropertyMetadata propMeta: m_propertyMetaData )
{
- PropertyMetadata propMeta = ( PropertyMetadata ) propertyIterator.next();
propMeta.validate( this );
m_properties.put( propMeta.getName(), propMeta.getValue() );
}
@@ -783,11 +858,9 @@
}
// Check that the references are ok
- HashSet refs = new HashSet();
- Iterator referenceIterator = m_references.iterator();
- while ( referenceIterator.hasNext() )
+ Set<String> refs = new HashSet<String>();
+ for ( ReferenceMetadata refMeta: m_references )
{
- ReferenceMetadata refMeta = ( ReferenceMetadata ) referenceIterator.next();
refMeta.validate( this, logger );
// flag duplicates
@@ -824,11 +897,33 @@
// the component is a factory component or an immediate component
if ( m_service != null )
{
- if ( m_service.isServiceFactory() && ( isFactory() || isImmediate() ) )
+ if ( (m_service.getScope() != ServiceMetadata.Scope.singleton) && ( isFactory() || isImmediate() ) )
{
- throw validationFailure( "ServiceFactory cannot be factory or immediate" );
+ throw validationFailure( "factory or immediate must be scope singleton not " + m_service.getScope());
}
}
+
+ if (m_namespaceCode == XmlHandler.DS_VERSION_1_2_FELIX)
+ {
+ m_configurableServiceProperties = true;
+ }
+ if (m_namespaceCode >= XmlHandler.DS_VERSION_1_3)
+ {
+ m_deleteCallsModify = true; //spec behavior as of 1.3
+ }
+ if (m_namespaceCode < XmlHandler.DS_VERSION_1_3 && m_configureWithInterfaces)
+ {
+ throw validationFailure("Configuration with interfaces or annotations only possible with version 1.3 or later");
+ }
+ if (m_namespaceCode >= XmlHandler.DS_VERSION_1_3 && m_obsoleteFactoryComponentFactory)
+ {
+ throw validationFailure("Configuration of component factory instances through config admin factory pids supported only through the 1.2 namespace");
+ }
+ if (m_persistentFactoryComponent && !isFactory())
+ {
+ throw validationFailure("Only a factory component can be a persistent factory component");
+ }
+
m_validated = true;
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ServiceMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ServiceMetadata.java
index 0c7ebe4..6853996 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ServiceMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ServiceMetadata.java
@@ -28,9 +28,13 @@
*
*/
public class ServiceMetadata {
+
+ public enum Scope { singleton, bundle, prototype}
// 112.4.6 Flag that indicates if the service is a ServiceFactory
- private boolean m_serviceFactory = false;
+ private Boolean m_serviceFactory;
+
+ private Scope m_scope;
// List of provided interfaces
private List<String> m_provides = new ArrayList<String>();
@@ -50,6 +54,19 @@
m_serviceFactory = serviceFactory;
}
+
+ public void setScope(Scope scope) {
+ if(m_validated) {
+ return;
+ }
+ this.m_scope = scope;
+ }
+
+
+
+ public Scope getScope() {
+ return m_scope;
+ }
/**
* Add a provided interface to this service
@@ -65,15 +82,6 @@
}
/**
- * Return the flag that defines if it is a service factory or not
- *
- * @return a boolean flag
- */
- public boolean isServiceFactory() {
- return m_serviceFactory;
- }
-
- /**
* Returns the implemented interfaces
*
* @return the implemented interfaces as a string array
@@ -93,6 +101,22 @@
throw componentMetadata
.validationFailure( "At least one provided interface must be declared in the service element" );
}
+ if (m_scope != null && componentMetadata.getNamespaceCode() < XmlHandler.DS_VERSION_1_3)
+ {
+ throw componentMetadata.validationFailure("scope can only be specified in version 1.3 and later");
+ }
+ if (m_serviceFactory != null)
+ {
+ if (componentMetadata.getNamespaceCode() >= XmlHandler.DS_VERSION_1_3)
+ {
+ throw componentMetadata.validationFailure("service-factory can only be specified in version 1.2 and earlier");
+ }
+ m_scope = m_serviceFactory? Scope.bundle: Scope.singleton;
+ }
+ if (m_scope == null)
+ {
+ m_scope = Scope.singleton;
+ }
m_validated = true;
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java
index e5df6e0..f193527 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java
@@ -30,6 +30,7 @@
import java.util.Properties;
import org.apache.felix.scr.impl.helper.Logger;
import org.apache.felix.scr.impl.parser.KXml2SAXHandler;
+import org.apache.felix.scr.impl.parser.KXml2SAXParser.Attributes;
import org.apache.felix.scr.impl.parser.ParseException;
import org.osgi.framework.Bundle;
import org.osgi.service.log.LogService;
@@ -60,6 +61,23 @@
// Namespace URI of DS 1.2-felix (see FELIX-3377)
public static final String NAMESPACE_URI_1_2_FELIX = "http://felix.apache.org/xmlns/scr/v1.2.0-felix";
+ // Namespace URI of DS 1.3
+ public static final String NAMESPACE_URI_1_3 = "http://www.osgi.org/xmlns/scr/v1.3.0";
+
+ // Namespace URI of felis DS extensions 1.0
+ public static final String NAMESPACE_URI_1_0_FELIX_EXTENSIONS = "http://felix.apache.org/xmlns/scr/extensions/v1.0.0";
+
+ //extension features
+ public static final String CONFIGURABLE_SERVICE_PROPERTIES = "configurableServiceProperties";
+
+ public static final String PERSISTENT_FACTORY_COMPONENT = "persistentFactoryComponent";
+
+ public static final String DELETE_CALLS_MODIFY = "deleteCallsModify";
+
+ public static final String OBSOLETE_FACTORY_COMPONENT_FACTORY = "obsoleteFactoryComponentFactory";
+
+ public static final String CONFIGURE_WITH_INTERFACES = "configureWithInterfaces";
+
// namespace code for non-DS namespace
public static final int DS_VERSION_NONE = -1;
@@ -78,8 +96,11 @@
// namespace code for the DS 1.2-felix specification
public static final int DS_VERSION_1_2_FELIX = 4;
+ // namespace code for the DS 1.3 specification
+ public static final int DS_VERSION_1_3 = 5;
+
// mapping of namespace URI to namespace code
- private static final Map NAMESPACE_CODE_MAP;
+ private static final Map<String, Integer> NAMESPACE_CODE_MAP;
// the bundle containing the XML resource being parsed
private final Bundle m_bundle;
@@ -94,7 +115,7 @@
private ServiceMetadata m_currentService;
// A list of component descriptors contained in the file
- private List m_components = new ArrayList();
+ private List<ComponentMetadata> m_components = new ArrayList<ComponentMetadata>();
// PropertyMetaData whose value attribute is missing, hence has element data
private PropertyMetadata m_pendingProperty;
@@ -110,13 +131,14 @@
static
{
- NAMESPACE_CODE_MAP = new HashMap();
+ NAMESPACE_CODE_MAP = new HashMap<String, Integer>();
NAMESPACE_CODE_MAP.put( NAMESPACE_URI_EMPTY, DS_VERSION_1_0 );
NAMESPACE_CODE_MAP.put( NAMESPACE_URI, DS_VERSION_1_0 );
NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1, DS_VERSION_1_1 );
NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1_FELIX, DS_VERSION_1_1_FELIX );
NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_2, DS_VERSION_1_2 );
NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_2_FELIX, DS_VERSION_1_2_FELIX );
+ NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_3, DS_VERSION_1_3 );
}
@@ -134,7 +156,7 @@
*
* @return A list of service descriptors
*/
- public List getComponentMetadataList()
+ public List<ComponentMetadata> getComponentMetadataList()
{
return m_components;
}
@@ -145,10 +167,10 @@
*
* @param uri
* @param localName
- * @param attrib
+ * @param attributes
* @exception ParseException
**/
- public void startElement( String uri, String localName, Properties attrib ) throws ParseException
+ public void startElement( String uri, String localName, Attributes attributes ) throws ParseException
{
// according to the spec, the elements should have the namespace,
// except when the root element is the "component" element
@@ -192,58 +214,64 @@
m_currentComponent = new ComponentMetadata( namespaceCode.intValue() );
// name attribute is optional (since DS 1.1)
- if ( attrib.getProperty( "name" ) != null )
+ if ( attributes.getAttribute( "name" ) != null )
{
- m_currentComponent.setName( attrib.getProperty( "name" ) );
+ m_currentComponent.setName( attributes.getAttribute( "name" ) );
}
// enabled attribute is optional
- if ( attrib.getProperty( "enabled" ) != null )
+ if ( attributes.getAttribute( "enabled" ) != null )
{
- m_currentComponent.setEnabled( attrib.getProperty( "enabled" ).equals( "true" ) );
+ m_currentComponent.setEnabled( attributes.getAttribute( "enabled" ).equals( "true" ) );
}
// immediate attribute is optional
- if ( attrib.getProperty( "immediate" ) != null )
+ if ( attributes.getAttribute( "immediate" ) != null )
{
- m_currentComponent.setImmediate( attrib.getProperty( "immediate" ).equals( "true" ) );
+ m_currentComponent.setImmediate( attributes.getAttribute( "immediate" ).equals( "true" ) );
}
// factory attribute is optional
- if ( attrib.getProperty( "factory" ) != null )
+ if ( attributes.getAttribute( "factory" ) != null )
{
- m_currentComponent.setFactoryIdentifier( attrib.getProperty( "factory" ) );
+ m_currentComponent.setFactoryIdentifier( attributes.getAttribute( "factory" ) );
}
// configuration-policy is optional (since DS 1.1)
- if ( attrib.getProperty( "configuration-policy" ) != null )
+ if ( attributes.getAttribute( "configuration-policy" ) != null )
{
- m_currentComponent.setConfigurationPolicy( attrib.getProperty( "configuration-policy" ) );
+ m_currentComponent.setConfigurationPolicy( attributes.getAttribute( "configuration-policy" ) );
}
// activate attribute is optional (since DS 1.1)
- if ( attrib.getProperty( "activate" ) != null )
+ if ( attributes.getAttribute( "activate" ) != null )
{
- m_currentComponent.setActivate( attrib.getProperty( "activate" ) );
+ m_currentComponent.setActivate( attributes.getAttribute( "activate" ) );
}
// deactivate attribute is optional (since DS 1.1)
- if ( attrib.getProperty( "deactivate" ) != null )
+ if ( attributes.getAttribute( "deactivate" ) != null )
{
- m_currentComponent.setDeactivate( attrib.getProperty( "deactivate" ) );
+ m_currentComponent.setDeactivate( attributes.getAttribute( "deactivate" ) );
}
// modified attribute is optional (since DS 1.1)
- if ( attrib.getProperty( "modified" ) != null )
+ if ( attributes.getAttribute( "modified" ) != null )
{
- m_currentComponent.setModified( attrib.getProperty( "modified" ) );
+ m_currentComponent.setModified( attributes.getAttribute( "modified" ) );
}
// configuration-pid attribute is optional (since DS 1.2)
- if (attrib.getProperty("configuration-pid") != null)
+ if (attributes.getAttribute("configuration-pid") != null)
{
- m_currentComponent.setConfigurationPid( attrib.getProperty( "configuration-pid" ) );
+ m_currentComponent.setConfigurationPid( attributes.getAttribute( "configuration-pid" ) );
}
+
+ m_currentComponent.setConfigurableServiceProperties("true".equals(attributes.getAttribute(NAMESPACE_URI_1_0_FELIX_EXTENSIONS, CONFIGURABLE_SERVICE_PROPERTIES)));
+ m_currentComponent.setPersistentFactoryComponent("true".equals(attributes.getAttribute(NAMESPACE_URI_1_0_FELIX_EXTENSIONS, PERSISTENT_FACTORY_COMPONENT)));
+ m_currentComponent.setDeleteCallsModify("true".equals(attributes.getAttribute(NAMESPACE_URI_1_0_FELIX_EXTENSIONS, DELETE_CALLS_MODIFY)));
+ m_currentComponent.setObsoleteFactoryComponentFactory("true".equals(attributes.getAttribute(NAMESPACE_URI_1_0_FELIX_EXTENSIONS, OBSOLETE_FACTORY_COMPONENT_FACTORY)));
+ m_currentComponent.setConfigureWithInterfaces("true".equals(attributes.getAttribute(NAMESPACE_URI_1_0_FELIX_EXTENSIONS, CONFIGURE_WITH_INTERFACES)));
// Add this component to the list
m_components.add( m_currentComponent );
@@ -261,7 +289,7 @@
else if ( localName.equals( "implementation" ) )
{
// Set the implementation class name (mandatory)
- m_currentComponent.setImplementationClassName( attrib.getProperty( "class" ) );
+ m_currentComponent.setImplementationClassName( attributes.getAttribute( "class" ) );
}
// 112.4.5 [...] Property Elements
else if ( localName.equals( "property" ) )
@@ -269,18 +297,18 @@
PropertyMetadata prop = new PropertyMetadata();
// name attribute is mandatory
- prop.setName( attrib.getProperty( "name" ) );
+ prop.setName( attributes.getAttribute( "name" ) );
// type attribute is optional
- if ( attrib.getProperty( "type" ) != null )
+ if ( attributes.getAttribute( "type" ) != null )
{
- prop.setType( attrib.getProperty( "type" ) );
+ prop.setType( attributes.getAttribute( "type" ) );
}
// 112.4.5: If the value attribute is specified, the body of the element is ignored.
- if ( attrib.getProperty( "value" ) != null )
+ if ( attributes.getAttribute( "value" ) != null )
{
- prop.setValue( attrib.getProperty( "value" ) );
+ prop.setValue( attributes.getAttribute( "value" ) );
m_currentComponent.addProperty( prop );
}
else
@@ -292,7 +320,7 @@
// 112.4.5 Properties [...] Elements
else if ( localName.equals( "properties" ) )
{
- readPropertiesEntry( attrib.getProperty( "entry" ) );
+ readPropertiesEntry( attributes.getAttribute( "entry" ) );
}
// 112.4.6 Service Element
else if ( localName.equals( "service" ) )
@@ -301,16 +329,16 @@
m_currentService = new ServiceMetadata();
// servicefactory attribute is optional
- if ( attrib.getProperty( "servicefactory" ) != null )
+ if ( attributes.getAttribute( "servicefactory" ) != null )
{
- m_currentService.setServiceFactory( attrib.getProperty( "servicefactory" ).equals( "true" ) );
+ m_currentService.setServiceFactory( attributes.getAttribute( "servicefactory" ).equals( "true" ) );
}
m_currentComponent.setService( m_currentService );
}
else if ( localName.equals( "provide" ) )
{
- m_currentService.addProvide( attrib.getProperty( "interface" ) );
+ m_currentService.addProvide( attributes.getAttribute( "interface" ) );
}
// 112.4.7 Reference element
@@ -319,34 +347,34 @@
ReferenceMetadata ref = new ReferenceMetadata();
// name attribute is optional (since DS 1.1)
- if ( attrib.getProperty( "name" ) != null )
+ if ( attributes.getAttribute( "name" ) != null )
{
- ref.setName( attrib.getProperty( "name" ) );
+ ref.setName( attributes.getAttribute( "name" ) );
}
- ref.setInterface( attrib.getProperty( "interface" ) );
+ ref.setInterface( attributes.getAttribute( "interface" ) );
// Cardinality
- if ( attrib.getProperty( "cardinality" ) != null )
+ if ( attributes.getAttribute( "cardinality" ) != null )
{
- ref.setCardinality( attrib.getProperty( "cardinality" ) );
+ ref.setCardinality( attributes.getAttribute( "cardinality" ) );
}
- if ( attrib.getProperty( "policy" ) != null )
+ if ( attributes.getAttribute( "policy" ) != null )
{
- ref.setPolicy( attrib.getProperty( "policy" ) );
+ ref.setPolicy( attributes.getAttribute( "policy" ) );
}
- if ( attrib.getProperty( "policy-option" ) != null )
+ if ( attributes.getAttribute( "policy-option" ) != null )
{
- ref.setPolicyOption( attrib.getProperty( "policy-option" ) );
+ ref.setPolicyOption( attributes.getAttribute( "policy-option" ) );
}
//if
- ref.setTarget( attrib.getProperty( "target" ) );
- ref.setBind( attrib.getProperty( "bind" ) );
- ref.setUpdated( attrib.getProperty( "updated" ) );
- ref.setUnbind( attrib.getProperty( "unbind" ) );
+ ref.setTarget( attributes.getAttribute( "target" ) );
+ ref.setBind( attributes.getAttribute( "bind" ) );
+ ref.setUpdated( attributes.getAttribute( "updated" ) );
+ ref.setUnbind( attributes.getAttribute( "unbind" ) );
m_currentComponent.addDependency( ref );
}
@@ -504,9 +532,8 @@
}
// create PropertyMetadata for the properties from the file
- for ( Iterator pi = props.entrySet().iterator(); pi.hasNext(); )
+ for ( Map.Entry<Object, Object> pEntry: props.entrySet() )
{
- Map.Entry pEntry = ( Map.Entry ) pi.next();
PropertyMetadata prop = new PropertyMetadata();
prop.setName( String.valueOf( pEntry.getKey() ) );
prop.setValue( String.valueOf( pEntry.getValue() ) );
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXHandler.java
index 6b7857b..9a46f61 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXHandler.java
@@ -20,6 +20,8 @@
import java.util.Properties;
+import org.apache.felix.scr.impl.parser.KXml2SAXParser.Attributes;
+
/**
* Interface for a SAX like handler with kXML
*/
@@ -38,13 +40,13 @@
*
* @param uri
* @param localName
- * @param attrib
+ * @param attributes
* @exception ParseException
*/
void startElement(
String uri,
String localName,
- Properties attrib)
+ Attributes attributes)
throws ParseException;
/**
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXParser.java b/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXParser.java
index f6e9938..ec79086 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXParser.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/parser/KXml2SAXParser.java
@@ -60,8 +60,9 @@
public void parseXML( KXml2SAXHandler handler ) throws Exception
{
- final Stack openElements = new Stack();
+ final Stack<XmlElement> openElements = new Stack<XmlElement>();
XmlElement currentElement = null;
+ final Attributes attributes = new Attributes();
while ( next() != XmlPullParser.END_DOCUMENT )
{
@@ -73,13 +74,7 @@
currentElement = new XmlElement( getNamespace(), getName(), getLineNumber(), getColumnNumber() );
openElements.push( currentElement );
- Properties props = new Properties();
- for ( int i = 0; i < getAttributeCount(); i++ )
- {
- props.put( getAttributeName( i ), getAttributeValue( i ) );
- }
-
- handler.startElement( getNamespace(), getName(), props );
+ handler.startElement( getNamespace(), getName(), attributes );
}
else if ( getEventType() == XmlPullParser.END_TAG )
{
@@ -156,4 +151,15 @@
return name + "@" + line + ":" + col;
}
}
+
+ public class Attributes {
+
+ public String getAttribute(String name) {
+ return getAttributeValue("", name);
+ }
+
+ public String getAttribute(String uri, String name) {
+ return getAttributeValue(uri, name);
+ }
+ }
}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java
index bd32067..833dc37 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java
@@ -270,8 +270,9 @@
// service setup
final ServiceMetadata sm = cm10.getServiceMetadata();
+ sm.validate( cm10 ); // service metadata requires validation to set scope properly
assertNotNull( "service", sm );
- assertEquals( "servicefactory", true, sm.isServiceFactory() );
+ assertEquals( "servicefactory", ServiceMetadata.Scope.bundle, sm.getScope() );
assertEquals( "1 interface", 1, sm.getProvides().length );
assertEquals( "service interface", "components.all.service", sm.getProvides()[0] );
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index 130042c..1c77465 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -535,8 +535,8 @@
out.print( " " );
out.println( services[i] );
}
- out.print( "Service Type: " );
- out.println( component.isServiceFactory() ? "service factory" : "service" );
+ out.print( "Service Scope: " );
+ out.println( component.getServiceScope() );
}
Reference[] refs = component.getReferences();