Added: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java?rev=1873971&view=auto
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
 (added)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
 Thu Feb 13 07:36:01 2020
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.felix.scr.impl.inject.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.ReferenceMethods;
+import org.apache.felix.scr.impl.inject.field.FieldMethods;
+import org.apache.felix.scr.impl.inject.methods.ActivateMethod;
+import org.apache.felix.scr.impl.inject.methods.BindMethods;
+import org.apache.felix.scr.impl.inject.methods.DeactivateMethod;
+import org.apache.felix.scr.impl.inject.methods.ModifiedMethod;
+import org.apache.felix.scr.impl.logger.ComponentLogger;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+/**
+ * @version $Rev$ $Date$
+ * @param <T>
+ */
+public class ComponentMethodsImpl<T> implements ComponentMethods<T>
+{
+    private LifecycleMethod m_activateMethod;
+    private LifecycleMethod m_modifiedMethod;
+    private LifecycleMethod m_deactivateMethod;
+    private ComponentConstructor<T> m_constructor;
+
+    private final Map<String, ReferenceMethods> bindMethodMap = new 
HashMap<>();
+
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+       public synchronized void initComponentMethods(
+               final ComponentMetadata componentMetadata,
+               final Class<T> implementationObjectClass,
+               final ComponentLogger logger)
+    {
+        if (m_activateMethod != null)
+        {
+            // do init only once
+            return;
+        }
+        DSVersion dsVersion = componentMetadata.getDSVersion();
+        boolean configurableServiceProperties = 
componentMetadata.isConfigurableServiceProperties();
+        boolean supportsInterfaces = 
componentMetadata.isConfigureWithInterfaces();
+
+        m_activateMethod = new ActivateMethod(
+                       componentMetadata.getActivate(),
+                       componentMetadata.isActivateDeclared(),
+                       implementationObjectClass,
+                       dsVersion,
+                       configurableServiceProperties,
+                       supportsInterfaces);
+        m_deactivateMethod = new DeactivateMethod( 
componentMetadata.getDeactivate(),
+                componentMetadata.isDeactivateDeclared(), 
implementationObjectClass, dsVersion, configurableServiceProperties, 
supportsInterfaces );
+
+        m_modifiedMethod = new ModifiedMethod( 
componentMetadata.getModified(), implementationObjectClass, dsVersion, 
configurableServiceProperties, supportsInterfaces );
+
+        for ( ReferenceMetadata referenceMetadata: 
componentMetadata.getDependencies() )
+        {
+            final String refName = referenceMetadata.getName();
+            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));
+            }
+
+            if ( methods.isEmpty() )
+            {
+                   bindMethodMap.put( refName, 
ReferenceMethods.NOPReferenceMethod );
+            }
+            else if ( methods.size() == 1 )
+            {
+                   bindMethodMap.put( refName, methods.get(0) );
+            }
+            else
+            {
+                   bindMethodMap.put( refName, new 
DuplexReferenceMethods(methods) );
+            }
+        }
+
+        m_constructor = new ComponentConstructorImpl(componentMetadata, 
implementationObjectClass, logger);
+    }
+
+       @Override
+    public LifecycleMethod getActivateMethod()
+    {
+        return m_activateMethod;
+    }
+
+       @Override
+    public LifecycleMethod getDeactivateMethod()
+    {
+        return m_deactivateMethod;
+    }
+
+       @Override
+    public LifecycleMethod getModifiedMethod()
+    {
+        return m_modifiedMethod;
+    }
+
+       @Override
+    public ReferenceMethods getBindMethods(String refName )
+    {
+        return bindMethodMap.get( refName );
+    }
+
+       @Override
+       public ComponentConstructor<T> getConstructor()
+       {
+               return m_constructor;
+       }
+}

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ComponentMethodsImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Added: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java?rev=1873971&view=auto
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
 (added)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
 Thu Feb 13 07:36:01 2020
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.inject.internal;
+
+import java.util.List;
+
+import org.apache.felix.scr.impl.inject.BindParameters;
+import org.apache.felix.scr.impl.inject.InitReferenceMethod;
+import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.ReferenceMethod;
+import org.apache.felix.scr.impl.inject.ReferenceMethods;
+import org.apache.felix.scr.impl.logger.ComponentLogger;
+import org.osgi.framework.BundleContext;
+
+public class DuplexReferenceMethods implements ReferenceMethods
+{
+    private final ReferenceMethod bind;
+    private final ReferenceMethod updated;
+    private final ReferenceMethod unbind;
+    private final InitReferenceMethod init;
+
+    public DuplexReferenceMethods(final List<ReferenceMethods> methods)
+    {
+       final ReferenceMethod[] bindList = new ReferenceMethod[methods.size()];
+           final ReferenceMethod[] updatedList = new 
ReferenceMethod[methods.size()];
+           final ReferenceMethod[] unbindList = new 
ReferenceMethod[methods.size()];
+           int index = 0;
+           for(final ReferenceMethods m : methods)
+           {
+                   bindList[index] = m.getBind();
+                   updatedList[index] = m.getUpdated();
+                   unbindList[index] = m.getUnbind();
+                   index++;
+           }
+        this.bind = new DuplexReferenceMethod(bindList);
+        this.updated = new DuplexReferenceMethod(updatedList);
+        this.unbind = new DuplexReferenceMethod(unbindList);
+        this.init = new InitReferenceMethod()
+        {
+            @Override
+            public boolean init(final Object componentInstance, final 
ComponentLogger logger)
+            {
+                   boolean result = true;
+                   for(final ReferenceMethods m : methods)
+                   {
+                           final InitReferenceMethod init = m.getInit();
+                           if ( init != null )
+                           {
+                                   result = init.init(componentInstance, 
logger);
+                                   if ( !result )
+                                   {
+                                           break;
+                                   }
+                           }
+               }
+                return result;
+            }
+        };
+    }
+
+    @Override
+    public ReferenceMethod getBind()
+    {
+           return this.bind;
+    }
+
+    @Override
+    public ReferenceMethod getUnbind()
+    {
+       return this.unbind;
+    }
+
+    @Override
+    public ReferenceMethod getUpdated()
+    {
+           return this.updated;
+    }
+
+    @Override
+    public InitReferenceMethod getInit()
+    {
+       return this.init;
+    }
+
+    private static final class DuplexReferenceMethod implements ReferenceMethod
+    {
+
+        private final ReferenceMethod[] methods;
+
+        public DuplexReferenceMethod(final ReferenceMethod[] methods)
+        {
+            this.methods = methods;
+        }
+
+        @Override
+        public MethodResult invoke(final Object componentInstance,
+                       final BindParameters parameters,
+                       final MethodResult methodCallFailureResult)
+        {
+               MethodResult result = null;
+                   for(final ReferenceMethod m : methods)
+                   {
+                           result = m.invoke(componentInstance, parameters, 
methodCallFailureResult);
+                           if ( result == null )
+                           {
+                                   break;
+                           }
+                   }
+            return result;
+        }
+
+        @Override
+        public <S, T> boolean getServiceObject(
+                       final BindParameters parameters,
+                       final BundleContext context)
+        {
+            // only if all return true, we return true
+               boolean result = false;
+               for(final ReferenceMethod m : methods)
+                   {
+                           result = m.getServiceObject(parameters, context);
+                           if (!result )
+                           {
+                                   break;
+                           }
+                   }
+            return result;
+        }
+    }
+}

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/DuplexReferenceMethods.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/ActivateMethod.java
 Thu Feb 13 07:36:01 2020
@@ -28,12 +28,12 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.felix.scr.impl.inject.ActivatorParameter;
-import org.apache.felix.scr.impl.inject.Annotations;
-import org.apache.felix.scr.impl.inject.ClassUtils;
 import org.apache.felix.scr.impl.inject.LifecycleMethod;
 import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
+import org.apache.felix.scr.impl.inject.internal.Annotations;
+import org.apache.felix.scr.impl.inject.internal.ClassUtils;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
-import org.apache.felix.scr.impl.manager.ComponentContextImpl;
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.osgi.service.log.LogService;
 
