You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2017/10/30 14:50:45 UTC
svn commit: r1813772 - in /felix/trunk/osgi-r7/scr/src:
main/java/org/apache/felix/scr/impl/inject/
main/java/org/apache/felix/scr/impl/manager/
main/java/org/apache/felix/scr/impl/metadata/
test/java/org/apache/felix/scr/integration/ test/java/org/apa...
Author: cziegeler
Date: Mon Oct 30 14:50:44 2017
New Revision: 1813772
URL: http://svn.apache.org/viewvc?rev=1813772&view=rev
Log:
FELIX-5455 : [R7] Constructor Injection. Supporting references
Added:
felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java (with props)
felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java (with props)
felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml (with props)
Removed:
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java
felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor_components.xml
Modified:
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethodsImpl.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurableComponentHolder.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentConstructorTest.java
felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentFieldActivationTest.java
felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorComponent.java
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java Mon Oct 30 14:50:44 2017
@@ -18,33 +18,329 @@
*/
package org.apache.felix.scr.impl.inject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.felix.scr.impl.inject.ValueUtils.ValueType;
+import org.apache.felix.scr.impl.inject.field.FieldUtils;
+import org.apache.felix.scr.impl.logger.ComponentLogger;
import org.apache.felix.scr.impl.manager.ComponentContextImpl;
import org.apache.felix.scr.impl.manager.DependencyManager;
+import org.apache.felix.scr.impl.manager.RefPair;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+import org.osgi.service.log.LogService;
/**
- * This object describes a constructor for a component.
- * The name ComponentConstructor has been chosen to avoid a clash with the
- * existing Constructor class.
+ * This implementation is used to construct a component instance object,
+ * call the constructor and set the activation fields.
*/
-public interface ComponentConstructor<T> {
+public class ComponentConstructor<S>
+{
+ public static class ReferencePair<S>
+ {
+ public DependencyManager<S, ?> dependencyManager; // TODO check if we need this
+ public DependencyManager.OpenStatus<S, ?> openStatus;
+ }
+
+ private final Field[] activationFields;
+ private final ValueType[] activationFieldTypes;
+
+ private final Constructor<S> constructor;
+ private final ValueType[] constructorArgTypes;
+ private final ReferenceMetadata[] constructorRefs;
+
+ @SuppressWarnings("unchecked")
+ public ComponentConstructor(final ComponentMetadata componentMetadata,
+ final Class<S> componentClass,
+ final ComponentLogger logger)
+ {
+ // constructor injection
+ // get reference parameter map
+ final Map<Integer, List<ReferenceMetadata>> paramMap = ( componentMetadata.getNumberOfConstructorParameters() > 0 ? new HashMap<Integer, List<ReferenceMetadata>>() : null);
+ for ( final ReferenceMetadata refMetadata : componentMetadata.getDependencies())
+ {
+ if ( refMetadata.getParameterIndex() != null )
+ {
+ final int index = refMetadata.getParameterIndex();
+ if ( index > componentMetadata.getNumberOfConstructorParameters() )
+ {
+ // if the index (starting at 0) is equal or higher than the number of constructor arguments
+ // we log an error and ignore the reference
+ logger.log(LogService.LOG_ERROR,
+ "Ignoring reference {0} for constructor injection. Parameter index is too high.", null,
+ refMetadata.getName() );
+ }
+ else if ( !refMetadata.isStatic() )
+ {
+ // if the reference is dynamic, we log an error and ignore the reference
+ logger.log(LogService.LOG_ERROR,
+ "Ignoring reference {0} for constructor injection. Reference is dynamic.", null,
+ refMetadata.getName() );
+ }
+ List<ReferenceMetadata> list = paramMap.get(index);
+ if ( list == null )
+ {
+ list = new ArrayList<>();
+ paramMap.put(index, list);
+ }
+ list.add(refMetadata);
+ }
+ }
+
+ // Search constructor
+ Constructor<S> found = null;
+ ValueType[] foundTypes = null;
+ ReferenceMetadata[] foundRefs = null;
+
+ final Constructor<?>[] constructors = componentClass.getConstructors();
+ for(final Constructor<?> c : constructors)
+ {
+ // we try each constructor with the right number of arguments
+ if ( c.getParameterTypes().length == componentMetadata.getNumberOfConstructorParameters() )
+ {
+ final Constructor<S> check = (Constructor<S>) c;
+ logger.log(LogService.LOG_DEBUG,
+ "Checking constructor {0}", null,
+ check );
+ // check argument types
+ if ( componentMetadata.getNumberOfConstructorParameters() > 0 )
+ {
+ boolean hasFailure = false;
+ final Class<?>[] argTypes = check.getParameterTypes();
+ foundTypes = new ValueType[argTypes.length];
+ foundRefs = new ReferenceMetadata[argTypes.length];
+ for(int i=0; i<foundTypes.length;i++)
+ {
+ final List<ReferenceMetadata> refs = paramMap.get(i);
+ if ( refs == null )
+ {
+ foundTypes[i] = ValueUtils.getValueType(argTypes[i]);
+ if ( foundTypes[i] == ValueType.ignore )
+ {
+ logger.log(LogService.LOG_DEBUG,
+ "Constructor argument type {0} not supported by constructor injection: {1}", null,
+ i, argTypes[i] );
+ }
+ }
+ else
+ {
+ for(final ReferenceMetadata ref : refs)
+ {
+ final ValueType t = ValueUtils.getReferenceValueType(componentClass, ref, argTypes[i], null, logger);
+ if ( t != null )
+ {
+ foundTypes[i] = t;
+ foundRefs[i] = ref;
+ break;
+ }
+ }
+ if ( foundTypes[i] == null )
+ {
+ foundTypes[i] = ValueType.ignore;
+ }
+ else
+ {
+ if ( refs.size() > 1 )
+ {
+ logger.log(LogService.LOG_ERROR,
+ "Several references for constructor injection of parameter {0}. Only {1} will be used out of: {2}.", null,
+ i, foundRefs[i].getName(), getNames(refs) );
+ }
+ }
+ }
+
+ if ( foundTypes[i] == ValueType.ignore )
+ {
+ hasFailure = true;
+ break;
+ }
+ }
+ if ( !hasFailure )
+ {
+ found = check;
+ break;
+ }
+ }
+ else
+ {
+ found = (Constructor<S>) c;
+ break;
+ }
+ }
+ }
+
+ this.constructor = found;
+ this.constructorArgTypes = foundTypes;
+ this.constructorRefs = foundRefs;
+
+ // activation fields
+ if ( componentMetadata.getActivationFields() != null )
+ {
+ activationFieldTypes = new ValueType[componentMetadata.getActivationFields().size()];
+ activationFields = new Field[activationFieldTypes.length];
- public class ReferencePair<S> {
- public DependencyManager<S, ?> dependencyManager; // TODO check if we need this
- public DependencyManager.OpenStatus<S, ?> openStatus;
+ int index = 0;
+ for(final String fieldName : componentMetadata.getActivationFields() )
+ {
+ final FieldUtils.FieldSearchResult result = FieldUtils.searchField(componentClass, fieldName, logger);
+ if ( result == null || result.field == null )
+ {
+ activationFieldTypes[index] = null;
+ activationFields[index] = null;
+ }
+ else
+ {
+ if ( result.usable )
+ {
+ activationFieldTypes[index] = ValueUtils.getValueType(result.field.getType());
+ activationFields[index] = result.field;
+ }
+ else
+ {
+ activationFieldTypes[index] = ValueType.ignore;
+ activationFields[index] = null;
+ }
+ }
+
+ index++;
+ }
+ }
+ else
+ {
+ activationFieldTypes = ValueUtils.EMPTY_VALUE_TYPES;
+ activationFields = null;
+ }
+
+ if ( constructor == null )
+ {
+ logger.log(LogService.LOG_ERROR,
+ "Constructor with {0} arguments not found. Component will fail.", null,
+ componentMetadata.getNumberOfConstructorParameters() );
+ }
+ else
+ {
+ logger.log(LogService.LOG_DEBUG,
+ "Found constructor with {0} arguments : {1}", null,
+ componentMetadata.getNumberOfConstructorParameters(), found );
+ }
}
- /**
- * Create a new instance
- * @param componentContext The component context
- * @param parameterMap A map of reference parameters for handling references in the
- * constructor
- * @return The instance
- * @throws Exception If anything goes wrong, like constructor can't be found etc.
- */
- <S> T newInstance(ComponentContextImpl<T> componentContext,
- Map<ReferenceMetadata, ReferencePair<S>> parameterMap)
- throws Exception;
+ /**
+ * Create a new instance
+ * @param componentContext The component context
+ * @param parameterMap A map of reference parameters for handling references in the
+ * constructor
+ * @return The instance
+ * @throws Exception If anything goes wrong, like constructor can't be found etc.
+ */
+ public <T> S newInstance(final ComponentContextImpl<S> componentContext,
+ final Map<ReferenceMetadata, ReferencePair<S>> parameterMap)
+ throws Exception
+ {
+ // no constructor -> throw
+ if ( constructor == null )
+ {
+ throw new InstantiationException("Constructor not found.");
+ }
+
+ final Object[] args;
+ if ( constructorArgTypes == null )
+ {
+ args = null;
+ }
+ else
+ {
+ args = new Object[constructorArgTypes.length];
+ for(int i=0; i<args.length; i++)
+ {
+ final ReferenceMetadata refMetadata = this.constructorRefs[i];
+ final ReferencePair<S> pair = refMetadata == null ? null : parameterMap.get(refMetadata);
+
+ if ( refMetadata == null )
+ {
+ args[i] = ValueUtils.getValue(constructor.getDeclaringClass().getName(),
+ constructorArgTypes[i],
+ constructor.getParameterTypes()[i],
+ componentContext,
+ null);
+ }
+ else
+ {
+ final List<Object> refs = refMetadata.isMultiple() ? new ArrayList<>() : null;
+ Object ref = null;
+ for(final RefPair<S, ?> refPair : pair.openStatus.refs)
+ {
+ if ( !refPair.isDeleted() && !refPair.isFailed() )
+ {
+ if ( refPair.getServiceObject(componentContext) == null
+ && (constructorArgTypes[i] == ValueType.ref_serviceType || constructorArgTypes[i] == ValueType.ref_tuple ) )
+ {
+ refPair.getServiceObject(componentContext, componentContext.getBundleContext());
+ }
+ ref = ValueUtils.getValue(constructor.getDeclaringClass().getName(),
+ constructorArgTypes[i],
+ constructor.getParameterTypes()[i],
+ componentContext,
+ refPair);
+ if ( refMetadata.isMultiple() && ref != null )
+ {
+ refs.add(ref);
+ }
+ }
+ }
+ if ( !refMetadata.isMultiple())
+ {
+ if ( ref == null )
+ {
+ throw new InstantiationException("Unable to get service for reference " + refMetadata.getName());
+ }
+ args[i] = ref;
+ }
+ else
+ {
+ args[i] = refs;
+ }
+ }
+ }
+ }
+ final S component = constructor.newInstance(args);
+
+ // activation fields
+ for(int i = 0; i<activationFieldTypes.length; i++)
+ {
+ if ( activationFieldTypes[i] != null && activationFieldTypes[i] != ValueType.ignore )
+ {
+ final Object value = ValueUtils.getValue(constructor.getDeclaringClass().getName(),
+ activationFieldTypes[i],
+ activationFields[i].getType(),
+ componentContext,
+ null); // null is ok as activation fields are not references
+ FieldUtils.setField(activationFields[i], component, value, componentContext.getLogger());
+ }
+ }
+
+ return component;
+ }
+
+ private String getNames(final List<ReferenceMetadata> refs)
+ {
+ final StringBuilder sb = new StringBuilder();
+ for(final ReferenceMetadata refMetadata : refs)
+ {
+ if ( sb.length() == 0 )
+ {
+ sb.append(refMetadata.getName());
+ }
+ else
+ {
+ sb.append(", ").append(refMetadata.getName());
+ }
+ }
+ return sb.toString();
+ }
}
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethodsImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethodsImpl.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethodsImpl.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethodsImpl.java Mon Oct 30 14:50:44 2017
@@ -103,7 +103,7 @@ public class ComponentMethodsImpl<T> imp
}
}
- m_constructor = new ComponentConstructorImpl(componentMetadata, implementationObjectClass, logger);
+ m_constructor = new ComponentConstructor(componentMetadata, implementationObjectClass, logger);
}
@Override
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ValueUtils.java Mon Oct 30 14:50:44 2017
@@ -80,10 +80,11 @@ public class ValueUtils {
{
return ValueType.config_map;
}
- else
+ else if ( typeClass.isAnnotation() )
{
return ValueType.config_annotation;
}
+ return ValueType.ignore;
}
/**
@@ -178,23 +179,24 @@ public class ValueUtils {
}
else
{
- if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE.equals(metadata.getFieldCollectionType()) )
+ String colType = field != null ? metadata.getFieldCollectionType() : metadata.getParameterCollectionType();
+ if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE.equals(colType) )
{
valueType = ValueType.ref_serviceType;
}
- else if ( ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE.equals(metadata.getFieldCollectionType()) )
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE.equals(colType) )
{
valueType = ValueType.ref_serviceReference;
}
- else if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS.equals(metadata.getFieldCollectionType()) )
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS.equals(colType) )
{
valueType = ValueType.ref_serviceObjects;
}
- else if ( ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES.equals(metadata.getFieldCollectionType()) )
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES.equals(colType) )
{
valueType = ValueType.ref_map;
}
- else if ( ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE.equals(metadata.getFieldCollectionType()) )
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE.equals(colType) )
{
valueType = ValueType.ref_tuple;
}
@@ -245,7 +247,7 @@ public class ValueUtils {
}
}
// static references only allowed for replace strategy
- if ( metadata.isStatic() && !metadata.isReplace() )
+ if ( field != null && metadata.isStatic() && !metadata.isReplace() )
{
logger.log( LogService.LOG_ERROR, "Update strategy for field {0} in class {1} only allowed for non static field references.", null,
metadata.getField(), componentClass );
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurableComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurableComponentHolder.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurableComponentHolder.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurableComponentHolder.java Mon Oct 30 14:50:44 2017
@@ -139,7 +139,7 @@ public abstract class ConfigurableCompon
private volatile Promise<Void> m_enablePromise;
private volatile Promise<Void> m_disablePromise = Promises.resolved(null);
- private final ComponentMethods m_componentMethods;
+ private final ComponentMethods<S> m_componentMethods;
private final ComponentLogger logger;
@@ -159,9 +159,9 @@ public abstract class ConfigurableCompon
this.m_enabled = false;
}
- protected abstract ComponentMethods createComponentMethods();
+ protected abstract ComponentMethods<S> createComponentMethods();
- protected ComponentMethods getComponentMethods() {
+ protected ComponentMethods<S> getComponentMethods() {
return m_componentMethods;
}
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Mon Oct 30 14:50:44 2017
@@ -1290,7 +1290,7 @@ public class DependencyManager<S, T> imp
return m_minCardinality == 0;
}
- private boolean cardinalitySatisfied(int serviceCount)
+ public boolean cardinalitySatisfied(int serviceCount)
{
return m_minCardinality <= serviceCount;
}
@@ -1621,12 +1621,20 @@ public class DependencyManager<S, T> imp
null, getName());
return false;
}
+ final ReferenceMethod bindMethod = m_bindMethods.getBind();
+ return this.bindDependency(componentContext, bindMethod, status);
+ }
+
+ boolean bindDependency(final ComponentContextImpl<S> componentContext,
+ final ReferenceMethod bindMethod,
+ final OpenStatus<S, T> status)
+ {
int serviceCount = 0;
- for (RefPair<S, T> refPair : status.refs)
+ for (final RefPair<S, T> refPair : status.refs)
{
if (!refPair.isDeleted() && !refPair.isFailed())
{
- if (!doInvokeBindMethod(componentContext, refPair, status.trackingCount.get()))
+ if (!doInvokeBindMethod(componentContext, bindMethod, refPair, status.trackingCount.get()))
{
m_componentManager.getLogger().log(LogService.LOG_DEBUG,
"For dependency {0}, failed to invoke bind method on object {1}",
@@ -1773,7 +1781,7 @@ public class DependencyManager<S, T> imp
}
}
//edgeInfo open has been set, so binding has started.
- return doInvokeBindMethod(componentContext, refPair, trackingCount);
+ return doInvokeBindMethod(componentContext, m_bindMethods.getBind(), refPair, trackingCount);
}
else
@@ -1785,10 +1793,11 @@ public class DependencyManager<S, T> imp
}
}
- private boolean doInvokeBindMethod(ComponentContextImpl<S> componentContext, RefPair<S, T> refPair,
+ private boolean doInvokeBindMethod(ComponentContextImpl<S> componentContext,
+ final ReferenceMethod bindMethod,
+ RefPair<S, T> refPair,
int trackingCount)
{
- final ReferenceMethod bindMethod = m_bindMethods.getBind();
if (!getServiceObject(componentContext, bindMethod, refPair))
{
m_componentManager.getLogger().log(LogService.LOG_WARNING,
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java Mon Oct 30 14:50:44 2017
@@ -62,7 +62,7 @@ public class ServiceFactoryComponentMana
* @param container ComponentHolder for configuration management
* @param componentMethods
*/
- public ServiceFactoryComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods )
+ public ServiceFactoryComponentManager( ComponentContainer<S> container, ComponentMethods<S> componentMethods )
{
super( container, componentMethods );
}
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Mon Oct 30 14:50:44 2017
@@ -28,14 +28,17 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.felix.scr.impl.inject.BindParameters;
import org.apache.felix.scr.impl.inject.ComponentConstructor;
import org.apache.felix.scr.impl.inject.ComponentMethods;
import org.apache.felix.scr.impl.inject.LifecycleMethod;
import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.ReferenceMethod;
import org.apache.felix.scr.impl.manager.DependencyManager.OpenStatus;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.apache.felix.scr.impl.metadata.TargetedPID;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
@@ -76,12 +79,12 @@ public class SingleComponentManager<S> e
* The constructor receives both the activator and the metadata
* @param componentMethods
*/
- public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods componentMethods )
+ public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods<S> componentMethods )
{
this(container, componentMethods, false);
}
- public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods componentMethods,
+ public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods<S> componentMethods,
final boolean factoryInstance )
{
super( container, componentMethods, factoryInstance );
@@ -217,7 +220,6 @@ public class SingleComponentManager<S> e
@SuppressWarnings("unchecked")
protected S createImplementationObject( Bundle usingBundle, SetImplementationObject<S> setter, ComponentContextImpl<S> componentContext )
{
- final Class<S> implementationObjectClass;
S implementationObject = null;
// 1. Load the component implementation class
@@ -252,6 +254,33 @@ public class SingleComponentManager<S> e
openStatusList.add(open);
if ( dm.getReferenceMetadata().getParameterIndex() != null)
{
+ if ( !dm.bindDependency(componentContext, new ReferenceMethod() {
+
+ @Override
+ public <S, T> MethodResult invoke(final Object componentInstance,
+ final BindParameters rawParameter,
+ final MethodResult methodCallFailureResult)
+ {
+ // nothing to do, binding will be done in constructor
+ return MethodResult.VOID;
+ }
+
+ @Override
+ public <S, T> boolean getServiceObject(
+ final BindParameters rawParameter,
+ final BundleContext context)
+ {
+ // nothing to do, binding will be done in constructor
+ return true;
+ }
+ },(OpenStatus) open) )
+ {
+ getLogger().log( LogService.LOG_DEBUG, "Cannot create component instance due to failure to bind reference {0}",
+ null, dm.getName() );
+ failed = true;
+ break;
+ }
+
final ComponentConstructor.ReferencePair<S> pair = new ComponentConstructor.ReferencePair<>();
pair.dependencyManager = dm;
pair.openStatus = open;
@@ -263,10 +292,6 @@ public class SingleComponentManager<S> e
{
try
{
- // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
- implementationObjectClass = (Class<S>) bundle.loadClass(
- getComponentMetadata().getImplementationClassName() ) ;
-
implementationObject = getComponentMethods().getConstructor().newInstance(
componentContext,
paramMap);
@@ -279,7 +304,7 @@ public class SingleComponentManager<S> e
this.setFailureReason(ie);
return null;
}
- catch ( Throwable t )
+ catch ( final Throwable t )
{
// failed to instantiate, return null
getLogger().log( LogService.LOG_ERROR, "Error during instantiation of the implementation object", t );
@@ -466,11 +491,8 @@ public class SingleComponentManager<S> e
@Override
public Map<String, Object> getProperties()
{
-
if ( m_properties == null )
{
-
-
// 1. Merge all the config properties
Map<String, Object> props = new HashMap<>();
if ( m_configurationProperties != null )
@@ -595,26 +617,26 @@ public class SingleComponentManager<S> e
}
else
{
- getLogger().log( LogService.LOG_DEBUG, "Not updating service registration, no change in properties", null, null );
+ getLogger().log( LogService.LOG_DEBUG, "Not updating service registration, no change in properties", null );
}
}
- catch ( IllegalStateException ise )
+ catch ( final IllegalStateException ise )
{
// service has been unregistered asynchronously, ignore
}
- catch ( IllegalArgumentException iae )
+ catch ( final IllegalArgumentException iae )
{
getLogger().log( LogService.LOG_ERROR,
"Unexpected configuration property problem when updating service registration", iae );
}
- catch ( Throwable t )
+ catch ( final Throwable t )
{
getLogger().log( LogService.LOG_ERROR, "Unexpected problem when updating service registration", t );
}
}
else
{
- getLogger().log( LogService.LOG_DEBUG, "No service registration to update", null, null );
+ getLogger().log( LogService.LOG_DEBUG, "No service registration to update", null );
}
}
@@ -958,7 +980,7 @@ public class SingleComponentManager<S> e
{
deleteComponent( ComponentConstants.DEACTIVATION_REASON_UNSPECIFIED );
}
- catch ( Throwable t )
+ catch ( final Throwable t )
{
getLogger().log( LogService.LOG_DEBUG, "Cannot delete incomplete component instance. Ignoring.", t );
}
Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java Mon Oct 30 14:50:44 2017
@@ -134,6 +134,9 @@ public class ReferenceMetadata
// Parameter index, set based on {@code m_parameter} after validation
private Integer m_parameterIndex;
+ // Name of the value type for the parameter (optional, since DS 1.4)
+ private String m_parameter_collection_type;
+
// Flags that store the values passed as strings
private boolean m_isStatic = true;
private boolean m_isOptional = false;
@@ -397,6 +400,21 @@ public class ReferenceMetadata
this.m_parameter = val;
}
+ /**
+ * Setter for the parameter value type attribute
+ * DS 1.4
+ * @param valuetype the parameter value type
+ */
+ public void setParameterCollectionType( final String valuetype )
+ {
+ if ( m_validated )
+ {
+ return;
+ }
+
+ m_parameter_collection_type = valuetype;
+ }
+
/////////////////////////////////////////////// getters ///////////////////////////////////
/**
@@ -540,6 +558,7 @@ public class ReferenceMetadata
* This method returns the correct value only after this metadata object has been validated
* by a call to {@link #validate(ComponentMetadata, Logger)} and the validation has been
* successful.
+ * DS 1.4
* @return The parameter index , if no parameter is set this returns {@code -null}
*/
public Integer getParameterIndex()
@@ -547,6 +566,17 @@ public class ReferenceMetadata
return m_parameterIndex;
}
+ /**
+ * Get the value type of a parameter in the component implementation class that is used to hold
+ * the reference
+ * DS 1.4
+ * @return a String with the value type for the parameter
+ */
+ public String getParameterCollectionType()
+ {
+ return m_parameter_collection_type;
+ }
+
// Getters for boolean values that determine both policy and cardinality
/**
@@ -769,6 +799,26 @@ public class ReferenceMetadata
{
throw componentMetadata.validationFailure( "Reference parameter value must be zero or higher: " + m_parameter );
}
+ // parameter value type
+ if ( !m_isMultiple )
+ {
+ // value type must not be specified for unary references
+ if ( m_parameter_collection_type != null )
+ {
+ throw componentMetadata.validationFailure( "Parameter value type must not be set for unary constructor references." );
+ }
+ }
+ else
+ {
+ if ( m_parameter_collection_type == null )
+ {
+ setParameterCollectionType( FIELD_VALUE_TYPE_SERVICE );
+ }
+ else if ( !FIELD_VALUE_TYPE_VALID.contains( m_parameter_collection_type ) )
+ {
+ throw componentMetadata.validationFailure( "Parameter value type must be one of " + FIELD_VALUE_TYPE_VALID );
+ }
+ }
}
m_validated = true;
}
Modified: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentConstructorTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentConstructorTest.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentConstructorTest.java (original)
+++ felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentConstructorTest.java Mon Oct 30 14:50:44 2017
@@ -43,7 +43,7 @@ public class ComponentConstructorTest ex
static
{
// use different components
- descriptorFile = "/integration_test_constructor_components.xml";
+ descriptorFile = "/integration_test_constructor.xml";
// uncomment to enable debugging of this test class
// paxRunnerVmOption = DEBUG_VM_OPTION;
@@ -61,7 +61,7 @@ public class ComponentConstructorTest ex
ConstructorComponent cmp = this.getServiceFromConfiguration(cc, ConstructorComponent.class);
final String msg = cmp.test();
- assertNull(msg, msg);
+ assertNull(msg);
disableAndCheck( cc );
}
@@ -95,4 +95,34 @@ public class ComponentConstructorTest ex
disableAndCheck( cc );
}
+
+ @Test
+ public void test_constructor_singleRef() throws Exception
+ {
+ final String componentname = "ConstructorComponent.refsingle";
+
+ ComponentConfigurationDTO cc = getDisabledConfigurationAndEnable(componentname, ComponentConfigurationDTO.SATISFIED);
+ assertEquals(1, cc.description.init);
+
+ ConstructorComponent cmp = this.getServiceFromConfiguration(cc, ConstructorComponent.class);
+
+ final String msg = cmp.test();
+ assertNull(msg);
+ disableAndCheck( cc );
+ }
+
+ @Test
+ public void test_constructor_multiRef() throws Exception
+ {
+ final String componentname = "ConstructorComponent.refmulti";
+
+ ComponentConfigurationDTO cc = getDisabledConfigurationAndEnable(componentname, ComponentConfigurationDTO.SATISFIED);
+ assertEquals(1, cc.description.init);
+
+ ConstructorComponent cmp = this.getServiceFromConfiguration(cc, ConstructorComponent.class);
+
+ final String msg = cmp.test();
+ assertNull(msg);
+ disableAndCheck( cc );
+ }
}
Modified: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentFieldActivationTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentFieldActivationTest.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentFieldActivationTest.java (original)
+++ felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/ComponentFieldActivationTest.java Mon Oct 30 14:50:44 2017
@@ -67,25 +67,7 @@ public class ComponentFieldActivationTes
disableAndCheck( cc );
}
-/**
- private <S> void failGetServiceFromConfiguration(ComponentConfigurationDTO dto, Class<S> clazz)
- {
- long id = dto.id;
- String filter = "(component.id=" + id + ")";
- Collection<ServiceReference<S>> srs;
- try
- {
- srs = bundleContext.getServiceReferences( clazz, filter );
- Assert.assertEquals( "Nothing for filter: " + filter, 1, srs.size() );
- ServiceReference<S> sr = srs.iterator().next();
- assertNull(bundleContext.getService( sr ));
- }
- catch ( InvalidSyntaxException e )
- {
- TestCase.fail( e.getMessage() );
- }
- }
-*/
+
@Test
public void test_field_activator_failure() throws Exception
{
Modified: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorComponent.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorComponent.java?rev=1813772&r1=1813771&r2=1813772&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorComponent.java (original)
+++ felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorComponent.java Mon Oct 30 14:50:44 2017
@@ -19,6 +19,9 @@
package org.apache.felix.scr.integration.components;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import org.osgi.framework.BundleContext;
@@ -27,7 +30,14 @@ import org.osgi.service.component.Compon
public class ConstructorComponent
{
- public @interface Config {
+ private enum Mode
+ {
+ FIELD,
+ SINGLE,
+ MULTI
+ }
+ public @interface Config
+ {
String email() default "bar"; // property in component xml with value foo
int port() default 443; // property in component xml with value 80
long test() default 5; // no property in component xml, will be 0
@@ -41,10 +51,14 @@ public class ConstructorComponent
private final Config annotation;
+ private final Mode mode;
+
private boolean activated;
private String activationTest;
+ private volatile Object ref;
+
public ConstructorComponent(BundleContext b,
ComponentContext c,
Map<String, Object> configMap,
@@ -54,57 +68,143 @@ public class ConstructorComponent
this.context = c;
this.config = configMap;
this.annotation = configAnnotation;
+ this.mode = Mode.FIELD;
+ }
+
+ public ConstructorComponent(final ConstructorSingleReference single)
+ {
+ this.bundle = null;
+ this.context = null;
+ this.config = null;
+ this.annotation = null;
+ this.mode = Mode.SINGLE;
+ this.ref = single;
+ }
+
+ public ConstructorComponent(final List<ConstructorMultiReference> list)
+ {
+ this.bundle = null;
+ this.context = null;
+ this.config = null;
+ this.annotation = null;
+ this.mode = Mode.MULTI;
+ this.ref = list;
}
@SuppressWarnings("unused")
- private void activator() {
+ private void activator()
+ {
// everything should be set here already
- activationTest = check();
+ switch ( mode )
+ {
+ case FIELD : activationTest = checkField();
+ break;
+ case SINGLE : activationTest = checkSingle();
+ break;
+ case MULTI : activationTest = checkMulti();
+ break;
+ }
activated = true;
}
- private String check()
+ @SuppressWarnings("rawtypes")
+ private String checkMulti()
+ {
+ if ( ref == null )
+ {
+ return "ref is null";
+ }
+ if ( !(ref instanceof List) )
+ {
+ return "ref is wrong type: " + ref.getClass();
+ }
+ if ( ((List)ref).size() != 3)
+ {
+ return "ref has wrong size: " + ((List)ref).size();
+ }
+ final List<String> names = new ArrayList<>(Arrays.asList("a", "b", "c"));
+ for(final Object obj : (List)ref)
+ {
+ if ( !(obj instanceof ConstructorMultiReference) )
+ {
+ return "ref has wrong type: " + obj.getClass();
+ }
+ names.remove(((ConstructorMultiReference)obj).getName());
+ }
+ if ( !names.isEmpty() )
+ {
+ return "Unexpected references found. Names not found: " + names;
+ }
+ return null;
+ }
+
+ private String checkSingle()
{
- if ( bundle == null ) {
+ if ( ref == null )
+ {
+ return "ref is null";
+ }
+ if ( !(ref instanceof ConstructorSingleReference) )
+ {
+ return "ref has wrong type: " + ref.getClass();
+ }
+ if ( !((ConstructorSingleReference)ref).getName().equals("single"))
+ {
+ return "ref has wrong name: " + ((ConstructorSingleReference)ref).getName().equals("single");
+ }
+ return null;
+ }
+
+ private String checkField()
+ {
+ if ( bundle == null )
+ {
return "bundle is null";
}
- if ( context == null ) {
+ if ( context == null )
+ {
return "context is null";
}
- if ( config == null ) {
+ if ( config == null )
+ {
return "config is null";
}
- if ( annotation == null ) {
+ if ( annotation == null )
+ {
return "annotation is null";
}
- if ( !annotation.email().equals("foo") ) {
+ if ( !annotation.email().equals("foo") )
+ {
return "Wrong value for annotation.email: " + annotation.email();
}
- if ( annotation.port() != 80 ) {
+ if ( annotation.port() != 80 )
+ {
return "Wrong value for annotation.port: " + annotation.port();
}
- if ( annotation.test() != 0 ) {
+ if ( annotation.test() != 0 )
+ {
return "Wrong value for annotation.test: " + annotation.test();
}
- if ( !config.get("email").equals("foo") ) {
+ if ( !config.get("email").equals("foo") )
+ {
return "Wrong value for map.email: " + config.get("email");
}
- if ( !config.get("port").equals("80") ) {
+ if ( !config.get("port").equals("80") )
+ {
return "Wrong value for map.email: " + config.get("port");
}
- if ( config.get("test") != null ) {
+ if ( config.get("test") != null )
+ {
return "Wrong value for map.test: " + config.get("test");
}
return null;
}
public String test() {
- if ( !activated ) {
+ if ( !activated )
+ {
return "activate not called";
}
- if ( activationTest != null ) {
- return "not set before activate: " + activationTest;
- }
- return check();
+ return activationTest;
}
}
Added: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java?rev=1813772&view=auto
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java (added)
+++ felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java Mon Oct 30 14:50:44 2017
@@ -0,0 +1,40 @@
+/*
+ * 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.integration.components;
+
+public class ConstructorMultiReference
+{
+ public @interface Config
+ {
+ String name();
+ }
+
+ private String name;
+
+ @SuppressWarnings("unused")
+ private void activator(final Config config)
+ {
+ this.name = config.name();
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+}
Propchange: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorMultiReference.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java?rev=1813772&view=auto
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java (added)
+++ felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java Mon Oct 30 14:50:44 2017
@@ -0,0 +1,40 @@
+/*
+ * 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.integration.components;
+
+public class ConstructorSingleReference
+{
+ public @interface Config
+ {
+ String name();
+ }
+
+ private String name;
+
+ @SuppressWarnings("unused")
+ private void activator(final Config config)
+ {
+ this.name = config.name();
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+}
Propchange: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/osgi-r7/scr/src/test/java/org/apache/felix/scr/integration/components/ConstructorSingleReference.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml?rev=1813772&view=auto
==============================================================================
--- felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml (added)
+++ felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml Mon Oct 30 14:50:44 2017
@@ -0,0 +1,94 @@
+<?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.4.0">
+
+ <!-- Use constructor -->
+ <scr:component name="ConstructorComponent.satisfied" enabled="false" activate="activator"
+ init="4">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorComponent" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorComponent"/>
+ </service>
+ <property name="email" value="foo"/>
+ <property name="port" value="80"/>
+ </scr:component>
+
+ <!-- Constructor does not exist -->
+ <scr:component name="ConstructorComponent.unsatisfied" enabled="false" activate="activator">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorComponent" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorComponent"/>
+ </service>
+ </scr:component>
+
+ <!-- Use constructor - single reference -->
+ <scr:component name="ConstructorComponent.refsingle" enabled="false" activate="activator"
+ init="1">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorComponent" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorComponent"/>
+ </service>
+ <reference interface="org.apache.felix.scr.integration.components.ConstructorSingleReference"
+ cardinality="1..1"
+ parameter="0"/>
+ </scr:component>
+
+ <!-- Use constructor - multi reference -->
+ <scr:component name="ConstructorComponent.refmulti" enabled="false" activate="activator"
+ init="1">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorComponent" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorComponent"/>
+ </service>
+ <reference interface="org.apache.felix.scr.integration.components.ConstructorMultiReference"
+ cardinality="1..n"
+ parameter="0"/>
+ </scr:component>
+
+ <!-- References -->
+ <scr:component name="SingleReference" activate="activator">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorSingleReference" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorSingleReference"/>
+ </service>
+ <property name="name" value="single"/>
+ </scr:component>
+ <scr:component name="MultiReferenceA" activate="activator">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorMultiReference" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorMultiReference"/>
+ </service>
+ <property name="name" value="a"/>
+ </scr:component>
+ <scr:component name="MultiReferenceB" activate="activator">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorMultiReference" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorMultiReference"/>
+ </service>
+ <property name="name" value="b"/>
+ </scr:component>
+ <scr:component name="MultiReferenceC" activate="activator">
+ <implementation class="org.apache.felix.scr.integration.components.ConstructorMultiReference" />
+ <service factory="false">
+ <provide interface="org.apache.felix.scr.integration.components.ConstructorMultiReference"/>
+ </service>
+ <property name="name" value="c"/>
+ </scr:component>
+</components>
Propchange: felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/osgi-r7/scr/src/test/resources/integration_test_constructor.xml
------------------------------------------------------------------------------
svn:keywords = Id