blob: 4a9809c18106203dd8528e824e7d803bce5bbb96 [file] [log] [blame]
Sithara Punnassery61a80252017-08-07 11:16:08 -07001/*
2 * Copyright 2017-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.store.primitives;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20import static com.google.common.base.Preconditions.checkState;
21
22import java.util.Objects;
23import java.util.function.Function;
24
25import org.onlab.util.ByteArraySizeHashPrinter;
26
27import com.google.common.base.MoreObjects;
28import org.onosproject.store.service.DocumentPath;
29
30/**
Yuta HIGUCHI47d96092017-11-17 14:05:26 -080031 * DocumentTree node update operation.
Sithara Punnassery61a80252017-08-07 11:16:08 -070032 *
33 * @param <V> map value type
34 */
35public final class NodeUpdate<V> {
36
37 /**
38 * Type of database update operation.
39 */
40 public enum Type {
Yuta HIGUCHI47d96092017-11-17 14:05:26 -080041 // FIXME revisit these, mismatch in description and actual implementation
42 // Also, type of update operations probably insufficient.
Sithara Punnassery61a80252017-08-07 11:16:08 -070043 /**
44 * Creates an entry if the current version matches specified version.
45 */
46 CREATE_NODE,
47 /**
48 * Updates an entry if the current version matches specified version.
49 */
50 UPDATE_NODE,
51 /**
52 * Deletes an entry if the current version matches specified version.
53 */
54 DELETE_NODE
55 }
56
57 private Type type;
58 private DocumentPath path;
59 private V value;
60 private long version = -1;
61
62 /**
63 * Returns the type of update operation.
64 * @return type of update.
65 */
66 public Type type() {
67 return type;
68 }
69
70 /**
71 * Returns the item path being updated.
72 * @return item path
73 */
74 public DocumentPath path() {
75 return path;
76 }
77
78 /**
79 * Returns the new value.
80 * @return item's target value.
81 */
82 public V value() {
83 return value;
84 }
85
86 /**
87 * Returns the expected current version in the database for the key.
88 * @return expected version.
89 */
90 public long version() {
91 return version;
92 }
93
94 /**
Jon Hall7d77fe12018-04-24 18:03:10 -070095 * Transforms this instance into an instance of different parameterized types.
Sithara Punnassery61a80252017-08-07 11:16:08 -070096 *
97 * @param valueMapper transcoder to value type
98 * @return new instance
99 * @param <T> value type of returned instance
100 */
101 public <T> NodeUpdate<T> map(Function<V, T> valueMapper) {
102 return NodeUpdate.<T>newBuilder()
103 .withType(type)
104 //.withKey(keyMapper.apply(key))
105 .withValue(value == null ? null : valueMapper.apply(value))
106 .withVersion(version)
107 .build();
108 }
109
110 @Override
111 public int hashCode() {
112 return Objects.hash(type, path, value, version);
113 }
114
115 @Override
116 public boolean equals(Object object) {
117 if (object instanceof NodeUpdate) {
118 NodeUpdate that = (NodeUpdate) object;
119 return this.type == that.type
120 && Objects.equals(this.path, that.path)
121 && Objects.equals(this.value, that.value)
122 && Objects.equals(this.version, that.version);
123 }
124 return false;
125 }
126
127 @Override
128 public String toString() {
129 return MoreObjects.toStringHelper(this)
130 .add("type", type)
131 .add("path", path)
132 .add("value", value instanceof byte[] ?
133 new ByteArraySizeHashPrinter((byte[]) value) : value)
134 .add("version", version)
135 .toString();
136 }
137
138 /**
139 * Creates a new builder instance.
140 *
141 * @param <V> value type
142 * @return builder.
143 */
144 public static <V> Builder<V> newBuilder() {
145 return new Builder<>();
146 }
147
148 /**
149 * NodeUpdate builder.
150 *
151 * @param <V> value type
152 */
153 public static final class Builder<V> {
154
155 private NodeUpdate<V> update = new NodeUpdate<>();
156
157 public NodeUpdate<V> build() {
158 validateInputs();
159 return update;
160 }
161
162 public Builder<V> withType(Type type) {
163 update.type = checkNotNull(type, "type cannot be null");
164 return this;
165 }
166
167 public Builder<V> withPath(DocumentPath key) {
168 update.path = checkNotNull(key, "key cannot be null");
169 return this;
170 }
171
172 public Builder<V> withValue(V value) {
173 update.value = value;
174 return this;
175 }
176
177 public Builder<V> withVersion(long version) {
178 update.version = version;
179 return this;
180 }
181
182 private void validateInputs() {
183 checkNotNull(update.type, "type must be specified");
184 switch (update.type) {
185 case CREATE_NODE:
186 checkNotNull(update.path, "key must be specified");
187 checkNotNull(update.value, "value must be specified.");
188 break;
189 case UPDATE_NODE:
190 checkNotNull(update.path, "key must be specified");
191 checkNotNull(update.value, "value must be specified.");
192 checkState(update.version >= 0, "version must be specified");
193 break;
194 case DELETE_NODE:
195 checkNotNull(update.path, "key must be specified");
196 checkState(update.version >= 0, "version must be specified");
197 break;
198 default:
199 throw new IllegalStateException("Unknown operation type");
200 }
201
202 }
203 }
204}