You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2007/06/18 22:43:18 UTC

svn commit: r548483 [2/3] - in /felix/trunk/servicebinder/src/main/java/org/apache/felix/servicebinder: InstanceManager.java InstanceMetadata.java PropertyMetadata.java

Modified: felix/trunk/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java?view=diff&rev=548483&r1=548482&r2=548483
==============================================================================
--- felix/trunk/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java (original)
+++ felix/trunk/servicebinder/src/main/java/org/apache/felix/servicebinder/InstanceManager.java Mon Jun 18 13:43:17 2007
@@ -1,64 +1,64 @@
-/* 
- * 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.servicebinder;
-
-import java.util.Properties;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-
-import org.apache.felix.servicebinder.architecture.Dependency;
-import org.apache.felix.servicebinder.architecture.DependencyChangeEvent;
-import org.apache.felix.servicebinder.architecture.Instance;
-import org.apache.felix.servicebinder.architecture.InstanceChangeEvent;
-import org.apache.felix.servicebinder.impl.ArchitectureServiceImpl;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Bundle;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
+/* 
+ * 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.servicebinder;
+
+import java.util.Properties;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.felix.servicebinder.architecture.Dependency;
+import org.apache.felix.servicebinder.architecture.DependencyChangeEvent;
+import org.apache.felix.servicebinder.architecture.Instance;
+import org.apache.felix.servicebinder.architecture.InstanceChangeEvent;
+import org.apache.felix.servicebinder.impl.ArchitectureServiceImpl;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Bundle;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 
 /**
- * A InstanceManager is created for every component instance.
 * 
 * When the InstanceManager is instantiated, a collection of DependencyManagers is
 * created. Each dependency manager corresponds to a required service
 * 
 * A InstanceManager follows a sequence of clearly defined steps.
 * 
 * 1.- Creation : the binder instance is created, its state becomes CREATED. This step is further divided
 *                in the following substeps:
 *                  - The binder instance checks if all of the dependencies are valid, if this
 *                    is false, it returns.
 *                  - If the dependendencies are valid, its state becomes executing. The object from
 *                    the instance class is created (if this object receives a ServiceBinderContext as
 *                    a parameter in its constructor, the context is passed to it.
 *                  - The validate() method is called on the dependency managers, this will cause
 *                   
  calls on the binding methods to occur
 *                  - The binder instance adds itself to the list of binder instances in the activator
 *                  - The binder instance registers the services implemented by the instance object.
 * 
 * 2.- Disposal :
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * A InstanceManager is created for every component instance. *  * When the InstanceManager is instantiated, a collection of DependencyManagers is * created. Each dependency manager corresponds to a required service *  * A InstanceManager follows a sequence of clearly defined steps. *  * 1.- Creation : the binder instance is created, its state becomes CREATED. This step is further divided *                in the following substeps: *                  - The binder instance checks if all of the dependencies are valid, if this *                    is false, it returns. *                  - If the dependendencies are valid, its state becomes executing. The object from *                    the instance class is created (if this object receives a ServiceBinderContext as *                    a parameter in its constructor, the context is passed to it. *                  - The validate() method is called on the dependency managers, this will cause *                    calls on the b
 inding methods to occur *                  - The binder instance adds itself to the list of binder instances in the activator *                  - The binder instance registers the services implemented by the instance object. *  * 2.- Disposal : *  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-
-public class InstanceManager implements InstanceReference, Instance
-{
-    // The values ranging from 0 to 3 are public and are defined in InstanceReference
-    static final int INSTANCE_CREATING = 4;
-    static final int INSTANCE_VALIDATING = 5;
-    static final int INSTANCE_INVALIDATING = 6;
-    static final int INSTANCE_DESTROYING = 7;
-
-    static final String m_states[]={"CREATED","VALID","INVALID",
-                                    "DESTROYED","CREATING","VALIDATING",
-                                    "INVALIDATING","DESTROYING"};
-
-    // The state of this instance manager
+
+public class InstanceManager implements InstanceReference, Instance
+{
+    // The values ranging from 0 to 3 are public and are defined in InstanceReference
+    static final int INSTANCE_CREATING = 4;
+    static final int INSTANCE_VALIDATING = 5;
+    static final int INSTANCE_INVALIDATING = 6;
+    static final int INSTANCE_DESTROYING = 7;
+
+    static final String m_states[]={"CREATED","VALID","INVALID",
+                                    "DESTROYED","CREATING","VALIDATING",
+                                    "INVALIDATING","DESTROYING"};
+
+    // The state of this instance manager
     private int m_state = INSTANCE_CREATING;
 
     /**
@@ -68,15 +68,15 @@
      */
     // The metadata
     private InstanceMetadata m_instanceMetadata;
