From c47ff94d8c0fc8bd298e1149825580d7ab7df921 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 19 Oct 2021 13:59:00 +0200 Subject: [PATCH] Narrow Notification.implementedInterface() return type All Notification interfaces should provide their own identity here, make sure there is no confusion about that. Change-Id: I9fb7f82fcee7acd38aa05b38a2721ef62f8a1750 Signed-off-by: Robert Varga --- .../api/NotificationPublishService.java | 6 +++--- .../binding/api/NotificationService.java | 7 ++++--- .../BindingDOMNotificationServiceAdapter.java | 5 +++-- .../SingleBindingDOMNotificationAdapter.java | 4 +++- .../adapter/osgi/OSGiNotificationService.java | 5 +++-- .../api/BindingNormalizedNodeSerializer.java | 6 +++--- .../BindingNormalizedNodeWriterFactory.java | 2 +- .../ForwardingBindingDOMCodecServices.java | 8 ++++---- .../dom/codec/impl/BindingCodecContext.java | 7 ++++--- .../impl/reactor/NotificationGenerator.java | 2 +- .../mdsal/binding/model/ri/BindingTypes.java | 19 ++++++++++++++++--- .../binding/model/ri/BindingTypesTest.java | 14 +++++++++++++- .../yangtools/yang/binding/Notification.java | 6 +++--- 13 files changed, 61 insertions(+), 30 deletions(-) diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationPublishService.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationPublishService.java index d679c18819..69bf606014 100644 --- a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationPublishService.java +++ b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationPublishService.java @@ -50,7 +50,7 @@ public interface NotificationPublishService extends BindingService { * @throws InterruptedException if interrupted while waiting * @throws NullPointerException if the notification is null */ - void putNotification(@NonNull Notification notification) throws InterruptedException; + void putNotification(@NonNull Notification notification) throws InterruptedException; /** * Publishes a notification to subscribed listeners. This initiates the process of sending the @@ -66,7 +66,7 @@ public interface NotificationPublishService extends BindingService { * resource constraints prevent * @throws NullPointerException if the notification is null */ - @NonNull ListenableFuture offerNotification(@NonNull Notification notification); + @NonNull ListenableFuture offerNotification(@NonNull Notification notification); /** * Publishes a notification to subscribed listeners. This initiates the process of sending the @@ -84,6 +84,6 @@ public interface NotificationPublishService extends BindingService { * @throws NullPointerException if the notification or unit is null * @throws IllegalArgumentException if timeout is negative. */ - @NonNull ListenableFuture offerNotification(@NonNull Notification notification, + @NonNull ListenableFuture offerNotification(@NonNull Notification notification, int timeout, @NonNull TimeUnit unit) throws InterruptedException; } diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationService.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationService.java index 6ff74ca341..c2cc18eeab 100644 --- a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationService.java +++ b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/NotificationService.java @@ -13,6 +13,7 @@ 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; @@ -110,7 +111,7 @@ public interface NotificationService extends BindingService { * @return a {@link Registration} instance that should be used to unregister the listener by invoking the * {@link Registration#close()} method when no longer needed */ - @NonNull Registration registerListener(Class type, Listener listener, + & DataObject> @NonNull Registration registerListener(Class type, Listener listener, Executor executor); /** @@ -126,7 +127,7 @@ public interface NotificationService extends BindingService { * @return a {@link Registration} instance that should be used to unregister the listener by invoking the * {@link Registration#close()} method when no longer needed */ - default @NonNull Registration registerListener(final Class type, + default & DataObject> @NonNull Registration registerListener(final Class type, final Listener listener) { return registerListener(type, listener, MoreExecutors.directExecutor()); } @@ -139,7 +140,7 @@ public interface NotificationService extends BindingService { * @param N Notification type */ @FunctionalInterface - interface Listener extends EventListener { + interface Listener & DataObject> extends EventListener { /** * Process a global notification. * diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java index ce26cbca98..63a4f78c0c 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java @@ -21,6 +21,7 @@ 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; @@ -47,8 +48,8 @@ public class BindingDOMNotificationServiceAdapter implements NotificationService } @Override - public Registration registerListener(final Class type, final Listener listener, - final Executor executor) { + public & DataObject> Registration registerListener(final Class type, + final Listener listener, final Executor executor) { final var domListener = new SingleBindingDOMNotificationAdapter<>(adapterContext, type, listener, executor); return domNotifService.registerNotificationListener(domListener, domListener.getSupportedNotifications()); } 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 index 0a7ead1061..9a7d002576 100644 --- 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 @@ -13,10 +13,12 @@ import java.util.Set; import java.util.concurrent.Executor; 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 extends AbstractDOMNotificationListenerAdapter { +final class SingleBindingDOMNotificationAdapter & DataObject> + extends AbstractDOMNotificationListenerAdapter { private final Listener delegate; private final Executor executor; private final Class type; diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/OSGiNotificationService.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/OSGiNotificationService.java index 0513f2efb2..775c3187a4 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/OSGiNotificationService.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/osgi/OSGiNotificationService.java @@ -14,6 +14,7 @@ import org.opendaylight.mdsal.binding.api.NotificationService; import org.opendaylight.mdsal.binding.api.NotificationService.Listener; 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; @@ -37,8 +38,8 @@ public final class OSGiNotificationService extends AbstractAdaptedService Registration registerListener(final Class type, final Listener listener, - final Executor executor) { + public & DataObject> Registration registerListener(final Class type, + final Listener listener, final Executor executor) { return delegate().registerListener(type, listener, executor); } diff --git a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeSerializer.java b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeSerializer.java index 418a3a254a..2d3a0a458d 100644 --- a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeSerializer.java +++ b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeSerializer.java @@ -80,7 +80,7 @@ public interface BindingNormalizedNodeSerializer { * @param data NormalizedNode representing data * @return Binding representation of Notification */ - @Nullable Notification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data); + @Nullable Notification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data); /** * Translates supplied NormalizedNode Notification into Binding data, optionally taking an instant @@ -92,7 +92,7 @@ public interface BindingNormalizedNodeSerializer { * @return Binding representation of Notification */ @Beta - @Nullable Notification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data, + @Nullable Notification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data, @Nullable Instant eventInstant); /** @@ -134,7 +134,7 @@ public interface BindingNormalizedNodeSerializer { * @param data NormalizedNode representing notification data * @return NormalizedNode representation of notification */ - @NonNull ContainerNode toNormalizedNodeNotification(@NonNull Notification data); + @NonNull ContainerNode toNormalizedNodeNotification(@NonNull Notification data); /** * Translates supplied Binding RPC input or output into NormalizedNode data. diff --git a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeWriterFactory.java b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeWriterFactory.java index da15c6be84..917415c702 100644 --- a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeWriterFactory.java +++ b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/BindingNormalizedNodeWriterFactory.java @@ -89,7 +89,7 @@ public interface BindingNormalizedNodeWriterFactory { * @return {@link BindingStreamEventWriter} which will write to supplied * {@link NormalizedNodeStreamWriter}. */ - @NonNull BindingStreamEventWriter newNotificationWriter(@NonNull Class notification, + @NonNull BindingStreamEventWriter newNotificationWriter(@NonNull Class> notification, @NonNull NormalizedNodeStreamWriter domWriter); /** diff --git a/binding/mdsal-binding-dom-codec-spi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/spi/ForwardingBindingDOMCodecServices.java b/binding/mdsal-binding-dom-codec-spi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/spi/ForwardingBindingDOMCodecServices.java index d1a18c27ed..167e65fb0d 100644 --- a/binding/mdsal-binding-dom-codec-spi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/spi/ForwardingBindingDOMCodecServices.java +++ b/binding/mdsal-binding-dom-codec-spi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/spi/ForwardingBindingDOMCodecServices.java @@ -67,7 +67,7 @@ public abstract class ForwardingBindingDOMCodecServices extends ForwardingObject } @Override - public ContainerNode toNormalizedNodeNotification(final Notification data) { + public ContainerNode toNormalizedNodeNotification(final Notification data) { return delegate().toNormalizedNodeNotification(data); } @@ -95,12 +95,12 @@ public abstract class ForwardingBindingDOMCodecServices extends ForwardingObject } @Override - public Notification fromNormalizedNodeNotification(final Absolute path, final ContainerNode data) { + public Notification fromNormalizedNodeNotification(final Absolute path, final ContainerNode data) { return delegate().fromNormalizedNodeNotification(path, data); } @Override - public Notification fromNormalizedNodeNotification(final Absolute path, final ContainerNode data, + public Notification fromNormalizedNodeNotification(final Absolute path, final ContainerNode data, final Instant eventInstant) { return delegate().fromNormalizedNodeNotification(path, data, eventInstant); } @@ -135,7 +135,7 @@ public abstract class ForwardingBindingDOMCodecServices extends ForwardingObject } @Override - public BindingStreamEventWriter newNotificationWriter(final Class notification, + public BindingStreamEventWriter newNotificationWriter(final Class> notification, final NormalizedNodeStreamWriter streamWriter) { return delegate().newNotificationWriter(notification, streamWriter); } diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java index 66f3e6d784..08bba8de63 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java @@ -217,7 +217,7 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri } @Override - public BindingStreamEventWriter newNotificationWriter(final Class notification, + public BindingStreamEventWriter newNotificationWriter(final Class> notification, final NormalizedNodeStreamWriter domWriter) { return root.getNotification(notification).createWriter(domWriter); } @@ -572,10 +572,11 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri @Override @SuppressFBWarnings("BC_UNCONFIRMED_CAST") - public ContainerNode toNormalizedNodeNotification(@NonNull final Notification data) { + public ContainerNode toNormalizedNodeNotification(@NonNull final Notification data) { // FIXME: Should the cast to DataObject be necessary? return serializeDataObject((DataObject) data, - (ctx, iface, domWriter) -> ctx.newNotificationWriter(iface.asSubclass(Notification.class), domWriter)); + (ctx, iface, domWriter) -> ctx.newNotificationWriter( + (Class>) iface.asSubclass(Notification.class), domWriter)); } @Override diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationGenerator.java index 39d0a89c85..f59965a8cf 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/NotificationGenerator.java @@ -58,7 +58,7 @@ final class NotificationGenerator extends AbstractCompositeGenerator parent = getParent(); if (parent instanceof ModuleGenerator) { - return BindingTypes.NOTIFICATION; + return BindingTypes.notification(builder); } final Type parentType = Type.of(parent.typeName()); diff --git a/binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/BindingTypes.java b/binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/BindingTypes.java index e1a3c5977c..c4beb7b174 100644 --- a/binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/BindingTypes.java +++ b/binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/BindingTypes.java @@ -51,7 +51,6 @@ public final class BindingTypes { public static final ConcreteType DATA_OBJECT = typeForClass(DataObject.class); public static final ConcreteType TYPE_OBJECT = typeForClass(TypeObject.class); public static final ConcreteType DATA_ROOT = typeForClass(DataRoot.class); - public static final ConcreteType NOTIFICATION = typeForClass(Notification.class); 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); @@ -79,6 +78,7 @@ public final class BindingTypes { private static final ConcreteType INSTANCE_NOTIFICATION = typeForClass(InstanceNotification.class); private static final ConcreteType KEYED_LIST_ACTION = typeForClass(KeyedListAction.class); private static final ConcreteType KEYED_LIST_NOTIFICATION = typeForClass(KeyedListNotification.class); + private static final ConcreteType NOTIFICATION = typeForClass(Notification.class); private static final ConcreteType OPAQUE_OBJECT = typeForClass(OpaqueObject.class); private static final ConcreteType RPC_RESULT = typeForClass(RpcResult.class); @@ -114,11 +114,23 @@ public final class BindingTypes { return parameterizedTypeFor(KEYED_LIST_ACTION, keyType, parent, input, output); } + /** + * Type specializing {@link Notification} for a particular type. + * + * @param concreteType The concrete type of this notification + * @return A parameterized type corresponding to {@code Notification} + * @throws NullPointerException if any argument is is null + */ + public static ParameterizedType notification(final Type concreteType) { + return parameterizedTypeFor(NOTIFICATION, concreteType); + } + /** * Type specializing {@link InstanceNotification} for a particular type. * + * @param concreteType The concrete type of this notification * @param parent Type of parent defining the notification - * @return A parameterized type corresponding to {@code InstanceNotification} + * @return A parameterized type corresponding to {@code InstanceNotification} * @throws NullPointerException if {@code parent} is is null */ public static ParameterizedType instanceNotification(final Type concreteType, final Type parent) { @@ -128,9 +140,10 @@ public final class BindingTypes { /** * Type specializing {@link InstanceNotification} for a particular type. * + * @param concreteType The concrete type of this notification * @param parent Type of parent defining the notification * @param keyType Type of parent's key - * @return A parameterized type corresponding to {@code KeyedInstanceNotification} + * @return A parameterized type corresponding to {@code KeyedInstanceNotification} * @throws NullPointerException if any argument is is null */ public static ParameterizedType keyedListNotification(final Type concreteType, final Type parent, diff --git a/binding/mdsal-binding-model-ri/src/test/java/org/opendaylight/mdsal/binding/model/ri/BindingTypesTest.java b/binding/mdsal-binding-model-ri/src/test/java/org/opendaylight/mdsal/binding/model/ri/BindingTypesTest.java index 1588d001ce..761861adbc 100644 --- a/binding/mdsal-binding-model-ri/src/test/java/org/opendaylight/mdsal/binding/model/ri/BindingTypesTest.java +++ b/binding/mdsal-binding-model-ri/src/test/java/org/opendaylight/mdsal/binding/model/ri/BindingTypesTest.java @@ -7,6 +7,7 @@ */ package org.opendaylight.mdsal.binding.model.ri; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; @@ -37,7 +38,6 @@ public class BindingTypesTest { assertEquals("IDENTIFIABLE", typeForClass(Identifiable.class), BindingTypes.IDENTIFIABLE); assertEquals("IDENTIFIER", typeForClass(Identifier.class), BindingTypes.IDENTIFIER); assertEquals("INSTANCE_IDENTIFIER", typeForClass(InstanceIdentifier.class), BindingTypes.INSTANCE_IDENTIFIER); - assertEquals("NOTIFICATION", typeForClass(Notification.class), BindingTypes.NOTIFICATION); assertEquals("NOTIFICATION_LISTENER", typeForClass(NotificationListener.class), BindingTypes.NOTIFICATION_LISTENER); assertEquals("RPC_SERVICE", typeForClass(RpcService.class), BindingTypes.RPC_SERVICE); @@ -74,4 +74,16 @@ public class BindingTypesTest { final ParameterizedType augmentationType = BindingTypes.augmentation(Types.objectType()); assertEquals("Augmentation", augmentationType.getName()); } + + @Test + public void testNotificationNull() { + assertThrows(NullPointerException.class, () -> BindingTypes.notification(null)); + } + + @Test + public void testNotification() { + final ParameterizedType notificationType = BindingTypes.notification(Types.objectType()); + assertEquals(Types.typeForClass(Notification.class), notificationType.getRawType()); + assertArrayEquals(new Object[] { Types.objectType() }, notificationType.getActualTypeArguments()); + } } \ No newline at end of file diff --git a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/Notification.java b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/Notification.java index 2bb40f371e..6acaa44d20 100644 --- a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/Notification.java +++ b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/Notification.java @@ -13,7 +13,7 @@ package org.opendaylight.yangtools.yang.binding; * interface. In case they do, {@link EventInstantAware#eventInstant()} returns the time when this notification was * generated. */ -// FIXME: 6.0.0: narrow implementedInterface() -public interface Notification extends BaseNotification { - +public interface Notification & DataObject> extends BaseNotification { + @Override + Class implementedInterface(); } -- 2.36.6