89e3feeb6fed88e65de8324627bb0a38d3128fff
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / impl / ListenerMapGeneration.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.binding.impl;
9
10 import java.util.Arrays;
11 import java.util.Collection;
12 import java.util.HashSet;
13 import java.util.Set;
14
15 import org.opendaylight.yangtools.yang.binding.Notification;
16
17 import com.google.common.base.Predicate;
18 import com.google.common.collect.ImmutableMultimap;
19 import com.google.common.collect.Iterables;
20 import com.google.common.collect.Multimap;
21
22 /**
23  * An immutable view of the current generation of listeners.
24  */
25 final class ListenerMapGeneration {
26     private final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> listeners;
27
28     ListenerMapGeneration() {
29         listeners = ImmutableMultimap.of();
30     }
31
32     ListenerMapGeneration(final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> listeners) {
33         this.listeners = ImmutableMultimap.copyOf(listeners);
34     }
35
36     /**
37      * Current listeners. Exposed for creating the next generation.
38      *
39      * @return Current type-to-listener map.
40      */
41     Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> getListeners() {
42         return listeners;
43     }
44
45     private static Iterable<Class<?>> getNotificationTypes(final Notification notification) {
46         final Class<?>[] ifaces = notification.getClass().getInterfaces();
47         return Iterables.filter(Arrays.asList(ifaces), new Predicate<Class<?>>() {
48             @Override
49             public boolean apply(final Class<?> input) {
50                 if (Notification.class.equals(input)) {
51                     return false;
52                 }
53                 return Notification.class.isAssignableFrom(input);
54             }
55         });
56     }
57
58     /**
59      * Look up the listeners which need to see this notification delivered.
60      *
61      * @param notification Notification object
62      * @return Iterable of listeners, may be null
63      *
64      * FIXME: improve such that it always returns non-null.
65      */
66     public Iterable<NotificationListenerRegistration<?>> listenersFor(final Notification notification) {
67         final Set<NotificationListenerRegistration<?>> ret = new HashSet<>();
68
69         for (final Class<?> type : getNotificationTypes(notification)) {
70             final Collection<NotificationListenerRegistration<?>> l = listeners.get((Class<? extends Notification>) type);
71             if (l != null) {
72                 ret.addAll(l);
73             }
74         }
75
76         return ret;
77     }
78 }