@@ -297,11 +297,12 @@ public class ActivateMethod extends Base
     }
 
     /**
-     * @see 
org.apache.felix.scr.impl.inject.LifecycleMethod#invoke(java.lang.Object, 
org.apache.felix.scr.impl.manager.ComponentContextImpl, int, 
org.apache.felix.scr.impl.inject.MethodResult)
+     * @see org.apache.felix.scr.impl.inject.LifecycleMethod#invoke(Object,
+     *      ScrComponentContext, int, MethodResult)
      */
     @Override
     public MethodResult invoke(final Object componentInstance,
-               final ComponentContextImpl<?> componentContext,
+            final ScrComponentContext componentContext,
                final int reason,
                final MethodResult methodCallFailureResult) {
         return invoke(componentInstance, new 
ActivatorParameter(componentContext, reason), methodCallFailureResult);

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BaseMethod.java
 Thu Feb 13 07:36:01 2020
@@ -28,8 +28,8 @@ import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.felix.scr.impl.inject.BaseParameter;
-import org.apache.felix.scr.impl.inject.ClassUtils;
 import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.internal.ClassUtils;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.osgi.service.log.LogService;

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/methods/BindMethod.java
 Thu Feb 13 07:36:01 2020
@@ -26,11 +26,11 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.felix.scr.impl.inject.BindParameters;
-import org.apache.felix.scr.impl.inject.ClassUtils;
+import org.apache.felix.scr.impl.inject.RefPair;
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.apache.felix.scr.impl.inject.ValueUtils;
+import org.apache.felix.scr.impl.inject.internal.ClassUtils;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
-import org.apache.felix.scr.impl.manager.ComponentContextImpl;
-import org.apache.felix.scr.impl.manager.RefPair;
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.log.LogService;
@@ -656,12 +656,13 @@ implements org.apache.felix.scr.impl.inj
     public <S, T> boolean getServiceObject( final BindParameters parameters, 
BundleContext context )
     {
         //??? this resolves which we need.... better way?
-        if ( parameters.getServiceObject() == null && methodExists( 
parameters.getComponentContext().getLogger() ) )
+        if 
(parameters.getRefPair().getServiceObject(parameters.getComponentContext()) == 
null
+                && methodExists(parameters.getComponentContext().getLogger()))
         {
             if ( m_paramTypes.contains(ValueUtils.ValueType.ref_serviceType)
                  || m_paramTypes.contains(ValueUtils.ValueType.ref_logger)
                  || 
m_paramTypes.contains(ValueUtils.ValueType.ref_formatterLogger)) {
-                return parameters.getServiceObject(context);
+                return 
parameters.getRefPair().getServiceObject(parameters.getComponentContext(), 
context);
             }
         }
         return true;
@@ -670,7 +671,7 @@ implements org.apache.felix.scr.impl.inj
     @Override
     protected Object[] getParameters( Method method, BindParameters bp )
     {
-        ComponentContextImpl<?> key = bp.getComponentContext();
+        ScrComponentContext key = bp.getComponentContext();
         Object[] result = new Object[ m_paramTypes.size()];
         RefPair<?, ?> refPair = bp.getRefPair();
         int i = 0;

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
 Thu Feb 13 07:36:01 2020
@@ -44,6 +44,7 @@ import java.util.concurrent.locks.Reentr
 
 import org.apache.felix.scr.impl.inject.ComponentMethods;
 import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.RefPair;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractPrototypeRefPair.java
 Thu Feb 13 07:36:01 2020
@@ -24,6 +24,8 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.felix.scr.impl.inject.RefPair;
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
@@ -39,22 +41,22 @@ public abstract class AbstractPrototypeR
     }
 
     @Override
-    public abstract T getServiceObject(ComponentContextImpl<S> key);
+    public abstract T getServiceObject(ScrComponentContext key);
 
     @Override
-    public abstract boolean setServiceObject(ComponentContextImpl<S> key, T 
serviceObject);
+    public abstract boolean setServiceObject(ScrComponentContext key, T 
serviceObject);
 
-    protected abstract T remove(ComponentContextImpl<S> key);
+    protected abstract T remove(ScrComponentContext key);
 
-    protected abstract Collection<Entry<ComponentContextImpl<S>, T>> 
clearEntries();
+    protected abstract Collection<Entry<ScrComponentContext, T>> 
clearEntries();
 
     @Override
-    public final T ungetServiceObject(ComponentContextImpl<S> key)
+    public final T ungetServiceObject(ScrComponentContext key)
     {
         if ( key == null )
         {
-            Collection<Map.Entry<ComponentContextImpl<S>,T>> keys = 
clearEntries();
-            for (Map.Entry<ComponentContextImpl<S>,T> e : keys)
+            Collection<Map.Entry<ScrComponentContext, T>> keys = 
clearEntries();
+            for (Map.Entry<ScrComponentContext, T> e : keys)
             {
                 doUngetService( e.getKey(), e.getValue() );
             }
@@ -76,12 +78,12 @@ public abstract class AbstractPrototypeR
     public abstract String toString();
 
     @Override
-    public final boolean getServiceObject(ComponentContextImpl<S> key, 
BundleContext context)
+    public final boolean getServiceObject(ScrComponentContext key, 
BundleContext context)
     {
         final T service = 
key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
         {
-            setFailed();
+            markFailed();
             key.getLogger().log(
                  LogService.LOG_WARNING,
                  "Could not get service from serviceobjects for ref {0}", 
null, getRef() );
@@ -96,8 +98,8 @@ public abstract class AbstractPrototypeR
     }
 
        @SuppressWarnings("unchecked")
-    private void doUngetService(ComponentContextImpl<S> key, final T service) {
-               try 
+    private void doUngetService(ScrComponentContext key, final T service) {
+               try
                {
                        
key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService(
 service );
                }

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
 Thu Feb 13 07:36:01 2020
@@ -27,9 +27,10 @@ import java.util.TreeMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.felix.scr.component.ExtComponentContext;
 import org.apache.felix.scr.impl.helper.ComponentServiceObjectsHelper;
 import org.apache.felix.scr.impl.helper.ReadOnlyDictionary;
+import org.apache.felix.scr.impl.inject.RefPair;
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Bundle;
@@ -44,7 +45,7 @@ import org.osgi.service.log.LogService;
  * Implementation for the ComponentContext interface
  *
  */
-public class ComponentContextImpl<S> implements ExtComponentContext {
+public class ComponentContextImpl<S> implements ScrComponentContext {
 
     private final SingleComponentManager<S> m_componentManager;
 
@@ -92,6 +93,7 @@ public class ComponentContextImpl<S> imp
         this.serviceObjectsHelper.cleanup();
     }
 
+    @Override
     public ComponentServiceObjectsHelper getComponentServiceObjectsHelper()
     {
         return this.serviceObjectsHelper;
@@ -204,6 +206,7 @@ public class ComponentContextImpl<S> imp
         return m_usingBundle;
     }
 
+    @Override
     public ComponentLogger getLogger()
     {
         return this.m_componentManager.getLogger();
@@ -305,6 +308,7 @@ public class ComponentContextImpl<S> imp
 
     }
 
+    @Override
     public synchronized Map<RefPair<?, ?>, Object> getBoundValues(final String 
key)
     {
         if ( this.boundValues == null )

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
 Thu Feb 13 07:36:01 2020
@@ -29,6 +29,7 @@ import java.util.Map;
 import org.apache.felix.scr.component.ExtFactoryComponentInstance;
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.inject.ComponentMethods;
+import org.apache.felix.scr.impl.inject.RefPair;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.apache.felix.scr.impl.metadata.TargetedPID;

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
 Thu Feb 13 07:36:01 2020
@@ -33,6 +33,8 @@ import java.util.concurrent.atomic.Atomi
 import org.apache.felix.scr.impl.helper.Coercions;
 import org.apache.felix.scr.impl.inject.BindParameters;
 import org.apache.felix.scr.impl.inject.MethodResult;
+import org.apache.felix.scr.impl.inject.OpenStatus;
+import org.apache.felix.scr.impl.inject.RefPair;
 import org.apache.felix.scr.impl.inject.ReferenceMethod;
 import org.apache.felix.scr.impl.inject.ReferenceMethods;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
@@ -1568,11 +1570,13 @@ public class DependencyManager<S, T> imp
         return m_customizer.prebind(key);
     }
 
-    public static final class OpenStatus<S, T> {
+    public static final class OpenStatusImpl<S, T> implements OpenStatus<S, T> 
{
         private final DependencyManager<S, T> dm;
-        OpenStatus(DependencyManager<S, T> dm) {
+
+        OpenStatusImpl(DependencyManager<S, T> dm) {
             this.dm = dm;
         }
+        @Override
         public Collection<RefPair<S, T>> getRefs(AtomicInteger trackingCount) {
             return dm.m_customizer.getRefs(trackingCount);
         }
@@ -1589,7 +1593,7 @@ public class DependencyManager<S, T> imp
     OpenStatus<S, T> open(ComponentContextImpl<S> componentContext, EdgeInfo 
edgeInfo)
     {
         int serviceCount = 0;
-        final OpenStatus<S, T> status = new OpenStatus<>(this);
+        final OpenStatus<S, T> status = new OpenStatusImpl<>(this);
         Collection<RefPair<S, T>> refs;
         AtomicInteger trackingCount = new AtomicInteger();
         CountDownLatch openLatch;
@@ -1681,9 +1685,9 @@ public class DependencyManager<S, T> imp
             {
                 invokeUnbindMethod(componentContext, boundRef, 
trackingCount.get(), edgeInfo);
             }
-            
+
             boundRef.ungetServiceObject(componentContext);
-            
+
         }
         latch.countDown();
     }
@@ -2309,7 +2313,7 @@ public class DependencyManager<S, T> imp
         }
         else
         {
-            refPair.setFailed();
+            refPair.markFailed();
             return false;
         }
     }

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
 Thu Feb 13 07:36:01 2020
@@ -26,6 +26,7 @@ import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -33,7 +34,7 @@ import org.osgi.framework.ServiceReferen
  */
 public class MultiplePrototypeRefPair<S, T> extends 
AbstractPrototypeRefPair<S, T>
 {
-    private final ConcurrentMap<ComponentContextImpl<S>, T> instances = new 
ConcurrentHashMap<>();
+    private final ConcurrentMap<ScrComponentContext, T> instances = new 
ConcurrentHashMap<>();
 
     public MultiplePrototypeRefPair( ServiceReference<T> ref )
     {
@@ -47,23 +48,23 @@ public class MultiplePrototypeRefPair<S,
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key) {
+    public T getServiceObject(ScrComponentContext key) {
         return instances.get(key);
     }
 
     @Override
-    public boolean setServiceObject(ComponentContextImpl<S> key, T 
serviceObject) {
+    public boolean setServiceObject(ScrComponentContext key, T serviceObject) {
         return instances.putIfAbsent(key, serviceObject) == null;
     }
 
     @Override
-    protected T remove(ComponentContextImpl<S> key) {
+    protected T remove(ScrComponentContext key) {
         return instances.remove(key);
     }
 
     @Override
-    protected Collection<Entry<ComponentContextImpl<S>, T>> clearEntries() {
-        Collection<Entry<ComponentContextImpl<S>, T>> result = new 
ArrayList<>(instances.entrySet());
+    protected Collection<Entry<ScrComponentContext, T>> clearEntries() {
+        Collection<Entry<ScrComponentContext, T>> result = new 
ArrayList<>(instances.entrySet());
         instances.clear();
         return result;
     }

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
 Thu Feb 13 07:36:01 2020
@@ -27,6 +27,7 @@ import java.util.IdentityHashMap;
 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.RefPair;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentConstants;

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
 Thu Feb 13 07:36:01 2020
@@ -31,8 +31,9 @@ import java.util.concurrent.atomic.Atomi
 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.OpenStatus;
+import org.apache.felix.scr.impl.inject.RefPair;
 import org.apache.felix.scr.impl.inject.ReferenceMethod;
-import org.apache.felix.scr.impl.manager.DependencyManager.OpenStatus;
 import org.apache.felix.scr.impl.metadata.DSVersion;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.apache.felix.scr.impl.metadata.TargetedPID;
@@ -237,16 +238,17 @@ public class SingleComponentManager<S> e
         }
 
         // bind target services
-        final List<DependencyManager.OpenStatus<S, ?>> openStatusList = new 
ArrayList<>();
+        final List<OpenStatus<S, ?>> openStatusList = new ArrayList<>();
 
-        final Map<ReferenceMetadata, DependencyManager.OpenStatus<S, ?>> 
paramMap = ( getComponentMetadata().getNumberOfConstructorParameters() > 0 ? 
new HashMap<ReferenceMetadata, DependencyManager.OpenStatus<S, ?>>() : null);
+        final Map<ReferenceMetadata, OpenStatus<S, ?>> paramMap = 
(getComponentMetadata()
+                .getNumberOfConstructorParameters() > 0 ? new 
HashMap<ReferenceMetadata, OpenStatus<S, ?>>() : null);
         boolean failed = false;
         for ( DependencyManager<S, ?> dm : getDependencyManagers())
         {
             // if a dependency turned unresolved since the validation check,
             // creating the instance fails here, so we deactivate and return
             // null.
-            DependencyManager.OpenStatus<S, ?> open = dm.open( 
componentContext, componentContext.getEdgeInfo( dm ) );
+            OpenStatus<S, ?> open = dm.open(componentContext, 
componentContext.getEdgeInfo(dm));
             if ( open == null )
             {
                 getLogger().log( LogService.LOG_DEBUG, "Cannot create 
component instance due to failure to bind reference {0}",
@@ -300,10 +302,10 @@ public class SingleComponentManager<S> e
             setter.presetComponentContext( componentContext );
 
             // 4. Bind the target services
-            final Iterator<DependencyManager.OpenStatus<S, ?>> iter = 
openStatusList.iterator();
+            final Iterator<OpenStatus<S, ?>> iter = openStatusList.iterator();
             for ( DependencyManager<S, ?> dm: getDependencyManagers())
             {
-                final DependencyManager.OpenStatus<S, ?> open = iter.next();
+                final OpenStatus<S, ?> open = iter.next();
                 if ( !dm.bind(componentContext, (OpenStatus) open) )
                 {
                     getLogger().log( LogService.LOG_DEBUG, "Cannot create 
component instance due to failure to bind reference {0}",

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
 Thu Feb 13 07:36:01 2020
@@ -20,13 +20,14 @@
 
 package org.apache.felix.scr.impl.manager;
 
+import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
-import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -34,7 +35,7 @@ import org.osgi.framework.ServiceReferen
  */
 public class SinglePrototypeRefPair<S, T> extends AbstractPrototypeRefPair<S, 
T>
 {
-    private final 
AtomicReference<SimpleImmutableEntry<ComponentContextImpl<S>, T>> instance = 
new AtomicReference<>();
+    private final AtomicReference<SimpleImmutableEntry<ScrComponentContext, 
T>> instance = new AtomicReference<>();
 
     public SinglePrototypeRefPair( ServiceReference<T> ref )
     {
@@ -48,22 +49,22 @@ public class SinglePrototypeRefPair<S, T
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key) {
+    public T getServiceObject(ScrComponentContext key) {
         return internalGetServiceObject(key, false);
     }
 
     @Override
-    public boolean setServiceObject(ComponentContextImpl<S> key, T 
serviceObject) {
+    public boolean setServiceObject(ScrComponentContext key, T serviceObject) {
         return instance.compareAndSet(null, new SimpleImmutableEntry<>(key, 
serviceObject));
     }
 
     @Override
-    protected T remove(ComponentContextImpl<S> key) {
+    protected T remove(ScrComponentContext key) {
         return internalGetServiceObject(key, true);
     }
 
-    private T internalGetServiceObject(ComponentContextImpl<S> key, boolean 
remove) {
-        SimpleImmutableEntry<ComponentContextImpl<S>, T> entry = 
instance.get();
+    private T internalGetServiceObject(ScrComponentContext key, boolean 
remove) {
+        SimpleImmutableEntry<ScrComponentContext, T> entry = instance.get();
         if (entry == null) {
             return null;
         }
@@ -75,9 +76,9 @@ public class SinglePrototypeRefPair<S, T
     }
 
     @Override
-    protected Collection<Entry<ComponentContextImpl<S>, T>> clearEntries() {
-        Map.Entry<ComponentContextImpl<S>, T> entry = instance.getAndSet(null);
-        return entry == null ? Collections.<Entry<ComponentContextImpl<S>, 
T>>emptyList() : Collections.singleton(entry);
+    protected Collection<Entry<ScrComponentContext, T>> clearEntries() {
+        Map.Entry<ScrComponentContext, T> entry = instance.getAndSet(null);
+        return entry == null ? Collections.<Entry<ScrComponentContext, 
T>>emptyList() : Collections.singleton(entry);
     }
 
 }

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java
 Thu Feb 13 07:36:01 2020
@@ -22,6 +22,8 @@ package org.apache.felix.scr.impl.manage
 
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.felix.scr.impl.inject.RefPair;
+import org.apache.felix.scr.impl.inject.ScrComponentContext;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
@@ -39,24 +41,24 @@ public class SingleRefPair<S, T> extends
     }
 
     @Override
-    public T getServiceObject(ComponentContextImpl<S> key)
+    public T getServiceObject(ScrComponentContext key)
     {
         return serviceObjectRef.get();
     }
 
     @Override
-    public boolean setServiceObject( ComponentContextImpl<S> key, T 
serviceObject )
+    public boolean setServiceObject(ScrComponentContext key, T serviceObject)
     {
         boolean set = serviceObjectRef.compareAndSet( null, serviceObject );
         if ( serviceObject != null)
         {
-            failed = false;
+            clearFailed();
         }
         return set;
     }
 
     @Override
-    public T ungetServiceObject(ComponentContextImpl<S> key) {
+    public T ungetServiceObject(ScrComponentContext key) {
         // null operation for singleRefPair
         return null;
     }
@@ -81,12 +83,12 @@ public class SingleRefPair<S, T> extends
     }
 
     @Override
-    public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext 
context)
+    public boolean getServiceObject(ScrComponentContext key, BundleContext 
context)
     {
         T service = context.getService( getRef() );
         if ( service == null )
         {
-            setFailed();
+            markFailed();
             key.getLogger().log(
                  LogService.LOG_WARNING,
                  "Could not get service from ref {0}", null, getRef() );

Modified: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/PackageIsolationTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/PackageIsolationTest.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/PackageIsolationTest.java
 (original)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/PackageIsolationTest.java
 Thu Feb 13 07:36:01 2020
@@ -55,6 +55,7 @@ public class PackageIsolationTest extend
                 "org/apache/felix/scr/impl/helper",
                 "org/apache/felix/scr/impl/inject",
                 "org/apache/felix/scr/impl/inject/field",
+                "org/apache/felix/scr/impl/inject/internal",
                 "org/apache/felix/scr/impl/inject/methods",
                 "org/apache/felix/scr/impl/logger",
                 "org/apache/felix/scr/impl/manager",

Added: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java?rev=1873971&view=auto
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
 (added)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
 Thu Feb 13 07:36:01 2020
@@ -0,0 +1,708 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.inject.internal;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scr.impl.inject.internal.Annotations;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+
+import junit.framework.TestCase;
+
+public class AnnotationTest extends TestCase
+{
+
+    public void testMapIdentifierToKey() throws Exception
+    {
+        assertEquals("foo", Annotations.mapIdentifierToKey("foo"));
+        assertEquals("foo", Annotations.mapIdentifierToKey("$foo"));
+        assertEquals("foo", Annotations.mapIdentifierToKey("foo$"));
+        assertEquals("$foo", Annotations.mapIdentifierToKey("$$foo"));
+        assertEquals("foobar", Annotations.mapIdentifierToKey("foo$bar"));
+        assertEquals("foo$bar", Annotations.mapIdentifierToKey("foo$$bar"));
+        assertEquals("foo.", Annotations.mapIdentifierToKey("foo_"));
+        assertEquals("foo_", Annotations.mapIdentifierToKey("foo__"));
+        assertEquals(".foo", Annotations.mapIdentifierToKey("_foo"));
+        assertEquals("_foo", Annotations.mapIdentifierToKey("__foo"));
+        assertEquals("foo.bar", Annotations.mapIdentifierToKey("foo_bar"));
+        assertEquals("foo_bar", Annotations.mapIdentifierToKey("foo__bar"));
+        assertEquals("foo$", Annotations.mapIdentifierToKey("foo$$$"));
+        assertEquals("foo_.", Annotations.mapIdentifierToKey("foo___"));
+        assertEquals("foo-.bar", Annotations.mapIdentifierToKey("foo$_$_bar"));
+        assertEquals("six-prop", Annotations.mapIdentifierToKey("six$_$prop"));
+        assertEquals("seven$.prop", 
Annotations.mapIdentifierToKey("seven$$_$prop"));
+    }
+
+    public void testMapTypeNameToKey() throws Exception
+    {
+        assertEquals("service.ranking", 
Annotations.mapTypeNameToKey("ServiceRanking"));
+        assertEquals("some_value", Annotations.mapTypeNameToKey("Some_Value"));
+        assertEquals("osgi.property", 
Annotations.mapTypeNameToKey("OSGiProperty"));
+    }
+
+    public enum E1 {a, b, c}
+    public @interface A1 {
+        boolean bool();
+        byte byt();
+        char cha();
+        Class<?> clas();
+        E1 e1();
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private Bundle mockBundle() throws ClassNotFoundException
+    {
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.loadClass(String.class.getName())).thenReturn((Class) 
String.class);
+        Mockito.when(b.loadClass(Integer.class.getName())).thenReturn((Class) 
Integer.class);
+        return b;
+    }
+
+    public void testA1() throws Exception
+    {
+        Map<String, Object> values = allValues();
+
+        Object o = Annotations.toObject( A1.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1", o instanceof A1);
+
+        A1 a = (A1) o;
+        checkA1(a);
+    }
+
+    private void checkA1(A1 a)
+    {
+        assertEquals(true, a.bool());
+        assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
+        assertEquals(String.class, a.clas());
+        assertEquals(E1.a, a.e1());
+        assertEquals(3.14d, a.doubl());
+        assertEquals(500f, a.floa());
+        assertEquals(3, a.integer());
+        assertEquals(12345678l,  a.lon());
+        assertEquals((short)3, a.shor());
+        assertEquals("3", a.string());
+    }
+
+    public void testA1FromArray() throws Exception
+    {
+        Map<String, Object> values = arrayValues();
+
+        Object o = Annotations.toObject( A1.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1", o instanceof A1);
+
+        A1 a = (A1) o;
+        assertEquals(true, a.bool());
+        assertEquals((byte)12, a.byt());
+        assertEquals(String.class, a.clas());
+        assertEquals(E1.a, a.e1());
+        assertEquals(3.14d, a.doubl());
+        assertEquals(500f, a.floa());
+        assertEquals(3, a.integer());
+        assertEquals(12345678l,  a.lon());
+        assertEquals((short)3, a.shor());
+        assertEquals(null, a.string());
+    }
+
+    private Map<String, Object> allValues()
+    {
+        Map<String, Object> values = new HashMap<>();
+        values.put("bool", "true");
+        values.put("byt", 12l);
+        values.put("cha", 'c');
+        values.put("clas", String.class.getName());
+        values.put("e1", E1.a.toString());
+        values.put("doubl", "3.14");
+        values.put("floa", 500l);
+        values.put("integer", 3.0d);
+        values.put("lon", "12345678");
+        values.put("shor", 3l);
+        values.put("string", 3);
+        values.put("array", new String[]{"foo", "bar"});
+        return values;
+    }
+
+    public void testA1NoValues() throws Exception
+    {
+        Map<String, Object> values = new HashMap<>();
+
+        Object o = Annotations.toObject( A1.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1", o instanceof A1);
+
+        A1 a = (A1) o;
+        assertEquals(false, a.bool());
+        assertEquals((byte)0, a.byt());
+        assertEquals((char)0, a.cha());
+        assertEquals(null, a.clas());
+        assertEquals(null, a.e1());
+        assertEquals(0d, a.doubl());
+        assertEquals(0f, a.floa());
+        assertEquals(0, a.integer());
+        assertEquals(0l,  a.lon());
+        assertEquals((short)0, a.shor());
+        assertEquals(null, a.string());
+    }
+
+    public @interface A2 {
+        boolean bool() default true;
+        byte byt() default 5;
+        char cha() default 'a';
+        Class<?> clas() default Integer.class;
+        E1 e1() default E1.b;
+        double doubl() default -2;
+        float floa() default -4;
+        int integer() default -5;
+        long lon() default Long.MIN_VALUE;
+        short shor() default -8;
+        String string() default "default";
+        String[] array() default {};
+    }
+
+    public void testA2AllValues() throws Exception
+    {
+        Map<String, Object> values = allValues();
+
+        Object o = Annotations.toObject( A2.class, values, mockBundle(), 
false);
+        assertTrue("expected an A2", o instanceof A2);
+
+        A2 a = (A2) o;
+        assertEquals(true, a.bool());
+        assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
+        assertEquals(String.class, a.clas());
+        assertEquals(E1.a, a.e1());
+        assertEquals(3.14d, a.doubl());
+        assertEquals(500f, a.floa());
+        assertEquals(3, a.integer());
+        assertEquals(12345678l,  a.lon());
+        assertEquals((short)3, a.shor());
+        assertEquals("3", a.string());
+        assertArrayEquals(new String[]{"foo", "bar"}, a.array());
+    }
+
+    public void testA2DefaultValues() throws Exception
+    {
+        Map<String, Object> values = Collections.emptyMap();
+
+        Object o = Annotations.toObject( A2.class, values, mockBundle(), 
false);
+        assertTrue("expected an A2", o instanceof A2);
+
+        A2 a = (A2) o;
+        assertEquals(false, a.bool());
+        assertEquals((byte)0, a.byt());
+        assertEquals((char)0, a.cha());
+        assertEquals(null, a.clas());
+        assertEquals(null, a.e1());
+        assertEquals(0.0, a.doubl());
+        assertEquals(0.0f, a.floa());
+        assertEquals(0, a.integer());
+        assertEquals(0, a.lon());
+        assertEquals((short)0, a.shor());
+        assertEquals(null, a.string());
+        assertEquals(0, a.array().length);
+    }
+
+    public @interface A1Arrays {
+        boolean[] bool();
+        byte[] byt();
+        char[] cha();
+        Class<?>[] clas();
+        E1[] e1();
+        double[] doubl();
+        float[] floa();
+        int[] integer();
+        long[] lon();
+        short[] shor();
+        String[] string();
+    }
+
+    public void testA1ArraysNoValues() throws Exception
+    {
+        Map<String, Object> values = new HashMap<>();
+
+        Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1Arrays", o instanceof A1Arrays);
+
+        A1Arrays a = (A1Arrays) o;
+        assertEquals(0, a.bool().length);
+        assertEquals(0, a.byt().length);
+        assertEquals(0, a.cha().length);
+        assertEquals(0, a.clas().length);
+        assertEquals(0, a.e1().length);
+        assertEquals(0, a.doubl().length);
+        assertEquals(0, a.floa().length);
+        assertEquals(0, a.integer().length);
+        assertEquals(0,  a.lon().length);
+        assertEquals(0, a.shor().length);
+        assertEquals(0, a.string().length);
+    }
+
+    public void testA1Array() throws Exception
+    {
+        Map<String, Object> values = allValues();
+
+        Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1Arrays", o instanceof A1Arrays);
+
+        A1Arrays a = (A1Arrays) o;
+        assertArrayEquals(new boolean[] {true}, a.bool());
+        assertArrayEquals(new byte[] {(byte)12}, a.byt());
+        assertArrayEquals(new char[] {'c'}, a.cha());
+        assertArrayEquals(new Class<?>[] {String.class}, a.clas());
+        assertArrayEquals(new E1[] {E1.a}, a.e1());
+        assertArrayEquals(new double[] {3.14d}, a.doubl());
+        assertArrayEquals(new float[] {500f}, a.floa());
+        assertArrayEquals(new int[] {3}, a.integer());
+        assertArrayEquals(new long[] {12345678l},  a.lon());
+        assertArrayEquals(new short[] {(short)3}, a.shor());
+        assertArrayEquals(new String[] {"3"}, a.string());
+    }
+
+    private void assertArrayEquals(Object a, Object b)
+    {
+        assertTrue(a.getClass().isArray());
+        assertTrue(b.getClass().isArray());
+        assertEquals("wrong length", Array.getLength(a), Array.getLength(b));
+        assertEquals("wrong type", a.getClass().getComponentType(), 
b.getClass().getComponentType());
+        for (int i = 0; i < Array.getLength(a); i++)
+        {
+            assertEquals("different value at " + i, Array.get(a, i), 
Array.get(b, i));
+        }
+
+    }
+
+    private Map<String, Object> arrayValues()
+    {
+        Map<String, Object> values = new HashMap<>();
+        values.put("bool", new boolean[] {true, false});
+        values.put("byt", new byte[] {12, 3});
+        values.put("cha", new char[] {'c', 'h', 'a', 'r'});
+        values.put("clas", new String[] {String.class.getName(), 
Integer.class.getName()});
+        values.put("e1", new String[] {E1.a.name(), E1.b.name()});
+        values.put("doubl", new double[] {3.14, 2.78, 9});
+        values.put("floa", new float[] {500, 37.44f});
+        values.put("integer", new int[] {3, 6, 9});
+        values.put("lon", new long[] {12345678l, -1});
+        values.put("shor", new short[] {3, 88});
+        values.put("string", new String[] {});
+        return values;
+    }
+
+    public void testA1ArrayFromArray() throws Exception
+    {
+        Map<String, Object> values = arrayValues();
+
+        doA1ArrayTest(values);
+    }
+
+    public void testA1ArrayFromCollection() throws Exception
+    {
+        Map<String, Object> values = arrayValues();
+        Map<String, Object> collectionValues = new HashMap<>();
+        for (Map.Entry<String, Object> entry: values.entrySet())
+        {
+            collectionValues.put(entry.getKey(), toList(entry.getValue()));
+        }
+
+        doA1ArrayTest(collectionValues);
+    }
+
+    private List<?> toList(Object value)
+    {
+        List<Object> result = new ArrayList<>();
+        for (int i = 0; i < Array.getLength(value); i++)
+        {
+            result.add(Array.get(value, i));
+        }
+        return result;
+    }
+
+    private void doA1ArrayTest(Map<String, Object> values) throws 
ClassNotFoundException
+    {
+        Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), 
false);
+        assertTrue("expected an A1Arrays", o instanceof A1Arrays);
+
+        A1Arrays a = (A1Arrays) o;
+        assertArrayEquals(new boolean[] {true, false}, a.bool());
+        assertArrayEquals(new byte[] {12, 3}, a.byt());
+        assertArrayEquals(new char[] {'c', 'h', 'a', 'r'}, a.cha());
+        assertArrayEquals(new Class<?>[] {String.class, Integer.class}, 
a.clas());
+        assertArrayEquals(new E1[] {E1.a, E1.b}, a.e1());
+        assertArrayEquals(new double[] {3.14, 2.78, 9}, a.doubl());
+        assertArrayEquals(new float[] {500f, 37.44f}, a.floa());
+        assertArrayEquals(new int[] {3, 6, 9}, a.integer());
+        assertArrayEquals(new long[] {12345678l, -1},  a.lon());
+        assertArrayEquals(new short[] {(short)3, 88}, a.shor());
+        assertArrayEquals(new String[] {}, a.string());
+    }
+
+    public @interface B1 {
+        boolean bool();
+        byte byt();
+        Class<?> clas();
+        E1 e1();
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+        A1 a1();
+        A1[] a1array();
+    }
+
+    public void testB1() throws Exception
+    {
+        Map<String, Object> values = b1Values();
+
+        Object o = Annotations.toObject( B1.class, values, mockBundle(), true);
+        assertTrue("expected an B1 " + o, o instanceof B1);
+        B1 b = (B1) o;
+        checkB1(b);
+    }
+
+    private void checkB1(B1 b)
+    {
+        checkA1(b.a1());
+        assertEquals(3, b.a1array().length);
+        checkA1(b.a1array()[0]);
+        checkA1(b.a1array()[1]);
+        checkA1(b.a1array()[2]);
+    }
+
+    private Map<String, Object> b1Values()
+    {
+        Map<String, Object> a1Values = allValues();
+        Map<String, Object> values = allValues();
+        nest(values, "a1", 0, a1Values);
+        nest(values, "a1array", 0, a1Values);
+        nest(values, "a1array", 1, a1Values);
+        nest(values, "a1array", 2, a1Values);
+        return values;
+    }
+
+    private void nest(Map<String, Object> values, String key, int i,
+        Map<String, Object> a1Values)
+    {
+        for (Map.Entry<String, Object> entry: a1Values.entrySet())
+        {
+            values.put(key + "." + i + "." + entry.getKey(), entry.getValue());
+        }
+    }
+
+    public @interface C1 {
+        boolean bool();
+        byte byt();
+        Class<?> clas();
+        E1 e1();
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+        B1 b1();
+        B1[] b1array();
+    }
+
+    public void testC1() throws Exception
+    {
+        Map<String, Object> values = c1Values();
+
+        Object o = Annotations.toObject( C1.class, values, mockBundle(), true);
+        assertTrue("expected an B1 " + o, o instanceof C1);
+        C1 c = (C1) o;
+        checkB1(c.b1());
+        assertEquals(3, c.b1array().length);
+        checkB1(c.b1array()[0]);
+        checkB1(c.b1array()[1]);
+        checkB1(c.b1array()[2]);
+
+    }
+
+    private Map<String, Object> c1Values()
+    {
+        Map<String, Object> b1Values = b1Values();
+        Map<String, Object> values = allValues();
+        nest(values, "b1", 0, b1Values);
+        nest(values, "b1array", 0, b1Values);
+        nest(values, "b1array", 1, b1Values);
+        nest(values, "b1array", 2, b1Values);
+        return values;
+    }
+
+    public interface I0 {
+        boolean bool();
+        byte byt();
+        Class<?> clas();
+        E1 e1();
+    }
+    public interface AI1 extends I0 {
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+    }
+
+    public interface BI1 extends I0 {
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+        AI1 a1();
+        AI1[] a1array();
+    }
+
+    public interface CI1 extends I0 {
+        double doubl();
+        float floa();
+        int integer();
+        long lon();
+        short shor();
+        String string();
+        BI1 b1();
+        BI1[] b1array();
+    }
+
+    public void testAI1() throws Exception
+    {
+        Map<String, Object> values = allValues();
+
+        Object o = Annotations.toObject( AI1.class, values, mockBundle(), 
true);
+        assertTrue("expected an AI1", o instanceof AI1);
+
+        AI1 a = (AI1) o;
+        checkAI1(a);
+    }
+
+    private void checkAI1(AI1 a)
+    {
+        assertEquals(true, a.bool());
+        assertEquals((byte)12, a.byt());
+        assertEquals(String.class, a.clas());
+        assertEquals(E1.a, a.e1());
+        assertEquals(3.14d, a.doubl());
+        assertEquals(500f, a.floa());
+        assertEquals(3, a.integer());
+        assertEquals(12345678l,  a.lon());
+        assertEquals((short)3, a.shor());
+        assertEquals("3", a.string());
+    }
+
+    public void testBI1() throws Exception
+    {
+        Map<String, Object> values = b1Values();
+
+        Object o = Annotations.toObject( BI1.class, values, mockBundle(), 
true);
+        assertTrue("expected an B1 " + o, o instanceof BI1);
+        BI1 b = (BI1) o;
+        checkBI1(b);
+    }
+
+    private void checkBI1(BI1 b)
+    {
+        checkAI1(b.a1());
+        assertEquals(3, b.a1array().length);
+        checkAI1(b.a1array()[0]);
+        checkAI1(b.a1array()[1]);
+        checkAI1(b.a1array()[2]);
+    }
+
+    public void testCI1() throws Exception
+    {
+        Map<String, Object> values = c1Values();
+
+        Object o = Annotations.toObject( CI1.class, values, mockBundle(), 
true);
+        assertTrue("expected an B1 " + o, o instanceof CI1);
+        CI1 c = (CI1) o;
+        checkBI1(c.b1());
+        assertEquals(3, c.b1array().length);
+        checkBI1(c.b1array()[0]);
+        checkBI1(c.b1array()[1]);
+        checkBI1(c.b1array()[2]);
+
+    }
+
+    class Odd
+    {
+        private final String content;
+
+        public Odd(String content)
+        {
+            this.content = content;
+        }
+
+        public String getContent()
+        {
+            return content;
+        }
+    }
+
+    class Odder extends Odd
+    {
+
+        public Odder(String content)
+        {
+            super(content);
+        }
+
+    }
+
+    interface OddTest
+    {
+        Odd odd1();
+
+        Odd odd2();
+
+        Odd odd3();
+
+        Odd odder1();
+
+        Odd odder2();
+
+        Odd odder3();
+    }
+
+    public void testOddClasses() throws Exception
+    {
+        Map<String, Object> values = new HashMap<>();
+        values.put("odd1", new Odd("one"));
+        values.put("odd2", Collections.singletonList(new Odd("two")));
+        values.put("odd3", new Odd[] {new Odd("three"), new Odd("four")});
+        values.put("odder1", new Odder("one"));
+        values.put("odder2", Collections.singletonList(new Odder("two")));
+        values.put("odder3", new Odder[] {new Odder("three"), new 
Odder("four")});
+
+        Object o = Annotations.toObject(OddTest.class, values, mockBundle(), 
true);
+        assertTrue("expected an OddTest", o instanceof OddTest);
+        OddTest ot = (OddTest)o;
+        assertOdd("one", ot.odd1());
+        assertOdd("two", ot.odd2());
+        assertOdd("three", ot.odd3());
+        assertOdder("one", ot.odder1());
+        assertOdder("two", ot.odder2());
+        assertOdder("three", ot.odder3());
+    }
+
+    public @interface SETest1 {
+        String value();
+    }
+
+    public @interface SETest2 {
+        boolean foo() default true;
+        String value();
+    }
+
+    public @interface SETest3 {
+        boolean foo();
+        String value();
+    }
+
+    public @interface SETest4 {
+        boolean foo();
+        String values();
+    }
+
+    public @interface PrefixTest {
+        String PREFIX_ = "org.apache.";
+
+        boolean foo() default true;
+        String[] values() default {"a"};
+        String value();
+    }
+
+    public @interface SingleElementTest {
+        String PREFIX_ = "org.apache.";
+
+        String value();
+    }
+
+    public void testSingleElementAnnotation() throws Exception
+    {
+        assertFalse(Annotations.isSingleElementAnnotation(Map.class));
+        assertTrue(Annotations.isSingleElementAnnotation(SETest1.class));
+        assertTrue(Annotations.isSingleElementAnnotation(SETest2.class));
+        assertFalse(Annotations.isSingleElementAnnotation(SETest3.class));
+        assertFalse(Annotations.isSingleElementAnnotation(SETest4.class));
+        
assertTrue(Annotations.isSingleElementAnnotation(SingleElementTest.class));
+    }
+
+    public void testGetPrefix() throws Exception
+    {
+        assertNull(Annotations.getPrefix(Map.class));
+        assertNull(Annotations.getPrefix(SETest1.class));
+        assertNull(Annotations.getPrefix(SETest2.class));
+        assertNull(Annotations.getPrefix(SETest3.class));
+        assertNull(Annotations.getPrefix(SETest4.class));
+        assertNull(Annotations.getPrefix(A1.class));
+        assertEquals("org.apache.", Annotations.getPrefix(PrefixTest.class));
+    }
+
+    public void testMappingWithPrefix() throws Exception
+    {
+        final Map<String, Object> values = new HashMap<>();
+        values.put("foo", false);
+        values.put("org.apache.foo", true);
+        values.put("values", "false-values");
+        values.put("org.apache.values", "true-values");
+        values.put("value", "false-value");
+        values.put("org.apache.prefix.test", "true-value");
+
+        final PrefixTest o = Annotations.toObject( PrefixTest.class, values, 
mockBundle(), true);
+        assertEquals("true-value", o.value());
+        assertEquals(1, o.values().length);
+        assertEquals("true-values", o.values()[0]);
+        assertEquals(true, o.foo());
+    }
+
+    public void testMappingWithPrefixSingleValue() throws Exception
+    {
+        final Map<String, Object> values = new HashMap<>();
+        values.put("value", "false-value");
+        values.put("org.apache.single.element.test", "true-value");
+
+        final SingleElementTest o = Annotations.toObject( 
SingleElementTest.class, values, mockBundle(), true);
+        assertEquals("true-value", o.value());
+    }
+
+    private void assertOdd(String expectedContent, Object actual) {
+        assertTrue("expected an Odd", actual instanceof Odd);
+        assertEquals("Expected Odd contents", expectedContent, 
((Odd)actual).getContent());
+    }
+    private void assertOdder(String expectedContent, Object actual) {
+        assertTrue("expected an Odder", actual instanceof Odder);
+        assertEquals("Expected Odd contents", expectedContent, 
((Odder)actual).getContent());
+    }
+}

Propchange: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/internal/AnnotationTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Modified: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/ActivateMethodTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/ActivateMethodTest.java?rev=1873971&r1=1873970&r2=1873971&view=diff
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/ActivateMethodTest.java
 (original)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/ActivateMethodTest.java
 Thu Feb 13 07:36:01 2020
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.felix.scr.impl.inject.ActivatorParameter;
-import org.apache.felix.scr.impl.inject.ComponentMethodsImpl;
+import org.apache.felix.scr.impl.inject.internal.ComponentMethodsImpl;
 import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.logger.MockComponentLogger;
 import org.apache.felix.scr.impl.manager.ComponentActivator;

Added: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/BindMethodTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/BindMethodTest.java?rev=1873971&view=auto
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/BindMethodTest.java
 (added)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/inject/methods/BindMethodTest.java
 Thu Feb 13 07:36:01 2020
@@ -0,0 +1,506 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.inject.methods;
+
+
+import org.apache.felix.scr.impl.MockBundle;
+import org.apache.felix.scr.impl.inject.BindParameters;
+import org.apache.felix.scr.impl.inject.RefPair;
+import org.apache.felix.scr.impl.inject.internal.ComponentMethodsImpl;
+import org.apache.felix.scr.impl.inject.methods.BindMethod;
+import org.apache.felix.scr.impl.logger.ComponentLogger;
+import org.apache.felix.scr.impl.logger.MockComponentLogger;
+import org.apache.felix.scr.impl.manager.ComponentActivator;
+import org.apache.felix.scr.impl.manager.ComponentContainer;
+import org.apache.felix.scr.impl.manager.ComponentContextImpl;
+import org.apache.felix.scr.impl.manager.SingleComponentManager;
+import org.apache.felix.scr.impl.manager.SingleRefPair;
+import org.apache.felix.scr.impl.manager.components.FakeService;
+import org.apache.felix.scr.impl.manager.components.T1;
+import org.apache.felix.scr.impl.manager.components.T1MapSR;
+import org.apache.felix.scr.impl.manager.components.T1a;
+import org.apache.felix.scr.impl.manager.components.T3;
+import org.apache.felix.scr.impl.manager.components2.T2;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+import junit.framework.TestCase;
+
+
+public class BindMethodTest extends TestCase
+{
+
+    private ServiceReference m_serviceReference;
+    private FakeService m_serviceInstance;
+    private BundleContext m_context;
+
+
+    @Override
+    public void setUp()
+    {
+        m_serviceReference = Mockito.mock( ServiceReference.class );
+        m_serviceInstance = Mockito.mock( FakeService.class );
+        m_context = Mockito.mock( BundleContext.class );
+
+        Mockito.when( m_context.getService( m_serviceReference ) ).thenReturn( 
m_serviceInstance );
+
+        Mockito.when( m_serviceReference.getPropertyKeys() ).thenReturn( new 
String[]
+            { Constants.SERVICE_ID } );
+        Mockito.when( m_serviceReference.getProperty( Constants.SERVICE_ID ) 
).thenReturn( "Fake Service" );
+    }
+
+
+    public void test_Unexistent()
+    {
+        testMethod( "unexistent", new T1(), DSVersion.DS10, null );
+        testMethod( "unexistent", new T1(), DSVersion.DS11, null );
+        testMethod( "unexistent", new T2(), DSVersion.DS10, null );
+        testMethod( "unexistent", new T2(), DSVersion.DS11, null );
+        testMethod( "unexistent", new T3(), DSVersion.DS10, null );
+        testMethod( "unexistent", new T3(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1()
+    {
+        testMethod( "privateT1", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT1", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1", new T2(), DSVersion.DS11, null );
+        testMethod( "privateT1", new T3(), DSVersion.DS10, null );
+        testMethod( "privateT1", new T3(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1SR()
+    {
+        testMethod( "privateT1SR", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1SR", new T1(), DSVersion.DS11, "privateT1SR" );
+        testMethod( "privateT1SR", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1SR", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1SI()
+    {
+        testMethod( "privateT1SI", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1SI", new T1(), DSVersion.DS11, "privateT1SI" );
+        testMethod( "privateT1SI", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1SI", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1SIMap()
+    {
+        testMethod( "privateT1SIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1SIMap", new T1(), DSVersion.DS11, 
"privateT1SIMap" );
+        testMethod( "privateT1SIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1SIMap", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1SSI()
+    {
+        testMethod( "privateT1SSI", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1SSI", new T1(), DSVersion.DS11, "privateT1SSI" );
+        testMethod( "privateT1SSI", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1SSI", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT1SSIMap()
+    {
+        testMethod( "privateT1SSIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT1SSIMap", new T1(), DSVersion.DS11, 
"privateT1SSIMap" );
+        testMethod( "privateT1SSIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT1SSIMap", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT2()
+    {
+        testMethod( "privateT2", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_privateT2SR()
+    {
+        testMethod( "privateT2SR", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2SR", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2SR", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2SR", new T2(), DSVersion.DS11, "privateT2SR" );
+    }
+
+
+    public void test_privateT2SI()
+    {
+        testMethod( "privateT2SI", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2SI", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2SI", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2SI", new T2(), DSVersion.DS11, "privateT2SI" );
+    }
+
+
+    public void test_privateT2SIMap()
+    {
+        testMethod( "privateT2SIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2SIMap", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2SIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2SIMap", new T2(), DSVersion.DS11, 
"privateT2SIMap" );
+    }
+
+
+    public void test_privateT2SSI()
+    {
+        testMethod( "privateT2SSI", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2SSI", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2SSI", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2SSI", new T2(), DSVersion.DS11, "privateT2SSI" );
+    }
+
+
+    public void test_privateT2SSIMap()
+    {
+        testMethod( "privateT2SSIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "privateT2SSIMap", new T1(), DSVersion.DS11, null );
+        testMethod( "privateT2SSIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "privateT2SSIMap", new T2(), DSVersion.DS11, 
"privateT2SSIMap" );
+    }
+
+
+    public void test_packageT1()
+    {
+        testMethod( "packageT1", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT1", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1", new T1a(), DSVersion.DS11, null );
+    }
+
+
+    public void test_packageT1SR()
+    {
+        testMethod( "packageT1SR", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1SR", new T1(), DSVersion.DS11, "packageT1SR" );
+        testMethod( "packageT1SR", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1SR", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1SR", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1SR", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1SR", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1SR", new T1a(), DSVersion.DS11, "packageT1SR" );
+    }
+
+
+    public void test_packageT1SI()
+    {
+        testMethod( "packageT1SI", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1SI", new T1(), DSVersion.DS11, "packageT1SI" );
+        testMethod( "packageT1SI", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1SI", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1SI", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1SI", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1SI", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1SI", new T1a(), DSVersion.DS11, "packageT1SI" );
+    }
+
+
+    public void test_packageT1SIMap()
+    {
+        testMethod( "packageT1SIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1SIMap", new T1(), DSVersion.DS11, 
"packageT1SIMap" );
+        testMethod( "packageT1SIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1SIMap", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1SIMap", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1SIMap", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1SIMap", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1SIMap", new T1a(), DSVersion.DS11, 
"packageT1SIMap" );
+    }
+
+
+    public void test_packageT1SSI()
+    {
+        testMethod( "packageT1SSI", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1SSI", new T1(), DSVersion.DS11, "packageT1SSI" );
+        testMethod( "packageT1SSI", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1SSI", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1SSI", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1SSI", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1SSI", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1SSI", new T1a(), DSVersion.DS11, "packageT1SSI" 
);
+    }
+
+
+    public void test_packageT1SSIMap()
+    {
+        testMethod( "packageT1SSIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT1SSIMap", new T1(), DSVersion.DS11, 
"packageT1SSIMap" );
+        testMethod( "packageT1SSIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT1SSIMap", new T2(), DSVersion.DS11, null );
+        testMethod( "packageT1SSIMap", new T3(), DSVersion.DS10, null );
+        testMethod( "packageT1SSIMap", new T3(), DSVersion.DS11, null );
+        testMethod( "packageT1SSIMap", new T1a(), DSVersion.DS10, null );
+        testMethod( "packageT1SSIMap", new T1a(), DSVersion.DS11, 
"packageT1SSIMap" );
+    }
+
+
+    public void test_packageT2()
+    {
+        testMethod( "packageT2", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_packageT2SR()
+    {
+        testMethod( "packageT2SR", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2SR", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2SR", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2SR", new T2(), DSVersion.DS11, "packageT2SR" );
+    }
+
+
+    public void test_packageT2SI()
+    {
+        testMethod( "packageT2SI", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2SI", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2SI", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2SI", new T2(), DSVersion.DS11, "packageT2SI" );
+    }
+
+
+    public void test_packageT2SIMap()
+    {
+        testMethod( "packageT2SIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2SIMap", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2SIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2SIMap", new T2(), DSVersion.DS11, 
"packageT2SIMap" );
+    }
+
+
+    public void test_packageT2SSI()
+    {
+        testMethod( "packageT2SSI", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2SSI", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2SSI", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2SSI", new T2(), DSVersion.DS11, "packageT2SSI" );
+    }
+
+
+    public void test_packageT2SSIMap()
+    {
+        testMethod( "packageT2SSIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "packageT2SSIMap", new T1(), DSVersion.DS11, null );
+        testMethod( "packageT2SSIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "packageT2SSIMap", new T2(), DSVersion.DS11, 
"packageT2SSIMap" );
+    }
+
+
+    public void test_protectedT1()
+    {
+        testMethod( "protectedT1", new T1(), DSVersion.DS10, null );
+        testMethod( "protectedT1", new T1(), DSVersion.DS11, null );
+        testMethod( "protectedT1", new T2(), DSVersion.DS10, null );
+        testMethod( "protectedT1", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_protectedT1SR()
+    {
+        testMethod( "protectedT1SR", new T1(), DSVersion.DS10, "protectedT1SR" 
);
+        testMethod( "protectedT1SR", new T1(), DSVersion.DS11, "protectedT1SR" 
);
+        testMethod( "protectedT1SR", new T2(), DSVersion.DS10, "protectedT1SR" 
);
+        testMethod( "protectedT1SR", new T2(), DSVersion.DS11, "protectedT1SR" 
);
+    }
+
+
+    public void test_protectedT1SI()
+    {
+        testMethod( "protectedT1SI", new T1(), DSVersion.DS10, "protectedT1SI" 
);
+        testMethod( "protectedT1SI", new T1(), DSVersion.DS11, "protectedT1SI" 
);
+        testMethod( "protectedT1SI", new T2(), DSVersion.DS10, "protectedT1SI" 
);
+        testMethod( "protectedT1SI", new T2(), DSVersion.DS11, "protectedT1SI" 
);
+    }
+
+
+    public void test_protectedT1SSI()
+    {
+        testMethod( "protectedT1SSI", new T1(), DSVersion.DS10, 
"protectedT1SSI" );
+        testMethod( "protectedT1SSI", new T1(), DSVersion.DS11, 
"protectedT1SSI" );
+        testMethod( "protectedT1SSI", new T2(), DSVersion.DS10, 
"protectedT1SSI" );
+        testMethod( "protectedT1SSI", new T2(), DSVersion.DS11, 
"protectedT1SSI" );
+    }
+
+
+    public void test_publicT1()
+    {
+        testMethod( "publicT1", new T1(), DSVersion.DS10, null );
+        testMethod( "publicT1", new T1(), DSVersion.DS11, null );
+        testMethod( "publicT1", new T2(), DSVersion.DS10, null );
+        testMethod( "publicT1", new T2(), DSVersion.DS11, null );
+    }
+
+
+    public void test_publicT1SR()
+    {
+        testMethod( "publicT1SR", new T1(), DSVersion.DS10, "publicT1SR" );
+        testMethod( "publicT1SR", new T1(), DSVersion.DS11, "publicT1SR" );
+        testMethod( "publicT1SR", new T2(), DSVersion.DS10, "publicT1SR" );
+        testMethod( "publicT1SR", new T2(), DSVersion.DS11, "publicT1SR" );
+    }
+
+
+    public void test_publicT1SI()
+    {
+        testMethod( "publicT1SI", new T1(), DSVersion.DS10, "publicT1SI" );
+        testMethod( "publicT1SI", new T1(), DSVersion.DS11, "publicT1SI" );
+        testMethod( "publicT1SI", new T2(), DSVersion.DS10, "publicT1SI" );
+        testMethod( "publicT1SI", new T2(), DSVersion.DS11, "publicT1SI" );
+    }
+
+
+    public void test_publicT1SIMap()
+    {
+        testMethod( "publicT1SIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "publicT1SIMap", new T1(), DSVersion.DS11, "publicT1SIMap" 
);
+        testMethod( "publicT1SIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "publicT1SIMap", new T2(), DSVersion.DS11, "publicT1SIMap" 
);
+    }
+
+
+    public void test_publicT1SSI()
+    {
+        testMethod( "publicT1SSI", new T1(), DSVersion.DS10, "publicT1SSI" );
+        testMethod( "publicT1SSI", new T1(), DSVersion.DS11, "publicT1SSI" );
+        testMethod( "publicT1SSI", new T2(), DSVersion.DS10, "publicT1SSI" );
+        testMethod( "publicT1SSI", new T2(), DSVersion.DS11, "publicT1SSI" );
+    }
+
+
+    public void test_publicT1SSIMap()
+    {
+        testMethod( "publicT1SSIMap", new T1(), DSVersion.DS10, null );
+        testMethod( "publicT1SSIMap", new T1(), DSVersion.DS11, 
"publicT1SSIMap" );
+        testMethod( "publicT1SSIMap", new T2(), DSVersion.DS10, null );
+        testMethod( "publicT1SSIMap", new T2(), DSVersion.DS11, 
"publicT1SSIMap" );
+    }
+
+
+    public void test_suitable()
+    {
+        // T1 should use its own public implementation
+        testMethod( "suitable", new T1(), DSVersion.DS10, "suitableT1" );
+        testMethod( "suitable", new T1(), DSVersion.DS11, "suitableT1" );
+
+        // T2's private implementation is only visible for DS 1.1
+        testMethod( "suitable", new T2(), DSVersion.DS10, null );
+        testMethod( "suitable", new T2(), DSVersion.DS11, "suitableT2" );
+
+        // T3 extends T2 and cannot see T2's private method
+        testMethod( "suitable", new T3(), DSVersion.DS10, null );
+        testMethod( "suitable", new T3(), DSVersion.DS11, null );
+
+        // T1a extends T1 and uses T1's public method
+        testMethod( "suitable", new T1a(), DSVersion.DS10, "suitableT1" );
+        testMethod( "suitable", new T1a(), DSVersion.DS11, "suitableT1" );
+    }
+
+    public void test_13()
+    {
+        //single map param
+        testMethod( "packageT1Map", new T1(), DSVersion.DS12, null);
+        testMethod( "packageT1Map", new T1(), DSVersion.DS13, "packageT1Map");
+
+        //map, sr
+        testMethod( "packageT1MapSR", new T1MapSR(), DSVersion.DS12, null);
+        testMethod( "packageT1MapSR", new T1MapSR(), DSVersion.DS13, 
"packageT1MapSR");
+    }
+
+
+    private void testMethod( final String methodName, final T1 component, 
final DSVersion dsVersion,
+        final String expectCallPerformed )
+    {
+        ComponentContainer container = newContainer();
+        SingleComponentManager icm = new SingleComponentManager( container, 
new ComponentMethodsImpl() );
+        BindMethod bm = new BindMethod( methodName, component.getClass(),
+                FakeService.class.getName(), dsVersion, false );
+        RefPair refPair = new SingleRefPair( m_serviceReference );
+        ComponentContextImpl<T1> cc = new ComponentContextImpl(icm, new 
MockBundle(), null);
+        assertTrue( bm.getServiceObject( new BindParameters(cc, refPair), 
m_context ) );
+        BindParameters bp = new BindParameters(cc, refPair);
+        bm.invoke( component, bp, null );
+        assertEquals( expectCallPerformed, component.callPerformed );
+    }
+
+    private ComponentContainer newContainer()
+    {
+        final ComponentActivator activator = 
Mockito.mock(ComponentActivator.class);
+        final ComponentMetadata metadata = newMetadata();
+        ComponentContainer container = new ComponentContainer() {
+
+            @Override
+            public ComponentActivator getActivator()
+            {
+                return activator;
+            }
+
+            @Override
+            public ComponentMetadata getComponentMetadata()
+            {
+                return metadata;
+            }
+
+            @Override
+            public void disposed(SingleComponentManager component)
+            {
+            }
+
+            public boolean isEnabled()
+            {
+                return false;
+            }
+
+            @Override
+            public ComponentLogger getLogger() {
+                return new MockComponentLogger();
+            }
+        };
+        return container;
+    }
+
+       private ComponentMetadata newMetadata() {
+               ComponentMetadata metadata = new ComponentMetadata( 
DSVersion.DS11 );
+        metadata.setName("foo");
+        metadata.setImplementationClassName(Object.class.getName());
+        metadata.validate();
+               return metadata;
+       }
+
+}


Reply via email to