You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2014/03/07 09:32:38 UTC
svn commit: r1575208 - in
/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo:
dependency/impl/ handlers/configuration/ util/
Author: clement
Date: Fri Mar 7 08:32:37 2014
New Revision: 1575208
URL: http://svn.apache.org/r1575208
Log:
Fix FELIX-4449 and FELIX-4448
Modified:
felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceUtils.java
felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java?rev=1575208&r1=1575207&r2=1575208&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java Fri Mar 7 08:32:37 2014
@@ -125,8 +125,9 @@ public class ServiceReferenceManager imp
}
public void open() {
- m_trackingInterceptorTracker = new Tracker(m_dependency.getBundleContext(),
- ServiceTrackingInterceptor.class.getName(),
+ // The opening order matters, first binding, then ranking and finally tracking.
+ m_bindingInterceptorTracker = new Tracker(m_dependency.getBundleContext(),
+ ServiceBindingInterceptor.class.getName(),
new TrackerCustomizer() {
public boolean addingService(ServiceReference reference) {
@@ -134,11 +135,10 @@ public class ServiceReferenceManager imp
}
public void addedService(ServiceReference reference) {
- ServiceTrackingInterceptor interceptor = (ServiceTrackingInterceptor) m_trackingInterceptorTracker
+ ServiceBindingInterceptor interceptor = (ServiceBindingInterceptor) m_bindingInterceptorTracker
.getService(reference);
-
if (interceptor != null) {
- addTrackingInterceptor(interceptor);
+ addBindingInterceptor(interceptor);
} else {
m_dependency.getComponentInstance().getFactory().getLogger().log(Log.ERROR,
"Cannot retrieve the interceptor object from service reference " + reference
@@ -148,20 +148,19 @@ public class ServiceReferenceManager imp
}
public void modifiedService(ServiceReference reference, Object service) {
- // Not supported yet.
- // TODO it would be nice to support the modification of the interceptor TARGET property.
+ // Not supported.
}
public void removedService(ServiceReference reference, Object service) {
- if (service != null && service instanceof ServiceTrackingInterceptor &&
- m_trackingInterceptors.contains(service)
- ) {
- removeTrackingInterceptor((ServiceTrackingInterceptor) service);
+ if (service != null && service instanceof ServiceBindingInterceptor &&
+ m_bindingInterceptors.contains(service)
+ ) {
+ removeBindingInterceptor((ServiceBindingInterceptor) service);
}
}
- });
-
- m_trackingInterceptorTracker.open();
+ }
+ );
+ m_bindingInterceptorTracker.open();
// Initialize the service interceptor tracker.
m_rankingInterceptorTracker = new Tracker(m_dependency.getBundleContext(), ServiceRankingInterceptor.class.getName(),
@@ -210,8 +209,8 @@ public class ServiceReferenceManager imp
});
m_rankingInterceptorTracker.open();
- m_bindingInterceptorTracker = new Tracker(m_dependency.getBundleContext(),
- ServiceBindingInterceptor.class.getName(),
+ m_trackingInterceptorTracker = new Tracker(m_dependency.getBundleContext(),
+ ServiceTrackingInterceptor.class.getName(),
new TrackerCustomizer() {
public boolean addingService(ServiceReference reference) {
@@ -219,10 +218,11 @@ public class ServiceReferenceManager imp
}
public void addedService(ServiceReference reference) {
- ServiceBindingInterceptor interceptor = (ServiceBindingInterceptor) m_bindingInterceptorTracker
+ ServiceTrackingInterceptor interceptor = (ServiceTrackingInterceptor) m_trackingInterceptorTracker
.getService(reference);
+
if (interceptor != null) {
- addBindingInterceptor(interceptor);
+ addTrackingInterceptor(interceptor);
} else {
m_dependency.getComponentInstance().getFactory().getLogger().log(Log.ERROR,
"Cannot retrieve the interceptor object from service reference " + reference
@@ -232,19 +232,20 @@ public class ServiceReferenceManager imp
}
public void modifiedService(ServiceReference reference, Object service) {
- // Not supported.
+ // Not supported yet.
+ // TODO it would be nice to support the modification of the interceptor TARGET property.
}
public void removedService(ServiceReference reference, Object service) {
- if (service != null && service instanceof ServiceBindingInterceptor &&
- m_bindingInterceptors.contains(service)
+ if (service != null && service instanceof ServiceTrackingInterceptor &&
+ m_trackingInterceptors.contains(service)
) {
- removeBindingInterceptor((ServiceBindingInterceptor) service);
+ removeTrackingInterceptor((ServiceTrackingInterceptor) service);
}
}
- }
- );
- m_bindingInterceptorTracker.open();
+ });
+
+ m_trackingInterceptorTracker.open();
}
private void addTrackingInterceptor(ServiceTrackingInterceptor interceptor) {
@@ -324,6 +325,8 @@ public class ServiceReferenceManager imp
private ChangeSet computeChangesInMatchingServices() {
if (m_dependency.getTracker() == null || m_dependency.getTracker().getServiceReferences() == null) {
// Tracker closed, no problem
+ m_dependency.getComponentInstance().getFactory().getLogger().log(Logger.DEBUG,
+ "Tracker closed when recomputing dependency " + m_dependency.getId());
return new ChangeSet(Collections.<ServiceReference>emptyList(),
Collections.<ServiceReference>emptyList(),
Collections.<ServiceReference>emptyList(),
@@ -349,6 +352,9 @@ public class ServiceReferenceManager imp
}
}
}
+ m_dependency.getComponentInstance().getFactory().getLogger().log(Logger.DEBUG,
+ "Matching services have been recomputed: " + ServiceReferenceUtils.toString(m_matchingReferences.values()));
+
// We have the new matching set.
List<ServiceReference> beforeRanking = getSelectedServices();
@@ -358,6 +364,8 @@ public class ServiceReferenceManager imp
if (allServices.isEmpty()) {
references = Collections.emptyList();
} else {
+ m_dependency.getComponentInstance().getFactory().getLogger().log(Logger.DEBUG,
+ "iPOJO >> Calling getServiceReferences on the interceptor " + m_rankingInterceptor);
references = m_rankingInterceptor.getServiceReferences(m_dependency, allServices);
}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceUtils.java?rev=1575208&r1=1575207&r2=1575208&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceUtils.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceUtils.java Fri Mar 7 08:32:37 2014
@@ -24,6 +24,7 @@ import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
+import java.util.Collection;
import java.util.List;
/**
@@ -124,4 +125,21 @@ public class ServiceReferenceUtils {
return !(ref1 == null || ref2 == null)
&& ref1.getProperty(Constants.SERVICE_ID).equals(ref2.getProperty(Constants.SERVICE_ID));
}
+
+ public static String toString(Collection<? extends ServiceReference> references) {
+ if (references == null || references.isEmpty()) {
+ return "[]";
+ } else {
+ StringBuilder buffer = new StringBuilder("[");
+ for (ServiceReference reference : references) {
+ if (buffer.length() == 1) {
+ buffer.append(reference.getProperty(Constants.SERVICE_ID));
+ } else {
+ buffer.append(", ").append(reference.getProperty(Constants.SERVICE_ID));
+ }
+ }
+ buffer.append("]");
+ return buffer.toString();
+ }
+ }
}
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java?rev=1575208&r1=1575207&r2=1575208&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java Fri Mar 7 08:32:37 2014
@@ -29,6 +29,7 @@ import org.apache.felix.ipojo.parser.Fie
import org.apache.felix.ipojo.parser.MethodMetadata;
import org.apache.felix.ipojo.parser.PojoMetadata;
import org.apache.felix.ipojo.util.Callback;
+import org.apache.felix.ipojo.util.Log;
import org.apache.felix.ipojo.util.Property;
import org.apache.felix.ipojo.util.SecurityHelper;
import org.osgi.framework.Constants;
@@ -96,7 +97,11 @@ public class ConfigurationHandler extend
/**
* The configuration listeners.
*/
- private List<ConfigurationListener> m_listeners = new ArrayList<ConfigurationListener>();
+ private final Set<ConfigurationListener> m_listeners = new LinkedHashSet<ConfigurationListener>();
+ /**
+ * The last configuration sent to listeners.
+ */
+ private Map<String, Object> m_lastConfiguration;
/**
* Initialize the component type.
@@ -198,7 +203,7 @@ public class ConfigurationHandler extend
String man = configurables[i].getAttribute("mandatory");
mandatory = man != null && man.equalsIgnoreCase("true");
- PropertyDescription pd = null;
+ PropertyDescription pd;
if (value == null) {
pd = new PropertyDescription(name, type, null, false); // Cannot be immutable if we have no value.
} else {
@@ -333,6 +338,7 @@ public class ConfigurationHandler extend
m_sr.unregister();
m_sr = null;
}
+ m_lastConfiguration = Collections.emptyMap();
}
/**
@@ -800,30 +806,27 @@ public class ConfigurationHandler extend
/**
* Remove the given listener from the configuration handler's list of listeners.
+ * If the listeners is not registered, this method does nothing.
*
* @param listener the {@code ConfigurationListener} object to be removed
* @throws NullPointerException if {@code listener} is {@code null}
- * @throws NoSuchElementException if {@code listener} wasn't present the in configuration handler's list of listeners
*/
public void removeListener(ConfigurationListener listener) {
if (listener == null) {
- throw new NullPointerException("null listener");
+ throw new NullPointerException("The list of listener is null");
}
synchronized (m_listeners) {
// We definitely cannot rely on listener's equals method...
// ...so we need to manually search for the listener, using ==.
- int i = -1;
- for (int j = m_listeners.size() - 1; j >= 0; j--) {
- if (m_listeners.get(j) == listener) {
- // Found!
- i = j;
+ ConfigurationListener found = null;
+ for (ConfigurationListener l : m_listeners) {
+ if (l == listener) {
+ found = l;
break;
}
}
- if (i != -1) {
- m_listeners.remove(i);
- } else {
- throw new NoSuchElementException("no such listener");
+ if (found != null) {
+ m_listeners.remove(found);
}
}
}
@@ -834,17 +837,54 @@ public class ConfigurationHandler extend
* @param map the new configuration of the component instance.
*/
private void notifyListeners(Map<String, Object> map) {
+
// Get a snapshot of the listeners
+ // and check if we had a change in the map.
List<ConfigurationListener> tmp;
synchronized (m_listeners) {
tmp = new ArrayList<ConfigurationListener>(m_listeners);
+
+ if (map == null) {
+ if (m_lastConfiguration == null) {
+ // No change.
+ return;
+ }
+ // Else trigger the change.
+ } else {
+ if (m_lastConfiguration != null && m_lastConfiguration.size() == map.size()) {
+ // Must compare key by key
+ boolean diff = false;
+ for (String k : map.keySet()) {
+ if (! map.get(k).equals(m_lastConfiguration.get(k))) {
+ // Difference found, break;
+ diff = true;
+ break;
+ }
+ }
+ if (! diff) {
+ // no difference found, skip notification
+ return;
+ }
+ }
+ // Else difference found, triggers the change
+ }
+
+ if (map == null) {
+ m_lastConfiguration = Collections.emptyMap();
+ } else {
+ m_lastConfiguration = Collections.unmodifiableMap(map);
+ }
+
+ }
+ if (! tmp.isEmpty()) {
+ getLogger().log(Log.DEBUG, String.format(
+ "[%s] Notifying configuration listener: %s", getInstanceManager().getInstanceName(), tmp));
}
// Protect the map.
- map = Collections.unmodifiableMap(map);
// Do notify, outside any lock
for (ConfigurationListener l : tmp) {
try {
- l.configurationChanged(getInstanceManager(), map);
+ l.configurationChanged(getInstanceManager(), m_lastConfiguration);
} catch (Throwable e) {
// Failure inside a listener: put a warning on the logger, and continue
warn(String.format(
Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java?rev=1575208&r1=1575207&r2=1575208&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java Fri Mar 7 08:32:37 2014
@@ -21,7 +21,6 @@ package org.apache.felix.ipojo.util;
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.IPOJOServiceFactory;
import org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager;
-import org.apache.felix.ipojo.handlers.dependency.DependencyCallback;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;