-
-
-    // The object that implements the service and that is bound to other services
-    private Object m_implementorObject;
-
-    // The dependency managers that manage every dependency
-    private List m_dependencyManagers;
-
-    // The ServiceRegistration
+
+
+    // The object that implements the service and that is bound to other services
+    private Object m_implementorObject;
+
+    // The dependency managers that manage every dependency
+    private List m_dependencyManagers;
+
+    // The ServiceRegistration
     private ServiceRegistration m_serviceRegistration;
 
     /**
@@ -103,626 +103,626 @@
     // Listeners to validation events
     private InstanceReferenceListener m_instanceListener = null;
 
-    // Properties that can be attached to te InstanceManager
-    private Properties m_localProperties = new Properties();
-    
-    // Flag that indicates that activate was called
-    private boolean m_activateCalled = false;
-
-    /**
-    * Constructor that creates a collection of dependency managers that will be in
-    * charge of the different dependencies for a particular instance.
-    *
-    * @param   activator A reference to the generic activator
-    * @param   descriptor an InstanceMetadata that contains information found in the descriptor file
-    * @throws  java.lang.ClassNotFoundException if the instance class (declared in the descriptor file) is not found
-    * @throws  java.lang.NoSuchMethodException if the bind or unbind methods are not found on the instance class
-    * @throws  org.osgi.framework.InvalidSyntaxException if the filter declared in the requires entry has an invalid syntax
-    **/
-    InstanceManager(GenericActivator activator,InstanceMetadata descriptor)
-        throws ClassNotFoundException, NoSuchMethodException, InvalidSyntaxException
-    {
-        m_activator = activator;
-
-        m_instanceMetadata = descriptor;
-
-        m_dependencyManagers = new ArrayList();
-
-        if (m_instanceMetadata.getDependencies().size() != 0)
-        {
-            Iterator dependencyit = m_instanceMetadata.getDependencies().iterator();
-
-            while(dependencyit.hasNext())
-            {
-                DependencyMetadata currentdependency = (DependencyMetadata)dependencyit.next();
-
-                DependencyManager depmanager = new DependencyManager(currentdependency);
-
-                m_dependencyManagers.add(depmanager);
-
-                // Register the dependency managers as listeners to service events so that they begin
-                // to manage the dependency autonomously
-
-                m_activator.getBundleContext().addServiceListener(depmanager,depmanager.getDependencyMetadata().getFilter());
-            }
-        }
-
-        m_sbcontext = new ServiceBinderContextImpl(this);
-
-        // Add this instance manager to the Generic activator list
-        m_activator.addInstanceManager(this);
-
-        setState(INSTANCE_CREATED);
-    }
-
-    /**
-    * Validate this Instance manager.
-    *
-    * CONCURRENCY NOTE: This method can be called either after an instance manager is created
-    * or after the instance is validated again after by the instance manager itself
-    */
-    synchronized void validate()
-    {
-        if (m_state == INSTANCE_VALID)
-        {
-            return;
-        }
-        else if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED)
-        {
-            GenericActivator.error("InstanceManager : create() called for a non INVALID or CREATED InstanceManager ("+m_states[m_state]+")");
-            return;
-        }
-
-        setState(INSTANCE_VALIDATING);
-
-        // Test if all dependency managers are valid
-
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            // It is not possible to call the isValid method yet in the DependencyManager
-            // since they have not been initialized yet, but we can't call initialize
-            // since the object where bindings will be done has not been created.
-            // This test is necessary, because we don't want to instantiate
-            // the object if the dependency managers won't be valid.
-            DependencyManager dm = (DependencyManager)it.next();
-            if (dm.getRequiredServiceRefs() == null && dm.getDependencyMetadata().isOptional() == false)
-            {
-                setState(INSTANCE_INVALID);
-                return;
-            }
-        }
-
-        // everything ok to go...
-
-        try
-        {
-            Class c = m_activator.getClass().getClassLoader().loadClass(m_instanceMetadata.getImplementorName());
-            try
-            {
-                Constructor cons = c.getConstructor(new Class[] {ServiceBinderContext.class});
-                m_implementorObject = cons.newInstance(new Object[] {m_sbcontext});
-            }
-            catch(NoSuchMethodException ex)
-            {
-                // Aparently he doesn't want a ServiceBinderContext...
-            }
-
-            // Create from no-param constructor
-            if (m_implementorObject == null)
-            {
-                m_implementorObject = c.newInstance();
-            }
-
-            /* is it a factory?
-            if (m_implementorObject instanceof GenericFactory)
-            {
-                ((GenericFactory) m_implementorObject).setActivator(m_activator, this);
-            }
-            */
-
-            // Allow somebody to proxy the object through the proxyProvidedServiceObject method
-            // in the activator
-            Object proxy = m_activator.proxyProvidedServiceObject(m_implementorObject, this.getInstanceMetadata());
-            if (proxy != null)
-            {
-                m_implementorObject = proxy;
-            }
-            else
-            {
-                GenericActivator.error("InstanceManager : Proxy method returned a null value");
-            }
-        }
-        catch (Throwable t)
-        {
-            // failure at creation
-            GenericActivator.error("InstanceManager : Error during instantiation : "+t);
-            t.printStackTrace();
-            _invalidate();
-            return;
-        }
-        
-        // initial bindings
-
-        it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            if (dm.initialize() == false)
-            {
-                _invalidate();
-                return;
-            }
-        }
-        
-        // We need to check if we are still validating because it is possible that when we
-        // registered the service above our thread causes an instance to become valid which
-        // then registered a service that then generated an event that we needed that
-        // caused validate() to be called again, thus if we are not still VALIDATING, it
-        // means we are already VALID.
-        if (m_state == INSTANCE_VALIDATING)
-        {
-            // activate
-
-            if (m_implementorObject instanceof Lifecycle)
-            {
-                try
-                {
-                    ((Lifecycle)m_implementorObject).activate();
-                    this.m_activateCalled=true;
-                }
-                catch(Exception e)
-                {
-                    GenericActivator.error("InstanceManager : exception during activate:"+e);
-                    e.printStackTrace();
-                    _invalidate();
-                    return;
-                }
-            }
-
-            // validated!
-
-            fireInstanceReferenceValidated();
-            setState(INSTANCE_VALID);
-        }
-        
-
-        // register services
-
-        boolean reg = requestRegistration();
-
-        if (!reg)
-        {
-            GenericActivator.error("InstanceManager : registration of the services failed...");
-            _invalidate();
-            return;
-        }
-        
-        // Configuration ended successfuly.
-
-    }
-
-    /**
-     * This method invalidates the InstanceManager
-     *
-     * CONCURRENCY NOTE: This method may be called either from application code or event thread.
-    **/
-    synchronized void invalidate()
-    {
-        if (m_state == INSTANCE_INVALID)
-        {
-            return;
-        }
-        else if (m_state != INSTANCE_VALID && m_state != INSTANCE_DESTROYING)
-        {
-            GenericActivator.error("InstanceManager : invalidate() called for a non VALID InstanceManager ("+m_states[m_state]+")");
-            return;
-        }
-
-        if (m_state != INSTANCE_DESTROYING)
-        {
-            setState(INSTANCE_INVALIDATING);
-        }
-
-        // Fire invalidating events
-        fireInstanceReferenceInvalidating();
-
-        _invalidate();
-
-
-    }
-
-    /**
-     * this method invalidates the InstanceManager without performing any of the callbacks
-     * associated with the Lifecycle interface or the InstanceReference event listeners.
-    **/
-    private void _invalidate()
-    {
-        // Unregister services
-
-        requestUnregistration();
-        
-        if(m_activateCalled==true)
-        {        
-            // Call deactivate on the Lifecycle
-
-            if (m_implementorObject instanceof Lifecycle)
-            {
-                try
-                {
-                    ((Lifecycle)m_implementorObject).deactivate();
-                }
-                catch(Exception e)
-                {
-                    GenericActivator.error("InstanceManager : exception during call to deactivate():"+e);
-                }
-            }
-
-        }
-
-        // Unbind all services
-
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            dm.unbindAll();
-        }
-
-        //m_activator.removeInstanceManager(this);
-
-        // remove all instances from a factory
-
-        /*
-        if (m_implementorObject instanceof GenericFactory)
-        {
-            ((GenericFactory)m_implementorObject).invalidateInstances();
-        }
-        */
-
-        // Release the object reference
-
-        m_implementorObject = null;
-
-        GenericActivator.trace("InstanceManager from bundle ["
-           + m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
-
-        if (m_state != INSTANCE_DESTROYING)
-        {
-            setState(INSTANCE_INVALID);
-        }
-    }
-
-    /**
-     * This method should be called to completely remove the InstanceManager from the system.
-     * This means that the dependency managers will stop listening to events.
-     *
-     * CONCURRENCY NOTE: This method is only called from the GenericActivator, which is
-     *                   essentially application code and not via events.
-    **/
-    synchronized void destroy()
-    {
-        if (m_state == INSTANCE_DESTROYED)
-        {
-            return;
-        }
-
-        // Theoretically this should never be in any state other than VALID or INVALID,
-        // because validate is called right after creation.
-        boolean invalidatefirst = (m_state == INSTANCE_VALID);
-
-        setState(INSTANCE_DESTROYING);
-
-        // Stop the dependency managers to listen to events...
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            m_activator.getBundleContext().removeServiceListener(dm);
-        }
-
-        if (invalidatefirst)
-        {
-            invalidate();
-        }
-
-        m_dependencyManagers.clear();
-
-        m_instanceListener = null;
-
-        GenericActivator.trace("InstanceManager from bundle ["
-           + m_activator.getBundleContext().getBundle().getBundleId() + "] was destroyed.");
-
-        m_activator.removeInstanceManager(this);
-        setState(INSTANCE_DESTROYED);
-
-        m_activator = null;
-    }
-
-    /**
-    * Returns the InstanceMetadata
-    */
-    public InstanceMetadata getInstanceMetadata()
-    {
-        return m_instanceMetadata;
-    }
-
-    /**
-    * Get the object that is implementing this descriptor
-    *
-    * @return the object that implements
-    */
-    public Object getObject()
-    {
-        return m_implementorObject;
-    }
-
-    /**
-    * Request the registration of the service provided by this binder instance
-    *
-    * @return returns false if registration was not successful,
-    *                returns true if registration was successful
-    **/
-    boolean requestRegistration()
-    {
-        if (!m_instanceMetadata.instanceRegistersServices())
-        {
-            return true;
-        }
-        else if (m_implementorObject == null)
-        {
-            GenericActivator.error("GenericActivator : Cannot register, implementor object not created!");
-            return false;
-        }
-        else if (m_serviceRegistration != null)
-        {
-            GenericActivator.error("GenericActivator : Cannot register, binder instance already registered :"
-                + m_instanceMetadata.getImplementorName());
-            return true;
-        }
-
-        // Check validity of dependencies before registering !
-        Iterator it = m_dependencyManagers.iterator();
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            if (dm.isValid() == false)
-                return false;
-        }
-
-        // When registering a factory, add an instanceClass property which is an array
-        // of service interfaces implemented by the objects created by the factory.
-
-        if (m_instanceMetadata.isFactory())
-        {
-            if(m_instanceMetadata.getProperties().get("instanceClass") == null)
-            {
-                m_instanceMetadata.getProperties().put("instanceClass",m_instanceMetadata.getInstantiates().getInterfaces());
-            }
-        }
-
-        m_serviceRegistration = m_activator.getBundleContext().registerService(
-            m_instanceMetadata.getInterfaces(), m_implementorObject, m_instanceMetadata.getProperties());
-
-        GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
-            + m_activator.getBundleContext().getBundle().getBundleId()
-            + "] successfully registered its services !");
-
-        return true;
-    }
-
-
-    /**
-    *
-    * Request the unfegistration of the service provided by this binder instance
-    *
-    **/
-    void requestUnregistration()
-    {
-        if (m_serviceRegistration != null)
-        {
-            m_serviceRegistration.unregister();
-            m_serviceRegistration = null;
-
-            GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
-                + m_activator.getBundleContext().getBundle().getBundleId()
-                + "] unregistered its services !");
-
-         }
-    }
-
-    /**
-    * Get the state
-    */
-    public int getState()
-    {
-        return m_state;
-    }
-
-    /**
-    * Get the state
-    */
-    public long getBundleId()
-    {
-        return m_activator.getBundleContext().getBundle().getBundleId();
-    }
-
-    /**
-     * Get a property associated with this instance. For classes
-     * implementing this method, special care must be taken for
-     * values implementing <tt>InstanceReference.ValueHolder</tt>.
-     * In such cases, the value itself should not be returned, but
-     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
-     * should be returned instead. This may be used to defer
-     * creating value objects in cases where creating the value
-     * object is expensive.
-     * @param name the name of the property to retrieve.
-     * @return the value of the associated property or <tt>null</tt>.
-    **/
-    public Object get(String name)
-    {
-        GenericActivator.trace("InstanceManager.get("+name+")");
-
-        if(name.equals(InstanceReference.INSTANCE_STATE))
-        {
-            return new Integer(m_state);
-        }
-        else if(name.equals(InstanceReference.INSTANCE_METADATA))
-        {
-            return getInstanceMetadata();
-        }
-        else if(name.equals(InstanceReference.INSTANCE_BUNDLE))
-        {
-            return new Integer((int) getBundleId());
-        }
-        else if(name.equals(InstanceReference.INSTANCE_DEPENDENCIES))
-        {
-            return getDependencies();
-        }
-        else
-        {
-            Object ret = m_localProperties.get(name);
-
-            if (ret != null)
-            {
-                if (ret instanceof ValueHolder)
-                {
-                    return ((ValueHolder)ret).get(this);
-                }
-                return ret;
-            }
-
-            return m_instanceMetadata.getProperties().get(name);
-        }
-
-    }
-
-    /**
-     * Associate a property with this instance. For classes
-     * implementing this method, special care must be taken for
-     * values implementing <tt>InstanceReference.ValueHolder</tt>.
-     * In such cases, the value itself should not be returned, but
-     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
-     * should be returned instead. This may be used to defer
-     * creating value objects in cases where creating the value
-     * object is expensive.
-     * @param name the name of the property to add.
-     * @param obj the value of the property.
-    **/
-    public void put(String name, Object obj)
-    {
-        m_localProperties.put(name,obj);
-    }
-
-    /**
-     * Adds an instance reference listener to listen for changes to
-     * the availability of the underlying object associated with this
-     * instance reference.
-     * @param l the listener to add.
-    **/
-    public void addInstanceReferenceListener(InstanceReferenceListener l)
-    {
-        m_instanceListener = StateChangeMulticaster.add(m_instanceListener, l);
-    }
-
-    /**
-     * Removes an instance reference listener.
-     * @param l the listener to remove.
-    **/
-    public void removeInstanceReferenceListener(InstanceReferenceListener l)
-    {
-        m_instanceListener = StateChangeMulticaster.remove(m_instanceListener, l);
-    }
-
-    /**
-     * Fires an event when the instance reference has been validated
-    **/
-    protected void fireInstanceReferenceValidated()
-    {
-        try
-        {
-            if (m_instanceListener != null)
-            {
-                m_instanceListener.validated(new InstanceReferenceEvent(this));
-            }
-        }
-        catch(Exception ex)
-        {
-            // Ignore any exception
-        }
-    }
-
-    /**
-     * Fires an event when the instance reference is invalidating
-    **/
-    protected void fireInstanceReferenceInvalidating()
-    {
-        try
-        {
-            if (m_instanceListener != null)
-            {
-                m_instanceListener.invalidating(new InstanceReferenceEvent(this));
-            }
-        }
-        catch(Exception ex)
-        {
-            // Ignore any exception
-        }
-    }
-
-    /**
-     * sets the state of the instanceManager
-    **/
-    synchronized void setState(int newState)
-    {
-        m_state = newState;
-
-        if(m_state == INSTANCE_CREATED || m_state == INSTANCE_VALID || m_state == INSTANCE_INVALID || m_state == INSTANCE_DESTROYED)
-        {
-            m_activator.fireInstanceChangeEvent(new InstanceChangeEvent(this,m_instanceMetadata,m_state));
-        }
-    }
-
-    /**
-     * Get an array of dependencies for this instance. This method is declared
-     * in the Instance interface
-     *
-     * @return an array of Dependencies
-    **/
-    public Dependency [] getDependencies()
-    {
-        Dependency deps [] = new Dependency[m_dependencyManagers.size()];
-        return (Dependency[]) m_dependencyManagers.toArray(deps);
-    }
-
-    /**
-     * Get a list of child instances in case this is a factory
-     *
-     * @return an array of Instances
-    **/
-     public Instance[] getChildInstances()
-    {
-        /*
-        if(m_implementorObject != null && m_implementorObject instanceof GenericFactory)
-        {
-            List instanceRefs = ((GenericFactory)m_implementorObject).getInstanceReferences();
-            Instance [] instances = new Instance[instanceRefs.size()];
-            instances = (Instance [])instanceRefs.toArray(instances);
-            return instances;
-        }
-        */
-        return null;
+    // Properties that can be attached to te InstanceManager
+    private Properties m_localProperties = new Properties();
+    
+    // Flag that indicates that activate was called
+    private boolean m_activateCalled = false;
+
+    /**
+    * Constructor that creates a collection of dependency managers that will be in
+    * charge of the different dependencies for a particular instance.
+    *
+    * @param   activator A reference to the generic activator
+    * @param   descriptor an InstanceMetadata that contains information found in the descriptor file
+    * @throws  java.lang.ClassNotFoundException if the instance class (declared in the descriptor file) is not found
+    * @throws  java.lang.NoSuchMethodException if the bind or unbind methods are not found on the instance class
+    * @throws  org.osgi.framework.InvalidSyntaxException if the filter declared in the requires entry has an invalid syntax
+    **/
+    InstanceManager(GenericActivator activator,InstanceMetadata descriptor)
+        throws ClassNotFoundException, NoSuchMethodException, InvalidSyntaxException
+    {
+        m_activator = activator;
+
+        m_instanceMetadata = descriptor;
+
+        m_dependencyManagers = new ArrayList();
+
+        if (m_instanceMetadata.getDependencies().size() != 0)
+        {
+            Iterator dependencyit = m_instanceMetadata.getDependencies().iterator();
+
+            while(dependencyit.hasNext())
+            {
+                DependencyMetadata currentdependency = (DependencyMetadata)dependencyit.next();
+
+                DependencyManager depmanager = new DependencyManager(currentdependency);
+
+                m_dependencyManagers.add(depmanager);
+
+                // Register the dependency managers as listeners to service events so that they begin
+                // to manage the dependency autonomously
+
+                m_activator.getBundleContext().addServiceListener(depmanager,depmanager.getDependencyMetadata().getFilter());
+            }
+        }
+
+        m_sbcontext = new ServiceBinderContextImpl(this);
+
+        // Add this instance manager to the Generic activator list
+        m_activator.addInstanceManager(this);
+
+        setState(INSTANCE_CREATED);
+    }
+
+    /**
+    * Validate this Instance manager.
+    *
+    * CONCURRENCY NOTE: This method can be called either after an instance manager is created
+    * or after the instance is validated again after by the instance manager itself
+    */
+    synchronized void validate()
+    {
+        if (m_state == INSTANCE_VALID)
+        {
+            return;
+        }
+        else if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED)
+        {
+            GenericActivator.error("InstanceManager : create() called for a non INVALID or CREATED InstanceManager ("+m_states[m_state]+")");
+            return;
+        }
+
+        setState(INSTANCE_VALIDATING);
+
+        // Test if all dependency managers are valid
+
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            // It is not possible to call the isValid method yet in the DependencyManager
+            // since they have not been initialized yet, but we can't call initialize
+            // since the object where bindings will be done has not been created.
+            // This test is necessary, because we don't want to instantiate
+            // the object if the dependency managers won't be valid.
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.getRequiredServiceRefs() == null && dm.getDependencyMetadata().isOptional() == false)
+            {
+                setState(INSTANCE_INVALID);
+                return;
+            }
+        }
+
+        // everything ok to go...
+
+        try
+        {
+            Class c = m_activator.getClass().getClassLoader().loadClass(m_instanceMetadata.getImplementorName());
+            try
+            {
+                Constructor cons = c.getConstructor(new Class[] {ServiceBinderContext.class});
+                m_implementorObject = cons.newInstance(new Object[] {m_sbcontext});
+            }
+            catch(NoSuchMethodException ex)
+            {
+                // Aparently he doesn't want a ServiceBinderContext...
+            }
+
+            // Create from no-param constructor
+            if (m_implementorObject == null)
+            {
+                m_implementorObject = c.newInstance();
+            }
+
+            /* is it a factory?
+            if (m_implementorObject instanceof GenericFactory)
+            {
+                ((GenericFactory) m_implementorObject).setActivator(m_activator, this);
+            }
+            */
+
+            // Allow somebody to proxy the object through the proxyProvidedServiceObject method
+            // in the activator
+            Object proxy = m_activator.proxyProvidedServiceObject(m_implementorObject, this.getInstanceMetadata());
+            if (proxy != null)
+            {
+                m_implementorObject = proxy;
+            }
+            else
+            {
+                GenericActivator.error("InstanceManager : Proxy method returned a null value");
+            }
+        }
+        catch (Throwable t)
+        {
+            // failure at creation
+            GenericActivator.error("InstanceManager : Error during instantiation : "+t);
+            t.printStackTrace();
+            _invalidate();
+            return;
+        }
+        
+        // initial bindings
+
+        it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.initialize() == false)
+            {
+                _invalidate();
+                return;
+            }
+        }
+        
+        // We need to check if we are still validating because it is possible that when we
+        // registered the service above our thread causes an instance to become valid which
+        // then registered a service that then generated an event that we needed that
+        // caused validate() to be called again, thus if we are not still VALIDATING, it
+        // means we are already VALID.
+        if (m_state == INSTANCE_VALIDATING)
+        {
+            // activate
+
+            if (m_implementorObject instanceof Lifecycle)
+            {
+                try
+                {
+                    ((Lifecycle)m_implementorObject).activate();
+                    this.m_activateCalled=true;
+                }
+                catch(Exception e)
+                {
+                    GenericActivator.error("InstanceManager : exception during activate:"+e);
+                    e.printStackTrace();
+                    _invalidate();
+                    return;
+                }
+            }
+
+            // validated!
+
+            fireInstanceReferenceValidated();
+            setState(INSTANCE_VALID);
+        }
+        
+
+        // register services
+
+        boolean reg = requestRegistration();
+
+        if (!reg)
+        {
+            GenericActivator.error("InstanceManager : registration of the services failed...");
+            _invalidate();
+            return;
+        }
+        
+        // Configuration ended successfuly.
+
+    }
+
+    /**
+     * This method invalidates the InstanceManager
+     *
+     * CONCURRENCY NOTE: This method may be called either from application code or event thread.
+    **/
+    synchronized void invalidate()
+    {
+        if (m_state == INSTANCE_INVALID)
+        {
+            return;
+        }
+        else if (m_state != INSTANCE_VALID && m_state != INSTANCE_DESTROYING)
+        {
+            GenericActivator.error("InstanceManager : invalidate() called for a non VALID InstanceManager ("+m_states[m_state]+")");
+            return;
+        }
+
+        if (m_state != INSTANCE_DESTROYING)
+        {
+            setState(INSTANCE_INVALIDATING);
+        }
+
+        // Fire invalidating events
+        fireInstanceReferenceInvalidating();
+
+        _invalidate();
+
+
+    }
+
+    /**
+     * this method invalidates the InstanceManager without performing any of the callbacks
+     * associated with the Lifecycle interface or the InstanceReference event listeners.
+    **/
+    private void _invalidate()
+    {
+        // Unregister services
+
+        requestUnregistration();
+        
+        if(m_activateCalled==true)
+        {        
+            // Call deactivate on the Lifecycle
+
+            if (m_implementorObject instanceof Lifecycle)
+            {
+                try
+                {
+                    ((Lifecycle)m_implementorObject).deactivate();
+                }
+                catch(Exception e)
+                {
+                    GenericActivator.error("InstanceManager : exception during call to deactivate():"+e);
+                }
+            }
+
+        }
+
+        // Unbind all services
+
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            dm.unbindAll();
+        }
+
+        //m_activator.removeInstanceManager(this);
+
+        // remove all instances from a factory
+
+        /*
+        if (m_implementorObject instanceof GenericFactory)
+        {
+            ((GenericFactory)m_implementorObject).invalidateInstances();
+        }
+        */
+
+        // Release the object reference
+
+        m_implementorObject = null;
+
+        GenericActivator.trace("InstanceManager from bundle ["
+           + m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+        if (m_state != INSTANCE_DESTROYING)
+        {
+            setState(INSTANCE_INVALID);
+        }
+    }
+
+    /**
+     * This method should be called to completely remove the InstanceManager from the system.
+     * This means that the dependency managers will stop listening to events.
+     *
+     * CONCURRENCY NOTE: This method is only called from the GenericActivator, which is
+     *                   essentially application code and not via events.
+    **/
+    synchronized void destroy()
+    {
+        if (m_state == INSTANCE_DESTROYED)
+        {
+            return;
+        }
+
+        // Theoretically this should never be in any state other than VALID or INVALID,
+        // because validate is called right after creation.
+        boolean invalidatefirst = (m_state == INSTANCE_VALID);
+
+        setState(INSTANCE_DESTROYING);
+
+        // Stop the dependency managers to listen to events...
+        Iterator it = m_dependencyManagers.iterator();
+
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            m_activator.getBundleContext().removeServiceListener(dm);
+        }
+
+        if (invalidatefirst)
+        {
+            invalidate();
+        }
+
+        m_dependencyManagers.clear();
+
+        m_instanceListener = null;
+
+        GenericActivator.trace("InstanceManager from bundle ["
+           + m_activator.getBundleContext().getBundle().getBundleId() + "] was destroyed.");
+
+        m_activator.removeInstanceManager(this);
+        setState(INSTANCE_DESTROYED);
+
+        m_activator = null;
+    }
+
+    /**
+    * Returns the InstanceMetadata
+    */
+    public InstanceMetadata getInstanceMetadata()
+    {
+        return m_instanceMetadata;
+    }
+
+    /**
+    * Get the object that is implementing this descriptor
+    *
+    * @return the object that implements
+    */
+    public Object getObject()
+    {
+        return m_implementorObject;
+    }
+
+    /**
+    * Request the registration of the service provided by this binder instance
+    *
+    * @return returns false if registration was not successful,
+    *                returns true if registration was successful
+    **/
+    boolean requestRegistration()
+    {
+        if (!m_instanceMetadata.instanceRegistersServices())
+        {
+            return true;
+        }
+        else if (m_implementorObject == null)
+        {
+            GenericActivator.error("GenericActivator : Cannot register, implementor object not created!");
+            return false;
+        }
+        else if (m_serviceRegistration != null)
+        {
+            GenericActivator.error("GenericActivator : Cannot register, binder instance already registered :"
+                + m_instanceMetadata.getImplementorName());
+            return true;
+        }
+
+        // Check validity of dependencies before registering !
+        Iterator it = m_dependencyManagers.iterator();
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            if (dm.isValid() == false)
+                return false;
+        }
+
+        // When registering a factory, add an instanceClass property which is an array
+        // of service interfaces implemented by the objects created by the factory.
+
+        if (m_instanceMetadata.isFactory())
+        {
+            if(m_instanceMetadata.getProperties().get("instanceClass") == null)
+            {
+                m_instanceMetadata.getProperties().put("instanceClass",m_instanceMetadata.getInstantiates().getInterfaces());
+            }
+        }
+
+        m_serviceRegistration = m_activator.getBundleContext().registerService(
+            m_instanceMetadata.getInterfaces(), m_implementorObject, m_instanceMetadata.getProperties());
+
+        GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
+            + m_activator.getBundleContext().getBundle().getBundleId()
+            + "] successfully registered its services !");
+
+        return true;
+    }
+
+
+    /**
+    *
+    * Request the unfegistration of the service provided by this binder instance
+    *
+    **/
+    void requestUnregistration()
+    {
+        if (m_serviceRegistration != null)
+        {
+            m_serviceRegistration.unregister();
+            m_serviceRegistration = null;
+
+            GenericActivator.trace("Generic Activator : InstanceManager inside bundle ["
+                + m_activator.getBundleContext().getBundle().getBundleId()
+                + "] unregistered its services !");
+
+         }
+    }
+
+    /**
+    * Get the state
+    */
+    public int getState()
+    {
+        return m_state;
+    }
+
+    /**
+    * Get the state
+    */
+    public long getBundleId()
+    {
+        return m_activator.getBundleContext().getBundle().getBundleId();
+    }
+
+    /**
+     * Get a property associated with this instance. For classes
+     * implementing this method, special care must be taken for
+     * values implementing <tt>InstanceReference.ValueHolder</tt>.
+     * In such cases, the value itself should not be returned, but
+     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
+     * should be returned instead. This may be used to defer
+     * creating value objects in cases where creating the value
+     * object is expensive.
+     * @param name the name of the property to retrieve.
+     * @return the value of the associated property or <tt>null</tt>.
+    **/
+    public Object get(String name)
+    {
+        GenericActivator.trace("InstanceManager.get("+name+")");
+
+        if(name.equals(InstanceReference.INSTANCE_STATE))
+        {
+            return new Integer(m_state);
+        }
+        else if(name.equals(InstanceReference.INSTANCE_METADATA))
+        {
+            return getInstanceMetadata();
+        }
+        else if(name.equals(InstanceReference.INSTANCE_BUNDLE))
+        {
+            return new Integer((int) getBundleId());
+        }
+        else if(name.equals(InstanceReference.INSTANCE_DEPENDENCIES))
+        {
+            return getDependencies();
+        }
+        else
+        {
+            Object ret = m_localProperties.get(name);
+
+            if (ret != null)
+            {
+                if (ret instanceof ValueHolder)
+                {
+                    return ((ValueHolder)ret).get(this);
+                }
+                return ret;
+            }
+
+            return m_instanceMetadata.getProperties().get(name);
+        }
+
+    }
+
+    /**
+     * Associate a property with this instance. For classes
+     * implementing this method, special care must be taken for
+     * values implementing <tt>InstanceReference.ValueHolder</tt>.
+     * In such cases, the value itself should not be returned, but
+     * the value of <tt>InstanceReference.ValueHolder.get()</tt>
+     * should be returned instead. This may be used to defer
+     * creating value objects in cases where creating the value
+     * object is expensive.
+     * @param name the name of the property to add.
+     * @param obj the value of the property.
+    **/
+    public void put(String name, Object obj)
+    {
+        m_localProperties.put(name,obj);
+    }
+
+    /**
+     * Adds an instance reference listener to listen for changes to
+     * the availability of the underlying object associated with this
+     * instance reference.
+     * @param l the listener to add.
+    **/
+    public void addInstanceReferenceListener(InstanceReferenceListener l)
+    {
+        m_instanceListener = StateChangeMulticaster.add(m_instanceListener, l);
+    }
+
+    /**
+     * Removes an instance reference listener.
+     * @param l the listener to remove.
+    **/
+    public void removeInstanceReferenceListener(InstanceReferenceListener l)
+    {
+        m_instanceListener = StateChangeMulticaster.remove(m_instanceListener, l);
+    }
+
+    /**
+     * Fires an event when the instance reference has been validated
+    **/
+    protected void fireInstanceReferenceValidated()
+    {
+        try
+        {
+            if (m_instanceListener != null)
+            {
+                m_instanceListener.validated(new InstanceReferenceEvent(this));
+            }
+        }
+        catch(Exception ex)
+        {
+            // Ignore any exception
+        }
+    }
+
+    /**
+     * Fires an event when the instance reference is invalidating
+    **/
+    protected void fireInstanceReferenceInvalidating()
+    {
+        try
+        {
+            if (m_instanceListener != null)
+            {
+                m_instanceListener.invalidating(new InstanceReferenceEvent(this));
+            }
+        }
+        catch(Exception ex)
+        {
+            // Ignore any exception
+        }
+    }
+
+    /**
+     * sets the state of the instanceManager
+    **/
+    synchronized void setState(int newState)
+    {
+        m_state = newState;
+
+        if(m_state == INSTANCE_CREATED || m_state == INSTANCE_VALID || m_state == INSTANCE_INVALID || m_state == INSTANCE_DESTROYED)
+        {
+            m_activator.fireInstanceChangeEvent(new InstanceChangeEvent(this,m_instanceMetadata,m_state));
+        }
+    }
+
+    /**
+     * Get an array of dependencies for this instance. This method is declared
+     * in the Instance interface
+     *
+     * @return an array of Dependencies
+    **/
+    public Dependency [] getDependencies()
+    {
+        Dependency deps [] = new Dependency[m_dependencyManagers.size()];
+        return (Dependency[]) m_dependencyManagers.toArray(deps);
+    }
+
+    /**
+     * Get a list of child instances in case this is a factory
+     *
+     * @return an array of Instances
+    **/
+     public Instance[] getChildInstances()
+    {
+        /*
+        if(m_implementorObject != null && m_implementorObject instanceof GenericFactory)
+        {
+            List instanceRefs = ((GenericFactory)m_implementorObject).getInstanceReferences();
+            Instance [] instances = new Instance[instanceRefs.size()];
+            instances = (Instance [])instanceRefs.toArray(instances);
+            return instances;
+        }
+        */
+        return null;
     }
 
 /**
- * This class implements the ServiceBinderContext, which cannot be directly
 * implemented by the activator because of the getInstanceReference() method
+ * This class implements the ServiceBinderContext, which cannot be directly * implemented by the activator because of the getInstanceReference() method
  */
