4581fc0dd8f96296b9115c4284111628609156b2
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / compat / 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.md.sal.binding.compat;
9
10 import com.google.common.cache.CacheBuilder;
11 import com.google.common.cache.CacheLoader;
12 import com.google.common.cache.LoadingCache;
13 import com.google.common.collect.ImmutableMultimap;
14 import com.google.common.collect.ImmutableSet;
15 import com.google.common.collect.Multimap;
16 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
17 import java.util.Arrays;
18 import java.util.Collection;
19 import java.util.HashSet;
20 import java.util.Set;
21 import java.util.stream.Collectors;
22 import org.opendaylight.yangtools.yang.binding.Notification;
23
24 /**
25  * An immutable view of the current generation of listeners.
26  */
27 @Deprecated
28 final class ListenerMapGeneration {
29     private static final int CACHE_MAX_ENTRIES = 1000;
30
31     /**
32      * Constant map of notification type to subscribed listeners.
33      */
34     private final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> typeToListeners;
35
36     /**
37      * Dynamic cache of notification implementation to matching listeners. This cache loads entries based on
38      * the contents of the {@link #typeToListeners} map.
39      */
40     private final LoadingCache<Class<?>, Iterable<NotificationListenerRegistration<?>>> implementationToListeners =
41             CacheBuilder.newBuilder()
42             .weakKeys()
43             .maximumSize(CACHE_MAX_ENTRIES)
44             .build(new CacheLoader<Class<?>, Iterable<NotificationListenerRegistration<?>>>() {
45                 @Override
46                 public Iterable<NotificationListenerRegistration<?>> load(final Class<?> key) {
47                     final Set<NotificationListenerRegistration<?>> regs = new HashSet<>();
48
49                     for (final Class<?> type : getNotificationTypes(key)) {
50                         @SuppressWarnings("unchecked")
51                         final Collection<NotificationListenerRegistration<?>> l =
52                                 typeToListeners.get((Class<? extends Notification>) type);
53                         if (l != null) {
54                             regs.addAll(l);
55                         }
56                     }
57
58                     return ImmutableSet.copyOf(regs);
59                 }
60             });
61
62     ListenerMapGeneration() {
63         typeToListeners = ImmutableMultimap.of();
64     }
65
66     ListenerMapGeneration(final Multimap<Class<? extends Notification>,
67             NotificationListenerRegistration<?>> listeners) {
68         this.typeToListeners = ImmutableMultimap.copyOf(listeners);
69     }
70
71     /**
72      * Current listeners. Exposed for creating the next generation.
73      *
74      * @return Current type-to-listener map.
75      */
76     Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> getListeners() {
77         return typeToListeners;
78     }
79
80     /**
81      * Look up the listeners which need to see this notification delivered.
82      *
83      * @param notification Notification object
84      * @return Iterable of listeners, guaranteed to be nonnull.
85      */
86     public Iterable<NotificationListenerRegistration<?>> listenersFor(final Notification notification) {
87         // Safe to use, as our loader does not throw checked exceptions
88         return implementationToListeners.getUnchecked(notification.getClass());
89     }
90
91     public Iterable<Class<? extends Notification>> getKnownTypes() {
92         return typeToListeners.keySet();
93     }
94
95     @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
96             justification = "https://github.com/spotbugs/spotbugs/issues/811")
97     private static Iterable<Class<?>> getNotificationTypes(final Class<?> cls) {
98         return Arrays.stream(cls.getInterfaces())
99                 .filter(input -> !Notification.class.equals(input) && Notification.class.isAssignableFrom(input))
100                 .collect(Collectors.toList());
101     }
102 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.