Remove superfluous @NonNull
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / LazySerializedDOMNotification.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.dom.adapter;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.cache.CacheBuilder;
13 import com.google.common.cache.CacheLoader;
14 import com.google.common.cache.LoadingCache;
15 import java.time.Instant;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
18 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
19 import org.opendaylight.mdsal.dom.api.DOMEvent;
20 import org.opendaylight.mdsal.dom.api.DOMNotification;
21 import org.opendaylight.yangtools.yang.binding.Notification;
22 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
23 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
24
25 /**
26  * Lazy serialized implementation of DOM Notification.
27  *
28  * <p>
29  * This implementation performs serialization of data, only if receiver of notification actually accessed data from
30  * notification.
31  */
32 final class LazySerializedDOMNotification implements DOMNotification, DOMEvent {
33     private static final LoadingCache<Class<?>, Absolute> PATHS = CacheBuilder.newBuilder().weakKeys()
34         .build(new CacheLoader<Class<?>, Absolute>() {
35             @Override
36             public Absolute load(final Class<?> key) {
37                 // TODO: for nested (YANG 1.1) notifications we will need the SchemaNodeIdentifier where the
38                 //       notification is being invoked and use that instead of ROOT. How Binding users will refer to
39                 //       it is TBD (but probably InstanceIdentifier, which means we will need to do some lifting to
40                 //       find the SchemaNodeIdentifier), as we will need to deal with the same multiplicies we need
41                 //       for data due to grouping-based reuse.
42                 return Absolute.of(BindingReflections.findQName(key)).intern();
43             }
44         });
45
46     private final @NonNull BindingNormalizedNodeSerializer codec;
47     private final @NonNull Notification<?> data;
48     private final @NonNull Absolute type;
49     private final @NonNull Instant eventInstant;
50
51     private volatile ContainerNode domBody;
52
53     LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec, final Notification<?> data,
54             final Absolute type, final Instant eventInstant) {
55         this.codec = requireNonNull(codec);
56         this.data = requireNonNull(data);
57         this.type = requireNonNull(type);
58         this.eventInstant = requireNonNull(eventInstant);
59     }
60
61     static @NonNull DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification<?> data,
62             final Instant eventInstant) {
63         final Absolute type = PATHS.getUnchecked(data.implementedInterface());
64         return new LazySerializedDOMNotification(codec, data, type, eventInstant);
65     }
66
67     @Override
68     public Absolute getType() {
69         return type;
70     }
71
72     @Override
73     public ContainerNode getBody() {
74         ContainerNode local = domBody;
75         if (local == null) {
76             domBody = local = codec.toNormalizedNodeNotification(data);
77         }
78         return local;
79     }
80
81     @Override
82     public Instant getEventInstant() {
83         return eventInstant;
84     }
85
86     @NonNull Notification<?> getBindingData() {
87         return data;
88     }
89 }