-
-    class ServiceBinderContextImpl implements ServiceBinderContext
+
+    class ServiceBinderContextImpl implements ServiceBinderContext
     {
 
         /**
@@ -732,41 +732,41 @@
          */
         private InstanceReference m_parent;
 
-        ServiceBinderContextImpl(InstanceReference parent)
-        {
-            m_parent = parent;
-        }
-
-        /**
-         * Get the bundle context
-        **/
-        public BundleContext getBundleContext()
-        {
-            return m_activator.getBundleContext();
-        }
-
-        /**
-         * Return all of the InstanceReferences created in the same bundle
-        **/
-        public List getInstanceReferences()
-        {
-            return m_activator.getInstanceReferences();
-        }
-
-        /**
-         * Get the parent InstanceReference
-        **/
-        public InstanceReference getInstanceReference()
-        {
-            return m_parent;
-        }
+        ServiceBinderContextImpl(InstanceReference parent)
+        {
+            m_parent = parent;
+        }
+
+        /**
+         * Get the bundle context
+        **/
+        public BundleContext getBundleContext()
+        {
+            return m_activator.getBundleContext();
+        }
+
+        /**
+         * Return all of the InstanceReferences created in the same bundle
+        **/
+        public List getInstanceReferences()
+        {
+            return m_activator.getInstanceReferences();
+        }
+
+        /**
+         * Get the parent InstanceReference
+        **/
+        public InstanceReference getInstanceReference()
+        {
+            return m_parent;
+        }
     }
 
 /**
- * The DependencyManager task is to listen to service events and to call the
 * bind/unbind methods on a given object. It is also responsible for requesting
 * the unregistration of a service in case a dependency is broken.
+ * The DependencyManager task is to listen to service events and to call the * bind/unbind methods on a given object. It is also responsible for requesting * the unregistration of a service in case a dependency is broken.
  */
