X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FNotificationBrokerImpl.java;h=7d844b3bf578c1958b3849e4b4d6841b2fd24ddb;hp=49d51025dd174d6980a6a7834a4c75284c1810e8;hb=537799b21364c2567314b54a4fad8c1307ca79f5;hpb=dc7c294911fd22c000eaa4e34d867482885975ed diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java index 49d51025dd..7d844b3bf5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java @@ -7,25 +7,25 @@ */ package org.opendaylight.controller.sal.binding.impl; -import java.util.Collections; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.ExecutorService; -import org.eclipse.xtext.xbase.lib.Conversions; -import org.eclipse.xtext.xbase.lib.Functions.Function1; -import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.opendaylight.controller.sal.binding.api.NotificationListener; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; +import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.concepts.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.Notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; @@ -37,8 +37,8 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto private final ListenerRegistry interestListeners = ListenerRegistry.create(); - private final Multimap, NotificationListener> listeners = - Multimaps.synchronizedSetMultimap(HashMultimap., NotificationListener>create()); + private final Multimap, NotificationListenerRegistration> listeners = + Multimaps.synchronizedSetMultimap(HashMultimap., NotificationListenerRegistration>create()); private ExecutorService executor; @Deprecated @@ -51,17 +51,16 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto } public Iterable> getNotificationTypes(final Notification notification) { - Class[] _interfaces = notification.getClass().getInterfaces(); - final Function1, Boolean> _function = new Function1, Boolean>() { + final Class[] ifaces = notification.getClass().getInterfaces(); + return Iterables.filter(Arrays.asList(ifaces), new Predicate>() { @Override - public Boolean apply(final Class it) { - if (Notification.class.equals(it)) { + public boolean apply(final Class input) { + if (Notification.class.equals(input)) { return false; } - return Notification.class.isAssignableFrom(it); + return Notification.class.isAssignableFrom(input); } - }; - return IterableExtensions.filter(((Iterable>)Conversions.doWrapArray(_interfaces)), _function); + }); } @Override @@ -71,29 +70,43 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto @Override public void publish(final Notification notification, final ExecutorService service) { - Iterable> listenerToNotify = Collections.emptySet(); + final Set> toNotify = new HashSet<>(); + for (final Class type : getNotificationTypes(notification)) { - listenerToNotify = Iterables.concat(listenerToNotify, listeners.get(((Class) type))); - } - final Function1,NotifyTask> _function = new Function1, NotifyTask>() { - @Override - public NotifyTask apply(final NotificationListener it) { - return new NotifyTask(it, notification); + final Collection> l = listeners.get((Class) type); + if (l != null) { + toNotify.addAll(l); } - }; - final Set tasks = IterableExtensions.toSet( - IterableExtensions., NotifyTask>map(listenerToNotify, _function)); + } - for (final NotifyTask task : tasks) { - service.submit(task); + for (NotificationListenerRegistration r : toNotify) { + service.submit(new NotifyTask(r, notification)); + } + } + + private void addRegistrations(final NotificationListenerRegistration... registrations) { + for (NotificationListenerRegistration reg : registrations) { + listeners.put(reg.getType(), reg); + this.announceNotificationSubscription(reg.getType()); + } + } + + void removeRegistrations(final NotificationListenerRegistration... registrations) { + for (NotificationListenerRegistration reg : registrations) { + listeners.remove(reg.getType(), reg); } } @Override - public Registration> registerNotificationListener(final Class notificationType, final NotificationListener listener) { - final GenericNotificationRegistration reg = new GenericNotificationRegistration(notificationType, listener, this); - this.listeners.put(notificationType, listener); - this.announceNotificationSubscription(notificationType); + public NotificationListenerRegistration registerNotificationListener(final Class notificationType, final NotificationListener listener) { + final NotificationListenerRegistration reg = new AbstractNotificationListenerRegistration(notificationType, listener) { + @Override + protected void removeRegistration() { + removeRegistrations(this); + } + }; + + addRegistrations(reg); return reg; } @@ -109,25 +122,36 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto } @Override - public Registration registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + public ListenerRegistration registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) { final NotificationInvoker invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); - for (final Class notifyType : invoker.getSupportedNotifications()) { - listeners.put(notifyType, invoker.getInvocationProxy()); - announceNotificationSubscription(notifyType); + final Set> types = invoker.getSupportedNotifications(); + final NotificationListenerRegistration[] regs = new NotificationListenerRegistration[types.size()]; + + // Populate the registrations... + int i = 0; + for (Class type : types) { + regs[i] = new AggregatedNotificationListenerRegistration(type, invoker.getInvocationProxy(), regs) { + @Override + protected void removeRegistration() { + // Nothing to do, will be cleaned up by parent (below) + } + }; + ++i; } - return new GeneratedListenerRegistration(listener, invoker, this); - } - - protected boolean unregisterListener(final GenericNotificationRegistration reg) { - return listeners.remove(reg.getType(), reg.getInstance()); - } + // ... now put them to use ... + addRegistrations(regs); - protected void unregisterListener(final GeneratedListenerRegistration reg) { - final NotificationInvoker invoker = reg.getInvoker(); - for (final Class notifyType : invoker.getSupportedNotifications()) { - this.listeners.remove(notifyType, invoker.getInvocationProxy()); - } + // ... finally return the parent registration + return new AbstractListenerRegistration(listener) { + @Override + protected void removeRegistration() { + removeRegistrations(regs); + for (ListenerRegistration reg : regs) { + reg.close(); + } + } + }; } @Override