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/21 14:41:16 UTC

svn commit: r1812829 - in /felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl: inject/ manager/ metadata/ xml/

Author: cziegeler
Date: Sat Oct 21 14:41:16 2017
New Revision: 1812829

URL: http://svn.apache.org/viewvc?rev=1812829&view=rev
Log:
FELIX-5455 : [R7] Constructor Injection

Added:
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java
      - copied, changed from r1812828, felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethod.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java
      - copied, changed from r1812828, felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethodImpl.java
Removed:
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethod.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethodImpl.java
Modified:
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethods.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/manager/SingleComponentManager.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlConstants.java
    felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java

Copied: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java (from r1812828, felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethod.java)
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java?p2=felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java&p1=felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethod.java&r1=1812828&r2=1812829&rev=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethod.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructor.java Sat Oct 21 14:41:16 2017
@@ -25,10 +25,10 @@ import org.apache.felix.scr.impl.manager
 
 /**
  * This object describes a constructor for a component.
- * The name ConstructorMethod has been chosen to avoid a clash with the
+ * The name ComponentConstructor has been chosen to avoid a clash with the
  * existing Constructor class.
  */
-public interface ConstructorMethod<T> {
+public interface ComponentConstructor<T> {
 
 	public class ReferencePair<S> {
 		public DependencyManager<S, ?> dependencyManager;
@@ -46,19 +46,4 @@ public interface ConstructorMethod<T> {
     		           ComponentContextImpl<T> componentContext,
     		           Map<Integer, ReferencePair<S>> parameterMap)
     throws Exception;
-
-    public ConstructorMethod<Object> DEFAULT = new ConstructorMethod<Object>() {
-
-		@Override
-		public <S> Object newInstance(Class<Object> componentClass,
-				ComponentContextImpl<Object> componentContext,
-				Map<Integer, ReferencePair<S>> parameterMap)
-				throws Exception
-		{
-            // 112.4.4 The class must be public and have a public constructor without arguments so component instances
-            // may be created by the SCR with the newInstance method on Class
-            return componentClass.newInstance();
-		}
-	};
-
 }

Copied: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java (from r1812828, felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethodImpl.java)
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java?p2=felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java&p1=felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethodImpl.java&r1=1812828&r2=1812829&rev=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ConstructorMethodImpl.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentConstructorImpl.java Sat Oct 21 14:41:16 2017
@@ -31,29 +31,29 @@ import org.apache.felix.scr.impl.metadat
  * This implementation is used to construct a component instance object,
  * call the constructor and set the activation fields.
  */
-public class ConstructorMethodImpl<T> implements ConstructorMethod<T>
+public class ComponentConstructorImpl<T> implements ComponentConstructor<T>
 {
-    private volatile boolean m_initialized = false;
+    private volatile boolean initialized = false;
 
-    private volatile ValueType[] m_paramTypes;
-    private volatile Field[] m_fields;
+    private volatile ValueType[] paramTypes;
+    private volatile Field[] fields;
 
-    private volatile Constructor<T> m_constructor;
-    private volatile ValueType[] m_constructorArgTypes;
+    private volatile Constructor<T> constructor;
+    private volatile ValueType[] constructorArgTypes;
 
     @SuppressWarnings("unchecked")
     @Override
-    public <S> T newInstance(Class<T> componentClass,
-            ComponentContextImpl<T> componentContext,
-            Map<Integer, ReferencePair<S>> parameterMap)
+    public <S> T newInstance(final Class<T> componentClass,
+            final ComponentContextImpl<T> componentContext,
+            final Map<Integer, ReferencePair<S>> parameterMap)
     throws Exception
     {
-        if ( !m_initialized ) {
+        if ( !initialized ) {
             // activation fields
             if ( componentContext.getComponentMetadata().getActivationFields() != null )
             {
-                m_paramTypes = new ValueType[componentContext.getComponentMetadata().getActivationFields().size()];
-                m_fields = new Field[m_paramTypes.length];
+                paramTypes = new ValueType[componentContext.getComponentMetadata().getActivationFields().size()];
+                fields = new Field[paramTypes.length];
 
                 int index = 0;
                 for(final String fieldName : componentContext.getComponentMetadata().getActivationFields() )
@@ -61,20 +61,20 @@ public class ConstructorMethodImpl<T> im
                     final FieldUtils.FieldSearchResult result = FieldUtils.searchField(componentClass, fieldName, componentContext.getLogger());
                     if ( result == null || result.field == null )
                     {
-                        m_paramTypes[index] = null;
-                        m_fields[index] = null;
+                        paramTypes[index] = null;
+                        fields[index] = null;
                     }
                     else
                     {
                         if ( result.usable )
                         {
-                            m_paramTypes[index] = ValueUtils.getValueType(result.field.getType());
-                            m_fields[index] = result.field;
+                            paramTypes[index] = ValueUtils.getValueType(result.field.getType());
+                            fields[index] = result.field;
                         }
                         else
                         {
-                            m_paramTypes[index] = ValueType.ignore;
-                            m_fields[index] = null;
+                            paramTypes[index] = ValueType.ignore;
+                            fields[index] = null;
                         }
                     }
                     index++;
@@ -82,49 +82,57 @@ public class ConstructorMethodImpl<T> im
             }
             else
             {
-                m_paramTypes = ValueUtils.EMPTY_VALUE_TYPES;
-                m_fields = null;
+                paramTypes = ValueUtils.EMPTY_VALUE_TYPES;
+                fields = null;
             }
-            // constructor injection
-            if ( componentContext.getComponentMetadata().isActivateConstructor() )
-            {
-                // TODO search constructor
-                m_constructor = null;
 
-                boolean hasFailure = false;
-                final Class<?>[] argTypes = m_constructor.getParameterTypes();
-                m_constructorArgTypes = new ValueType[argTypes.length];
-                for(int i=0;i<m_constructorArgTypes.length;i++)
+            // Search constructor
+            final Constructor<?>[] constructors = componentClass.getConstructors();
+            for(final Constructor<?> c : constructors)
+            {
+                // we pick the first one with the right number of arguments
+                if ( c.getParameterTypes().length == componentContext.getComponentMetadata().getNumberOfConstructorParameters() )
                 {
-                    final ReferencePair<S> pair = parameterMap.get(i);
-                    ReferenceMetadata reference = pair == null ? null : pair.dependencyManager.getReferenceMetadata();
-                    if ( reference == null )
-                    {
-                        m_constructorArgTypes[i] = ValueUtils.getValueType(argTypes[i]);
-                    }
-                    else
+                    constructor = (Constructor<T>) c;
+                    break;
+                }
+                if ( constructor != null && componentContext.getComponentMetadata().getNumberOfConstructorParameters() > 0 )
+                {
+                    boolean hasFailure = false;
+                    final Class<?>[] argTypes = constructor.getParameterTypes();
+                    constructorArgTypes = new ValueType[argTypes.length];
+                    for(int i=0;i<constructorArgTypes.length;i++)
                     {
-                        m_constructorArgTypes[i] = ValueUtils.getReferenceValueType(componentClass, reference, argTypes[i], null, componentContext.getLogger());
+                        final ReferencePair<S> pair = parameterMap.get(i);
+                        ReferenceMetadata reference = pair == null ? null : pair.dependencyManager.getReferenceMetadata();
+                        if ( reference == null )
+                        {
+                            constructorArgTypes[i] = ValueUtils.getValueType(argTypes[i]);
+                        }
+                        else
+                        {
+                            constructorArgTypes[i] = ValueUtils.getReferenceValueType(componentClass, reference, argTypes[i], null, componentContext.getLogger());
+                        }
+                        if ( constructorArgTypes[i] == ValueType.ignore )
+                        {
+                            hasFailure = true;
+                            break;
+                        }
                     }
-                    if ( m_constructorArgTypes[i] == ValueType.ignore )
+                    if ( hasFailure )
                     {
-                        hasFailure = true;
-                        break;
+                        constructor = null;
                     }
                 }
-                if ( hasFailure )
-                {
-                    m_constructor = null;
-                }
             }
 
             // done
-            m_initialized = true;
+            initialized = true;
         }
 
         // if we have fields and one is in state failure (type == null) we can directly throw
         int index = 0;
-        for(final ValueType t : m_paramTypes)
+        for(final ValueType t : paramTypes)
         {
             if ( t == null )
             {
@@ -135,43 +143,43 @@ public class ConstructorMethodImpl<T> im
         }
 
         // constructor
-        final T component;
-        if ( componentContext.getComponentMetadata().isActivateConstructor() )
+        if ( constructor == null )
         {
-            if ( m_constructor == null )
-            {
-                throw new InstantiationException("Constructor not found; Component will fail");
-            }
-            final Object[] args = new Object[m_constructorArgTypes.length];
+            throw new InstantiationException("Constructor not found; Component will fail");
+        }
+        final Object[] args;
+        if ( constructorArgTypes == null )
+        {
+            args = null;
+        }
+        else
+        {
+            args = new Object[constructorArgTypes.length];
             for(int i=0; i<args.length; i++)
             {
-                // TODO - get ref pair
+                // TODO - handle reference cardinality multiple
+                // TODO - can we assume that pair.openStatus.refs.iterator().next() always returns a value?
                 final ReferencePair<S> pair = parameterMap.get(i);
                 args[i] = ValueUtils.getValue(componentClass.getName(),
-                        m_constructorArgTypes[i],
-                        m_constructor.getParameterTypes()[i],
+                        constructorArgTypes[i],
+                        constructor.getParameterTypes()[i],
                         componentContext,
-                        null);
+                        pair != null ? pair.openStatus.refs.iterator().next() : null);
             }
-            component = m_constructor.newInstance(args);
-        }
-        else
-        {
-            component = (T)ConstructorMethod.DEFAULT.newInstance((Class<Object>)componentClass,
-                    (ComponentContextImpl<Object>)componentContext, null);
         }
+        final T component = constructor.newInstance(args);
 
         // activation fields
-        for(int i = 0; i<m_paramTypes.length; i++)
+        for(int i = 0; i<paramTypes.length; i++)
         {
-            if ( m_paramTypes[i] != ValueType.ignore )
+            if ( paramTypes[i] != ValueType.ignore )
             {
                 final Object value = ValueUtils.getValue(componentClass.getName(),
-                        m_paramTypes[i],
-                        m_fields[i].getType(),
+                        paramTypes[i],
+                        fields[i].getType(),
                         componentContext,
-                        null);
-                FieldUtils.setField(m_fields[i], component, value, componentContext.getLogger());
+                        null); // null is ok as activation fields are not references
+                FieldUtils.setField(fields[i], component, value, componentContext.getLogger());
             }
         }
 

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethods.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethods.java?rev=1812829&r1=1812828&r2=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethods.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/inject/ComponentMethods.java Sat Oct 21 14:41:16 2017
@@ -35,6 +35,6 @@ public interface ComponentMethods<T>
 
     ReferenceMethods getBindMethods(String refName );
 
-	ConstructorMethod<T> getConstructor();
+	ComponentConstructor<T> getConstructor();
 
 }

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=1812829&r1=1812828&r2=1812829&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 Sat Oct 21 14:41:16 2017
@@ -43,10 +43,11 @@ public class ComponentMethodsImpl<T> imp
     private LifecycleMethod m_activateMethod;
     private LifecycleMethod m_modifiedMethod;
     private LifecycleMethod m_deactivateMethod;
-    private ConstructorMethod<T> m_constructor;
+    private ComponentConstructor<T> m_constructor;
 
-    private final Map<String, ReferenceMethods> bindMethodMap = new HashMap<String, ReferenceMethods>();
+    private final Map<String, ReferenceMethods> bindMethodMap = new HashMap<>();
 
+    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
 	public synchronized void initComponentMethods( ComponentMetadata componentMetadata, Class<T> implementationObjectClass )
     {
@@ -57,13 +58,13 @@ public class ComponentMethodsImpl<T> imp
         DSVersion dsVersion = componentMetadata.getDSVersion();
         boolean configurableServiceProperties = componentMetadata.isConfigurableServiceProperties();
         boolean supportsInterfaces = componentMetadata.isConfigureWithInterfaces();
-        
-        m_activateMethod = new ActivateMethod( 
-        		componentMetadata.isActivateConstructor() ? null : componentMetadata.getActivate(), 
-        		componentMetadata.isActivateDeclared(), 
-        		implementationObjectClass, 
-        		dsVersion, 
-        		configurableServiceProperties, 
+
+        m_activateMethod = new ActivateMethod(
+        		componentMetadata.getActivate(),
+        		componentMetadata.isActivateDeclared(),
+        		implementationObjectClass,
+        		dsVersion,
+        		configurableServiceProperties,
         		supportsInterfaces);
         m_deactivateMethod = new DeactivateMethod( componentMetadata.getDeactivate(),
                 componentMetadata.isDeactivateDeclared(), implementationObjectClass, dsVersion, configurableServiceProperties, supportsInterfaces );
@@ -73,40 +74,31 @@ public class ComponentMethodsImpl<T> imp
         for ( ReferenceMetadata referenceMetadata: componentMetadata.getDependencies() )
         {
             final String refName = referenceMetadata.getName();
-            final List<ReferenceMethods> methods = new ArrayList<ReferenceMethods>();
+            final List<ReferenceMethods> methods = new ArrayList<>();
             if ( referenceMetadata.getField() != null )
             {
                 methods.add(new FieldMethods( referenceMetadata, implementationObjectClass, dsVersion, configurableServiceProperties));
             }
             if ( referenceMetadata.getBind() != null )
             {
-            	methods.add(new BindMethods( referenceMetadata, implementationObjectClass, dsVersion, configurableServiceProperties));
+                methods.add(new BindMethods( referenceMetadata, implementationObjectClass, dsVersion, configurableServiceProperties));
             }
 
             if ( methods.isEmpty() )
             {
-            	bindMethodMap.put( refName, ReferenceMethods.NOPReferenceMethod );
+            	    bindMethodMap.put( refName, ReferenceMethods.NOPReferenceMethod );
             }
             else if ( methods.size() == 1 )
             {
-            	bindMethodMap.put( refName, methods.get(0) );
+            	    bindMethodMap.put( refName, methods.get(0) );
             }
             else
             {
-            	bindMethodMap.put( refName, new DuplexReferenceMethods(methods) );
+            	    bindMethodMap.put( refName, new DuplexReferenceMethods(methods) );
             }
         }
-        
-        // special constructor handling with activation fields and/or constructor injection
-        if ( componentMetadata.getActivationFields() != null 
-             || componentMetadata.isActivateConstructor())
-        {
-        	m_constructor = new ConstructorMethodImpl();
-        }
-        else
-        {
-        	m_constructor = (ConstructorMethod<T>) ConstructorMethod.DEFAULT;
-        }
+
+    	    m_constructor = new ComponentConstructorImpl();
     }
 
 	@Override
@@ -134,7 +126,7 @@ public class ComponentMethodsImpl<T> imp
     }
 
 	@Override
-	public ConstructorMethod<T> getConstructor() 
+	public ComponentConstructor<T> getConstructor()
 	{
 		return m_constructor;
 	}

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=1812829&r1=1812828&r2=1812829&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 Sat Oct 21 14:41:16 2017
@@ -29,7 +29,7 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.felix.scr.impl.inject.ComponentMethods;
-import org.apache.felix.scr.impl.inject.ConstructorMethod;
+import org.apache.felix.scr.impl.inject.ComponentConstructor;
 import org.apache.felix.scr.impl.inject.LifecycleMethod;
 import org.apache.felix.scr.impl.inject.MethodResult;
 import org.apache.felix.scr.impl.manager.DependencyManager.OpenStatus;
@@ -75,13 +75,13 @@ public class SingleComponentManager<S> e
      * The constructor receives both the activator and the metadata
      * @param componentMethods
      */
-    public SingleComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods )
+    public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods componentMethods )
     {
         this(container, componentMethods, false);
     }
 
-    public SingleComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods,
-            boolean factoryInstance )
+    public SingleComponentManager( final ComponentContainer<S> container, final ComponentMethods componentMethods,
+            final boolean factoryInstance )
     {
         super( container, componentMethods, factoryInstance );
     }
@@ -234,9 +234,9 @@ public class SingleComponentManager<S> e
         }
 
         // bind target services
