Remove support for composite NotificationListener 50/108950/5
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 14 Nov 2023 11:53:58 +0000 (12:53 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 14 Nov 2023 14:11:35 +0000 (15:11 +0100)
We have a much more flexible mechanism for dealing with notifications
via the Notification interface, which is a proper FunctionalInterface.

Remove support for aggregated moduled-level FooListener interfaces.

JIRA: MDSAL-497
Change-Id: I7dd82c477de6ca836cce84354c016d5ebd21022d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
20 files changed:
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationService.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/AbstractDOMNotificationListenerAdapter.java [deleted file]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationListenerAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/SingleBindingDOMNotificationAdapter.java [deleted file]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvoker.java [deleted file]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/OSGiNotificationService.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/ForwardedNotificationAdapterTest.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvokerTest.java [deleted file]
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractExplicitGenerator.java
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractImplicitGenerator.java [deleted file]
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationServiceGenerator.java [deleted file]
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/StatementNamespace.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal554Test.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal810Test.java
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/CompilationTest.java
binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/BindingTypes.java
binding/mdsal-binding-model-ri/src/test/java/org/opendaylight/mdsal/binding/model/ri/BindingTypesTest.java
binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/NotificationListener.java [deleted file]

index a3b41ea2f13359a96716a87aa145a36d8347aecc..cf5012bad7ccff62db417b7d9c4463ab122b756d 100644 (file)
@@ -16,95 +16,15 @@ import java.util.EventListener;
 import java.util.Set;
 import java.util.concurrent.Executor;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
 /**
- * Notification broker which allows clients to subscribe for and publish YANG-modeled notifications.
+ * Notification broker which allows clients to subscribe for and publish YANG 1.0 notifications, which is to say
+ * {@code notification} statements occurring directly within a {@code module} or a {@code submodule} statement.
  */
 public interface NotificationService extends BindingService {
-    /**
-     * Registers a listener which implements a YANG-generated notification interface derived from
-     * {@link NotificationListener}. The listener is registered for all notifications present in the implemented
-     * interface.
-     *
-     * <p>
-     * Each YANG module which defines notifications results in a generated interface <code>{ModuleName}Listener</code>
-     * which handles all the notifications defined in the YANG model. Each notification type translates to a specific
-     * method of the form <code>on{NotificationType}</code> on the generated interface. The generated interface also
-     * extends the {@link org.opendaylight.yangtools.yang.binding.NotificationListener} interface and implementations
-     * are registered using this method.
-     *
-     * <b>Dispatch Listener Example</b>
-     *
-     * <p>
-     * Lets assume we have following YANG model:
-     *
-     * <pre>
-     * module example {
-     *      ...
-     *
-     *      notification start {
-     *          ...
-     *      }
-     *
-     *      notification stop {
-     *           ...
-     *      }
-     * }
-     * </pre>
-     *
-     * <p>
-     * The generated interface will be:
-     *
-     * <pre>
-     * public interface ExampleListener extends NotificationListener {
-     *     void onStart(Start notification);
-     *
-     *     void onStop(Stop notification);
-     * }
-     * </pre>
-     *
-     * <p>
-     * The following defines an implementation of the generated interface:
-     *
-     * <pre>
-     * public class MyExampleListener implements ExampleListener {
-     *     public void onStart(Start notification) {
-     *         // do something
-     *     }
-     *
-     *     public void onStop(Stop notification) {
-     *         // do something
-     *     }
-     * }
-     * </pre>
-     *
-     * <p>
-     * The implementation is registered as follows:
-     *
-     * <pre>
-     * MyExampleListener listener = new MyExampleListener();
-     * ListenerRegistration&lt;NotificationListener&gt; reg = service.registerNotificationListener(listener);
-     * </pre>
-     *
-     * <p>
-     * The {@code onStart} method will be invoked when someone publishes a {@code Start} notification and the
-     * {@code onStop} method will be invoked when someone publishes a {@code Stop} notification.
-     *
-     * @param <T> NotificationListener type
-     * @param listener the listener implementation that will receive notifications.
-     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
-     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
-     * @deprecated Prefer {@link #registerListener(Class, Listener)} or
-     *             {@link #registerListener(Class, Listener, Executor)} instead.
-     */
-    @Deprecated(since = "10.0.0", forRemoval = true)
-    <T extends NotificationListener> @NonNull ListenerRegistration<T> registerNotificationListener(@NonNull T listener);
-
     /**
      * Registers a {@link Listener} to receive callbacks for {@link Notification}s of a particular type.
      *
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/AbstractDOMNotificationListenerAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/AbstractDOMNotificationListenerAdapter.java
deleted file mode 100644 (file)
index eae5f76..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- * Copyright (c) 2021 PANTHEON.tech, s.r.o.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter;
-
-import static com.google.common.base.Verify.verify;
-import static com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-
-import java.util.Set;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.dom.api.DOMEvent;
-import org.opendaylight.mdsal.dom.api.DOMNotification;
-import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
-import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-
-abstract class AbstractDOMNotificationListenerAdapter implements DOMNotificationListener {
-    private final AdapterContext adapterContext;
-
-    AbstractDOMNotificationListenerAdapter(final AdapterContext adapterContext) {
-        this.adapterContext = requireNonNull(adapterContext);
-    }
-
-    @Override
-    public final void onNotification(final DOMNotification notification) {
-        onNotification(notification.getType(), verifyNotNull(deserialize(notification)));
-    }
-
-    abstract void onNotification(@NonNull Absolute domType, @NonNull Notification<?> notification);
-
-    abstract Set<Absolute> getSupportedNotifications();
-
-    private Notification<?> deserialize(final DOMNotification notification) {
-        if (notification instanceof LazySerializedNotification) {
-            // TODO: This is a routed-back notification, for which we may end up losing event time here, but that is
-            //       okay, for now at least.
-            return ((LazySerializedNotification) notification).getBindingData();
-        }
-
-        final var serializer = adapterContext.currentSerializer();
-        final var result = notification instanceof DOMEvent
-            ? serializer.fromNormalizedNodeNotification(notification.getType(), notification.getBody(),
-                ((DOMEvent) notification).getEventInstant())
-                : serializer.fromNormalizedNodeNotification(notification.getType(), notification.getBody());
-        verify(result instanceof Notification, "Unexpected codec result %s", result);
-        return (Notification<?>) result;
-    }
-}
index b97853e7d729a23b5621b21dc5d16c9b930a106e..7ce80210c3ed7cca5a7b05d85cb719464f7563c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -7,70 +7,65 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.Executor;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.dom.adapter.invoke.NotificationListenerInvoker;
+import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener.Component;
+import org.opendaylight.mdsal.binding.api.NotificationService.Listener;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
+import org.opendaylight.mdsal.dom.api.DOMEvent;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
-final class BindingDOMNotificationListenerAdapter extends AbstractDOMNotificationListenerAdapter {
-    private final ImmutableMap<Absolute, NotificationListenerInvoker> invokers;
-    private final @NonNull NotificationListener delegate;
+final class BindingDOMNotificationListenerAdapter<N extends Notification<N> & DataObject>
+        implements DOMNotificationListener {
+    private final AdapterContext adapterContext;
+    private final Listener<N> delegate;
+    private final Executor executor;
+    private final Class<N> type;
 
-    BindingDOMNotificationListenerAdapter(final AdapterContext adapterContext, final NotificationListener delegate) {
-        super(adapterContext);
+    BindingDOMNotificationListenerAdapter(final AdapterContext adapterContext, final Class<N> type,
+            final Listener<N> delegate, final Executor executor) {
+        this.adapterContext = requireNonNull(adapterContext);
+        this.type = requireNonNull(type);
         this.delegate = requireNonNull(delegate);
-        invokers = createInvokerMapFor(delegate.getClass());
+        this.executor = requireNonNull(executor);
     }
 
-    @Override
-    void onNotification(final Absolute domType, final Notification<?> notification) {
-        invokers.get(domType).invokeNotification(delegate, domType.lastNodeIdentifier(), notification);
+    BindingDOMNotificationListenerAdapter(final AdapterContext adapterContext, final Component<N> component,
+            final Executor executor) {
+        this(adapterContext, component.type(), component.listener(), executor);
     }
 
-    @Override
-    Set<Absolute> getSupportedNotifications() {
-        return invokers.keySet();
+    @NonNull Absolute schemaPath() {
+        return Absolute.of(BindingReflections.findQName(type));
     }
 
-    private static ImmutableMap<Absolute, NotificationListenerInvoker> createInvokerMapFor(
-            final Class<? extends NotificationListener> implClz) {
-        final Map<Absolute, NotificationListenerInvoker> builder = new HashMap<>();
-        for (final TypeToken<?> ifaceToken : TypeToken.of(implClz).getTypes().interfaces()) {
-            Class<?> iface = ifaceToken.getRawType();
-            if (NotificationListener.class.isAssignableFrom(iface) && BindingReflections.isBindingClass(iface)) {
-                @SuppressWarnings("unchecked")
-                final Class<? extends NotificationListener> listenerType
-                        = (Class<? extends NotificationListener>) iface;
-                final NotificationListenerInvoker invoker = NotificationListenerInvoker.from(listenerType);
-                for (final Absolute path : getNotificationTypes(listenerType)) {
-                    builder.put(path, invoker);
-                }
-            }
-        }
-        return ImmutableMap.copyOf(builder);
+    @Override
+    public void onNotification(final DOMNotification notification) {
+        final var binding = type.cast(verifyNotNull(deserialize(notification)));
+        executor.execute(() -> delegate.onNotification(binding));
     }
 
-    private static Set<Absolute> getNotificationTypes(final Class<? extends NotificationListener> type) {
-        // TODO: Investigate possibility and performance impact if we cache this or expose
-        // it from NotificationListenerInvoker
-        final Set<Absolute> ret = new HashSet<>();
-        for (final Method method : type.getMethods()) {
-            if (NotificationListenerInvoker.isNotificationCallback(method)) {
-                final Class<?> notification = method.getParameterTypes()[0];
-                ret.add(Absolute.of(BindingReflections.findQName(notification)));
-            }
+    private Notification<?> deserialize(final DOMNotification notification) {
+        if (notification instanceof LazySerializedNotification lazy) {
+            // TODO: This is a routed-back notification, for which we may end up losing event time here, but that is
+            //       okay, for now at least.
+            return lazy.getBindingData();
         }
-        return ret;
+
+        final var serializer = adapterContext.currentSerializer();
+        final var result = notification instanceof DOMEvent domEvent
+            ? serializer.fromNormalizedNodeNotification(notification.getType(), notification.getBody(),
+                domEvent.getEventInstant())
+                : serializer.fromNormalizedNodeNotification(notification.getType(), notification.getBody());
+        verify(result instanceof Notification, "Unexpected codec result %s", result);
+        return (Notification<?>) result;
     }
 }
index 00709df52093d3a5bf42851b0be7910342e75048..6b4dd076428533bb69c213cdc71f31f0d31b1c4c 100644 (file)
@@ -20,12 +20,9 @@ import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMAdapterBuilder.Facto
 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
 import org.opendaylight.mdsal.dom.api.DOMNotificationService;
 import org.opendaylight.mdsal.dom.api.DOMService;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 @VisibleForTesting
@@ -42,19 +39,11 @@ public class BindingDOMNotificationServiceAdapter implements NotificationService
         this.domNotifService = domNotifService;
     }
 
-    @Override
-    @Deprecated(since = "10.0.0", forRemoval = true)
-    public <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(final T listener) {
-        final var domListener = new BindingDOMNotificationListenerAdapter(adapterContext, listener);
-        return new ListenerRegistrationImpl<>(listener,
-            domNotifService.registerNotificationListener(domListener, domListener.getSupportedNotifications()));
-    }
-
     @Override
     public <N extends Notification<N> & DataObject> Registration registerListener(final Class<N> type,
             final Listener<N> listener, final Executor executor) {
-        final var domListener = new SingleBindingDOMNotificationAdapter<>(adapterContext, type, listener, executor);
-        return domNotifService.registerNotificationListener(domListener, domListener.getSupportedNotifications());
+        final var domListener = new BindingDOMNotificationListenerAdapter<>(adapterContext, type, listener, executor);
+        return domNotifService.registerNotificationListener(domListener, Set.of(domListener.schemaPath()));
     }
 
     @Override
@@ -62,29 +51,13 @@ public class BindingDOMNotificationServiceAdapter implements NotificationService
         final var exec = requireNonNull(executor);
         final var listeners = new HashMap<Absolute, DOMNotificationListener>();
         for (var constituent : listener.constituents()) {
-            final var domListener = new SingleBindingDOMNotificationAdapter<>(adapterContext, constituent, exec);
-            listeners.put(domListener.getSupportedNotifications().iterator().next(), domListener);
+            final var domListener = new BindingDOMNotificationListenerAdapter<>(adapterContext, constituent, exec);
+            listeners.put(domListener.schemaPath(), domListener);
         }
 
         return domNotifService.registerNotificationListeners(listeners);
     }
 
-    @Deprecated(since = "10.0.0", forRemoval = true)
-    private static final class ListenerRegistrationImpl<T extends NotificationListener>
-            extends AbstractListenerRegistration<T> {
-        private final ListenerRegistration<?> listenerRegistration;
-
-        ListenerRegistrationImpl(final T listener, final ListenerRegistration<?> listenerRegistration) {
-            super(listener);
-            this.listenerRegistration = listenerRegistration;
-        }
-
-        @Override
-        protected void removeRegistration() {
-            listenerRegistration.close();
-        }
-    }
-
     private static class Builder extends BindingDOMAdapterBuilder<NotificationService> {
         Builder(final AdapterContext adapterContext) {
             super(adapterContext);
@@ -92,8 +65,8 @@ public class BindingDOMNotificationServiceAdapter implements NotificationService
 
         @Override
         protected NotificationService createInstance(final ClassToInstanceMap<DOMService> delegates) {
-            final DOMNotificationService domNotification = delegates.getInstance(DOMNotificationService.class);
-            return new BindingDOMNotificationServiceAdapter(adapterContext(), domNotification);
+            return new BindingDOMNotificationServiceAdapter(adapterContext(),
+                delegates.getInstance(DOMNotificationService.class));
         }
 
         @Override
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/SingleBindingDOMNotificationAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/SingleBindingDOMNotificationAdapter.java
deleted file mode 100644 (file)
index a392fd5..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Set;
-import java.util.concurrent.Executor;
-import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener.Component;
-import org.opendaylight.mdsal.binding.api.NotificationService.Listener;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
-
-final class SingleBindingDOMNotificationAdapter<N extends Notification<N> & DataObject>
-        extends AbstractDOMNotificationListenerAdapter {
-    private final Listener<N> delegate;
-    private final Executor executor;
-    private final Class<N> type;
-
-    SingleBindingDOMNotificationAdapter(final AdapterContext adapterContext, final Class<N> type,
-            final Listener<N> delegate, final Executor executor) {
-        super(adapterContext);
-        this.type = requireNonNull(type);
-        this.delegate = requireNonNull(delegate);
-        this.executor = requireNonNull(executor);
-    }
-
-    SingleBindingDOMNotificationAdapter(final AdapterContext adapterContext, final Component<N> component,
-            final Executor executor) {
-        this(adapterContext, component.type(), component.listener(), executor);
-    }
-
-    @Override
-    void onNotification(final Absolute domType, final Notification<?> notification) {
-        executor.execute(() -> delegate.onNotification(type.cast(notification)));
-    }
-
-    @Override
-    Set<Absolute> getSupportedNotifications() {
-        return Set.of(Absolute.of(BindingReflections.findQName(type)));
-    }
-}
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvoker.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvoker.java
deleted file mode 100644 (file)
index b177ceb..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter.invoke;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Throwables;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Method;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.QName;
-
-/**
- * Provides single method invocation of notificatoin callbacks on supplied instance.
- *
- * <p>
- * Notification Listener invoker provides common invocation interface for any subtype of {@link NotificationListener}.
- * via {@link #invokeNotification(NotificationListener, QName, DataContainer)} method.
- */
-public final class NotificationListenerInvoker {
-    private static final LoadingCache<Class<? extends NotificationListener>, NotificationListenerInvoker> INVOKERS =
-            CacheBuilder.newBuilder().weakKeys()
-            .build(new CacheLoader<Class<? extends NotificationListener>, NotificationListenerInvoker>() {
-                @Override
-                public NotificationListenerInvoker load(final Class<? extends NotificationListener> key) {
-                    return new NotificationListenerInvoker(createInvokerMap(key));
-                }
-
-                private ImmutableMap<QName, MethodHandle> createInvokerMap(
-                        final Class<? extends NotificationListener> key) {
-                    final Builder<QName, MethodHandle> ret = ImmutableMap.builder();
-                    for (final Method method : key.getMethods()) {
-                        if (isNotificationCallback(method)) {
-                            final Class<?> notification = method.getParameterTypes()[0];
-                            final QName name = BindingReflections.findQName(notification);
-                            MethodHandle handle;
-                            try {
-                                handle = MethodHandles.publicLookup().unreflect(method).asType(
-                                    MethodType.methodType(void.class, NotificationListener.class, DataContainer.class));
-                                ret.put(name, handle);
-                            } catch (final IllegalAccessException e) {
-                                throw new IllegalStateException("Can not access public method.", e);
-                            }
-                        }
-
-                    }
-                    return ret.build();
-                }
-            });
-
-    private final ImmutableMap<QName, MethodHandle> methodInvokers;
-
-    NotificationListenerInvoker(final ImmutableMap<QName, MethodHandle> map) {
-        methodInvokers = map;
-    }
-
-    /**
-     * Creates RPCServiceInvoker for specified RpcService type.
-     *
-     * @param type
-     *            RpcService interface, which was generated from model.
-     * @return Cached instance of {@link NotificationListenerInvoker} for
-     *         supplied RPC type.
-     */
-    public static NotificationListenerInvoker from(final Class<? extends NotificationListener> type) {
-        checkArgument(type.isInterface());
-        checkArgument(BindingReflections.isBindingClass(type));
-        return INVOKERS.getUnchecked(type);
-    }
-
-    /**
-     * Invokes supplied RPC on provided implementation of RPC Service.
-     *
-     * @param impl Implementation on which notification callback should be invoked.
-     * @param rpcName Name of RPC to be invoked.
-     * @param input Input data for RPC.
-     */
-    @SuppressWarnings("checkstyle:illegalCatch")
-    public void invokeNotification(final @NonNull NotificationListener impl, final @NonNull QName rpcName,
-            final @Nullable DataContainer input) {
-        requireNonNull(impl, "implemetation must be supplied");
-        final MethodHandle invoker = methodInvokers.get(rpcName);
-        checkArgument(invoker != null, "Supplied notification is not valid for implementation %s", impl);
-        try {
-            invoker.invokeExact(impl, input);
-        } catch (final Throwable e) {
-            Throwables.throwIfUnchecked(e);
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Checks if supplied method is callback for notifications.
-     *
-     * @param method method to check
-     * @return true if method is notification callback.
-     */
-    public static boolean isNotificationCallback(final Method method) {
-        if (method.getName().startsWith("on") && method.getParameterCount() == 1) {
-            Class<?> potentialNotification = method.getParameterTypes()[0];
-            if (Notification.class.isAssignableFrom(potentialNotification)
-                    && method.getName().equals("on" + potentialNotification.getSimpleName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
index a8cb76f049505fdc2c4fddbbb0ba44cba76e8fbf..85e4c5e501687d567e8c041a2c7ad7ddd2c63700 100644 (file)
@@ -11,11 +11,9 @@ import com.google.common.annotations.Beta;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import org.opendaylight.mdsal.binding.api.NotificationService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -31,12 +29,6 @@ public final class OSGiNotificationService extends AbstractAdaptedService<Notifi
         super(NotificationService.class);
     }
 
-    @Override
-    @Deprecated(since = "10.0.0", forRemoval = true)
-    public <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(final T listener) {
-        return delegate().registerNotificationListener(listener);
-    }
-
     @Override
     public <N extends Notification<N> & DataObject> Registration registerListener(final Class<N> type,
             final NotificationService.Listener<N> listener, final Executor executor) {
index 024bf793a2a53b1292f31280bc6e42aa1cc088a8..8b8b4384af8a512af8b1d9a4f27771411d30619a 100644 (file)
@@ -15,16 +15,13 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import org.eclipse.jdt.annotation.NonNull;
 import org.junit.Test;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.mdsal.binding.api.NotificationService.Listener;
 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractNotificationBrokerTest;
-import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.OpendaylightMdsalBindingTestListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.$YangModuleInfoImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TwoLevelListChanged;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TwoLevelListChangedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
@@ -35,137 +32,78 @@ import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 public class ForwardedNotificationAdapterTest extends AbstractNotificationBrokerTest {
     @Override
     protected Set<YangModuleInfo> getModuleInfos() throws Exception {
-        return Set.of(BindingRuntimeHelpers.getYangModuleInfo(TwoLevelListChanged.class));
+        return Set.of($YangModuleInfoImpl.getInstance());
     }
 
     @Test
-    public void testPutSubscription() throws InterruptedException {
-        final var listener = new TestNotifListener(1);
-        try (var reg = getNotificationService().registerNotificationListener(listener)) {
-            assertPutSubscription(listener);
-        }
-    }
-
-    @Test
-    public void testPutSubscriptionSimple() throws InterruptedException {
-        final var listener = new SimpleNotifListener(1);
+    public void testPutSubscription() throws Exception {
+        final var listener = new NotifListener(1);
         try (var reg = getNotificationService().registerListener(TwoLevelListChanged.class, listener)) {
-            assertPutSubscription(listener);
-        }
-    }
-
-    private void assertPutSubscription(final AbstractNotifListener listener) throws InterruptedException {
-        final var testData = createTestData();
-        getNotificationPublishService().putNotification(testData);
-
-        final var received = listener.awaitNotifications();
-        assertEquals(1, received.size());
-        assertSame(testData, received.get(0));
-    }
+            final var testData = createTestData();
+            getNotificationPublishService().putNotification(testData);
 
-    @Test
-    public void testOfferSubscription() throws InterruptedException {
-        final var listener = new TestNotifListener(1);
-        try (var reg = getNotificationService().registerNotificationListener(listener)) {
-            assertOfferNotification(listener);
+            final var received = listener.awaitNotifications();
+            assertEquals(1, received.size());
+            assertSame(testData, received.get(0));
         }
     }
 
     @Test
-    public void testOfferSubscriptionSimple() throws InterruptedException {
-        final var listener = new SimpleNotifListener(1);
+    public void testOfferSubscription() throws Exception {
+        final var listener = new NotifListener(1);
         try (var reg = getNotificationService().registerListener(TwoLevelListChanged.class, listener)) {
-            assertOfferNotification(listener);
-        }
-    }
+            final var testData = createTestData();
 
-    private void assertOfferNotification(final AbstractNotifListener listener) throws InterruptedException {
-        final var testData = createTestData();
-
-        try {
             getNotificationPublishService().offerNotification(testData).get(1, TimeUnit.SECONDS);
-        } catch (ExecutionException | TimeoutException e) {
-            throw new AssertionError("Notification should be delivered", e);
-        }
-
-        final var received = listener.awaitNotifications();
-        assertEquals(1, received.size());
-        assertSame(testData, received.get(0));
-    }
 
-    @Test
-    public void testOfferTimedNotification() throws InterruptedException {
-        final var listener = new TestNotifListener(1);
-        try (var reg = getNotificationService().registerNotificationListener(listener)) {
-            assertOfferTimedNotification(listener);
+            final var received = listener.awaitNotifications();
+            assertEquals(1, received.size());
+            assertSame(testData, received.get(0));
         }
     }
 
     @Test
-    public void testOfferTimedNotificationSimple() throws InterruptedException {
-        final var listener = new SimpleNotifListener(1);
+    public void testOfferTimedNotification() throws Exception {
+        final var listener = new NotifListener(1);
         try (var reg = getNotificationService().registerListener(TwoLevelListChanged.class, listener)) {
-            assertOfferTimedNotification(listener);
-        }
-    }
-
-    private void assertOfferTimedNotification(final AbstractNotifListener listener) throws InterruptedException {
-        final var testData = createTestData();
+            final var testData = createTestData();
 
-        assertNotSame(NotificationPublishService.REJECTED,
-            getNotificationPublishService().offerNotification(testData, 5, TimeUnit.SECONDS));
+            assertNotSame(NotificationPublishService.REJECTED,
+                getNotificationPublishService().offerNotification(testData, 5, TimeUnit.SECONDS));
 
-        final var received = listener.awaitNotifications();
-        assertEquals(1, received.size());
-        assertSame(testData, received.get(0));
+            final var received = listener.awaitNotifications();
+            assertEquals(1, received.size());
+            assertSame(testData, received.get(0));
+        }
     }
 
-
     private static @NonNull TwoLevelListChanged createTestData() {
         return new TwoLevelListChangedBuilder()
             .setTopLevelList(BindingMap.of(new TopLevelListBuilder().withKey(new TopLevelListKey("test")).build()))
             .build();
     }
 
-    private abstract static class AbstractNotifListener {
+    private static  final class NotifListener implements Listener<TwoLevelListChanged> {
         private final List<TwoLevelListChanged> receivedNotifications = new ArrayList<>();
         private final CountDownLatch latch;
 
-        AbstractNotifListener(final int expectedCount) {
+        NotifListener(final int expectedCount) {
             latch = new CountDownLatch(expectedCount);
         }
 
-        final void receiveNotification(final TwoLevelListChanged notification) {
+        void receiveNotification(final TwoLevelListChanged notification) {
             receivedNotifications.add(notification);
             latch.countDown();
         }
 
-        final List<TwoLevelListChanged> awaitNotifications() throws InterruptedException {
+        List<TwoLevelListChanged> awaitNotifications() throws InterruptedException {
             latch.await();
             return receivedNotifications;
         }
-    }
-
-    private static class SimpleNotifListener extends AbstractNotifListener implements Listener<TwoLevelListChanged> {
-        SimpleNotifListener(final int expectedCount) {
-            super(expectedCount);
-        }
 
         @Override
         public void onNotification(final TwoLevelListChanged notification) {
             receiveNotification(notification);
         }
     }
-
-    private static class TestNotifListener extends AbstractNotifListener
-            implements OpendaylightMdsalBindingTestListener {
-        TestNotifListener(final int expectedCount) {
-            super(expectedCount);
-        }
-
-        @Override
-        public void onTwoLevelListChanged(final TwoLevelListChanged notification) {
-            receiveNotification(notification);
-        }
-    }
 }
diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvokerTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/invoke/NotificationListenerInvokerTest.java
deleted file mode 100644 (file)
index ee761fc..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter.invoke;
-
-import static org.hamcrest.CoreMatchers.endsWith;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.WrongMethodTypeException;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.notification.rev150205.OpendaylightTestNotificationListener;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class NotificationListenerInvokerTest {
-    @Test
-    public void fromTest() throws Exception {
-        assertNotNull(NotificationListenerInvoker.from(OpendaylightTestNotificationListener.class));
-    }
-
-    @Test
-    public void fromWithExceptionTest() {
-        final var cause = assertThrows(UncheckedExecutionException.class,
-            () -> NotificationListenerInvoker.from(TestPrivateInterface.class))
-            .getCause();
-        assertThat(cause, instanceOf(IllegalStateException.class));
-        assertThat(cause.getCause(), instanceOf(IllegalAccessException.class));
-    }
-
-    @Test
-    public void invokeNotification() throws Exception {
-        final var notificationListener = mock(NotificationListener.class);
-        final var methodHandle = MethodHandles.publicLookup().unreflect(String.class.getDeclaredMethod("toString"));
-
-        final var notificationListenerInvoker = new NotificationListenerInvoker(
-            ImmutableMap.of(QName.create("test", "test"), methodHandle));
-
-        final var ex = assertThrows(WrongMethodTypeException.class,
-            () -> notificationListenerInvoker.invokeNotification(notificationListener, QName.create("test", "test"),
-                null));
-        assertThat(ex.getMessage(), endsWith(" (String)String but found (NotificationListener,DataContainer)void"));
-    }
-
-    private interface TestPrivateInterface extends NotificationListener, Augmentation {
-        QName QNAME = QName.create("test", "test");
-
-        void onTestNotificationInterface(TestNotificationInterface notif);
-    }
-
-    public interface TestNotificationInterface extends DataObject, Notification<TestNotificationInterface> {
-        QName QNAME = QName.create("test", "test");
-    }
-}
\ No newline at end of file
index 9fe590e9a543c837f9450311ef4d3a22aa5badc9..938412c1d5e9ff787d1560d36d71d6bf08b26676 100644 (file)
@@ -570,18 +570,6 @@ public abstract class AbstractCompositeGenerator<S extends EffectiveStatement<?,
         // substatements to establish this order.
         tmpAug.sort(AbstractAugmentGenerator.COMPARATOR);
         tmp.addAll(tmpAug);
-
-        // Compatibility FooService and FooListener interfaces, only generated for modules.
-        if (this instanceof ModuleGenerator moduleGen) {
-            final var notifs = tmp.stream()
-                .filter(NotificationGenerator.class::isInstance)
-                .map(NotificationGenerator.class::cast)
-                .collect(Collectors.toUnmodifiableList());
-            if (!notifs.isEmpty()) {
-                tmp.add(new NotificationServiceGenerator(moduleGen, notifs));
-            }
-        }
-
         return List.copyOf(tmp);
     }
 
index f11042e2c35b7c5c28d4f064e09a0a75e453cff8..609bdedca704a06559f95405e6e513cec559dc7f 100644 (file)
@@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory;
 /**
  * An explicit {@link Generator}, associated with a particular {@link EffectiveStatement}.
  */
+// FIXME: unify this with Generator
 public abstract class AbstractExplicitGenerator<S extends EffectiveStatement<?, ?>, R extends RuntimeType>
         extends Generator implements CopyableNode, StatementRepresentation<S> {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractExplicitGenerator.class);
diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractImplicitGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractImplicitGenerator.java
deleted file mode 100644 (file)
index 9b93edf..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.generator.impl.reactor;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.generator.impl.reactor.CollisionDomain.Member;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-/**
- * An implicit {@link Generator}, not associated with any particular statement. We use these only for aggregate services
- * harking back to the original specification for Java 7. As such we want to eventually get rid of it.
- */
-// FIXME: eventually remove this subclass and unify Generator and AbstractExplicitGenerator
-abstract class AbstractImplicitGenerator extends Generator {
-    AbstractImplicitGenerator(final ModuleGenerator parent) {
-        super(parent);
-    }
-
-    @Override
-    final void pushToInference(final SchemaInferenceStack inferenceStack) {
-        // No-op
-    }
-
-    @Override
-    final ClassPlacement classPlacement() {
-        return ClassPlacement.TOP_LEVEL;
-    }
-
-    @Override
-    final Member createMember(final CollisionDomain domain) {
-        return domain.addSecondary(this, ((ModuleGenerator) getParent()).getPrefixMember(), classSuffix());
-    }
-
-    abstract @NonNull String classSuffix();
-}
diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationServiceGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationServiceGenerator.java
deleted file mode 100644 (file)
index 5953c75..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.generator.impl.reactor;
-
-import static com.google.common.base.Verify.verify;
-import static java.util.Objects.requireNonNull;
-
-import java.util.List;
-import org.opendaylight.mdsal.binding.model.api.AccessModifier;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
-import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
-import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder;
-import org.opendaylight.mdsal.binding.model.ri.BindingTypes;
-import org.opendaylight.mdsal.binding.model.ri.Types;
-import org.opendaylight.yangtools.yang.binding.contract.Naming;
-import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
-import org.opendaylight.yangtools.yang.model.api.Status;
-import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
-
-/**
- * Aggregate service for top-level {@code notification} statements for a particular module. It does not handle nested
- * (YANG 1.1) notifications.
- */
-// FIXME: MDSAL-497: remove this generator
-final class NotificationServiceGenerator extends AbstractImplicitGenerator {
-    private final List<NotificationGenerator> notifs;
-
-    NotificationServiceGenerator(final ModuleGenerator parent, final List<NotificationGenerator> notifs) {
-        super(parent);
-        this.notifs = requireNonNull(notifs);
-    }
-
-    @Override
-    StatementNamespace namespace() {
-        return StatementNamespace.NOTIFICATION_LISTENER;
-    }
-
-    @Override
-    String classSuffix() {
-        return Naming.NOTIFICATION_LISTENER_SUFFIX;
-    }
-
-    @Override
-    GeneratedType createTypeImpl(final TypeBuilderFactory builderFactory) {
-        final GeneratedTypeBuilder builder = builderFactory.newGeneratedTypeBuilder(typeName());
-        builder.addImplementsType(BindingTypes.NOTIFICATION_LISTENER)
-            .addAnnotation(DEPRECATED_ANNOTATION);
-
-        for (NotificationGenerator gen : notifs) {
-            final MethodSignatureBuilder notificationMethod = builder.addMethod("on" + gen.assignedName())
-                .setAccessModifier(AccessModifier.PUBLIC)
-                .addParameter(gen.getGeneratedType(builderFactory), "notification")
-                .setReturnType(Types.primitiveVoidType());
-
-            final NotificationEffectiveStatement stmt = gen.statement();
-            verify(stmt instanceof WithStatus, "Unexpected statement %s", stmt);
-            final WithStatus withStatus = (WithStatus) stmt;
-
-            annotateDeprecatedIfNecessary(withStatus, notificationMethod);
-            if (withStatus.getStatus() == Status.OBSOLETE) {
-                notificationMethod.setDefault(true);
-            }
-
-            // FIXME: finish this up
-            // addComment(notificationMethod, notification);
-        }
-
-        return builder.build();
-    }
-}
index f25df47efa0055dfbfff1d4937596c77f044037a..c548f20277dc74d3b8b1b13c0d470d17e8a6b1d4 100644 (file)
@@ -11,7 +11,6 @@ import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
 /**
  * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-6.2.1">YANG statement namespaces</a> which we process.
@@ -87,25 +86,7 @@ enum StatementNamespace {
      * </code>
      * In this case the module-derived FooData gets shifted to {@code $D}.
      */
-    DATA_ROOT("$D", true),
-    /**
-     * The namespace for combined {@link NotificationListener} interface. This typically does not conflict, but could in
-     * case of
-     * <code>
-     *   <pre>
-     *     module foo {
-     *       container foo-listener; // results in FooListener
-     *       notification bar; // Triggers FooListener generation for module
-     *     }
-     *   </pre>
-     * </code>
-     * In this case the module-derived FooListener gets shifted to {@code $LL}.
-     *
-     * @deprecated This will be removed once {@link NotificationServiceGenerator} is gone.
-     */
-    // FIXME: MDSAL-497: remove this value
-    @Deprecated
-    NOTIFICATION_LISTENER("$LL", true);
+    DATA_ROOT("$D", true);
 
     private final @NonNull String suffix;
     private final boolean resistant;
index d8ed00d54ca2d7575507af07ac2c95c098f17d37..b953e4b03083263ce11aef7251fbbfc45a98c392 100644 (file)
@@ -8,61 +8,48 @@
 package org.opendaylight.mdsal.binding.generator.impl;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.model.api.AnnotationType;
-import org.opendaylight.mdsal.binding.model.api.AnnotationType.Parameter;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
-import org.opendaylight.mdsal.binding.model.api.MethodSignature;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 public class Mdsal554Test {
     @Test
     public void builderTemplateGenerateListenerMethodsTest() {
-        final List<GeneratedType> genTypes = DefaultBindingGenerator.generateFor(
+        final var genTypes = DefaultBindingGenerator.generateFor(
             YangParserTestUtils.parseYangResource("/mdsal554.yang"));
-        assertEquals(5, genTypes.size());
-
-        final List<MethodSignature> methods = genTypes.get(4).getMethodDefinitions();
-        assertEquals(3, methods.size());
+        assertEquals(4, genTypes.size());
 
         // status deprecated
-        final MethodSignature deprecated = methods.get(0);
-        assertEquals("onDeprecatedNotification", deprecated.getName());
-        assertFalse(deprecated.isDefault());
-
-        final List<AnnotationType> deprecatedAnnotations = deprecated.getAnnotations();
+        final var deprecated = genTypes.get(1);
+        assertEquals("DeprecatedNotification", deprecated.getName());
+        final var deprecatedAnnotations = deprecated.getAnnotations();
         assertEquals(1, deprecatedAnnotations.size());
 
-        AnnotationType annotation = deprecatedAnnotations.get(0);
+        var annotation = deprecatedAnnotations.get(0);
         assertEquals(JavaTypeName.create(Deprecated.class), annotation.getIdentifier());
         assertEquals(List.of(), annotation.getParameters());
 
         // status obsolete
-        final MethodSignature obsolete = methods.get(1);
-        assertEquals("onObsoleteNotification", obsolete.getName());
-        assertTrue(obsolete.isDefault());
+        final var obsolete = genTypes.get(2);
+        assertEquals("ObsoleteNotification", obsolete.getName());
 
-        final List<AnnotationType> obsoleteAnnotations = obsolete.getAnnotations();
+        final var obsoleteAnnotations = obsolete.getAnnotations();
         assertEquals(1, obsoleteAnnotations.size());
 
         annotation = obsoleteAnnotations.get(0);
         assertEquals(JavaTypeName.create(Deprecated.class), annotation.getIdentifier());
 
-        final List<Parameter> annotationParameters = annotation.getParameters();
+        final var annotationParameters = annotation.getParameters();
         assertEquals(1, annotationParameters.size());
 
         assertEquals("forRemoval", annotationParameters.get(0).getName());
         assertEquals("true", annotationParameters.get(0).getValue());
 
         // status current
-        final MethodSignature current = methods.get(2);
-        assertEquals("onTestNotification", current.getName());
-        assertFalse(current.isDefault());
+        final var current = genTypes.get(3);
+        assertEquals("TestNotification", current.getName());
         assertEquals(List.of(), current.getAnnotations());
     }
 }
index 65d2799703bb71e2c7e015517db1c70ae942d138..04fcb5c1855f09fbd33b8e2fb0837bc59bf9e366 100644 (file)
@@ -27,9 +27,8 @@ public class Mdsal810Test {
     public void testListenerConflict() {
         assertGeneratedNames("listener-conflict.yang",
             "org.opendaylight.yang.gen.v1.listener.conflict.norev.ListenerConflictData",
-            "org.opendaylight.yang.gen.v1.listener.conflict.norev.ListenerConflictListener$CO",
-            "org.opendaylight.yang.gen.v1.listener.conflict.norev.Bar",
-            "org.opendaylight.yang.gen.v1.listener.conflict.norev.ListenerConflictListener");
+            "org.opendaylight.yang.gen.v1.listener.conflict.norev.ListenerConflictListener",
+            "org.opendaylight.yang.gen.v1.listener.conflict.norev.Bar");
     }
 
     @Test
@@ -71,8 +70,7 @@ public class Mdsal810Test {
             "org.opendaylight.yang.gen.v1.schema.conflict.norev.FooBar$NO",
             "org.opendaylight.yang.gen.v1.schema.conflict.norev.FooBar$RP",
             "org.opendaylight.yang.gen.v1.schema.conflict.norev.FooBar$RPInput",
-            "org.opendaylight.yang.gen.v1.schema.conflict.norev.FooBar$RPOutput",
-            "org.opendaylight.yang.gen.v1.schema.conflict.norev.SchemaConflictListener");
+            "org.opendaylight.yang.gen.v1.schema.conflict.norev.FooBar$RPOutput");
     }
 
     private static void assertGeneratedNames(final String yangFile, final String... fqcns) {
index 2cadd4f2ad29c30de0bed1d33565ff8f0f063815..0e5f744a2016079dd4839d99d3983c7d7191d080 100644 (file)
@@ -300,11 +300,10 @@ public class CompilationTest extends BaseCompilationTest {
         // Test if all sources were generated from 'module foo'
         File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO);
         assertTrue(new File(parent, "FooData.java").exists());
-        assertTrue(new File(parent, "FooListener.java").exists());
         assertTrue(new File(parent, "PathAttributes.java").exists());
         assertTrue(new File(parent, "Update.java").exists());
         assertTrue(new File(parent, "UpdateBuilder.java").exists());
-        CompilationTestUtils.assertFilesCount(parent, 8);
+        CompilationTestUtils.assertFilesCount(parent, 7);
 
         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "path");
         CompilationTestUtils.assertFilesCount(parent, 1);
index b5d6d8cb225ca6aa4e90c98e969c08f80ddfafce..b54a221934e550c632e0e51cccf6846afab4ed98 100644 (file)
@@ -39,7 +39,6 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedListAction;
 import org.opendaylight.yangtools.yang.binding.KeyedListNotification;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.binding.OpaqueObject;
 import org.opendaylight.yangtools.yang.binding.Rpc;
 import org.opendaylight.yangtools.yang.binding.RpcInput;
@@ -60,8 +59,6 @@ public final class BindingTypes {
     public static final ConcreteType DATA_CONTAINER = typeForClass(DataContainer.class);
     public static final ConcreteType DATA_OBJECT = typeForClass(DataObject.class);
     public static final ConcreteType DATA_ROOT = typeForClass(DataRoot.class);
-    @Deprecated(since = "10.0.0", forRemoval = true)
-    public static final ConcreteType NOTIFICATION_LISTENER = typeForClass(NotificationListener.class);
     public static final ConcreteType QNAME = typeForClass(QName.class);
     public static final ConcreteType RPC_INPUT = typeForClass(RpcInput.class);
     public static final ConcreteType RPC_OUTPUT = typeForClass(RpcOutput.class);
index 6ac6e289ab418a313510c0ac9ece6d1073a4577e..ea22004eb9aeb4790549a7d9708617314ccf5f2f 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.Key;
 import org.opendaylight.yangtools.yang.binding.KeyAware;
 import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
 public class BindingTypesTest {
     @Test
@@ -37,8 +36,6 @@ public class BindingTypesTest {
         assertEquals("KEY_AWARE", typeForClass(KeyAware.class), BindingTypes.KEY_AWARE);
         assertEquals("KEY", typeForClass(Key.class), BindingTypes.KEY);
         assertEquals("INSTANCE_IDENTIFIER", typeForClass(InstanceIdentifier.class), BindingTypes.INSTANCE_IDENTIFIER);
-        assertEquals("NOTIFICATION_LISTENER", typeForClass(NotificationListener.class),
-            BindingTypes.NOTIFICATION_LISTENER);
     }
 
     @Test
diff --git a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/NotificationListener.java b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/NotificationListener.java
deleted file mode 100644 (file)
index acd7ead..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.binding;
-
-import java.util.EventListener;
-
-/**
- * Marker interface for generated notification listener interfaces. This interface exists solely as support for
- * generated code. Users should never implement this interface directly, but rather implement one of the sub-interfaces
- * generated from a YANG model.
- *
- * <p>
- * The subclasses of this interface have callbacks for events, which are derived from {@link Notification} class in form
- * <pre>
- *   void on{NotificationType}(NotificationType notification)
- * </pre>
- *
- * <p>
- * E.g. if we have notification SessionUp the callback will have signature:
- * {@code void  onSessionUp(SessionUp notification)}
- */
-@Deprecated(since = "10.0.0", forRemoval = true)
-public interface NotificationListener extends EventListener {
-
-}