Author: pderop
Date: Mon Jan 4 11:23:04 2016
New Revision: 1722848
URL: http://svn.apache.org/viewvc?rev=1722848&view=rev
Log:
FELIX-5155: Adapter/Aspect extra service dependencies injected twice if using
callback instance.
The fix simply consists in detecting any callback instances from extra
dependencies that are added into adapter
or aspect components. And when a callback instance is detected, it is removed
from the dependency;
and is then re-added to actual aspect/adapter component instances.
See FilterComponent.add(Dependency ... dependencies) and
FilterComponent.copyDependenciescopyDependencies(List<DependencyContext>
dependencies, Component component) methods.
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
Mon Jan 4 11:23:04 2016
@@ -538,8 +538,27 @@ public abstract class AbstractDependency
public ComponentContext getComponentContext() {
return m_component;
}
+
+ /**
+ * Returns the dependency callback instance, if there is one.
+ * @returns the dependency callback instance if there is one, else null.
+ */
+ public Object getCallbackInstance() {
+ return m_callbackInstance;
+ }
/**
+ * Sets the dependency callback instance
+ * @param callbackInstance the dependency callback instance
+ * @return the previous callbackInstance, or <code>null</code> if it did
not have one
+ */
+ public Object setCallbackInstance(Object callbackInstance) {
+ Object currentCallbackInstance = m_callbackInstance;
+ m_callbackInstance = callbackInstance;
+ return currentCallbackInstance;
+ }
+
+ /**
* Returns the default service, or null.
* @param nullObject if true, a null object may be returned.
* @return the default service
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
Mon Jan 4 11:23:04 2016
@@ -126,4 +126,17 @@ public interface DependencyContext exten
* @return a clone of this dependency.
*/
public DependencyContext createCopy();
+
+ /**
+ * Returns the dependency callback instance, if there is one.
+ * @returns the dependency callback instance if there is one, else null.
+ */
+ public Object getCallbackInstance();
+
+ /**
+ * Sets the dependency callback instance
+ * @param callbackInstance the dependency callback instance
+ * @return the previous callbackInstance, or <code>null</code> if it did
not have one
+ */
+ public Object setCallbackInstance(Object callbackInstance);
}
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
Mon Jan 4 11:23:04 2016
@@ -122,11 +122,8 @@ public class AdapterServiceImpl extends
.add(dependency);
configureAutoConfigState(service, m_component);
-
- for (DependencyContext dc : dependencies) {
- service.add((Dependency) dc.createCopy());
- }
-
+ copyDependencies(dependencies, service);
+
for (ComponentStateListener stateListener : m_stateListeners) {
service.add(stateListener);
}
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
Mon Jan 4 11:23:04 2016
@@ -152,9 +152,7 @@ public class AspectServiceImpl extends F
configureAutoConfigState(service, m_component);
- for (DependencyContext dc : dependencies) {
- service.add((Dependency) dc.createCopy());
- }
+ copyDependencies(dependencies, service);
for (int i = 0; i < m_stateListeners.size(); i++) {
service.add((ComponentStateListener) m_stateListeners.get(i));
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
Mon Jan 4 11:23:04 2016
@@ -104,9 +104,7 @@ public class BundleAdapterImpl extends F
.setCallbacks(m_cbInstance, m_add, m_change, m_remove) //
if no callbacks, autoconfig is enabled
.setRequired(true));
- for (DependencyContext dc : dependencies) {
- service.add((Dependency) dc.createCopy());
- }
+ copyDependencies(dependencies, service);
for (ComponentStateListener stateListener : m_stateListeners) {
service.add(stateListener);
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
Mon Jan 4 11:23:04 2016
@@ -134,9 +134,7 @@ public class FactoryConfigurationAdapter
newService.setCallbacks(m_callbackObject, m_init, m_start, m_stop,
m_destroy); // if not set, no effect
configureAutoConfigState(newService, m_component);
- for (DependencyContext dc : m_component.getDependencies()) {
- newService.add((Dependency) dc.createCopy());
- }
+ copyDependencies(m_component.getDependencies(), newService);
for (int i = 0; i < m_stateListeners.size(); i ++) {
newService.add(m_stateListeners.get(i));
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
Mon Jan 4 11:23:04 2016
@@ -19,6 +19,7 @@
package org.apache.felix.dm.impl;
import java.util.Dictionary;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -61,6 +62,7 @@ public class FilterComponent implements
protected volatile Object m_factory;
protected volatile String m_factoryCreateMethod;
protected volatile Dictionary<String, Object> m_serviceProperties;
+ private final Map<DependencyContext, Object> m_dependencyCallbacks = new
HashMap<>();
public FilterComponent(Component service) {
m_component = (ComponentImpl) service;
@@ -77,21 +79,33 @@ public class FilterComponent implements
}
public Component add(Dependency ... dependencies) {
- m_component.add(dependencies);
- // Add the dependencies to all already instantiated services.
- // If one dependency from the list is required, we have nothing to do,
since our internal
- // service will be stopped/restarted.
+ // First, detect if one of the added dependencies is required, and
also, remove any callback instance found in
+ // dependencies. We'll store such dependency callback instance in our
m_dependencyCallbacks map and will
+ // re-add them later, in concrete aspect or adapter instances (see the
copyDependencies method).
+ // We remove dependency callback instance because we don't want to
call with internal abstract decorator instances).
+
+ boolean allDependenciesOptional = true;
for (Dependency dependency : dependencies) {
- if (((DependencyContext) dependency).isRequired()) {
- return this;
+ DependencyContext dc = (DependencyContext) dependency;
+ if (dc.isRequired()) {
+ allDependenciesOptional = false;
+ }
+ if (dc.getCallbackInstance() != null) {
+ m_dependencyCallbacks.put(dc, dc.setCallbackInstance(null));
}
}
- // Ok, the list contains no required dependencies: add optionals
dependencies in already instantiated services.
- Object[] instances = m_component.getInstances();
- if (instances.length > 0) {
- AbstractDecorator ad = (AbstractDecorator) instances[0];
- if (ad != null) {
- ad.addDependency(dependencies);
+
+ // Now, add the dependencies in the internal abstract decorator
component.
+ m_component.add(dependencies);
+
+ // If all dependencies are optional, add them to already instantiated
aspect or adapter components.
+ if (allDependenciesOptional) {
+ Object[] instances = m_component.getInstances();
+ if (instances.length > 0) {
+ AbstractDecorator ad = (AbstractDecorator) instances[0];
+ if (ad != null) {
+ ad.addDependency(dependencies);
+ }
}
}
return this;
@@ -356,4 +370,15 @@ public class FilterComponent implements
public Logger getLogger() {
return m_component.getLogger();
}
+
+ protected void copyDependencies(List<DependencyContext> dependencies,
Component component) {
+ for (DependencyContext dc : dependencies) {
+ DependencyContext copy = dc.createCopy();
+ Object callbackInstance = m_dependencyCallbacks.get(dc);
+ if (callbackInstance != null) {
+ copy.setCallbackInstance(callbackInstance);
+ }
+ component.add(copy);
+ }
+ }
}
\ No newline at end of file
Modified:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java?rev=1722848&r1=1722847&r2=1722848&view=diff
==============================================================================
---
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
(original)
+++
felix/trunk/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
Mon Jan 4 11:23:04 2016
@@ -131,9 +131,7 @@ public class ResourceAdapterImpl extends
configureAutoConfigState(service, m_component);
- for (DependencyContext dc : dependencies) {
- service.add((Dependency) dc.createCopy());
- }
+ copyDependencies(dependencies, service);
for (ComponentStateListener stateListener : m_stateListeners) {
service.add(stateListener);