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