Removed ^M line endings.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@447121 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java b/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
index 2b79da7..c43b1e2 100644
--- a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
@@ -1,1193 +1,1193 @@
-/*
- * Copyright 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.felix.scr;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.osgi.framework.*;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.ComponentInstance;
-
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
-/**
- * The default ComponentManager. Objects of this class are responsible for managing
- * implementation object's lifecycle.
- *
- */
-public class ComponentManagerImpl implements ComponentManager, ComponentInstance
-{
- // States of the instance manager
- static final int INSTANCE_CREATING = 0;
- static final int INSTANCE_CREATED = 1;
- static final int INSTANCE_VALIDATING = 2;
- static final int INSTANCE_VALID = 3;
- static final int INSTANCE_INVALIDATING = 4;
- static final int INSTANCE_INVALID = 5;
- static final int INSTANCE_DESTROYING = 6;
- static final int INSTANCE_DESTROYED = 7;
-
-
- static final String m_states[]={"CREATING","CREATED",
- "VALIDATING","VALID",
- "INVALIDATING","INVALID",
- "DESTROYING","DESTROYED"
- };
-
- // The state of this instance manager
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The default ComponentManager. Objects of this class are responsible for managing
+ * implementation object's lifecycle.
+ *
+ */
+public class ComponentManagerImpl implements ComponentManager, ComponentInstance
+{
+ // States of the instance manager
+ static final int INSTANCE_CREATING = 0;
+ static final int INSTANCE_CREATED = 1;
+ static final int INSTANCE_VALIDATING = 2;
+ static final int INSTANCE_VALID = 3;
+ static final int INSTANCE_INVALIDATING = 4;
+ static final int INSTANCE_INVALID = 5;
+ static final int INSTANCE_DESTROYING = 6;
+ static final int INSTANCE_DESTROYED = 7;
+
+
+ static final String m_states[]={"CREATING","CREATED",
+ "VALIDATING","VALID",
+ "INVALIDATING","INVALID",
+ "DESTROYING","DESTROYED"
+ };
+
+ // The state of this instance manager
private int m_state = INSTANCE_CREATING;
// The metadata
- private ComponentMetadata m_componentMetadata;
-
- // The object that implements the service and that is bound to other services
- private Object m_implementationObject = null;
-
- // The dependency managers that manage every dependency
- private List m_dependencyManagers = new ArrayList();
-
- // The ServiceRegistration
+ private ComponentMetadata m_componentMetadata;
+
+ // The object that implements the service and that is bound to other services
+ private Object m_implementationObject = null;
+
+ // The dependency managers that manage every dependency
+ private List m_dependencyManagers = new ArrayList();
+
+ // The ServiceRegistration
private ServiceRegistration m_serviceRegistration = null;
// A reference to the GenericActivator
private GenericActivator m_activator = null;
- // The context that will be passed to the implementationObject
+ // The context that will be passed to the implementationObject
private ComponentContext m_componentContext = null;
-
- // In case of a delayed component, this holds a reference to the factory
- private DelayedComponentServiceFactory m_delayedComponentServiceFactory;
-
- /**
- * The constructor receives both the activator and the metadata
- *
- * @param activator
- * @param metadata
- */
- ComponentManagerImpl(GenericActivator activator,ComponentMetadata metadata)
- {
- // Store the activator reference
- m_activator = activator;
-
- // Store the metadata reference
- m_componentMetadata = metadata;
- }
-
- /**
- * Enable this component
- *
- * @return true if enabling was successful
- */
- public boolean enable() {
-
- GenericActivator.trace("Enabling component", m_componentMetadata);
-
- try
- {
- // If this component has got dependencies, create dependency managers for each one of them.
- if (m_componentMetadata.getDependencies().size() != 0)
- {
- Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
-
- while(dependencyit.hasNext())
- {
- ReferenceMetadata currentdependency = (ReferenceMetadata)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.m_dependencyMetadata.getTarget());
- }
- }
-
- // TODO: create the context
- //m_sbcontext = new ServiceBinderContextImpl(this);
-
- // Add this instance manager to the Generic activator list
- //m_activator.addInstanceManager(this);
-
-
- setState(INSTANCE_CREATED);
-
- activate();
-
- return true;
- }
- catch(Exception ex)
- {
- // TODO: Log this error
- return false;
- }
- }
-
- /**
- * Activate this Instance manager.
- *
- * 112.5.6 Activating a component configuration consists of the following steps
- * 1. Load the component implementation class
- * 2. Create the component instance and component context
- * 3. Bind the target services
- * 4. Call the activate method, if present
- * [5. Register provided services]
- */
- synchronized private void activate()
- {
- // CONCURRENCY NOTE: This method is called either by the enable() method or by the dependency
- // managers.
- if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED) {
- // This state can only be entered from the CREATED or INVALID states
- return;
- }
-
- setState(INSTANCE_VALIDATING);
-
- // Before creating the implementation object, we are going to
- // test if all the mandatory dependencies are satisfied
- Iterator it = m_dependencyManagers.iterator();
-
- while (it.hasNext())
- {
- // It is not possible to call the isValid method yet in the DependencyManagers
- // since they have not been initialized yet, but they can't be initialized yet
- // because the implementationObject has not been created yet.
- // This test is necessary, because we don't want to instantiate
- // the implementationObject if the dependency managers aren't valid.
- DependencyManager dm = (DependencyManager)it.next();
- if (dm.getRequiredServiceRefs() == null && dm.m_dependencyMetadata.isOptional() == false)
- {
- setState(INSTANCE_INVALID);
- return;
- }
- }
-
- // 1. Load the component implementation class
- // 2. Create the component instance and component context
- // If the component is not immediate, this is not done at this moment
- if( m_componentMetadata.isImmediate() == true )
- {
- //GenericActivator.trace("Loading implementation class and creating instance for component '"+m_componentMetadata.getName()+"'");
- try
- {
- // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
- Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
-
- // 112.4.4 The class must be public and have a public constructor without arguments so component instances
- // may be created by the SCR with the newInstance method on Class
- m_componentContext = new ComponentContextImpl(null);
- m_implementationObject = c.newInstance();
- }
- catch (Exception ex)
- {
- // TODO: manage this exception when implementation object cannot be created
- GenericActivator.exception("Error during instantiation", m_componentMetadata, ex);
- deactivate();
- //invalidate();
- return;
- }
- } else {
- m_delayedComponentServiceFactory = new DelayedComponentServiceFactory();
- }
-
- // 3. Bind the target services
- it = m_dependencyManagers.iterator();
-
- //GenericActivator.trace("Binding target services for component '"+m_componentMetadata.getName()+"'");
-
- while (it.hasNext())
- {
- DependencyManager dm = (DependencyManager)it.next();
-
- // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
- if (dm.bind() == false)
- {
- deactivate();
- return;
- }
- }
-
- //GenericActivator.trace("Calling activate for component '"+m_componentMetadata.getName()+"'");
-
- // 4. Call the activate method, if present
- // 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_componentMetadata.isImmediate() == true && m_state == INSTANCE_VALIDATING)
- {
- // Search for the activate method
- try {
- Method activateMethod = getMethod(m_implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
- activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
- }
- catch(NoSuchMethodException ex) {
- // We can safely ignore this one
- GenericActivator.trace("activate() method not implemented", m_componentMetadata);
- }
- catch(IllegalAccessException ex) {
- // TODO: Log this exception?
- GenericActivator.trace("activate() method cannot be called", m_componentMetadata);
- }
- catch(InvocationTargetException ex) {
- // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
- // containing the exception with the Log Service
- GenericActivator.exception("The activate method has thrown an exception", m_componentMetadata, ex.getTargetException());
- }
- }
-
- // Validation occurs before the services are provided, otherwhise the service provider's service may be called
- // by a service requester while it is still VALIDATING
- setState(INSTANCE_VALID);
-
- // 5. Register provided services
- if(m_componentMetadata.getServiceMetadata() != null)
- {
- GenericActivator.trace("registering services", m_componentMetadata);
-
- if( m_componentMetadata.isImmediate() == true ) {
- // In the case the component is immediate, the implementation object is registered
- m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_implementationObject, m_componentMetadata.getProperties());
- }else {
- // In the case the component is delayed, a factory is registered
- m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_delayedComponentServiceFactory, m_componentMetadata.getProperties());
- }
- }
- }
-
- /**
- * This method deactivates the manager, performing the following steps
- *
- * [0. Remove published services from the registry]
- * 1. Call the deactivate() method, if present
- * 2. Unbind any bound services
- * 3. Release references to the component instance and component context
- **/
- synchronized private void deactivate()
- {
- // CONCURRENCY NOTE: This method may be called either from application code or by the dependency managers
- if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
- return;
- }
-
- // In case the instance is valid when this is called, the manager is set to an invalidating state
- if (m_state != INSTANCE_DESTROYING)
- {
- setState(INSTANCE_INVALIDATING);
- }
-
- // 0.- Remove published services from the registry
- if(m_serviceRegistration != null)
- {
- m_serviceRegistration.unregister();
- m_serviceRegistration = null;
-
- GenericActivator.trace("unregistering the services", m_componentMetadata);
- }
-
- // 1.- Call the deactivate method, if present
- // Search the deactivate method
- try {
- // It is necessary to check that the implementation Object is not null. This may happen if the component
- // is delayed and its service was never requested.
- if(m_implementationObject != null)
- {
- Method activateMethod = getMethod(m_implementationObject.getClass(), "deactivate", new Class[]{ComponentContext.class});
- activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
- }
- }
- catch(NoSuchMethodException ex) {
- // We can safely ignore this one
- GenericActivator.trace("deactivate() method is not implemented", m_componentMetadata);
- }
- catch(IllegalAccessException ex) {
- // Ignored, but should it be logged?
- GenericActivator.trace("deactivate() method cannot be called", m_componentMetadata);
- }
- catch(InvocationTargetException ex) {
- // TODO: 112.5.12 If the deactivate method throws an exception, SCR must log an error message
- // containing the exception with the Log Service
- GenericActivator.exception("The deactivate method has thrown and exception", m_componentMetadata, ex);
- }
-
- // 2. Unbind any bound services
- Iterator it = m_dependencyManagers.iterator();
-
- while (it.hasNext())
- {
- DependencyManager dm = (DependencyManager)it.next();
- dm.unbind();
- }
-
- // 3. Release references to the component instance and component context
- m_implementationObject = null;
- m_componentContext = null;
- m_delayedComponentServiceFactory = null;
-
- //GenericActivator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
-
- if (m_state != INSTANCE_DESTROYING)
- {
- setState(INSTANCE_INVALID);
- }
- }
-
- /**
- *
- */
- public synchronized void dispose()
- {
- // CONCURRENCY NOTE: This method is only called from the GenericActivator or by application logic
- // but not by the dependency managers
-
- // Theoretically this should never be in any state other than VALID or INVALID,
- // because validate is called right after creation.
- if (m_state != INSTANCE_VALID && m_state != INSTANCE_INVALID)
- {
- return;
- }
-
- boolean deactivationRequired = (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);
- }
-
- // in case the component is disposed when it was VALID, it is necessary to deactivate it first.
- if (deactivationRequired)
- {
- deactivate();
- }
-
- m_dependencyManagers.clear();
-
- setState(INSTANCE_DESTROYED);
-
- m_activator = null;
- }
-
- //**********************************************************************************************************
-
- /**
- * Get the object that is implementing this descriptor
- *
- * @return the object that implements the services
- */
- public Object getInstance() {
- return m_implementationObject;
- }
-
- /**
- *
- */
- public ComponentMetadata getComponentMetadata() {
- return m_componentMetadata;
- }
-
- /**
- * sets the state of the manager
- **/
- private synchronized void setState(int newState) {
- GenericActivator.trace("State transition : "+m_states[m_state]+" -> "+m_states[newState], m_componentMetadata);
-
- 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));
- }
+
+ // In case of a delayed component, this holds a reference to the factory
+ private DelayedComponentServiceFactory m_delayedComponentServiceFactory;
+
+ /**
+ * The constructor receives both the activator and the metadata
+ *
+ * @param activator
+ * @param metadata
+ */
+ ComponentManagerImpl(GenericActivator activator,ComponentMetadata metadata)
+ {
+ // Store the activator reference
+ m_activator = activator;
+
+ // Store the metadata reference
+ m_componentMetadata = metadata;
+ }
+
+ /**
+ * Enable this component
+ *
+ * @return true if enabling was successful
+ */
+ public boolean enable() {
+
+ GenericActivator.trace("Enabling component", m_componentMetadata);
+
+ try
+ {
+ // If this component has got dependencies, create dependency managers for each one of them.
+ if (m_componentMetadata.getDependencies().size() != 0)
+ {
+ Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
+
+ while(dependencyit.hasNext())
+ {
+ ReferenceMetadata currentdependency = (ReferenceMetadata)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.m_dependencyMetadata.getTarget());
+ }
+ }
+
+ // TODO: create the context
+ //m_sbcontext = new ServiceBinderContextImpl(this);
+
+ // Add this instance manager to the Generic activator list
+ //m_activator.addInstanceManager(this);
+
+
+ setState(INSTANCE_CREATED);
+
+ activate();
+
+ return true;
+ }
+ catch(Exception ex)
+ {
+ // TODO: Log this error
+ return false;
+ }
+ }
+
+ /**
+ * Activate this Instance manager.
+ *
+ * 112.5.6 Activating a component configuration consists of the following steps
+ * 1. Load the component implementation class
+ * 2. Create the component instance and component context
+ * 3. Bind the target services
+ * 4. Call the activate method, if present
+ * [5. Register provided services]
+ */
+ synchronized private void activate()
+ {
+ // CONCURRENCY NOTE: This method is called either by the enable() method or by the dependency
+ // managers.
+ if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED) {
+ // This state can only be entered from the CREATED or INVALID states
+ return;
+ }
+
+ setState(INSTANCE_VALIDATING);
+
+ // Before creating the implementation object, we are going to
+ // test if all the mandatory dependencies are satisfied
+ Iterator it = m_dependencyManagers.iterator();
+
+ while (it.hasNext())
+ {
+ // It is not possible to call the isValid method yet in the DependencyManagers
+ // since they have not been initialized yet, but they can't be initialized yet
+ // because the implementationObject has not been created yet.
+ // This test is necessary, because we don't want to instantiate
+ // the implementationObject if the dependency managers aren't valid.
+ DependencyManager dm = (DependencyManager)it.next();
+ if (dm.getRequiredServiceRefs() == null && dm.m_dependencyMetadata.isOptional() == false)
+ {
+ setState(INSTANCE_INVALID);
+ return;
+ }
+ }
+
+ // 1. Load the component implementation class
+ // 2. Create the component instance and component context
+ // If the component is not immediate, this is not done at this moment
+ if( m_componentMetadata.isImmediate() == true )
+ {
+ //GenericActivator.trace("Loading implementation class and creating instance for component '"+m_componentMetadata.getName()+"'");
+ try
+ {
+ // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
+ Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
+
+ // 112.4.4 The class must be public and have a public constructor without arguments so component instances
+ // may be created by the SCR with the newInstance method on Class
+ m_componentContext = new ComponentContextImpl(null);
+ m_implementationObject = c.newInstance();
+ }
+ catch (Exception ex)
+ {
+ // TODO: manage this exception when implementation object cannot be created
+ GenericActivator.exception("Error during instantiation", m_componentMetadata, ex);
+ deactivate();
+ //invalidate();
+ return;
+ }
+ } else {
+ m_delayedComponentServiceFactory = new DelayedComponentServiceFactory();
+ }
+
+ // 3. Bind the target services
+ it = m_dependencyManagers.iterator();
+
+ //GenericActivator.trace("Binding target services for component '"+m_componentMetadata.getName()+"'");
+
+ while (it.hasNext())
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+
+ // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
+ if (dm.bind() == false)
+ {
+ deactivate();
+ return;
+ }
+ }
+
+ //GenericActivator.trace("Calling activate for component '"+m_componentMetadata.getName()+"'");
+
+ // 4. Call the activate method, if present
+ // 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_componentMetadata.isImmediate() == true && m_state == INSTANCE_VALIDATING)
+ {
+ // Search for the activate method
+ try {
+ Method activateMethod = getMethod(m_implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
+ activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
+ }
+ catch(NoSuchMethodException ex) {
+ // We can safely ignore this one
+ GenericActivator.trace("activate() method not implemented", m_componentMetadata);
+ }
+ catch(IllegalAccessException ex) {
+ // TODO: Log this exception?
+ GenericActivator.trace("activate() method cannot be called", m_componentMetadata);
+ }
+ catch(InvocationTargetException ex) {
+ // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
+ // containing the exception with the Log Service
+ GenericActivator.exception("The activate method has thrown an exception", m_componentMetadata, ex.getTargetException());
+ }
+ }
+
+ // Validation occurs before the services are provided, otherwhise the service provider's service may be called
+ // by a service requester while it is still VALIDATING
+ setState(INSTANCE_VALID);
+
+ // 5. Register provided services
+ if(m_componentMetadata.getServiceMetadata() != null)
+ {
+ GenericActivator.trace("registering services", m_componentMetadata);
+
+ if( m_componentMetadata.isImmediate() == true ) {
+ // In the case the component is immediate, the implementation object is registered
+ m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_implementationObject, m_componentMetadata.getProperties());
+ }else {
+ // In the case the component is delayed, a factory is registered
+ m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_delayedComponentServiceFactory, m_componentMetadata.getProperties());
+ }
+ }
+ }
+
+ /**
+ * This method deactivates the manager, performing the following steps
+ *
+ * [0. Remove published services from the registry]
+ * 1. Call the deactivate() method, if present
+ * 2. Unbind any bound services
+ * 3. Release references to the component instance and component context
+ **/
+ synchronized private void deactivate()
+ {
+ // CONCURRENCY NOTE: This method may be called either from application code or by the dependency managers
+ if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
+ return;
+ }
+
+ // In case the instance is valid when this is called, the manager is set to an invalidating state
+ if (m_state != INSTANCE_DESTROYING)
+ {
+ setState(INSTANCE_INVALIDATING);
+ }
+
+ // 0.- Remove published services from the registry
+ if(m_serviceRegistration != null)
+ {
+ m_serviceRegistration.unregister();
+ m_serviceRegistration = null;
+
+ GenericActivator.trace("unregistering the services", m_componentMetadata);
+ }
+
+ // 1.- Call the deactivate method, if present
+ // Search the deactivate method
+ try {
+ // It is necessary to check that the implementation Object is not null. This may happen if the component
+ // is delayed and its service was never requested.
+ if(m_implementationObject != null)
+ {
+ Method activateMethod = getMethod(m_implementationObject.getClass(), "deactivate", new Class[]{ComponentContext.class});
+ activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
+ }
+ }
+ catch(NoSuchMethodException ex) {
+ // We can safely ignore this one
+ GenericActivator.trace("deactivate() method is not implemented", m_componentMetadata);
+ }
+ catch(IllegalAccessException ex) {
+ // Ignored, but should it be logged?
+ GenericActivator.trace("deactivate() method cannot be called", m_componentMetadata);
+ }
+ catch(InvocationTargetException ex) {
+ // TODO: 112.5.12 If the deactivate method throws an exception, SCR must log an error message
+ // containing the exception with the Log Service
+ GenericActivator.exception("The deactivate method has thrown and exception", m_componentMetadata, ex);
+ }
+
+ // 2. Unbind any bound services
+ Iterator it = m_dependencyManagers.iterator();
+
+ while (it.hasNext())
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+ dm.unbind();
+ }
+
+ // 3. Release references to the component instance and component context
+ m_implementationObject = null;
+ m_componentContext = null;
+ m_delayedComponentServiceFactory = null;
+
+ //GenericActivator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+ if (m_state != INSTANCE_DESTROYING)
+ {
+ setState(INSTANCE_INVALID);
+ }
+ }
+
+ /**
+ *
+ */
+ public synchronized void dispose()
+ {
+ // CONCURRENCY NOTE: This method is only called from the GenericActivator or by application logic
+ // but not by the dependency managers
+
+ // Theoretically this should never be in any state other than VALID or INVALID,
+ // because validate is called right after creation.
+ if (m_state != INSTANCE_VALID && m_state != INSTANCE_INVALID)
+ {
+ return;
+ }
+
+ boolean deactivationRequired = (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);
+ }
+
+ // in case the component is disposed when it was VALID, it is necessary to deactivate it first.
+ if (deactivationRequired)
+ {
+ deactivate();
+ }
+
+ m_dependencyManagers.clear();
+
+ setState(INSTANCE_DESTROYED);
+
+ m_activator = null;
+ }
+
+ //**********************************************************************************************************
+
+ /**
+ * Get the object that is implementing this descriptor
+ *
+ * @return the object that implements the services
+ */
+ public Object getInstance() {
+ return m_implementationObject;
+ }
+
+ /**
+ *
+ */
+ public ComponentMetadata getComponentMetadata() {
+ return m_componentMetadata;
+ }
+
+ /**
+ * sets the state of the manager
+ **/
+ private synchronized void setState(int newState) {
+ GenericActivator.trace("State transition : "+m_states[m_state]+" -> "+m_states[newState], m_componentMetadata);
+
+ 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));
+ }
}
/**
- * 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
- {
+ * 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
+ {
// Reference to the metadata
private ReferenceMetadata m_dependencyMetadata;
-
+
// The bound services <ServiceReference>
- private Set m_boundServicesRefs = new HashSet();
-
- // A flag that denotes if the dependency is satisfied at any given moment
- private boolean m_isValid;
-
- // A flag that defines if the bind method receives a ServiceReference
- private boolean m_bindUsesServiceReference = false;
-
- /**
- * Constructor that receives several parameters.
- *
- * @param dependency An object that contains data about the dependency
- **/
- private DependencyManager(ReferenceMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
- {
- m_dependencyMetadata = dependency;
- m_isValid = false;
-
- //m_bindMethod = getTargetMethod(m_dependencyMetadata.getBind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
- //m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
- }
-
- /**
- * initializes a dependency. This method binds all of the service occurrences to the instance object
- *
- * @return true if the operation was successful, false otherwise
- **/
- private boolean bind()
- {
- /*
- if(getInstance() == null)
- {
- return false;
- }*/
-
- // Get service references
- ServiceReference refs[] = getRequiredServiceRefs();
-
- // If no references were received, we have to check if the dependency
- // is optional, if it is not then the dependency is invalid
- if (refs == null && m_dependencyMetadata.isOptional() == false)
- {
- m_isValid = false;
- return m_isValid;
- }
-
- m_isValid = true;
-
- // refs can be null if the dependency is optional
- 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 = invokeBindMethod(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;
- }
-
- /**
- * Revoke all bindings. This method cannot throw an exception since it must try
- * to complete all that it can
- *
- **/
- private void unbind()
- {
- Object []allrefs = m_boundServicesRefs.toArray();
-
- if (allrefs == null)
- return;
-
- for (int i = 0; i < allrefs.length; i++)
- {
- invokeUnbindMethod((ServiceReference)allrefs[i]);
- }
- }
-
- /**
- *
- * 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
- **/
- private ServiceReference [] getRequiredServiceRefs()
- {
- try
- {
- ArrayList list=new ArrayList();
-
- ServiceReference temprefs[] = m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getInterface(), m_dependencyMetadata.getTarget());
-
- 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 bind or unbind method according to the policies described in the specification
- *
- * @param methodname The name of the method
- * @param targetClass the class to which the method belongs to
- * @param parameterClassName the name of the class of the parameter that is passed to the method
- * @return the method or null
- * @throws java.lang.ClassNotFoundException if the class was not found
- **/
- private Method getBindingMethod(String methodname, Class targetClass, String parameterClassName)
- {
- Method method = null;
-
- Class parameterClass = null;
-
- // 112.3.1 The method is searched for using the following priority
- // 1. The method's parameter type is org.osgi.framework.ServiceReference
- // 2. The method's parameter type is the type specified by the reference's interface attribute
- // 3. The method's parameter type is assignable from the type specified by the reference's interface attribute
- try{
- // Case 1
-
- method = getMethod(targetClass, methodname, new Class[]{ServiceReference.class});
-
- m_bindUsesServiceReference = true;
- }
- catch(NoSuchMethodException ex){
-
- try {
- // Case2
-
- m_bindUsesServiceReference = false;
-
- parameterClass = m_activator.getBundleContext().getBundle().loadClass(parameterClassName);
-
- method = getMethod(targetClass, methodname, new Class[]{parameterClass});
- }
- catch(NoSuchMethodException ex2) {
-
- // Case 3
- method = null;
-
- // iterate on class hierarchy
- for ( ; method == null && targetClass != null; targetClass = targetClass.getSuperclass())
- {
- // Get all potential bind methods
- Method candidateBindMethods[] = targetClass.getDeclaredMethods();
-
- // Iterate over them
- for(int i = 0; method == null && i < candidateBindMethods.length; i++) {
- Method currentMethod = candidateBindMethods[i];
-
- // Get the parameters for the current method
- Class[] parameters = currentMethod.getParameterTypes();
-
- // Select only the methods that receive a single parameter
- // and a matching name
- if(parameters.length == 1 && currentMethod.getName().equals(methodname)) {
-
- // Get the parameter type
- Class theParameter = parameters[0];
-
- // Check if the parameter type is assignable from the type specified by the reference's interface attribute
- if(theParameter.isAssignableFrom(parameterClass)) {
-
- // Final check: it must be public or protected
- if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers()))
- {
- if (!method.isAccessible())
- {
- method.setAccessible(true);
- }
- method = currentMethod;
-
- }
- }
- }
- }
- }
- }
- catch(ClassNotFoundException ex2) {
- GenericActivator.exception("Cannot load class used as parameter "+parameterClassName,m_componentMetadata,ex2);
- }
-
- }
-
- 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
- * @param storeRef A boolean that indicates if the reference must be stored (this is used for the delayed components)
- * @return true if the call was successful, false otherwise
- **/
- private boolean invokeBindMethod(ServiceReference ref) {
- // The bind method is only invoked if the implementation object is not null. This is valid
- // for both immediate and delayed components
- if(m_implementationObject != null) {
-
- try {
- // Get the bind method
- Method bindMethod = getBindingMethod(m_dependencyMetadata.getBind(), getInstance().getClass(), m_dependencyMetadata.getInterface());
-
- if(bindMethod == null){
- // 112.3.1 If the method is not found , SCR must log an error
- // message with the log service, if present, and ignore the method
- // TODO: log error message
- GenericActivator.trace("bind() method not found", m_componentMetadata);
- return false;
- }
-
- // Get the parameter
- Object parameter;
-
- if(m_bindUsesServiceReference == false) {
- parameter = m_activator.getBundleContext().getService(ref);
- }
- else {
- parameter = ref;
- }
-
- // Invoke the method
- bindMethod.invoke(getInstance(),new Object[] {parameter});
-
- // Store the reference
- m_boundServicesRefs.add(ref);
-
- return true;
- }
- catch(IllegalAccessException ex)
- {
- // 112.3.1 If the method is not is not declared protected or public, SCR must log an error
- // message with the log service, if present, and ignore the method
- // TODO: log error message
- return false;
- }
- catch(InvocationTargetException ex)
- {
- GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getBind()+"()", m_componentMetadata, ex);
- return false;
- }
- } else if( m_implementationObject == null && m_componentMetadata.isImmediate() == false) {
- // In the case the implementation object is null and the component is delayed
- // then we still have to store the object that is passed to the bind methods
- // so that it can be used once the implementation object is created.
- m_boundServicesRefs.add(ref);
- return true;
- } else {
- // TODO: assert false : this theoretically never happens...
- return false;
- }
- }
-
- /**
- * Call the unbind method
- *
- * @param ref A service reference corresponding to the service that will be unbound
- * @return true if the call was successful, false otherwise
- **/
- private boolean invokeUnbindMethod(ServiceReference ref) {
- // TODO: assert m_boundServices.contains(ref) == true : "DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!";
-
- // The unbind method is only invoked if the implementation object is not null. This is valid
- // for both immediate and delayed components
- if ( m_implementationObject != null ) {
- try
- {
- // TODO: me quede aqui por que el unbind method no funciona
- GenericActivator.trace("getting unbind: "+m_dependencyMetadata.getUnbind(), m_componentMetadata);
- Method unbindMethod = getBindingMethod(m_dependencyMetadata.getUnbind(), getInstance().getClass(), m_dependencyMetadata.getInterface());
-
- // Recover the object that is bound from the map.
- //Object parameter = m_boundServices.get(ref);
- Object parameter = null;
-
- if(m_bindUsesServiceReference == true) {
- parameter = ref;
- } else {
- parameter = m_activator.getBundleContext().getService(ref);
- }
-
- if(unbindMethod == null){
- // 112.3.1 If the method is not found , SCR must log an error
- // message with the log service, if present, and ignore the method
- // TODO: log error message
- GenericActivator.trace("unbind() method not found", m_componentMetadata);
- return false;
- }
-
- unbindMethod.invoke(getInstance(),new Object [] {parameter});
-
- m_boundServicesRefs.remove(ref);
-
- m_activator.getBundleContext().ungetService(ref);
-
- return true;
- }
- catch (IllegalAccessException ex) {
- // 112.3.1 If the method is not is not declared protected or public, SCR must log an error
- // message with the log service, if present, and ignore the method
- // TODO: log error message
- return false;
- }
- catch (InvocationTargetException ex) {
- GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbind()+"()", m_componentMetadata, ex);
- return false;
- }
-
- } else if( m_implementationObject == null && m_componentMetadata.isImmediate() == false) {
- // In the case the implementation object is null and the component is delayed
- // then we still have to store the object that is passed to the bind methods
- // so that it can be used once the implementation object is created.
- m_boundServicesRefs.remove(ref);
- return true;
- } else {
- // TODO: assert false : this theoretically never happens...
- return false;
- }
- }
-
- /**
- * 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 (ComponentManagerImpl.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_boundServicesRefs.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", m_componentMetadata);
- deactivate();
- GenericActivator.trace("Dependency Manager: RECREATING", m_componentMetadata);
- activate();
- }
- catch(Exception ex)
- {
- GenericActivator.exception("Exception while recreating dependency ",m_componentMetadata, ex);
- }
- }
- // dynamic dependency
- else
- {
- // Release references to the service, call unbinder method
- // and eventually request service unregistration
-
- invokeUnbindMethod(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_boundServicesRefs.size() == 0)
- {
- // try to reinitialize
- if (!bind())
- {
- if (!m_dependencyMetadata.isOptional())
- {
- GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...", m_componentMetadata);
- deactivate();
- GenericActivator.trace("Dependency Manager: Recreating", m_componentMetadata);
- activate();
- }
- }
- }
- }
- }
- }
- // A service is registering.
- else if (evt.getType() == ServiceEvent.REGISTERED)
- {
- if (m_boundServicesRefs.contains(evt.getServiceReference()) == true)
- {
- // This is a duplicate
- GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)", m_componentMetadata);
- }
- else
- {
- m_isValid = true;
- //setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
-
- // If the InstanceManager is invalid, a call to validate is made
- // which will fix everything.
- if (ComponentManagerImpl.this.m_state != INSTANCE_VALID)
- {
- activate();
- }
- // 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_boundServicesRefs.size() == 0)
- {
- invokeBindMethod(evt.getServiceReference());
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Implementation for the ComponentContext interface
- *
+ private Set m_boundServicesRefs = new HashSet();
+
+ // A flag that denotes if the dependency is satisfied at any given moment
+ private boolean m_isValid;
+
+ // A flag that defines if the bind method receives a ServiceReference
+ private boolean m_bindUsesServiceReference = false;
+
+ /**
+ * Constructor that receives several parameters.
+ *
+ * @param dependency An object that contains data about the dependency
+ **/
+ private DependencyManager(ReferenceMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
+ {
+ m_dependencyMetadata = dependency;
+ m_isValid = false;
+
+ //m_bindMethod = getTargetMethod(m_dependencyMetadata.getBind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
+ //m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
+ }
+
+ /**
+ * initializes a dependency. This method binds all of the service occurrences to the instance object
+ *
+ * @return true if the operation was successful, false otherwise
+ **/
+ private boolean bind()
+ {
+ /*
+ if(getInstance() == null)
+ {
+ return false;
+ }*/
+
+ // Get service references
+ ServiceReference refs[] = getRequiredServiceRefs();
+
+ // If no references were received, we have to check if the dependency
+ // is optional, if it is not then the dependency is invalid
+ if (refs == null && m_dependencyMetadata.isOptional() == false)
+ {
+ m_isValid = false;
+ return m_isValid;
+ }
+
+ m_isValid = true;
+
+ // refs can be null if the dependency is optional
+ 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 = invokeBindMethod(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;
+ }
+
+ /**
+ * Revoke all bindings. This method cannot throw an exception since it must try
+ * to complete all that it can
+ *
+ **/
+ private void unbind()
+ {
+ Object []allrefs = m_boundServicesRefs.toArray();
+
+ if (allrefs == null)
+ return;
+
+ for (int i = 0; i < allrefs.length; i++)
+ {
+ invokeUnbindMethod((ServiceReference)allrefs[i]);
+ }
+ }
+
+ /**
+ *
+ * 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
+ **/
+ private ServiceReference [] getRequiredServiceRefs()
+ {
+ try
+ {
+ ArrayList list=new ArrayList();
+
+ ServiceReference temprefs[] = m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getInterface(), m_dependencyMetadata.getTarget());
+
+ 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 bind or unbind method according to the policies described in the specification
+ *
+ * @param methodname The name of the method
+ * @param targetClass the class to which the method belongs to
+ * @param parameterClassName the name of the class of the parameter that is passed to the method
+ * @return the method or null
+ * @throws java.lang.ClassNotFoundException if the class was not found
+ **/
+ private Method getBindingMethod(String methodname, Class targetClass, String parameterClassName)
+ {
+ Method method = null;
+
+ Class parameterClass = null;
+
+ // 112.3.1 The method is searched for using the following priority
+ // 1. The method's parameter type is org.osgi.framework.ServiceReference
+ // 2. The method's parameter type is the type specified by the reference's interface attribute
+ // 3. The method's parameter type is assignable from the type specified by the reference's interface attribute
+ try{
+ // Case 1
+
+ method = getMethod(targetClass, methodname, new Class[]{ServiceReference.class});
+
+ m_bindUsesServiceReference = true;
+ }
+ catch(NoSuchMethodException ex){
+
+ try {
+ // Case2
+
+ m_bindUsesServiceReference = false;
+
+ parameterClass = m_activator.getBundleContext().getBundle().loadClass(parameterClassName);
+
+ method = getMethod(targetClass, methodname, new Class[]{parameterClass});
+ }
+ catch(NoSuchMethodException ex2) {
+
+ // Case 3
+ method = null;
+
+ // iterate on class hierarchy
+ for ( ; method == null && targetClass != null; targetClass = targetClass.getSuperclass())
+ {
+ // Get all potential bind methods
+ Method candidateBindMethods[] = targetClass.getDeclaredMethods();
+
+ // Iterate over them
+ for(int i = 0; method == null && i < candidateBindMethods.length; i++) {
+ Method currentMethod = candidateBindMethods[i];
+
+ // Get the parameters for the current method
+ Class[] parameters = currentMethod.getParameterTypes();
+
+ // Select only the methods that receive a single parameter
+ // and a matching name
+ if(parameters.length == 1 && currentMethod.getName().equals(methodname)) {
+
+ // Get the parameter type
+ Class theParameter = parameters[0];
+
+ // Check if the parameter type is assignable from the type specified by the reference's interface attribute
+ if(theParameter.isAssignableFrom(parameterClass)) {
+
+ // Final check: it must be public or protected
+ if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers()))
+ {
+ if (!method.isAccessible())
+ {
+ method.setAccessible(true);
+ }
+ method = currentMethod;
+
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(ClassNotFoundException ex2) {
+ GenericActivator.exception("Cannot load class used as parameter "+parameterClassName,m_componentMetadata,ex2);
+ }
+
+ }
+
+ 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
+ * @param storeRef A boolean that indicates if the reference must be stored (this is used for the delayed components)
+ * @return true if the call was successful, false otherwise
+ **/
+ private boolean invokeBindMethod(ServiceReference ref) {
+ // The bind method is only invoked if the implementation object is not null. This is valid
+ // for both immediate and delayed components
+ if(m_implementationObject != null) {
+
+ try {
+ // Get the bind method
+ Method bindMethod = getBindingMethod(m_dependencyMetadata.getBind(), getInstance().getClass(), m_dependencyMetadata.getInterface());
+
+ if(bindMethod == null){
+ // 112.3.1 If the method is not found , SCR must log an error
+ // message with the log service, if present, and ignore the method
+ // TODO: log error message
+ GenericActivator.trace("bind() method not found", m_componentMetadata);
+ return false;
+ }
+
+ // Get the parameter
+ Object parameter;
+
+ if(m_bindUsesServiceReference == false) {
+ parameter = m_activator.getBundleContext().getService(ref);
+ }
+ else {
+ parameter = ref;
+ }
+
+ // Invoke the method
+ bindMethod.invoke(getInstance(),new Object[] {parameter});
+
+ // Store the reference
+ m_boundServicesRefs.add(ref);
+
+ return true;
+ }
+ catch(IllegalAccessException ex)
+ {
+ // 112.3.1 If the method is not is not declared protected or public, SCR must log an error
+ // message with the log service, if present, and ignore the method
+ // TODO: log error message
+ return false;
+ }
+ catch(InvocationTargetException ex)
+ {
+ GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getBind()+"()", m_componentMetadata, ex);
+ return false;
+ }
+ } else if( m_implementationObject == null && m_componentMetadata.isImmediate() == false) {
+ // In the case the implementation object is null and the component is delayed
+ // then we still have to store the object that is passed to the bind methods
+ // so that it can be used once the implementation object is created.
+ m_boundServicesRefs.add(ref);
+ return true;
+ } else {
+ // TODO: assert false : this theoretically never happens...
+ return false;
+ }
+ }
+
+ /**
+ * Call the unbind method
+ *
+ * @param ref A service reference corresponding to the service that will be unbound
+ * @return true if the call was successful, false otherwise
+ **/
+ private boolean invokeUnbindMethod(ServiceReference ref) {
+ // TODO: assert m_boundServices.contains(ref) == true : "DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!";
+
+ // The unbind method is only invoked if the implementation object is not null. This is valid
+ // for both immediate and delayed components
+ if ( m_implementationObject != null ) {
+ try
+ {
+ // TODO: me quede aqui por que el unbind method no funciona
+ GenericActivator.trace("getting unbind: "+m_dependencyMetadata.getUnbind(), m_componentMetadata);
+ Method unbindMethod = getBindingMethod(m_dependencyMetadata.getUnbind(), getInstance().getClass(), m_dependencyMetadata.getInterface());
+
+ // Recover the object that is bound from the map.
+ //Object parameter = m_boundServices.get(ref);
+ Object parameter = null;
+
+ if(m_bindUsesServiceReference == true) {
+ parameter = ref;
+ } else {
+ parameter = m_activator.getBundleContext().getService(ref);
+ }
+
+ if(unbindMethod == null){
+ // 112.3.1 If the method is not found , SCR must log an error
+ // message with the log service, if present, and ignore the method
+ // TODO: log error message
+ GenericActivator.trace("unbind() method not found", m_componentMetadata);
+ return false;
+ }
+
+ unbindMethod.invoke(getInstance(),new Object [] {parameter});
+
+ m_boundServicesRefs.remove(ref);
+
+ m_activator.getBundleContext().ungetService(ref);
+
+ return true;
+ }
+ catch (IllegalAccessException ex) {
+ // 112.3.1 If the method is not is not declared protected or public, SCR must log an error
+ // message with the log service, if present, and ignore the method
+ // TODO: log error message
+ return false;
+ }
+ catch (InvocationTargetException ex) {
+ GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbind()+"()", m_componentMetadata, ex);
+ return false;
+ }
+
+ } else if( m_implementationObject == null && m_componentMetadata.isImmediate() == false) {
+ // In the case the implementation object is null and the component is delayed
+ // then we still have to store the object that is passed to the bind methods
+ // so that it can be used once the implementation object is created.
+ m_boundServicesRefs.remove(ref);
+ return true;
+ } else {
+ // TODO: assert false : this theoretically never happens...
+ return false;
+ }
+ }
+
+ /**
+ * 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 (ComponentManagerImpl.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_boundServicesRefs.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", m_componentMetadata);
+ deactivate();
+ GenericActivator.trace("Dependency Manager: RECREATING", m_componentMetadata);
+ activate();
+ }
+ catch(Exception ex)
+ {
+ GenericActivator.exception("Exception while recreating dependency ",m_componentMetadata, ex);
+ }
+ }
+ // dynamic dependency
+ else
+ {
+ // Release references to the service, call unbinder method
+ // and eventually request service unregistration
+
+ invokeUnbindMethod(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_boundServicesRefs.size() == 0)
+ {
+ // try to reinitialize
+ if (!bind())
+ {
+ if (!m_dependencyMetadata.isOptional())
+ {
+ GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...", m_componentMetadata);
+ deactivate();
+ GenericActivator.trace("Dependency Manager: Recreating", m_componentMetadata);
+ activate();
+ }
+ }
+ }
+ }
+ }
+ }
+ // A service is registering.
+ else if (evt.getType() == ServiceEvent.REGISTERED)
+ {
+ if (m_boundServicesRefs.contains(evt.getServiceReference()) == true)
+ {
+ // This is a duplicate
+ GenericActivator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)", m_componentMetadata);
+ }
+ else
+ {
+ m_isValid = true;
+ //setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
+
+ // If the InstanceManager is invalid, a call to validate is made
+ // which will fix everything.
+ if (ComponentManagerImpl.this.m_state != INSTANCE_VALID)
+ {
+ activate();
+ }
+ // 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_boundServicesRefs.size() == 0)
+ {
+ invokeBindMethod(evt.getServiceReference());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Implementation for the ComponentContext interface
+ *
*/
- class ComponentContextImpl implements ComponentContext {
-
- private Bundle m_usingBundle;
-
- ComponentContextImpl(Bundle usingBundle)
- {
- m_usingBundle = usingBundle;
- }
-
- public Dictionary getProperties() {
- //TODO: 112.11.3.5 The Dictionary is read-only and cannot be modified
- return m_componentMetadata.getProperties();
- }
-
- public Object locateService(String name) {
- DependencyManager dm = getDependencyManager(name);
- if (dm == null || dm.m_boundServicesRefs.isEmpty())
- {
- return null;
- }
-
- ServiceReference selectedRef;
- if (dm.m_boundServicesRefs.size() == 1)
- {
- // short cut for single bound service
- selectedRef = (ServiceReference) dm.m_boundServicesRefs.iterator().next();
- }
- else
- {
- // is it correct to assume an ordered bound services set ?
- int maxRanking = Integer.MIN_VALUE;
- long minId = Long.MAX_VALUE;
- selectedRef = null;
-
- Iterator it = dm.m_boundServicesRefs.iterator();
- while (it.hasNext())
- {
- ServiceReference ref = (ServiceReference) it.next();
- Integer rank = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
- int ranking = (rank == null) ? Integer.MIN_VALUE : rank.intValue();
- long id = ((Long) ref.getProperty(Constants.SERVICE_ID)).longValue();
- if (maxRanking < ranking || (maxRanking == ranking && id < minId))
- {
- maxRanking = ranking;
- minId = id;
- selectedRef = ref;
- }
- }
- }
-
- // this is not realistic, as at least one service is available
- // whose service id is smaller than Long.MAX_VALUE, still be sure
- if (selectedRef == null)
- {
- return null;
- }
-
- // return the service for the selected reference
- return getBundleContext().getService(selectedRef);
- }
-
- public Object locateService(String name, ServiceReference ref) {
- DependencyManager dm = getDependencyManager(name);
- if (dm == null || dm.m_boundServicesRefs.isEmpty())
- {
- return null;
- }
-
- // is it correct to assume an ordered bound services set ?
- Iterator it = dm.m_boundServicesRefs.iterator();
- while (it.hasNext())
- {
- if (it.next().equals(ref))
- {
- return getBundleContext().getService(ref);
- }
- }
-
- // no matching name and service reference found
- return null;
- }
-
- public Object[] locateServices(String name) {
- DependencyManager dm = getDependencyManager(name);
- if (dm == null || dm.m_boundServicesRefs.isEmpty())
- {
- return null;
- }
-
- Object[] services = new Object[dm.m_boundServicesRefs.size()];
- Iterator it = dm.m_boundServicesRefs.iterator();
- for (int i=0; i < services.length && it.hasNext(); i++)
- {
- ServiceReference ref = (ServiceReference) it.next();
- services[i] = getBundleContext().getService(ref);
- }
- return services;
- }
-
- private DependencyManager getDependencyManager(String name) {
- Iterator it = m_dependencyManagers.iterator();
- while (it.hasNext())
- {
- DependencyManager dm = (DependencyManager)it.next();
-
- // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
- if (name.equals(dm.m_dependencyMetadata.getName()))
- {
- return dm;
- }
- }
-
- // not found
- return null;
- }
-
- public BundleContext getBundleContext() {
- return m_activator.getBundleContext();
- }
-
- public Bundle getUsingBundle() {
- return m_usingBundle;
- }
-
- public ComponentInstance getComponentInstance() {
- return ComponentManagerImpl.this;
- }
-
- public void enableComponent(String arg0) {
- // TODO implement this method
-
- }
-
- public void disableComponent(String arg0) {
- // TODO implement this method
-
- }
-
- public ServiceReference getServiceReference() {
- if(m_serviceRegistration != null) {
- return m_serviceRegistration.getReference();
- }
- else {
- return null;
- }
- }
- }
-
- /**
- * This class is a ServiceFactory that is used when a delayed component is created
- *
- */
- class DelayedComponentServiceFactory implements ServiceFactory {
-
- public Object getService(Bundle arg0, ServiceRegistration arg1) {
-
- GenericActivator.trace("DelayedComponentServiceFactory.getService()", m_componentMetadata);
- // When the getServiceMethod is called, the implementation object must be created
-
- // 1. Load the component implementation class
- // 2. Create the component instance and component context
- // If the component is not immediate, this is not done at this moment
- try
- {
- // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
- Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
-
- // 112.4.4 The class must be public and have a public constructor without arguments so component instances
- // may be created by the SCR with the newInstance method on Class
- m_componentContext = new ComponentContextImpl(arg0);
- m_implementationObject = c.newInstance();
- }
- catch (Exception ex)
- {
- // TODO: manage this exception when implementation object cannot be created
- GenericActivator.exception("Error during instantiation of the implementation object",m_componentMetadata,ex);
- deactivate();
- //invalidate();
- return null;
- }
-
-
- // 3. Bind the target services
- Iterator it = m_dependencyManagers.iterator();
-
- while ( it.hasNext() )
- {
- DependencyManager dm = (DependencyManager)it.next();
- Iterator bound = dm.m_boundServicesRefs.iterator();
- while ( bound.hasNext() ) {
- ServiceReference nextRef = (ServiceReference) bound.next();
- dm.invokeBindMethod(nextRef);
- }
- }
-
- // 4. Call the activate method, if present
- // Search for the activate method
- try {
- Method activateMethod = getMethod(m_implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
- activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
- }
- catch(NoSuchMethodException ex) {
- // We can safely ignore this one
- GenericActivator.trace("activate() method is not implemented", m_componentMetadata);
- }
- catch(IllegalAccessException ex) {
- // Ignored, but should it be logged?
- GenericActivator.trace("activate() method cannot be called", m_componentMetadata);
- }
- catch(InvocationTargetException ex) {
- // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
- // containing the exception with the Log Service
- GenericActivator.exception("The activate method has thrown and exception", m_componentMetadata, ex);
- }
-
- return m_implementationObject;
- }
-
- public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
- // TODO Auto-generated method stub
-
- }
- }
-
- /**
- * Finds the named public or protected method in the given class or any
- * super class. If such a method is found, its accessibility is enfored by
- * calling the <code>Method.setAccessible</code> method if required and
- * the method is returned. Enforcing accessibility is required to support
- * invocation of protected methods.
- *
- * @param clazz The <code>Class</code> which provides the method.
- * @param name The name of the method.
- * @param parameterTypes The parameters to the method. Passing
- * <code>null</code> is equivalent to using an empty array.
- *
- * @return The named method with enforced accessibility
- *
- * @throws NoSuchMethodException If no public or protected method with
- * the given name can be found in the class or any of its super classes.
- */
- private Method getMethod(Class clazz, String name, Class[] parameterTypes)
- throws NoSuchMethodException
- {
- // try the default mechanism first, which only yields public methods
- try
- {
- return clazz.getMethod(name, parameterTypes);
- }
- catch (NoSuchMethodException nsme)
- {
- // it is ok to not find a public method, try to find a protected now
- }
-
- // now use method declarations, requiring walking up the class
- // hierarchy manually. this algorithm also returns protected methods
- // which is, what we need here
- for ( ; clazz != null; clazz = clazz.getSuperclass())
- {
- try
- {
- Method method = clazz.getDeclaredMethod(name, parameterTypes);
-
- // only accept a protected method, a public method should
- // have been found above and neither private nor package
- // protected methods are acceptable here
- if (Modifier.isProtected(method.getModifiers())) {
- method.setAccessible(true);
- return method;
- }
- }
- catch (NoSuchMethodException nsme)
- {
- // ignore for now
- }
- }
-
- // walked up the complete super class hierarchy and still not found
- // anything, sigh ...
- throw new NoSuchMethodException(name);
- }
-}
\ No newline at end of file
+ class ComponentContextImpl implements ComponentContext {
+
+ private Bundle m_usingBundle;
+
+ ComponentContextImpl(Bundle usingBundle)
+ {
+ m_usingBundle = usingBundle;
+ }
+
+ public Dictionary getProperties() {
+ //TODO: 112.11.3.5 The Dictionary is read-only and cannot be modified
+ return m_componentMetadata.getProperties();
+ }
+
+ public Object locateService(String name) {
+ DependencyManager dm = getDependencyManager(name);
+ if (dm == null || dm.m_boundServicesRefs.isEmpty())
+ {
+ return null;
+ }
+
+ ServiceReference selectedRef;
+ if (dm.m_boundServicesRefs.size() == 1)
+ {
+ // short cut for single bound service
+ selectedRef = (ServiceReference) dm.m_boundServicesRefs.iterator().next();
+ }
+ else
+ {
+ // is it correct to assume an ordered bound services set ?
+ int maxRanking = Integer.MIN_VALUE;
+ long minId = Long.MAX_VALUE;
+ selectedRef = null;
+
+ Iterator it = dm.m_boundServicesRefs.iterator();
+ while (it.hasNext())
+ {
+ ServiceReference ref = (ServiceReference) it.next();
+ Integer rank = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
+ int ranking = (rank == null) ? Integer.MIN_VALUE : rank.intValue();
+ long id = ((Long) ref.getProperty(Constants.SERVICE_ID)).longValue();
+ if (maxRanking < ranking || (maxRanking == ranking && id < minId))
+ {
+ maxRanking = ranking;
+ minId = id;
+ selectedRef = ref;
+ }
+ }
+ }
+
+ // this is not realistic, as at least one service is available
+ // whose service id is smaller than Long.MAX_VALUE, still be sure
+ if (selectedRef == null)
+ {
+ return null;
+ }
+
+ // return the service for the selected reference
+ return getBundleContext().getService(selectedRef);
+ }
+
+ public Object locateService(String name, ServiceReference ref) {
+ DependencyManager dm = getDependencyManager(name);
+ if (dm == null || dm.m_boundServicesRefs.isEmpty())
+ {
+ return null;
+ }
+
+ // is it correct to assume an ordered bound services set ?
+ Iterator it = dm.m_boundServicesRefs.iterator();
+ while (it.hasNext())
+ {
+ if (it.next().equals(ref))
+ {
+ return getBundleContext().getService(ref);
+ }
+ }
+
+ // no matching name and service reference found
+ return null;
+ }
+
+ public Object[] locateServices(String name) {
+ DependencyManager dm = getDependencyManager(name);
+ if (dm == null || dm.m_boundServicesRefs.isEmpty())
+ {
+ return null;
+ }
+
+ Object[] services = new Object[dm.m_boundServicesRefs.size()];
+ Iterator it = dm.m_boundServicesRefs.iterator();
+ for (int i=0; i < services.length && it.hasNext(); i++)
+ {
+ ServiceReference ref = (ServiceReference) it.next();
+ services[i] = getBundleContext().getService(ref);
+ }
+ return services;
+ }
+
+ private DependencyManager getDependencyManager(String name) {
+ Iterator it = m_dependencyManagers.iterator();
+ while (it.hasNext())
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+
+ // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
+ if (name.equals(dm.m_dependencyMetadata.getName()))
+ {
+ return dm;
+ }
+ }
+
+ // not found
+ return null;
+ }
+
+ public BundleContext getBundleContext() {
+ return m_activator.getBundleContext();
+ }
+
+ public Bundle getUsingBundle() {
+ return m_usingBundle;
+ }
+
+ public ComponentInstance getComponentInstance() {
+ return ComponentManagerImpl.this;
+ }
+
+ public void enableComponent(String arg0) {
+ // TODO implement this method
+
+ }
+
+ public void disableComponent(String arg0) {
+ // TODO implement this method
+
+ }
+
+ public ServiceReference getServiceReference() {
+ if(m_serviceRegistration != null) {
+ return m_serviceRegistration.getReference();
+ }
+ else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * This class is a ServiceFactory that is used when a delayed component is created
+ *
+ */
+ class DelayedComponentServiceFactory implements ServiceFactory {
+
+ public Object getService(Bundle arg0, ServiceRegistration arg1) {
+
+ GenericActivator.trace("DelayedComponentServiceFactory.getService()", m_componentMetadata);
+ // When the getServiceMethod is called, the implementation object must be created
+
+ // 1. Load the component implementation class
+ // 2. Create the component instance and component context
+ // If the component is not immediate, this is not done at this moment
+ try
+ {
+ // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
+ Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
+
+ // 112.4.4 The class must be public and have a public constructor without arguments so component instances
+ // may be created by the SCR with the newInstance method on Class
+ m_componentContext = new ComponentContextImpl(arg0);
+ m_implementationObject = c.newInstance();
+ }
+ catch (Exception ex)
+ {
+ // TODO: manage this exception when implementation object cannot be created
+ GenericActivator.exception("Error during instantiation of the implementation object",m_componentMetadata,ex);
+ deactivate();
+ //invalidate();
+ return null;
+ }
+
+
+ // 3. Bind the target services
+ Iterator it = m_dependencyManagers.iterator();
+
+ while ( it.hasNext() )
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+ Iterator bound = dm.m_boundServicesRefs.iterator();
+ while ( bound.hasNext() ) {
+ ServiceReference nextRef = (ServiceReference) bound.next();
+ dm.invokeBindMethod(nextRef);
+ }
+ }
+
+ // 4. Call the activate method, if present
+ // Search for the activate method
+ try {
+ Method activateMethod = getMethod(m_implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
+ activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
+ }
+ catch(NoSuchMethodException ex) {
+ // We can safely ignore this one
+ GenericActivator.trace("activate() method is not implemented", m_componentMetadata);
+ }
+ catch(IllegalAccessException ex) {
+ // Ignored, but should it be logged?
+ GenericActivator.trace("activate() method cannot be called", m_componentMetadata);
+ }
+ catch(InvocationTargetException ex) {
+ // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
+ // containing the exception with the Log Service
+ GenericActivator.exception("The activate method has thrown and exception", m_componentMetadata, ex);
+ }
+
+ return m_implementationObject;
+ }
+
+ public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ /**
+ * Finds the named public or protected method in the given class or any
+ * super class. If such a method is found, its accessibility is enfored by
+ * calling the <code>Method.setAccessible</code> method if required and
+ * the method is returned. Enforcing accessibility is required to support
+ * invocation of protected methods.
+ *
+ * @param clazz The <code>Class</code> which provides the method.
+ * @param name The name of the method.
+ * @param parameterTypes The parameters to the method. Passing
+ * <code>null</code> is equivalent to using an empty array.
+ *
+ * @return The named method with enforced accessibility
+ *
+ * @throws NoSuchMethodException If no public or protected method with
+ * the given name can be found in the class or any of its super classes.
+ */
+ private Method getMethod(Class clazz, String name, Class[] parameterTypes)
+ throws NoSuchMethodException
+ {
+ // try the default mechanism first, which only yields public methods
+ try
+ {
+ return clazz.getMethod(name, parameterTypes);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // it is ok to not find a public method, try to find a protected now
+ }
+
+ // now use method declarations, requiring walking up the class
+ // hierarchy manually. this algorithm also returns protected methods
+ // which is, what we need here
+ for ( ; clazz != null; clazz = clazz.getSuperclass())
+ {
+ try
+ {
+ Method method = clazz.getDeclaredMethod(name, parameterTypes);
+
+ // only accept a protected method, a public method should
+ // have been found above and neither private nor package
+ // protected methods are acceptable here
+ if (Modifier.isProtected(method.getModifiers())) {
+ method.setAccessible(true);
+ return method;
+ }
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // ignore for now
+ }
+ }
+
+ // walked up the complete super class hierarchy and still not found
+ // anything, sigh ...
+ throw new NoSuchMethodException(name);
+ }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
index 8fe037e..707b13f 100644
--- a/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
@@ -1,301 +1,298 @@
-/*
- * Copyright 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.felix.scr;
-
-import java.util.*;
-
-import org.osgi.service.component.ComponentException;
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
+
+import java.util.*;
+
+import org.osgi.service.component.ComponentException;
/**
- * This class holds the information associated to a component in the descriptor
*
*/
-public class ComponentMetadata {
- // 112.4.3: A Globally unique component name (required)
- private String m_name;
-
- // 112.4.3: Controls whether the component is enabled when the bundle is started. (optional, default is true).
- private boolean m_enabled = true;
-
- // 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
- private String m_factory = null;
-
- // 112.4.3: Controls whether component configurations must be immediately activated after becoming
- // satisfied or whether activation should be delayed. (optional, default value is false).
- private boolean m_immediate = false;
-
- // 112.4.4 Implementation Element (required)
- private String m_implementationClassName = null;
-
- // Associated properties (0..*)
- private Dictionary m_properties = new Hashtable();
-
- // List of Property metadata - used while building the meta data
- // while validating the properties contained in the PropertyMetadata
- // instances are copied to the m_properties Dictionary while this
- // list will be cleared
- private List m_propertyMetaData = new ArrayList();
-
- // Provided services (0..1)
- private ServiceMetadata m_service = null;
-
- // List of service references, (required services 0..*)
- private List m_references = new ArrayList();
-
- // Flag that is set once the component is verified (its properties cannot be changed)
- private boolean m_validated = false;
-
-
- /////////////////////////////////////////// SETTERS //////////////////////////////////////
-
- /**
- * Setter for the name
- *
- * @param name
- */
- public void setName(String name) {
- if(m_validated) {
- return;
- }
- m_name = name;
- }
-
- /**
- * Setter for the enabled property
- *
- * @param enabled
- */
- public void setEnabled(boolean enabled) {
- if(m_validated) {
- return;
- }
- m_enabled = enabled;
- }
-
- /**
- *
- * @param factoryIdentifier
- */
- public void setFactoryIdentifier(String factoryIdentifier) {
- if(m_validated) {
- return;
- }
- m_factory = factoryIdentifier;
- }
-
- /**
- * Setter for the immediate property
- *
- * @param immediate
- */
- public void setImmediate(boolean immediate) {
- if(m_validated) {
- return;
- }
- m_immediate = immediate;
- }
-
- /**
- * Sets the name of the implementation class
- *
- * @param implementationClassName a class name
- */
- public void setImplementationClassName(String implementationClassName) {
- if(m_validated) {
- return;
- }
- m_implementationClassName = implementationClassName;
- }
-
- /**
- * Used to add a property to the instance
- *
- * @param newProperty a property metadata object
- */
- public void addProperty(PropertyMetadata newProperty) {
- if(m_validated) {
- return;
- }
- if(newProperty == null) {
- throw new IllegalArgumentException ("Cannot add a null property");
- }
- m_propertyMetaData.add(newProperty);
- }
-
- /**
- * Used to set a ServiceMetadata object.
- *
- * @param service a ServiceMetadata
- */
- public void setService(ServiceMetadata service) {
- if(m_validated) {
- return;
- }
- m_service = service;
- }
-
- /**
- * Used to add a reference metadata to the component
- *
- * @param newReference a new ReferenceMetadata to be added
- */
- public void addDependency(ReferenceMetadata newReference) {
- if(newReference == null) {
- throw new IllegalArgumentException ("Cannot add a null ReferenceMetadata");
- }
- m_references.add(newReference);
- }
-
-
- /////////////////////////////////////////// GETTERS //////////////////////////////////////
-
- /**
- * Returns the name of the component
- *
- * @return A string containing the name of the component
- */
- public String getName() {
- return m_name;
- }
-
- /**
- * Returns the value of the enabled flag
- *
- * @return a boolean containing the value of the enabled flag
- */
- public boolean isEnabled() {
- return m_enabled;
- }
-
- /**
- * Returns the factory identifier
- *
- * @return A string containing a factory identifier or null
- */
- public String getFactoryIdentifier() {
- return m_factory;
- }
-
- /**
- * Returns the flag that defines the activation policy for the component
- *
- * @return a boolean that defines the activation policy
- */
- public boolean isImmediate() {
- return m_immediate;
- }
-
- /**
- * Returns the name of the implementation class
- *
- * @return the name of the implementation class
- */
- public String getImplementationClassName() {
- return m_implementationClassName;
- }
-
- /**
- * Returns the associated ServiceMetadata
- *
- * @return a ServiceMetadata object or null if the Component does not provide any service
- */
- public ServiceMetadata getServiceMetadata() {
- return m_service;
- }
-
- /**
- * Returns the properties.
- *
- * @return the properties as a Dictionary
- */
- public Dictionary getProperties() {
- return m_properties;
- }
-
- /**
- * Returns the dependency descriptors
- *
- * @return a Collection of dependency descriptors
- */
- public List getDependencies() {
- return m_references;
- }
-
- /**
- * Test to see if this service is a factory
- *
- * @return true if it is a factory, false otherwise
- */
- public boolean isFactory() {
- return m_factory != null;
- }
-
- /**
- * Method used to verify if the semantics of this metadata are correct
- */
- void validate() {
-
- // First check if the properties are valid (and extract property values)
- Iterator propertyIterator = m_propertyMetaData.iterator();
- while ( propertyIterator.hasNext() ) {
- PropertyMetadata propMeta = (PropertyMetadata) propertyIterator.next();
- propMeta.validate();
- m_properties.put(propMeta.getName(), propMeta.getValue());
- }
- m_propertyMetaData.clear();
-
- // Check that the provided services are valid too
- if(m_service != null) {
- m_service.validate();
- }
-
- // Check that the references are ok
- Iterator referenceIterator = m_references.iterator();
- while ( referenceIterator.hasNext() ) {
- ((ReferenceMetadata)referenceIterator.next()).validate();
- }
-
- // 112.10 The name of the component is required
- if( m_name == null ) {
- throw new ComponentException("The component name has not been set");
- }
-
- // 112.10 There must be one implementation element and the class atribute is required
- if ( m_implementationClassName == null ) {
- throw new ComponentException("The implementation class name has not been set for this component");
- }
-
- // 112.2.3 A delayed component specifies a service, is not specified to be a factory component
- // and does not have the immediate attribute of the component element set to true.
- if(m_immediate == false && m_service == null) {
- throw new ComponentException("Component '"+m_name+"' is specified as being delayed but does not provide any service.");
- }
-
- if ( m_factory != null && m_immediate == false) {
- throw new ComponentException("A factory cannot be a delayed component");
- }
-
- // TODO: 112.4.6 The serviceFactory attribute (of a provided service) must not be true if
- // the component is a factory component or an immediate component
-
-
- m_validated = true;
- // TODO: put a similar flag on the references and the services
- }
-
-}
-
-
-
+ * This class holds the information associated to a component in the descriptor * */
+public class ComponentMetadata {
+ // 112.4.3: A Globally unique component name (required)
+ private String m_name;
+
+ // 112.4.3: Controls whether the component is enabled when the bundle is started. (optional, default is true).
+ private boolean m_enabled = true;
+
+ // 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
+ private String m_factory = null;
+
+ // 112.4.3: Controls whether component configurations must be immediately activated after becoming
+ // satisfied or whether activation should be delayed. (optional, default value is false).
+ private boolean m_immediate = false;
+
+ // 112.4.4 Implementation Element (required)
+ private String m_implementationClassName = null;
+
+ // Associated properties (0..*)
+ private Dictionary m_properties = new Hashtable();
+
+ // List of Property metadata - used while building the meta data
+ // while validating the properties contained in the PropertyMetadata
+ // instances are copied to the m_properties Dictionary while this
+ // list will be cleared
+ private List m_propertyMetaData = new ArrayList();
+
+ // Provided services (0..1)
+ private ServiceMetadata m_service = null;
+
+ // List of service references, (required services 0..*)
+ private List m_references = new ArrayList();
+
+ // Flag that is set once the component is verified (its properties cannot be changed)
+ private boolean m_validated = false;
+
+
+ /////////////////////////////////////////// SETTERS //////////////////////////////////////
+
+ /**
+ * Setter for the name
+ *
+ * @param name
+ */
+ public void setName(String name) {
+ if(m_validated) {
+ return;
+ }
+ m_name = name;
+ }
+
+ /**
+ * Setter for the enabled property
+ *
+ * @param enabled
+ */
+ public void setEnabled(boolean enabled) {
+ if(m_validated) {
+ return;
+ }
+ m_enabled = enabled;
+ }
+
+ /**
+ *
+ * @param factoryIdentifier
+ */
+ public void setFactoryIdentifier(String factoryIdentifier) {
+ if(m_validated) {
+ return;
+ }
+ m_factory = factoryIdentifier;
+ }
+
+ /**
+ * Setter for the immediate property
+ *
+ * @param immediate
+ */
+ public void setImmediate(boolean immediate) {
+ if(m_validated) {
+ return;
+ }
+ m_immediate = immediate;
+ }
+
+ /**
+ * Sets the name of the implementation class
+ *
+ * @param implementationClassName a class name
+ */
+ public void setImplementationClassName(String implementationClassName) {
+ if(m_validated) {
+ return;
+ }
+ m_implementationClassName = implementationClassName;
+ }
+
+ /**
+ * Used to add a property to the instance
+ *
+ * @param newProperty a property metadata object
+ */
+ public void addProperty(PropertyMetadata newProperty) {
+ if(m_validated) {
+ return;
+ }
+ if(newProperty == null) {
+ throw new IllegalArgumentException ("Cannot add a null property");
+ }
+ m_propertyMetaData.add(newProperty);
+ }
+
+ /**
+ * Used to set a ServiceMetadata object.
+ *
+ * @param service a ServiceMetadata
+ */
+ public void setService(ServiceMetadata service) {
+ if(m_validated) {
+ return;
+ }
+ m_service = service;
+ }
+
+ /**
+ * Used to add a reference metadata to the component
+ *
+ * @param newReference a new ReferenceMetadata to be added
+ */
+ public void addDependency(ReferenceMetadata newReference) {
+ if(newReference == null) {
+ throw new IllegalArgumentException ("Cannot add a null ReferenceMetadata");
+ }
+ m_references.add(newReference);
+ }
+
+
+ /////////////////////////////////////////// GETTERS //////////////////////////////////////
+
+ /**
+ * Returns the name of the component
+ *
+ * @return A string containing the name of the component
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * Returns the value of the enabled flag
+ *
+ * @return a boolean containing the value of the enabled flag
+ */
+ public boolean isEnabled() {
+ return m_enabled;
+ }
+
+ /**
+ * Returns the factory identifier
+ *
+ * @return A string containing a factory identifier or null
+ */
+ public String getFactoryIdentifier() {
+ return m_factory;
+ }
+
+ /**
+ * Returns the flag that defines the activation policy for the component
+ *
+ * @return a boolean that defines the activation policy
+ */
+ public boolean isImmediate() {
+ return m_immediate;
+ }
+
+ /**
+ * Returns the name of the implementation class
+ *
+ * @return the name of the implementation class
+ */
+ public String getImplementationClassName() {
+ return m_implementationClassName;
+ }
+
+ /**
+ * Returns the associated ServiceMetadata
+ *
+ * @return a ServiceMetadata object or null if the Component does not provide any service
+ */
+ public ServiceMetadata getServiceMetadata() {
+ return m_service;
+ }
+
+ /**
+ * Returns the properties.
+ *
+ * @return the properties as a Dictionary
+ */
+ public Dictionary getProperties() {
+ return m_properties;
+ }
+
+ /**
+ * Returns the dependency descriptors
+ *
+ * @return a Collection of dependency descriptors
+ */
+ public List getDependencies() {
+ return m_references;
+ }
+
+ /**
+ * Test to see if this service is a factory
+ *
+ * @return true if it is a factory, false otherwise
+ */
+ public boolean isFactory() {
+ return m_factory != null;
+ }
+
+ /**
+ * Method used to verify if the semantics of this metadata are correct
+ */
+ void validate() {
+
+ // First check if the properties are valid (and extract property values)
+ Iterator propertyIterator = m_propertyMetaData.iterator();
+ while ( propertyIterator.hasNext() ) {
+ PropertyMetadata propMeta = (PropertyMetadata) propertyIterator.next();
+ propMeta.validate();
+ m_properties.put(propMeta.getName(), propMeta.getValue());
+ }
+ m_propertyMetaData.clear();
+
+ // Check that the provided services are valid too
+ if(m_service != null) {
+ m_service.validate();
+ }
+
+ // Check that the references are ok
+ Iterator referenceIterator = m_references.iterator();
+ while ( referenceIterator.hasNext() ) {
+ ((ReferenceMetadata)referenceIterator.next()).validate();
+ }
+
+ // 112.10 The name of the component is required
+ if( m_name == null ) {
+ throw new ComponentException("The component name has not been set");
+ }
+
+ // 112.10 There must be one implementation element and the class atribute is required
+ if ( m_implementationClassName == null ) {
+ throw new ComponentException("The implementation class name has not been set for this component");
+ }
+
+ // 112.2.3 A delayed component specifies a service, is not specified to be a factory component
+ // and does not have the immediate attribute of the component element set to true.
+ if(m_immediate == false && m_service == null) {
+ throw new ComponentException("Component '"+m_name+"' is specified as being delayed but does not provide any service.");
+ }
+
+ if ( m_factory != null && m_immediate == false) {
+ throw new ComponentException("A factory cannot be a delayed component");
+ }
+
+ // TODO: 112.4.6 The serviceFactory attribute (of a provided service) must not be true if
+ // the component is a factory component or an immediate component
+
+
+ m_validated = true;
+ // TODO: put a similar flag on the references and the services
+ }
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
index 28d028a..134070c 100644
--- a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
@@ -1,111 +1,111 @@
-/*
- * Copyright 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.felix.scr;
-
-import org.osgi.service.component.ComponentException;
-
-/**
- * A property descriptor that contains the information for properties
- * defined in the descriptor
- *
- */
-public class PropertyMetadata {
-
- // Name of the property (required)
- private String m_name;
-
- // Type of the property (optional)
- private String m_type = "String";
-
- // Value of the type (optional)
- private Object m_value;
-
- // Flag that indicates if this PropertyMetadata has been validated and thus has become immutable
- private boolean m_validated = false;
-
- /**
- * Set the name
- *
- * @param name
- */
- public void setName(String name) {
- if (m_validated == true) {
- return;
- }
-
- m_name = name;
- }
-
-
- /**
- * Set the type
- *
- * @param type
- */
- public void setType(String type) {
- if (m_validated == true) {
- return;
- }
- m_type = type;
- }
-
- /**
- * Set the value
- *
- * @param value
- */
- public void setValue(String value) {
- if (m_validated == true) {
- return;
- }
-
- // 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
- // Should the type accept lowercase too?
- if(m_type.equals("String")) {
- m_value = String.valueOf(value);
- }
- else if(m_type.equals("Long")) {
- m_value = Long.valueOf(value);
- }
- else if(m_type.equals("Double")) {
- m_value = Double.valueOf(value);
- }
- else if(m_type.equals("Float")) {
- m_value = Float.valueOf(value);
- }
- else if(m_type.equals("Integer")) {
- m_value = Integer.valueOf(value);
- }
- else if(m_type.equals("Byte")) {
- m_value = Byte.valueOf(value);
- }
- else if(m_type.equals("Char")) {
- //TODO: verify if this is adequate for Characters
- m_value = Byte.valueOf(value);
- }
- else if(m_type.equals("Boolean")) {
- m_value = Boolean.valueOf(value);
- }
- else if(m_type.equals("Short")) {
- m_value = Short.valueOf(value);
- }
- else {
- throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
- }
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
+
+import org.osgi.service.component.ComponentException;
+
+/**
+ * A property descriptor that contains the information for properties
+ * defined in the descriptor
+ *
+ */
+public class PropertyMetadata {
+
+ // Name of the property (required)
+ private String m_name;
+
+ // Type of the property (optional)
+ private String m_type = "String";
+
+ // Value of the type (optional)
+ private Object m_value;
+
+ // Flag that indicates if this PropertyMetadata has been validated and thus has become immutable
+ private boolean m_validated = false;
+
+ /**
+ * Set the name
+ *
+ * @param name
+ */
+ public void setName(String name) {
+ if (m_validated == true) {
+ return;
+ }
+
+ m_name = name;
+ }
+
+
+ /**
+ * Set the type
+ *
+ * @param type
+ */
+ public void setType(String type) {
+ if (m_validated == true) {
+ return;
+ }
+ m_type = type;
+ }
+
+ /**
+ * Set the value
+ *
+ * @param value
+ */
+ public void setValue(String value) {
+ if (m_validated == true) {
+ return;
+ }
+
+ // 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
+ // Should the type accept lowercase too?
+ if(m_type.equals("String")) {
+ m_value = String.valueOf(value);
+ }
+ else if(m_type.equals("Long")) {
+ m_value = Long.valueOf(value);
+ }
+ else if(m_type.equals("Double")) {
+ m_value = Double.valueOf(value);
+ }
+ else if(m_type.equals("Float")) {
+ m_value = Float.valueOf(value);
+ }
+ else if(m_type.equals("Integer")) {
+ m_value = Integer.valueOf(value);
+ }
+ else if(m_type.equals("Byte")) {
+ m_value = Byte.valueOf(value);
+ }
+ else if(m_type.equals("Char")) {
+ //TODO: verify if this is adequate for Characters
+ m_value = Byte.valueOf(value);
+ }
+ else if(m_type.equals("Boolean")) {
+ m_value = Boolean.valueOf(value);
+ }
+ else if(m_type.equals("Short")) {
+ m_value = Short.valueOf(value);
+ }
+ else {
+ throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
+ }
}
/**
@@ -134,14 +134,14 @@
public Object getValue() {
return m_value;
}
-
- /**
- * Method used to verify if the semantics of this metadata are correct
- */
- public void validate(){
- if(m_name == null)
- {
- throw new ComponentException("Property name attribute is mandatory");
- }
+
+ /**
+ * Method used to verify if the semantics of this metadata are correct
+ */
+ public void validate(){
+ if(m_name == null)
+ {
+ throw new ComponentException("Property name attribute is mandatory");
+ }
}
-}
+}