Remove superfluous @NonNull
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / LazySerializedDOMNotification.java
index e3dfbd6dbc885524c359742d773968824f071da5..6f56169aba3942b60eedbe0662a63e2afa276410 100644 (file)
@@ -7,55 +7,83 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import java.time.Instant;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+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.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 /**
  * Lazy serialized implementation of DOM Notification.
  *
  * <p>
- * This implementation performs serialization of data, only if receiver
- * of notification actually accessed data from notification.
- *
+ * This implementation performs serialization of data, only if receiver of notification actually accessed data from
+ * notification.
  */
-public final class LazySerializedDOMNotification implements DOMNotification {
+final class LazySerializedDOMNotification implements DOMNotification, DOMEvent {
+    private static final LoadingCache<Class<?>, Absolute> PATHS = CacheBuilder.newBuilder().weakKeys()
+        .build(new CacheLoader<Class<?>, Absolute>() {
+            @Override
+            public Absolute load(final Class<?> key) {
+                // TODO: for nested (YANG 1.1) notifications we will need the SchemaNodeIdentifier where the
+                //       notification is being invoked and use that instead of ROOT. How Binding users will refer to
+                //       it is TBD (but probably InstanceIdentifier, which means we will need to do some lifting to
+                //       find the SchemaNodeIdentifier), as we will need to deal with the same multiplicies we need
+                //       for data due to grouping-based reuse.
+                return Absolute.of(BindingReflections.findQName(key)).intern();
+            }
+        });
 
-    private final BindingNormalizedNodeSerializer codec;
-    private final Notification data;
-    private final SchemaPath type;
+    private final @NonNull BindingNormalizedNodeSerializer codec;
+    private final @NonNull Notification<?> data;
+    private final @NonNull Absolute type;
+    private final @NonNull Instant eventInstant;
 
-    private ContainerNode domBody;
+    private volatile ContainerNode domBody;
 
-    private LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec,
-            final Notification data, final SchemaPath type) {
-        this.codec = codec;
-        this.data = data;
-        this.type = type;
+    LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec, final Notification<?> data,
+            final Absolute type, final Instant eventInstant) {
+        this.codec = requireNonNull(codec);
+        this.data = requireNonNull(data);
+        this.type = requireNonNull(type);
+        this.eventInstant = requireNonNull(eventInstant);
     }
 
-    static DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification data) {
-        final SchemaPath type = SchemaPath.create(true, BindingReflections.findQName(data.getImplementedInterface()));
-        return new LazySerializedDOMNotification(codec, data, type);
+    static @NonNull DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification<?> data,
+            final Instant eventInstant) {
+        final Absolute type = PATHS.getUnchecked(data.implementedInterface());
+        return new LazySerializedDOMNotification(codec, data, type, eventInstant);
     }
 
     @Override
-    public SchemaPath getType() {
+    public Absolute getType() {
         return type;
     }
 
     @Override
     public ContainerNode getBody() {
-        if (domBody == null) {
-            domBody = codec.toNormalizedNodeNotification(data);
+        ContainerNode local = domBody;
+        if (local == null) {
+            domBody = local = codec.toNormalizedNodeNotification(data);
         }
-        return domBody;
+        return local;
+    }
+
+    @Override
+    public Instant getEventInstant() {
+        return eventInstant;
     }
 
-    public Notification getBindingData() {
+    @NonNull Notification<?> getBindingData() {
         return data;
     }
 }