listeners.put(entry.getKey(), new RemoveOnlyCollection<ListenerInfo>(entry.getValue()));
}
listeners = new RemoveOnlyMap<ModuleContext, Collection<ListenerInfo>>(listeners);
// Construct the ServiceEvent
ServiceEvent event = new ServiceEventImpl(type, reference);
String typeName = ConstantsHelper.serviceEvent(event.getType());
LOGGER.trace("Service {}: {}", typeName, reference);
// Nobody is interested
if (listeners.isEmpty())
return;
// Call the listeners. All service events are synchronously delivered
for (Map.Entry<ModuleContext, Collection<ListenerInfo>> entry : listeners.entrySet()) {
for (ListenerInfo info : entry.getValue()) {
ServiceListenerRegistration listenerReg = info.getRegistration();
Module owner = info.getModuleContext().getModule();
if (owner.getState() == Module.State.UNINSTALLED) {
continue;
}
// Service events must only be delivered to event listeners which can validly cast the event
if (!listenerReg.isAllServiceListener()) {
boolean assignableToOwner = true;
String[] clazzes = (String[]) reference.getProperty(org.jboss.gravia.Constants.OBJECTCLASS);
for (String clazz : clazzes) {
if (reference.isAssignableTo(owner, clazz) == false) {
assignableToOwner = false;
break;
}
}
if (assignableToOwner == false)
continue;
}
try {
String filterstr = info.getFilter();
ServiceListener listener = listenerReg.getListener();
if (listenerReg.isAllServiceListener() || listenerReg.filter.match(reference)) {
listener.serviceChanged(event);
}
// The MODIFIED_ENDMATCH event is synchronously delivered after the service properties have been modified.
// This event is only delivered to listeners which were added with a non-null filter where
// the filter matched the service properties prior to the modification but the filter does
// not match the modified service properties.
else if (filterstr != null && ServiceEvent.MODIFIED == event.getType()) {
Filter filter = listenerReg.filter;
if (/* filter.match(reference.getPreviousProperties()) && */ !filter.match(reference)) {
ServiceEvent endmatch = new ServiceEventImpl(ServiceEvent.MODIFIED_ENDMATCH, reference);
listener.serviceChanged(endmatch);
}
}
} catch (Throwable th) {
LOGGER.warn("Error while firing service event " + typeName + " for: " + reference, th);