blob: 4a9809c18106203dd8528e824e7d803bce5bbb96 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.store.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Objects;
import java.util.function.Function;
import org.onlab.util.ByteArraySizeHashPrinter;
import com.google.common.base.MoreObjects;
import org.onosproject.store.service.DocumentPath;
/**
* DocumentTree node update operation.
*
* @param <V> map value type
*/
public final class NodeUpdate<V> {
/**
* Type of database update operation.
*/
public enum Type {
// FIXME revisit these, mismatch in description and actual implementation
// Also, type of update operations probably insufficient.
/**
* Creates an entry if the current version matches specified version.
*/
CREATE_NODE,
/**
* Updates an entry if the current version matches specified version.
*/
UPDATE_NODE,
/**
* Deletes an entry if the current version matches specified version.
*/
DELETE_NODE
}
private Type type;
private DocumentPath path;
private V value;
private long version = -1;
/**
* Returns the type of update operation.
* @return type of update.
*/
public Type type() {
return type;
}
/**
* Returns the item path being updated.
* @return item path
*/
public DocumentPath path() {
return path;
}
/**
* Returns the new value.
* @return item's target value.
*/
public V value() {
return value;
}
/**
* Returns the expected current version in the database for the key.
* @return expected version.
*/
public long version() {
return version;
}
/**
* Transforms this instance into an instance of different parameterized types.
*
* @param valueMapper transcoder to value type
* @return new instance
* @param <T> value type of returned instance
*/
public <T> NodeUpdate<T> map(Function<V, T> valueMapper) {
return NodeUpdate.<T>newBuilder()
.withType(type)
//.withKey(keyMapper.apply(key))
.withValue(value == null ? null : valueMapper.apply(value))
.withVersion(version)
.build();
}
@Override
public int hashCode() {
return Objects.hash(type, path, value, version);
}
@Override
public boolean equals(Object object) {
if (object instanceof NodeUpdate) {
NodeUpdate that = (NodeUpdate) object;
return this.type == that.type
&& Objects.equals(this.path, that.path)
&& Objects.equals(this.value, that.value)
&& Objects.equals(this.version, that.version);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("type", type)
.add("path", path)
.add("value", value instanceof byte[] ?
new ByteArraySizeHashPrinter((byte[]) value) : value)
.add("version", version)
.toString();
}
/**
* Creates a new builder instance.
*
* @param <V> value type
* @return builder.
*/
public static <V> Builder<V> newBuilder() {
return new Builder<>();
}
/**
* NodeUpdate builder.
*
* @param <V> value type
*/
public static final class Builder<V> {
private NodeUpdate<V> update = new NodeUpdate<>();
public NodeUpdate<V> build() {
validateInputs();
return update;
}
public Builder<V> withType(Type type) {
update.type = checkNotNull(type, "type cannot be null");
return this;
}
public Builder<V> withPath(DocumentPath key) {
update.path = checkNotNull(key, "key cannot be null");
return this;
}
public Builder<V> withValue(V value) {
update.value = value;
return this;
}
public Builder<V> withVersion(long version) {
update.version = version;
return this;
}
private void validateInputs() {
checkNotNull(update.type, "type must be specified");
switch (update.type) {
case CREATE_NODE:
checkNotNull(update.path, "key must be specified");
checkNotNull(update.value, "value must be specified.");
break;
case UPDATE_NODE:
checkNotNull(update.path, "key must be specified");
checkNotNull(update.value, "value must be specified.");
checkState(update.version >= 0, "version must be specified");
break;
case DELETE_NODE:
checkNotNull(update.path, "key must be specified");
checkState(update.version >= 0, "version must be specified");
break;
default:
throw new IllegalStateException("Unknown operation type");
}
}
}
}