Fix configuration location-binding.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1480615 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
index 8853dc0..80942ba 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
@@ -23,10 +23,7 @@
 import org.apache.felix.ipojo.util.Log;
 import org.apache.felix.ipojo.util.Logger;
 import org.apache.felix.ipojo.util.ServiceLocator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.*;
 import org.osgi.service.cm.*;
 import org.osgi.service.cm.ConfigurationException;
 
@@ -108,7 +105,7 @@
         }
     }
 
-    public synchronized void instanceCreated(IPojoFactory factory, ComponentInstance instance) {
+    public synchronized void instanceCreated(ComponentInstance instance) {
         ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
                 .class, m_context);
         final ConfigurationAdmin admin = locator.get();
@@ -171,7 +168,7 @@
                     break;
                 }
                 final Configuration config = getConfiguration(admin, event.getPid(),
-                        factory.getBundleContext().getBundle().getLocation());
+                        factory.getBundleContext().getBundle());
                 if (config != null) {
                     try {
                         factory.updated(event.getPid(), config.getProperties());
@@ -202,7 +199,7 @@
                     break;
                 }
                 final Configuration config = getConfiguration(admin, event.getPid(),
-                        instance.getFactory().getBundleContext().getBundle().getLocation());
+                        instance.getFactory().getBundleContext().getBundle());
                 if (config != null) {
                     Hashtable<String, Object> conf = copyConfiguration(config);
                     if (!conf.containsKey(Factory.INSTANCE_NAME_PROPERTY)) {
@@ -257,7 +254,7 @@
     }
 
     private Configuration getConfiguration(final ConfigurationAdmin admin, final String pid,
-                                           final String bundleLocation) {
+                                           final Bundle bundle) {
         if (admin == null) {
             return null;
         }
@@ -266,20 +263,14 @@
             // Even if it is possible, we don't build the filter with bundle.location to detect the case where the
             // configuration exists but can't be managed by iPOJO.
             final Configuration cfg = admin.getConfiguration(pid);
-
-            if (bundleLocation.equals(cfg.getBundleLocation())) {
+            final String bundleLocation = bundle.getLocation();
+            if (cfg.getBundleLocation() == null || bundleLocation.equals(cfg.getBundleLocation())) {
                 return cfg;
             }
 
-            // Multi-location with only ?
-            if (cfg.getBundleLocation().equals("?")) {
-                return cfg;
-            }
-
-            // Multi-location specifying the pid
+            // Multi-location
             if (cfg.getBundleLocation().startsWith("?")) {
-                String sn = cfg.getBundleLocation().substring(1); // Remove ?
-                if (sn.equals(pid)) {
+                if (bundle.hasPermission(new ConfigurationPermission(cfg.getBundleLocation(), "target"))) {
                     return cfg;
                 }
             }
@@ -329,4 +320,5 @@
         }
         return configurations;
     }
+
 }
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
index dee0bdf..2606230 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -41,7 +41,7 @@
  *

  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

-public abstract class IPojoFactory implements Factory, ManagedServiceFactory {

+public abstract class IPojoFactory implements Factory {

     /*

      * TODO there is potentially an issue when calling FactoryStateListener callbacks with the lock

      * It should be called by a separate thread dispatching events to listeners.

@@ -155,6 +155,7 @@
         // Compute the component type version.

         String version = metadata.getAttribute("version");

         if ("bundle".equalsIgnoreCase(version)) { // Handle the "bundle" constant: use the bundle version.

+            // The cast is necessary in KF.

             m_version = (String) m_context.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);

         } else {

             m_version = version;

@@ -253,7 +254,7 @@
             configuration = new Properties();

         }

 

-        IPojoContext context = null;

+        IPojoContext context;

         if (serviceContext == null) {

             context = new IPojoContext(m_context);

         } else {

@@ -307,7 +308,7 @@
             m_componentInstances.put(name, instance);

             m_logger.log(Logger.INFO, "Instance " + name + " from factory " + m_factoryName + " created");

             // Register the instance on the ConfigurationTracker to be updated if needed.

-            ConfigurationTracker.get().instanceCreated(this, instance);

+            ConfigurationTracker.get().instanceCreated(instance);

             return instance;

         } catch (ConfigurationException e) {

             INSTANCE_NAME.remove(name);

@@ -552,7 +553,7 @@
         instances = new ComponentInstance[col.size()]; // Stack confinement

         int index = 0;

         while (it.hasNext()) {

-            instances[index] = (ComponentInstance) (m_componentInstances.get(it.next()));

+            instances[index] = m_componentInstances.get(it.next());

             index++;

         }

 

@@ -631,9 +632,6 @@
             m_sr =

                     bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc

                             .getPropertiesToPublish());

-

-            // Register the factory on the ConfigurationTracker

-            ConfigurationTracker.get().registerFactory(this);

         }

 

         m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");

@@ -659,13 +657,12 @@
 

     /**

      * Creates or updates an instance.

+     * This method is used from the configuration tracker.

      * @param name the name of the instance

      * @param properties the new configuration of the instance

-     * @throws org.osgi.service.cm.ConfigurationException if the configuration is not consistent for this component type

-     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)

-     * TODO this method should disappear.

      */

-    public void updated(String name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {

+    public void updated(String name, Dictionary properties) throws org.osgi.service.cm

+            .ConfigurationException {

         ComponentInstance instance;

         synchronized (this) {

             instance = m_componentInstances.get(name);

@@ -703,12 +700,10 @@
     /**

      * Deletes an instance.

      * @param name the name of the instance to delete

-     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)

-     * todo this method should disappear.

      */

     public synchronized void deleted(String name) {

         INSTANCE_NAME.remove(name);

-        ComponentInstance instance = (ComponentInstance) m_componentInstances.remove(name);

+        ComponentInstance instance = m_componentInstances.remove(name);

         if (instance != null) {

             instance.dispose();

         }

@@ -737,7 +732,6 @@
     protected void computeDescription() {

         for (RequiredHandler req : m_requiredHandlers) {

             if (getHandler(req, null) == null) {

-                // TODO this does not really looks good.

                 m_logger.log(Logger.ERROR, "Cannot extract handler object from " + m_factoryName + " " + req

                         .getFullName());

             } else {

@@ -785,6 +779,10 @@
                 if (m_sr != null) {

                     m_sr.setProperties(m_componentDesc.getPropertiesToPublish());

                 }

+

+                // Register the factory on the ConfigurationTracker

+                ConfigurationTracker.get().registerFactory(this);

+

                 for (FactoryStateListener listener : m_listeners) {

                     listener.stateChanged(this, VALID);

                 }

@@ -793,6 +791,9 @@
             if (m_state == VALID) {

                 m_state = INVALID;

 

+                // Un-register the factory on the ConfigurationTracker

+                ConfigurationTracker.get().unregisterFactory(this);

+

                 // Notify listeners.

                 for (FactoryStateListener listener : m_listeners) {

                     listener.stateChanged(this, INVALID);

@@ -825,7 +826,7 @@
      * @param ref the service reference.

      * @return <code>true</code> if the service reference can fulfill the handler requirement

      */

-    protected boolean match(RequiredHandler req, ServiceReference<? extends Object> ref) {

+    protected boolean match(RequiredHandler req, ServiceReference<?> ref) {

         String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);

         String namespace = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);

         if (HandlerFactory.IPOJO_NAMESPACE.equals(namespace)) {

@@ -895,7 +896,7 @@
         /**

          * The Service Reference of the handler factory.

          */

-        private ServiceReference m_reference;

+        private ServiceReference<? extends HandlerFactory> m_reference;

 

         /**

          * Crates a Required Handler.

@@ -998,11 +999,11 @@
          * This method is called with the lock on the current factory.

          * @param ref the new service reference.

          */

-        public void setReference(ServiceReference ref) {

+        public void setReference(ServiceReference<? extends HandlerFactory> ref) {

             m_reference = ref;

             Integer level = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);

             if (level != null) {

-                m_level = level.intValue();

+                m_level = level;

             }

         }