FELIX-4505 : [Core R6] Support Prototype Service Factory - inital version supporting ServiceObjects for singleton and bundle scope

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1614660 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index c731253..436dcc5 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -531,9 +531,46 @@
      */
     public <S> ServiceObjects<S> getServiceObjects(final ServiceReference<S> ref)
     {
-        // Get the service registration.
-        final ServiceRegistrationImpl reg =
-            ((ServiceRegistrationImpl.ServiceReferenceImpl) ref).getRegistration();
-        return reg.getServiceObjects(m_bundle);
+        return new ServiceObjectsImpl(ref);
     }
+
+    //
+    // ServiceObjects implementation
+    //
+    class ServiceObjectsImpl<S> implements ServiceObjects<S>
+    {
+        private final ServiceReference<S> m_ref;
+
+        public ServiceObjectsImpl(final ServiceReference<S> ref)
+        {
+            this.m_ref = ref;
+        }
+
+        public S getService() {
+            // special handling for prototype scope
+            if ( m_ref.getProperty(Constants.SERVICE_SCOPE) == Constants.SCOPE_PROTOTYPE )
+            {
+                throw new UnsupportedOperationException();
+            }
+            // getService handles singleton and bundle scope
+            return BundleContextImpl.this.getService(m_ref);
+        }
+
+        public void ungetService(final S service)
+        {
+            // special handling for prototype scope
+            if ( m_ref.getProperty(Constants.SERVICE_SCOPE) == Constants.SCOPE_PROTOTYPE )
+            {
+                throw new UnsupportedOperationException();
+            }
+            // ungetService handles singleton and bundle scope
+            BundleContextImpl.this.ungetService(m_ref);
+        }
+
+        public ServiceReference<S> getServiceReference()
+        {
+            return m_ref;
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 93eab8a..6d77019 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -36,9 +36,9 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
 import org.osgi.framework.Constants;
+import org.osgi.framework.PrototypeServiceFactory;
 import org.osgi.framework.ServiceException;
 import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleCapability;
@@ -60,7 +60,7 @@
     // Service factory interface.
     private volatile ServiceFactory m_factory;
     // Associated property dictionary.
-    private volatile Map m_propMap = new StringMap();
+    private volatile Map<String, Object> m_propMap = new StringMap();
     // Re-usable service reference.
     private final ServiceReferenceImpl m_ref;
     // Flag indicating that we are unregistering.
@@ -293,18 +293,18 @@
         }
     }
 
-    private void initializeProperties(Dictionary dict)
+    private void initializeProperties(Dictionary<String, Object> dict)
     {
         // Create a case-insensitive map for the properties.
-        Map props = new StringMap();
+        Map<String, Object> props = new StringMap();
 
         if (dict != null)
         {
             // Make sure there are no duplicate keys.
-            Enumeration keys = dict.keys();
+            Enumeration<String> keys = dict.keys();
             while (keys.hasMoreElements())
             {
-                Object key = keys.nextElement();
+                String key = keys.nextElement();
                 if (props.get(key) == null)
                 {
                     props.put(key, dict.get(key));
@@ -320,6 +320,16 @@
         props.put(Constants.OBJECTCLASS, m_classes);
         props.put(Constants.SERVICE_ID, m_serviceId);
         props.put(Constants.SERVICE_BUNDLEID, m_bundle.getBundleId());
+        if ( m_factory != null )
+        {
+            props.put(Constants.SERVICE_SCOPE,
+                      (m_factory instanceof PrototypeServiceFactory
+                       ? Constants.SCOPE_PROTOTYPE : Constants.SCOPE_BUNDLE));
+        }
+        else
+        {
+            props.put(Constants.SERVICE_SCOPE, Constants.SCOPE_SINGLETON);
+        }
 
         // Update the service property map.
         m_propMap = props;
@@ -404,14 +414,6 @@
         }
     }
 
-    /**
-     * Get the service objects for the provided bundle
-     */
-    public ServiceObjects getServiceObjects(Bundle bundle)
-    {
-        throw new UnsupportedOperationException();
-    }
-
     //
     // ServiceReference implementation
     //