-
-    class DependencyManager implements ServiceListener, Dependency
+
+    class DependencyManager implements ServiceListener, Dependency
     {
 
         /**
@@ -776,452 +776,452 @@
          */
         private DependencyMetadata m_dependencyMetadata;
 
-        private Map m_boundServices = new HashMap();
-        private Method m_bindMethod;
-        private Method m_unbindMethod;
-        private boolean m_isValid;
-        private int m_depState;
-        private boolean m_receivesRef = false;
-
-        /**
-         * Constructor that receives several parameters.
-         *
-         * @param   dependency  An object that contains data about the dependency
-        **/
-        DependencyManager(DependencyMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
-        {
-            m_dependencyMetadata = dependency;
-            m_isValid = false;
-
-            m_bindMethod = getTargetMethod(m_dependencyMetadata.getBindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
-            m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
-
-            setStateDependency(DependencyChangeEvent.DEPENDENCY_CREATED);
-        }
-
-        /**
-         * initializes a dependency. This method binds all of the service occurrences to the instance object
-         *
-         * @return true if the operation was successful, false otherwise
-        **/
-        boolean initialize()
-        {
-            if(getObject() == null)
-            {
-                return false;
-            }
-
-            ServiceReference refs[] = getRequiredServiceRefs();
-
-            if (refs == null && m_dependencyMetadata.isOptional() == false)
-            {
-                m_isValid = false;
-                setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
-                return m_isValid;
-            }
-
-            m_isValid = true;
-            setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
-
-            if (refs != null)
-            {
-                int max = 1;
-                boolean retval = true;
-
-                if (m_dependencyMetadata.isMultiple() == true)
-                {
-                    max = refs.length;
-                }
-
-                for (int index = 0; index < max; index++)
-                {
-                    retval = callBindMethod(refs[index]);
-                    if(retval == false && (max == 1))
-                    {
-                        // There was an exception when calling the bind method
-                        GenericActivator.error("Dependency Manager: Possible exception in the bind method during initialize()");
-                        m_isValid = false;
-                        setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
-                        return m_isValid;
-                    }
-                }
-            }
-
-            return m_isValid;
-        }
-
-        /**
-         * Called upon a service event. This method is responsible for calling the
-         * binding and unbinding methods and also to request the eventual unregistering
-         * of a service when a dependency breaks
-         *
-         * @param evt  The ServiceEvent
-        **/
-        public void serviceChanged(ServiceEvent evt)
-        {
-            synchronized (InstanceManager.this)
-            {
-                // If the object is being created or destroyed, we can safely ignore events.
-                if (m_state == INSTANCE_DESTROYING || m_state == INSTANCE_DESTROYED || m_state == INSTANCE_CREATING || m_state == INSTANCE_CREATED)
-                {
-                    return;
-                }
-
-                // If we are in the process of invalidating, it is not necessary to pass
-                // unregistration events, since we are unbinding everything anyway.
-                else if (m_state == INSTANCE_INVALIDATING && evt.getType() == ServiceEvent.UNREGISTERING)
-                {
-                    return;
-                }
-
-                // We do not have an entry for VALIDATING because it is reentrant.
-
-                // A service is unregistering
-                if (evt.getType() == ServiceEvent.UNREGISTERING)
-                {
-                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
-                    {
-                        // A static dependency is broken the instance manager will be invalidated
-                        if (m_dependencyMetadata.isStatic())
-                        {
-                            m_isValid = false;
-                            setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
-                            try
-                            {
-                                GenericActivator.trace("Dependency Manager: Static dependency is broken");
-                                invalidate();
-                                GenericActivator.trace("Dependency Manager: RECREATING");
-                                validate();
-                            }
-                            catch(Exception e)
-                            {
-                                e.printStackTrace();
-                            }
-                        }
-                        // dynamic dependency
-                        else
-                        {
-                            // Release references to the service, call unbinder method
-                            // and eventually request service unregistration
-
-                            callUnbindMethod(evt.getServiceReference());
-
-                            // The only thing we need to do here is check if we can reinitialize
-                            // once the bound services becomes zero. This tries to repair dynamic
-                            // 1..1 or rebind 0..1, since replacement services may be available.
-                            // In the case of aggregates, this will only invalidate them since they
-                            // can't be repaired.
-                            if (m_boundServices.size() == 0)
-                            {
-                                // try to reinitialize
-                                if (!initialize())
-                                {
-                                    if (!m_dependencyMetadata.isOptional())
-                                    {
-                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...");
-                                        invalidate();
-                                        GenericActivator.trace("Dependency Manager: RECREATING");
-                                        validate();
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                // A service is registering.
-                else if (evt.getType() == ServiceEvent.REGISTERED)
-                {
-                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
-                    {
-                        // This is a duplicate
-                        GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)");
-                    }
-                    else
-                    {
-                        m_isValid = true;
-                        setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
-
-                        // If the InstanceManager is invalid, a call to validate is made
-                        // which will fix everything.
-                        if (InstanceManager.this.getState() != INSTANCE_VALID)
-                        {
-                            validate();
-                        }
-                        // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N it never
-                        // checks for 1..1 dynamic which is done above by the validate()
-                        else if (!m_dependencyMetadata.isStatic())
-                        {
-                            // For dependency that are aggregates, always bind the service
-                            // Otherwise only bind if bind services is zero, which captures the 0..1 case
-                            if (m_dependencyMetadata.isMultiple() || m_boundServices.size() == 0)
-                            {
-                                callBindMethod(evt.getServiceReference());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * Revoke all bindings. This method cannot throw an exception since it must try
-         * to complete all that it can
-         *
-        **/
-        void unbindAll()
-        {
-            Object []allrefs = m_boundServices.keySet().toArray();
-
-            if (allrefs == null)
-                return;
-
-            for (int i = 0; i < allrefs.length; i++)
-            {
-                callUnbindMethod((ServiceReference)allrefs[i]);
-            }
-        }
-
-        /**
-         * Test if this dependency managed by this object is valid
-        **/
-        boolean isValid()
-        {
-            return m_isValid;
-        }
-
-        /**
-         *
-         * Returns an array containing the service references that are pertinent to the
-         * dependency managed by this object. This method filters out services that
-         * belong to bundles that are being (or are actually) shutdown. This is an issue
-         * since is not clearly specified in the OSGi specification if a getServiceReference
-         * call should return the services that belong to bundles that are stopping.
-         *
-         * @return an array of ServiceReferences valid in the context of this dependency
-        **/
-        ServiceReference [] getRequiredServiceRefs()
-        {
-            try
-            {
-                ArrayList list=new ArrayList();
-                ServiceReference temprefs[] =
-                    m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getServiceName(), m_dependencyMetadata.getFilter());
-
-                if (temprefs == null)
-                {
-                    return null;
-                }
-
-                for (int i = 0; i < temprefs.length; i++)
-                {
-                     if (temprefs[i].getBundle().getState() == Bundle.ACTIVE
-                            || temprefs[i].getBundle().getState() == Bundle.STARTING)
-                     {
-                         list.add(temprefs[i]);
-                     }
-                }
-
-                return (ServiceReference []) list.toArray(new ServiceReference [temprefs.length]);
-
-            }
-            catch (Exception e)
-            {
-                GenericActivator.error("DependencyManager: exception while getting references :"+e);
-                return null;
-            }
-        }
-
-        /**
-         * Gets a target method based on a set of parameters
-         *
-         * @param methodname The name of the method
-         * @param targetClass the class to which the method belongs to
-         * @param paramClass the class of the parameter that is passed to the method
-         * @throws java.lang.ClassNotFoundException if the class was not found
-         * @throws java.lang.NoSuchMethodException if the method was not found
-        **/
-        private Method getTargetMethod(String methodname, String targetClass, String paramClass)
-            throws ClassNotFoundException, NoSuchMethodException
-        {
-            Class targetclass = m_activator.getClass().getClassLoader().loadClass(targetClass);
-
-            Method method = null;
-            
-            try
-            {
-                method = targetclass.getMethod(methodname, 
-                    new Class[]{m_activator.getClass().getClassLoader().loadClass(paramClass)});
-               
-            }
-            catch(NoSuchMethodException ex)
-            {
-                // Test if the bind method receives a ServiceReference as the first parameter
-                
-                method = targetclass.getMethod(methodname, 
-                    new Class[]{ServiceReference.class, m_activator.getClass().getClassLoader().loadClass(paramClass)});
-               
-                m_receivesRef = true;
-            }
-            
-            return method;
-        }
-
-        /**
-         * Call the bind method. In case there is an exception while calling the bind method, the service
-         * is not considered to be bound to the instance object
-         *
-         * @param ref A ServiceReference with the service that will be bound to the instance object
-         * @return true if the call was successful, false otherwise
-        **/
-        boolean callBindMethod(ServiceReference ref)
-        {
-            try
-            {
-                Object requiredService = m_activator.getBundleContext().getService(ref);
-                Object proxy = m_activator.proxyRequiredServiceObject(requiredService,m_dependencyMetadata);
-                
-                if(proxy == null)
-                {
-                    // ignore a null return value from the proxy method
-                    proxy = requiredService;
-                }
-                if(m_receivesRef == false)
-                {
-                    m_bindMethod.invoke(getObject(),new Object[] {proxy});
-                }
-                else
-                {
-                    m_bindMethod.invoke(getObject(),new Object[] {ref,proxy});
-                }
-                m_boundServices.put(ref,proxy);
-                
-                return true;
-            }
-            catch(Exception e)
-            {
-                if(e instanceof InvocationTargetException)
-                {
-                    InvocationTargetException ite = (InvocationTargetException) e;
-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+ite.getTargetException());
-                }
-                else
-                {
-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+e);
-                }
-                e.printStackTrace();
-                return false;
-            }
-        }
-
-        /**
-         * Call the unbind method
-         *
-         * @param ref A service reference corresponding to the service that will be unbound
-        **/
-        void callUnbindMethod(ServiceReference ref)
-        {
-            Object requiredService = m_boundServices.get(ref);
-            if (requiredService == null)
-            {
-                GenericActivator.error("DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!");
-                return;
-            }
-
-            try
-            {
-                if(m_receivesRef == false)
-                {
-                    m_unbindMethod.invoke(getObject(),new Object [] {requiredService});
-                }
-                else
-                {
-                    m_unbindMethod.invoke(getObject(),new Object [] {ref, requiredService});
-                }
-                
-                m_boundServices.remove(ref);
-                m_activator.getBundleContext().ungetService(ref);
-            }
-            catch(Exception e)
-            {
-                if(e instanceof InvocationTargetException)
-                {
-                    InvocationTargetException ite = (InvocationTargetException) e;
-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+ite.getTargetException());
-                }
-                else
-                {
-                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+e);
-                }
-                e.printStackTrace();
-            }
-        }
-
-        /**
-         * Return the dependency descriptor
-         *
-         * @return the corresponding dependency descriptor
-        **/
-        public DependencyMetadata getDependencyMetadata()
-        {
-            return m_dependencyMetadata;
-        }
-
-        /**
-         * Fire a state change event.
-         *
-         * @param state the state of the dependency manager
-        **/
-        void setStateDependency(int state)
-        {
-            m_depState = state;
-            m_activator.fireDependencyChangeEvent(new DependencyChangeEvent(this,m_dependencyMetadata,state));
-        }
-
-        /**
-         * Get the state of the dependency.
-         *
-         * @return the state of the dependency manager
-        **/
-        public int getDependencyState()
-        {
-            return m_depState;
-        }
-
-        /**
-         * Get the bound service objects. This method is declared in the Dependency interface
-         * and is used for to get a model.
-         *
-         * @return an array containing the bound service objects
-        **/
-        public Instance[] getBoundInstances()
-        {
-            Object bound[] = m_boundServices.values().toArray();
-
-            ArrayList tempArray = new ArrayList();
-
-            for(int i=0; i<bound.length; i++)
-            {
-                InstanceReference ref = ArchitectureServiceImpl.findInstanceReference(bound[i]);
-                if(ref != null)
-                {
-                    tempArray.add(ref);
-                }
-            }
-
-            Instance instances[]= new Instance[tempArray.size()];
-            instances = (Instance [])tempArray.toArray(instances);
-
-            return instances;
-
-
-        }
+        private Map m_boundServices = new HashMap();
+        private Method m_bindMethod;
+        private Method m_unbindMethod;
+        private boolean m_isValid;
+        private int m_depState;
+        private boolean m_receivesRef = false;
+
+        /**
+         * Constructor that receives several parameters.
+         *
+         * @param   dependency  An object that contains data about the dependency
+        **/
+        DependencyManager(DependencyMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
+        {
+            m_dependencyMetadata = dependency;
+            m_isValid = false;
+
+            m_bindMethod = getTargetMethod(m_dependencyMetadata.getBindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
+            m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbindMethodName(),InstanceManager.this.getInstanceMetadata().getImplementorName(),m_dependencyMetadata.getServiceName());
+
+            setStateDependency(DependencyChangeEvent.DEPENDENCY_CREATED);
+        }
+
+        /**
+         * initializes a dependency. This method binds all of the service occurrences to the instance object
+         *
+         * @return true if the operation was successful, false otherwise
+        **/
+        boolean initialize()
+        {
+            if(getObject() == null)
+            {
+                return false;
+            }
+
+            ServiceReference refs[] = getRequiredServiceRefs();
+
+            if (refs == null && m_dependencyMetadata.isOptional() == false)
+            {
+                m_isValid = false;
+                setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                return m_isValid;
+            }
+
+            m_isValid = true;
+            setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
+
+            if (refs != null)
+            {
+                int max = 1;
+                boolean retval = true;
+
+                if (m_dependencyMetadata.isMultiple() == true)
+                {
+                    max = refs.length;
+                }
+
+                for (int index = 0; index < max; index++)
+                {
+                    retval = callBindMethod(refs[index]);
+                    if(retval == false && (max == 1))
+                    {
+                        // There was an exception when calling the bind method
+                        GenericActivator.error("Dependency Manager: Possible exception in the bind method during initialize()");
+                        m_isValid = false;
+                        setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                        return m_isValid;
+                    }
+                }
+            }
+
+            return m_isValid;
+        }
+
+        /**
+         * Called upon a service event. This method is responsible for calling the
+         * binding and unbinding methods and also to request the eventual unregistering
+         * of a service when a dependency breaks
+         *
+         * @param evt  The ServiceEvent
+        **/
+        public void serviceChanged(ServiceEvent evt)
+        {
+            synchronized (InstanceManager.this)
+            {
+                // If the object is being created or destroyed, we can safely ignore events.
+                if (m_state == INSTANCE_DESTROYING || m_state == INSTANCE_DESTROYED || m_state == INSTANCE_CREATING || m_state == INSTANCE_CREATED)
+                {
+                    return;
+                }
+
+                // If we are in the process of invalidating, it is not necessary to pass
+                // unregistration events, since we are unbinding everything anyway.
+                else if (m_state == INSTANCE_INVALIDATING && evt.getType() == ServiceEvent.UNREGISTERING)
+                {
+                    return;
+                }
+
+                // We do not have an entry for VALIDATING because it is reentrant.
+
+                // A service is unregistering
+                if (evt.getType() == ServiceEvent.UNREGISTERING)
+                {
+                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
+                    {
+                        // A static dependency is broken the instance manager will be invalidated
+                        if (m_dependencyMetadata.isStatic())
+                        {
+                            m_isValid = false;
+                            setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                            try
+                            {
+                                GenericActivator.trace("Dependency Manager: Static dependency is broken");
+                                invalidate();
+                                GenericActivator.trace("Dependency Manager: RECREATING");
+                                validate();
+                            }
+                            catch(Exception e)
+                            {
+                                e.printStackTrace();
+                            }
+                        }
+                        // dynamic dependency
+                        else
+                        {
+                            // Release references to the service, call unbinder method
+                            // and eventually request service unregistration
+
+                            callUnbindMethod(evt.getServiceReference());
+
+                            // The only thing we need to do here is check if we can reinitialize
+                            // once the bound services becomes zero. This tries to repair dynamic
+                            // 1..1 or rebind 0..1, since replacement services may be available.
+                            // In the case of aggregates, this will only invalidate them since they
+                            // can't be repaired.
+                            if (m_boundServices.size() == 0)
+                            {
+                                // try to reinitialize
+                                if (!initialize())
+                                {
+                                    if (!m_dependencyMetadata.isOptional())
+                                    {
+                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...");
+                                        invalidate();
+                                        GenericActivator.trace("Dependency Manager: RECREATING");
+                                        validate();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                // A service is registering.
+                else if (evt.getType() == ServiceEvent.REGISTERED)
+                {
+                    if (m_boundServices.keySet().contains(evt.getServiceReference()) == true)
+                    {
+                        // This is a duplicate
+                        GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)");
+                    }
+                    else
+                    {
+                        m_isValid = true;
+                        setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
+
+                        // If the InstanceManager is invalid, a call to validate is made
+                        // which will fix everything.
+                        if (InstanceManager.this.getState() != INSTANCE_VALID)
+                        {
+                            validate();
+                        }
+                        // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N it never
+                        // checks for 1..1 dynamic which is done above by the validate()
+                        else if (!m_dependencyMetadata.isStatic())
+                        {
+                            // For dependency that are aggregates, always bind the service
+                            // Otherwise only bind if bind services is zero, which captures the 0..1 case
+                            if (m_dependencyMetadata.isMultiple() || m_boundServices.size() == 0)
+                            {
+                                callBindMethod(evt.getServiceReference());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Revoke all bindings. This method cannot throw an exception since it must try
+         * to complete all that it can
+         *
+        **/
+        void unbindAll()
+        {
+            Object []allrefs = m_boundServices.keySet().toArray();
+
+            if (allrefs == null)
+                return;
+
+            for (int i = 0; i < allrefs.length; i++)
+            {
+                callUnbindMethod((ServiceReference)allrefs[i]);
+            }
+        }
+
+        /**
+         * Test if this dependency managed by this object is valid
+        **/
+        boolean isValid()
+        {
+            return m_isValid;
+        }
+
+        /**
+         *
+         * Returns an array containing the service references that are pertinent to the
+         * dependency managed by this object. This method filters out services that
+         * belong to bundles that are being (or are actually) shutdown. This is an issue
+         * since is not clearly specified in the OSGi specification if a getServiceReference
+         * call should return the services that belong to bundles that are stopping.
+         *
+         * @return an array of ServiceReferences valid in the context of this dependency
+        **/
+        ServiceReference [] getRequiredServiceRefs()
+        {
+            try
+            {
+                ArrayList list=new ArrayList();
+                ServiceReference temprefs[] =
+                    m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getServiceName(), m_dependencyMetadata.getFilter());
+
+                if (temprefs == null)
+                {
+                    return null;
+                }
+
+                for (int i = 0; i < temprefs.length; i++)
+                {
+                     if (temprefs[i].getBundle().getState() == Bundle.ACTIVE
+                            || temprefs[i].getBundle().getState() == Bundle.STARTING)
+                     {
+                         list.add(temprefs[i]);
+                     }
+                }
+
+                return (ServiceReference []) list.toArray(new ServiceReference [temprefs.length]);
+
+            }
+            catch (Exception e)
+            {
+                GenericActivator.error("DependencyManager: exception while getting references :"+e);
+                return null;
+            }
+        }
+
+        /**
+         * Gets a target method based on a set of parameters
+         *
+         * @param methodname The name of the method
+         * @param targetClass the class to which the method belongs to
+         * @param paramClass the class of the parameter that is passed to the method
+         * @throws java.lang.ClassNotFoundException if the class was not found
+         * @throws java.lang.NoSuchMethodException if the method was not found
+        **/
+        private Method getTargetMethod(String methodname, String targetClass, String paramClass)
+            throws ClassNotFoundException, NoSuchMethodException
+        {
+            Class targetclass = m_activator.getClass().getClassLoader().loadClass(targetClass);
+
+            Method method = null;
+            
+            try
+            {
+                method = targetclass.getMethod(methodname, 
+                    new Class[]{m_activator.getClass().getClassLoader().loadClass(paramClass)});
+               
+            }
+            catch(NoSuchMethodException ex)
+            {
+                // Test if the bind method receives a ServiceReference as the first parameter
+                
+                method = targetclass.getMethod(methodname, 
+                    new Class[]{ServiceReference.class, m_activator.getClass().getClassLoader().loadClass(paramClass)});
+               
+                m_receivesRef = true;
+            }
+            
+            return method;
+        }
+
+        /**
+         * Call the bind method. In case there is an exception while calling the bind method, the service
+         * is not considered to be bound to the instance object
+         *
+         * @param ref A ServiceReference with the service that will be bound to the instance object
+         * @return true if the call was successful, false otherwise
+        **/
+        boolean callBindMethod(ServiceReference ref)
+        {
+            try
+            {
+                Object requiredService = m_activator.getBundleContext().getService(ref);
+                Object proxy = m_activator.proxyRequiredServiceObject(requiredService,m_dependencyMetadata);
+                
+                if(proxy == null)
+                {
+                    // ignore a null return value from the proxy method
+                    proxy = requiredService;
+                }
+                if(m_receivesRef == false)
+                {
+                    m_bindMethod.invoke(getObject(),new Object[] {proxy});
+                }
+                else
+                {
+                    m_bindMethod.invoke(getObject(),new Object[] {ref,proxy});
+                }
+                m_boundServices.put(ref,proxy);
+                
+                return true;
+            }
+            catch(Exception e)
+            {
+                if(e instanceof InvocationTargetException)
+                {
+                    InvocationTargetException ite = (InvocationTargetException) e;
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+ite.getTargetException());
+                }
+                else
+                {
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getBindMethodName()+" :"+e);
+                }
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        /**
+         * Call the unbind method
+         *
+         * @param ref A service reference corresponding to the service that will be unbound
+        **/
+        void callUnbindMethod(ServiceReference ref)
+        {
+            Object requiredService = m_boundServices.get(ref);
+            if (requiredService == null)
+            {
+                GenericActivator.error("DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!");
+                return;
+            }
+
+            try
+            {
+                if(m_receivesRef == false)
+                {
+                    m_unbindMethod.invoke(getObject(),new Object [] {requiredService});
+                }
+                else
+                {
+                    m_unbindMethod.invoke(getObject(),new Object [] {ref, requiredService});
+                }
+                
+                m_boundServices.remove(ref);
+                m_activator.getBundleContext().ungetService(ref);
+            }
+            catch(Exception e)
+            {
+                if(e instanceof InvocationTargetException)
+                {
+                    InvocationTargetException ite = (InvocationTargetException) e;
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+ite.getTargetException());
+                }
+                else
+                {
+                    GenericActivator.error("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbindMethodName()+" :"+e);
+                }
+                e.printStackTrace();
+            }
+        }
+
+        /**
+         * Return the dependency descriptor
+         *
+         * @return the corresponding dependency descriptor
+        **/
+        public DependencyMetadata getDependencyMetadata()
+        {
+            return m_dependencyMetadata;
+        }
+
+        /**
+         * Fire a state change event.
+         *
+         * @param state the state of the dependency manager
+        **/
+        void setStateDependency(int state)
+        {
+            m_depState = state;
+            m_activator.fireDependencyChangeEvent(new DependencyChangeEvent(this,m_dependencyMetadata,state));
+        }
+
+        /**
+         * Get the state of the dependency.
+         *
+         * @return the state of the dependency manager
+        **/
+        public int getDependencyState()
+        {
+            return m_depState;
+        }
+
+        /**
+         * Get the bound service objects. This method is declared in the Dependency interface
+         * and is used for to get a model.
+         *
+         * @return an array containing the bound service objects
+        **/
+        public Instance[] getBoundInstances()
+        {
+            Object bound[] = m_boundServices.values().toArray();
+
+            ArrayList tempArray = new ArrayList();
+
+            for(int i=0; i<bound.length; i++)
+            {
+                InstanceReference ref = ArchitectureServiceImpl.findInstanceReference(bound[i]);
+                if(ref != null)
+                {
+                    tempArray.add(ref);
+                }
+            }
+
+            Instance instances[]= new Instance[tempArray.size()];
+            instances = (Instance [])tempArray.toArray(instances);
+
+            return instances;
+
+
+        }
     }
 
 /**
- * @version X.XX Feb 3, 2004 
 * @author Humberto Cervantes
+ * @version X.XX Feb 3, 2004  * @author Humberto Cervantes
  */
-
-    static public class StateChangeMulticaster implements InstanceReferenceListener
+
+    static public class StateChangeMulticaster implements InstanceReferenceListener
     {
 
         /**
@@ -1238,43 +1238,43 @@
          */
         protected InstanceReferenceListener b;
 
-        protected StateChangeMulticaster(InstanceReferenceListener a, InstanceReferenceListener b)    
-        {        
-            this.a = a;        
-            this.b = b;    
-        }    
-    
-    
-        public void validated(InstanceReferenceEvent e)    
-        {
-            a.validated(e);        
-            b.validated(e);
-        }
-    
-        public void invalidating(InstanceReferenceEvent e)    
-        {
-            a.invalidating(e);        
-            b.invalidating(e);
-        }
-    
-        public static InstanceReferenceListener add(InstanceReferenceListener a, InstanceReferenceListener b)
-        {
-            if (a == null)
-                return b;
-            else if (b == null)

[... 57 lines stripped ...]