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