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