-        final List<DependencyManager.OpenStatus<S, ?>> openStatusList = new ArrayList<DependencyManager.OpenStatus<S,?>>();
+        final List<DependencyManager.OpenStatus<S, ?>> openStatusList = new ArrayList<>();
 
-        final Map<Integer, ConstructorMethod.ReferencePair<S>> paramMap = ( getComponentMetadata().isActivateConstructor() ? new HashMap<Integer, ConstructorMethod.ReferencePair<S>>() : null);
+        final Map<Integer, ComponentConstructor.ReferencePair<S>> paramMap = ( getComponentMetadata().getNumberOfConstructorParameters() > 0 ? new HashMap<Integer, ComponentConstructor.ReferencePair<S>>() : null);
         boolean failed = false;
         for ( DependencyManager<S, ?> dm : getDependencyManagers())
         {
@@ -255,7 +255,7 @@ public class SingleComponentManager<S> e
             openStatusList.add(open);
             if ( dm.getReferenceMetadata().getParameterIndex() != null)
             {
-                final ConstructorMethod.ReferencePair<S> pair = new ConstructorMethod.ReferencePair<S>();
+                final ComponentConstructor.ReferencePair<S> pair = new ComponentConstructor.ReferencePair<>();
                 pair.dependencyManager = dm;
                 pair.openStatus = open;
                 paramMap.put(dm.getReferenceMetadata().getParameterIndex(), pair);
@@ -471,7 +471,7 @@ public class SingleComponentManager<S> e
 
 
             // 1. Merge all the config properties
-            Map<String, Object> props = new HashMap<String, Object>();
+            Map<String, Object> props = new HashMap<>();
             if ( m_configurationProperties != null )
             {
                 props.putAll(m_configurationProperties);
@@ -481,7 +481,7 @@ public class SingleComponentManager<S> e
                 props.putAll(m_factoryProperties);
                 if (getComponentMetadata().getDSVersion().isDS13() && m_factoryProperties.containsKey(Constants.SERVICE_PID))
                 {
-                    final List<String> servicePids = new ArrayList<String>();
+                    final List<String> servicePids = new ArrayList<>();
                     final Object configPropServicePids = m_configurationProperties.get(Constants.SERVICE_PID);
                     if ( configPropServicePids instanceof List )
                     {
@@ -823,7 +823,7 @@ public class SingleComponentManager<S> e
      */
     private boolean servicePropertiesMatches( ServiceRegistration<S> reg, Dictionary<String, Object> props )
     {
-        Dictionary<String, Object> regProps = new Hashtable<String, Object>();
+        Dictionary<String, Object> regProps = new Hashtable<>();
         String[] keys = reg.getReference().getPropertyKeys();
         for ( int i = 0; keys != null && i < keys.length; i++ )
         {
@@ -892,7 +892,7 @@ public class SingleComponentManager<S> e
         boolean success = true;
         if ( m_componentContext == null )
         {
-            ComponentContextImpl<S> componentContext = new ComponentContextImpl<S>(this, this.getBundle(), serviceRegistration);
+            ComponentContextImpl<S> componentContext = new ComponentContextImpl<>(this, this.getBundle(), serviceRegistration);
             if ( collectDependencies(componentContext))
             {
                 log( LogService.LOG_DEBUG,

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java?rev=1812829&r1=1812828&r2=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java Sat Oct 21 14:41:16 2017
@@ -55,9 +55,6 @@ public class ComponentMetadata
     // marker value indicating duplicate service setting
     private static final ServiceMetadata SERVICE_DUPLICATE = new ServiceMetadata();
 
-	/** If the activate method has this value, a constructor is used instead. */
-	private static final String CONSTRUCTOR_MARKER = "-init-";
-
     // the namespace code of the namespace declaring this component
     private final DSVersion m_dsVersion;
 
@@ -103,28 +100,28 @@ public class ComponentMetadata
     private List<String> m_activationFields;
 
     // Associated properties (0..*)
-    private final Map<String, Object> m_properties = new HashMap<String, Object>();
+    private final Map<String, Object> m_properties = new HashMap<>();
 
     // Associated factory properties (0..*)
-    private final Map<String, Object> m_factoryProperties = new HashMap<String, Object>();
+    private final Map<String, Object> m_factoryProperties = new HashMap<>();
 
     // List of Property metadata - used while building the meta data
     // while validating the properties contained in the PropertyMetadata
     // instances are copied to the m_properties Dictionary while this
     // list will be cleared
-    private final List<PropertyMetadata> m_propertyMetaData = new ArrayList<PropertyMetadata>();
+    private final List<PropertyMetadata> m_propertyMetaData = new ArrayList<>();
 
     // List of Property metadata - used while building the meta data
     // while validating the properties contained in the PropertyMetadata
     // instances are copied to the m_factoryProperties Dictionary while this
     // list will be cleared
-    private final List<PropertyMetadata> m_factoryPropertyMetaData = new ArrayList<PropertyMetadata>();
+    private final List<PropertyMetadata> m_factoryPropertyMetaData = new ArrayList<>();
 
     // Provided services (0..1)
     private ServiceMetadata m_service;
 
     // List of service references, (required services 0..*)
-    private final List<ReferenceMetadata> m_references = new ArrayList<ReferenceMetadata>();
+    private final List<ReferenceMetadata> m_references = new ArrayList<>();
 
     private boolean m_configurableServiceProperties;
     private boolean m_persistentFactoryComponent;
@@ -133,12 +130,14 @@ public class ComponentMetadata
     private boolean m_configureWithInterfaces;
     private boolean m_delayedKeepInstances;
 
+    private String m_init;
+
     // 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<String>();
+        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 );
@@ -162,7 +161,7 @@ public class ComponentMetadata
         {
             return;
         }
-        m_configurationPid = new ArrayList<String>( Arrays.asList( configurationPid ) );
+        m_configurationPid = new ArrayList<>( Arrays.asList( configurationPid ) );
     }
 
     /**
@@ -441,11 +440,18 @@ public class ComponentMetadata
 
 	public void setActivationFields( final String[] fields )
 	{
-		if ( m_validated )
+		if ( !m_validated )
 		{
-			return;
+	        this.m_activationFields = new ArrayList<>( Arrays.asList( fields ) );
 		}
-		this.m_activationFields = new ArrayList<String>( Arrays.asList( fields ) );
+	}
+
+	public void setInit( final String value )
+	{
+	    if ( !m_validated )
+	    {
+	        this.m_init = value;
+	    }
 	}
 
     /////////////////////////////////////////// GETTERS //////////////////////////////////////
@@ -619,14 +625,14 @@ public class ComponentMetadata
     }
 
     /**
-     * Returns whether the activate is done through a constructor rather
-     * than a method
-     * @return {@code true} if a constructor is used
+     * Returns the number of constructor parameters (0 is default)
+     * @return The number of constructor parameters
      * @since 2.1.0 (DS 1.4)
      */
-    public boolean isActivateConstructor()
+    public int getNumberOfConstructorParameters()
     {
-    	return CONSTRUCTOR_MARKER.equals(m_activate);
+        // validate() ensures this is a valid integer
+      	return m_init == null ? 0 : Integer.valueOf(m_init);
     }
 
     /**
@@ -926,7 +932,7 @@ public class ComponentMetadata
                     m_configurationPid.set( i, getName() );
                 }
             }
-            if ( new HashSet<String>( m_configurationPid ).size() != m_configurationPid.size())
+            if ( new HashSet<>( m_configurationPid ).size() != m_configurationPid.size())
             {
                 throw validationFailure( "Duplicate pids not allowed: " + m_configurationPid );
             }
@@ -947,11 +953,11 @@ public class ComponentMetadata
         }
         if ( m_dsVersion.isDS14() && isFactory() )
         {
-        	for ( PropertyMetadata propMeta: m_factoryPropertyMetaData )
-        	{
-        		propMeta.validate( this );
-        		m_factoryProperties.put( propMeta.getName(), propMeta.getValue() );
-        	}
+        	    for ( PropertyMetadata propMeta: m_factoryPropertyMetaData )
+        	    {
+        		    propMeta.validate( this );
+        		    m_factoryProperties.put( propMeta.getName(), propMeta.getValue() );
+        	    }
         }
         // if this is not a factory, these props are ignored, so nothing else to do
         m_factoryPropertyMetaData.clear();
@@ -967,7 +973,7 @@ public class ComponentMetadata
         }
 
         // Check that the references are ok
-        Set<String> refs = new HashSet<String>();
+        Set<String> refs = new HashSet<>();
         for ( ReferenceMetadata refMeta: m_references )
         {
             refMeta.validate( this );
@@ -1019,36 +1025,56 @@ public class ComponentMetadata
         }
 
         // constructor injection requires DS 1.4
-        if ( this.isActivateConstructor() )
+        if ( this.m_init != null )
         {
-        	if ( !m_dsVersion.isDS14() )
-        	{
+            if ( !m_dsVersion.isDS14() )
+            {
                 throw validationFailure( "Constructor injection requires version 1.4 or later");
-        	}
-        	final Set<Integer> parIndexSet = new HashSet<Integer>();
-        	for(final ReferenceMetadata ref : this.m_references)
-        	{
-        		if ( ref.getParameterIndex() != null && !parIndexSet.add(ref.getParameterIndex()) )
-        		{
-                    throw validationFailure( "Duplicate reference for argument " + ref.getParameterIndex() + " in constructor" );
-        		}
-        	}
+            }
+            int constructorParameters = 0;
+            try
+            {
+                constructorParameters = Integer.valueOf(m_init);
+                if ( constructorParameters < 0)
+                {
+                    throw validationFailure( "Init parameter must have non negative value: " + m_init);
+                }
+            }
+            catch ( final NumberFormatException nfe)
+            {
+                throw validationFailure( "Init parameter is not a number: " + m_init);
+            }
+        	    final Set<Integer> parIndexSet = new HashSet<>();
+        	    for(final ReferenceMetadata ref : this.m_references)
+        	    {
+        		    if ( ref.getParameterIndex() != null )
+        		    {
+                    if ( ref.getParameterIndex() >= constructorParameters )
+                    {
+                        throw validationFailure( "Reference parameter index of " + ref.getParameterIndex().toString() + " is higher than init parameter: " + m_init);
+                    }
+        		        if ( !parIndexSet.add(ref.getParameterIndex()) )
+         		    {
+                        throw validationFailure( "Duplicate reference for argument " + ref.getParameterIndex() + " in constructor" );
+         		    }
+        		    }
+        	    }
         }
         else
         {
-        	// no constructor injection, check references for having a parameter index
-        	for(final ReferenceMetadata ref : this.m_references)
-        	{
-        		if ( ref.getParameterIndex() != null )
-        		{
+        	    // no constructor injection, check references for having a parameter index
+        	    for(final ReferenceMetadata ref : this.m_references)
+        	    {
+        		    if ( ref.getParameterIndex() != null )
+        		    {
                     throw validationFailure( "Reference must not use parameter attribute if no constructor injection is used" );
-        		}
-        	}
+        		    }
+        	    }
         }
 
         if (m_dsVersion == DSVersion.DS12Felix)
         {
-        	m_configurableServiceProperties = true;
+            m_configurableServiceProperties = true;
         }
         if ( m_configurableServiceProperties && getServiceScope() != Scope.singleton )
         {
@@ -1056,19 +1082,19 @@ public class ComponentMetadata
         }
         if (m_dsVersion.isDS13())
         {
-        	m_deleteCallsModify = true; //spec behavior as of 1.3
+        	    m_deleteCallsModify = true; //spec behavior as of 1.3
         }
         if ( !m_dsVersion.isDS13() && m_configureWithInterfaces)
         {
-        	throw validationFailure("Configuration with interfaces or annotations only possible with version 1.3 or later");
+        	    throw validationFailure("Configuration with interfaces or annotations only possible with version 1.3 or later");
         }
         if (m_dsVersion.isDS13() && m_obsoleteFactoryComponentFactory != null)
         {
-        	throw validationFailure("Configuration of component factory instances through config admin factory pids supported only through the 1.2 namespace");
+          	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");
+         	throw validationFailure("Only a factory component can be a persistent factory component");
         }
 
         m_validated = true;

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=1812829&r1=1812828&r2=1812829&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 Sat Oct 21 14:41:16 2017
@@ -146,25 +146,25 @@ public class ReferenceMetadata
 
     static
     {
-        CARDINALITY_VALID = new TreeSet<String>();
+        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<String>();
+        POLICY_VALID = new TreeSet<>();
         POLICY_VALID.add( POLICY_DYNAMIC );
         POLICY_VALID.add( POLICY_STATIC );
 
-        POLICY_OPTION_VALID = new TreeSet<String>();
+        POLICY_OPTION_VALID = new TreeSet<>();
         POLICY_OPTION_VALID.add( POLICY_OPTION_RELUCTANT );
         POLICY_OPTION_VALID.add( POLICY_OPTION_GREEDY );
 
-        FIELD_STRATEGY_VALID = new TreeSet<String>();
+        FIELD_STRATEGY_VALID = new TreeSet<>();
         FIELD_STRATEGY_VALID.add( FIELD_STRATEGY_REPLACE );
         FIELD_STRATEGY_VALID.add( FIELD_STRATEGY_UPDATE );
 
-        FIELD_VALUE_TYPE_VALID = new TreeSet<String>();
+        FIELD_VALUE_TYPE_VALID = new TreeSet<>();
         FIELD_VALUE_TYPE_VALID.add ( FIELD_VALUE_TYPE_PROPERTIES );
         FIELD_VALUE_TYPE_VALID.add ( FIELD_VALUE_TYPE_REFERENCE );
         FIELD_VALUE_TYPE_VALID.add ( FIELD_VALUE_TYPE_SERVICE );
@@ -679,19 +679,18 @@ public class ReferenceMetadata
         }
 
         if (m_scopeName != null) {
-        	if ( !dsVersion.isDS13() )
-        	{
-        		throw componentMetadata.validationFailure( "reference scope can be set only for DS >= 1.3");
-        	}
-        	try
-        	{
-        		m_scope = ReferenceScope.valueOf(m_scopeName);
-        	}
-        	catch (final IllegalArgumentException e)
-        	{
-        		throw componentMetadata.validationFailure( "reference scope must be 'bundle' or 'prototype' not " + m_scopeName);
-
-        	}
+        	    if ( !dsVersion.isDS13() )
+        	    {
+        		    throw componentMetadata.validationFailure( "reference scope can be set only for DS >= 1.3");
+        	    }
+            	try
+        	    {
+        		    m_scope = ReferenceScope.valueOf(m_scopeName);
+        	    }
+        	    catch (final IllegalArgumentException e)
+        	    {
+        		    throw componentMetadata.validationFailure( "reference scope must be 'bundle' or 'prototype' not " + m_scopeName);
+        	    }
         }
 
         // checks for event based injection
@@ -760,7 +759,7 @@ public class ReferenceMetadata
             }
             try
             {
-            	m_parameterIndex = Integer.valueOf(m_parameter);
+              	m_parameterIndex = Integer.valueOf(m_parameter);
             }
             catch ( final NumberFormatException nfe)
             {

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlConstants.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlConstants.java?rev=1812829&r1=1812828&r2=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlConstants.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlConstants.java Sat Oct 21 14:41:16 2017
@@ -78,6 +78,7 @@ public abstract class XmlConstants
     public static final String ATTR_ENTRY = "entry";
     public static final String ATTR_FACTORY = "factory";
     public static final String ATTR_IMMEDIATE = "immediate";
+    public static final String ATTR_INIT = "init";
     public static final String ATTR_INTERFACE = "interface";
     public static final String ATTR_MODIFIED = "modified";
     public static final String ATTR_NAME = "name";
@@ -103,7 +104,7 @@ public abstract class XmlConstants
 
     static
     {
-        NAMESPACE_CODE_MAP = new HashMap<String, DSVersion>();
+        NAMESPACE_CODE_MAP = new HashMap<>();
         NAMESPACE_CODE_MAP.put( NAMESPACE_URI_EMPTY, DSVersion.DS10 );
         NAMESPACE_CODE_MAP.put( NAMESPACE_URI, DSVersion.DS10 );
         NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1, DSVersion.DS11 );

Modified: felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java?rev=1812829&r1=1812828&r2=1812829&view=diff
==============================================================================
--- felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java (original)
+++ felix/trunk/osgi-r7/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java Sat Oct 21 14:41:16 2017
@@ -60,7 +60,7 @@ public class XmlHandler implements KXml2
     private ServiceMetadata m_currentService;
 
     // A list of component descriptors contained in the file
-    private List<ComponentMetadata> m_components = new ArrayList<ComponentMetadata>();
+    private List<ComponentMetadata> m_components = new ArrayList<>();
 
     // PropertyMetaData whose value attribute is missing, hence has element data
     private PropertyMetadata m_pendingProperty;
@@ -222,13 +222,20 @@ public class XmlHandler implements KXml2
                     m_currentComponent.setDelayedKeepInstances(m_globalDelayedKeepInstances || "true".equals(attributes.getAttribute(XmlConstants.NAMESPACE_URI_1_0_FELIX_EXTENSIONS, XmlConstants.ATTR_DELAYED_KEEP_INSTANCES)));
 
                     // activation-fields is optional (since DS 1.4)
-                    String activationFields = attributes.getAttribute( "activation-fields" );
+                    String activationFields = attributes.getAttribute( XmlConstants.ATTR_ACTIVATION_FIELDS );
                     if ( activationFields != null )
                     {
                         final String[] fields = activationFields.split(" ");
                         m_currentComponent.setActivationFields( fields );
                     }
 
+                    // init is optional (since DS 1.4)
+                    String init = attributes.getAttribute( XmlConstants.ATTR_INIT );
+                    if ( init != null )
+                    {
+                        m_currentComponent.setInit( init );
+                    }
+
                     // Add this component to the list
                     m_components.add( m_currentComponent );
                 }