Change OpenEXI version to -SNAPSHOT
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / store / impl / DOMImmutableDataChangeEvent.java
1 package org.opendaylight.controller.md.sal.dom.store.impl;
2
3 import java.util.Map;
4 import java.util.Set;
5
6 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
7 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
8 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
9 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
10 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
11
12 import com.google.common.base.Preconditions;
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.ImmutableSet;
15
16 public final class DOMImmutableDataChangeEvent implements
17         AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> {
18
19
20     private static final RemoveEventFactory REMOVE_EVENT_FACTORY = new RemoveEventFactory();
21     private static final CreateEventFactory CREATE_EVENT_FACTORY = new CreateEventFactory();
22
23     private final NormalizedNode<?, ?> original;
24     private final NormalizedNode<?, ?> updated;
25     private final Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> originalData;
26     private final Map<InstanceIdentifier, NormalizedNode<?, ?>> createdData;
27     private final Map<InstanceIdentifier, NormalizedNode<?, ?>> updatedData;
28     private final Set<InstanceIdentifier> removedPaths;
29     private final DataChangeScope scope;
30
31
32
33     private DOMImmutableDataChangeEvent(final Builder change) {
34         original = change.before;
35         updated = change.after;
36         originalData = change.original.build();
37         createdData = change.created.build();
38         updatedData = change.updated.build();
39         removedPaths = change.removed.build();
40         scope = change.scope;
41     }
42
43     public static final Builder builder(final DataChangeScope scope) {
44         return new Builder(scope);
45     }
46
47     protected DataChangeScope getScope() {
48         return scope;
49     }
50
51     @Override
52     public NormalizedNode<?, ?> getOriginalSubtree() {
53         return original;
54     }
55
56     @Override
57     public NormalizedNode<?, ?> getUpdatedSubtree() {
58         return updated;
59     }
60
61     @Override
62     public Map<InstanceIdentifier, ? extends NormalizedNode<?, ?>> getOriginalData() {
63         return originalData;
64     }
65
66     @Override
67     public Map<InstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
68         return createdData;
69     }
70
71     @Override
72     public Map<InstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
73         return updatedData;
74     }
75
76     @Override
77     public Set<InstanceIdentifier> getRemovedPaths() {
78         return removedPaths;
79     }
80
81     @Override
82     public String toString() {
83         return "DOMImmutableDataChangeEvent [created=" + createdData.keySet() + ", updated=" + updatedData.keySet()
84                 + ", removed=" + removedPaths + "]";
85     }
86
87     /**
88      * Simple event factory which creates event based on path and data
89      *
90      *
91      */
92     public interface SimpleEventFactory {
93         DOMImmutableDataChangeEvent create(InstanceIdentifier path, NormalizedNode<PathArgument,?> data);
94     }
95
96     /**
97      * Event factory which takes after state and creates event for it.
98      *
99      * Factory for events based on path and after state.
100      * After state is set as {@link #getUpdatedSubtree()} and is path,
101      * state mapping is also present in {@link #getUpdatedData()}.
102      *
103      * @return
104      */
105     public static final SimpleEventFactory getCreateEventFactory() {
106         return CREATE_EVENT_FACTORY;
107     }
108
109     /**
110      * Event factory which takes before state and creates event for it.
111      *
112      * Factory for events based on path and after state.
113      * After state is set as {@link #getOriginalSubtree()} and is path,
114      * state mapping is also present in {@link #getOriginalSubtree()}.
115      *
116      * Path is present in {@link #getRemovedPaths()}.
117      * @return
118      */
119     public static final SimpleEventFactory getRemoveEventFactory() {
120         return REMOVE_EVENT_FACTORY;
121     }
122     public static class Builder {
123
124         public DataChangeScope scope;
125         private NormalizedNode<?, ?> after;
126         private NormalizedNode<?, ?> before;
127
128         private final ImmutableMap.Builder<InstanceIdentifier, NormalizedNode<?, ?>> original = ImmutableMap.builder();
129         private final ImmutableMap.Builder<InstanceIdentifier, NormalizedNode<?, ?>> created = ImmutableMap.builder();
130         private final ImmutableMap.Builder<InstanceIdentifier, NormalizedNode<?, ?>> updated = ImmutableMap.builder();
131         private final ImmutableSet.Builder<InstanceIdentifier> removed = ImmutableSet.builder();
132
133         private Builder(final DataChangeScope scope) {
134             Preconditions.checkNotNull(scope, "Data change scope should not be null.");
135             this.scope = scope;
136         }
137
138         public Builder setAfter(final NormalizedNode<?, ?> node) {
139             after = node;
140             return this;
141         }
142
143         public DOMImmutableDataChangeEvent build() {
144
145             return new DOMImmutableDataChangeEvent(this);
146         }
147
148         public void merge(final DOMImmutableDataChangeEvent nestedChanges) {
149
150             original.putAll(nestedChanges.getOriginalData());
151             created.putAll(nestedChanges.getCreatedData());
152             updated.putAll(nestedChanges.getUpdatedData());
153             removed.addAll(nestedChanges.getRemovedPaths());
154
155         }
156
157         public Builder setBefore(final NormalizedNode<?, ?> node) {
158             this.before = node;
159             return this;
160         }
161
162         public Builder addCreated(final InstanceIdentifier path, final NormalizedNode<?, ?> node) {
163             created.put(path, node);
164             return this;
165         }
166
167         public Builder addRemoved(final InstanceIdentifier path, final NormalizedNode<?, ?> node) {
168             original.put(path, node);
169             removed.add(path);
170             return this;
171         }
172
173         public Builder addUpdated(final InstanceIdentifier path, final NormalizedNode<?, ?> before,
174                 final NormalizedNode<?, ?> after) {
175             original.put(path, before);
176             updated.put(path, after);
177             return this;
178         }
179     }
180
181     private static final class RemoveEventFactory implements SimpleEventFactory {
182
183         @Override
184         public DOMImmutableDataChangeEvent create(final InstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
185             return builder(DataChangeScope.BASE) //
186                     .setBefore(data) //
187                     .addRemoved(path, data) //
188                     .build();
189         }
190
191     }
192
193     private static final class CreateEventFactory implements SimpleEventFactory {
194
195         @Override
196         public DOMImmutableDataChangeEvent create(final InstanceIdentifier path, final NormalizedNode<PathArgument, ?> data) {
197             return builder(DataChangeScope.BASE) //
198                     .setAfter(data) //
199                     .addCreated(path, data) //
200                     .build();
201         }
202     }
203
204 }