Specialize JSONCodec to JSONValueWriter
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / ListenerRegistry.java
index e8b1a3dca975adbfbba831ace82a1045557c9af5..ea6a870ffaf4d9926578ae972df3e7ac544f244b 100644 (file)
@@ -7,73 +7,81 @@
  */
 package org.opendaylight.yangtools.util;
 
+import static java.util.Objects.requireNonNull;
 
-import java.util.Collections;
+import com.google.common.base.MoreObjects;
+import java.util.Collection;
 import java.util.EventListener;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import java.util.stream.Stream;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Mutable;
 
+/**
+ * A registry of EventListeners, maintaining a set of registrations. This class is thread-safe.
+ *
+ * @param <T> Type of listeners this registry handles
+ * @deprecated Use {@link ObjectRegistry} instead
+ */
+@Deprecated(since = "12.0.0", forRemoval = true)
+public final class ListenerRegistry<T extends EventListener> implements Mutable {
+    private final Set<RegistrationImpl<? extends T>> listeners = ConcurrentHashMap.newKeySet();
+    private final String name;
 
-public class ListenerRegistry<T extends EventListener> implements Iterable<ListenerRegistration<T>> {
+    private ListenerRegistry(final String name) {
+        this.name = name;
+    }
 
-    private final ConcurrentHashMap<ListenerRegistration<? extends T>,ListenerRegistration<? extends T>> listeners;
-    final Set<ListenerRegistration<T>> unmodifiableView;
+    public static <T extends EventListener> @NonNull ListenerRegistry<T> create() {
+        return new ListenerRegistry<>(null);
+    }
 
-    @SuppressWarnings("unchecked")
-    public ListenerRegistry() {
-        listeners = new ConcurrentHashMap<>();
-        // This conversion is known to be safe.
-        @SuppressWarnings("rawtypes")
-        final Set rawSet = Collections.unmodifiableSet(listeners.keySet());
-        unmodifiableView = rawSet;
+    public static <T extends EventListener> @NonNull ListenerRegistry<T> create(final @NonNull String name) {
+        return new ListenerRegistry<>(requireNonNull(name));
     }
 
-    public Iterable<ListenerRegistration<T>> getListeners() {
-        return unmodifiableView;
+    public void clear() {
+        listeners.stream().forEach(RegistrationImpl::close);
     }
 
-    public ListenerRegistration<T> register(T listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("Listener should not be null.");
-        }
-        ListenerRegistrationImpl<T> ret = new ListenerRegistrationImpl<T>(listener);
-        listeners.put(ret,ret);
-        return ret;
+    public boolean isEmpty() {
+        return listeners.isEmpty();
     }
-    
-    public <L extends T> ListenerRegistration<L> registerWithType(L listener) {
-        ListenerRegistrationImpl<L> ret = new ListenerRegistrationImpl<L>(listener);
-        listeners.put(ret,ret);
-        return ret;
+
+    public Stream<? extends T> streamListeners() {
+        return listeners.stream().filter(RegistrationImpl::notClosed).map(RegistrationImpl::getInstance);
     }
-    
-    @Override
-    public java.util.Iterator<ListenerRegistration<T>> iterator() {
-        return unmodifiableView.iterator();
+
+    public <L extends T> @NonNull ListenerRegistration<L> register(final L listener) {
+        final RegistrationImpl<L> ret = new RegistrationImpl<>(listener, listeners);
+        listeners.add(ret);
+        return ret;
     }
 
-    @SuppressWarnings("rawtypes")
-    private void remove(ListenerRegistrationImpl registration) {
-        listeners.remove(registration);
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).omitNullValues()
+                .add("name", name)
+                .add("size", listeners.size())
+                .toString();
     }
 
-    private class ListenerRegistrationImpl<P extends EventListener> //
-            extends AbstractObjectRegistration<P> //
-            implements ListenerRegistration<P> {
+    private static final class RegistrationImpl<T extends EventListener> extends AbstractListenerRegistration<T> {
+        private Collection<?> removeFrom;
 
-        public ListenerRegistrationImpl(P instance) {
+        RegistrationImpl(final T instance, final Collection<?> removeFrom) {
             super(instance);
+            this.removeFrom = requireNonNull(removeFrom);
         }
 
         @Override
         protected void removeRegistration() {
-            ListenerRegistry.this.remove(this);
+            removeFrom.remove(this);
+            // Do not retain reference to that state
+            removeFrom = null;
         }
     }
-
-    public static <T extends EventListener> ListenerRegistry<T> create() {
-        return new ListenerRegistry<>();
-    }
 }