Madan Jampani
Committed by Gerrit Code Review

Added Change utility class for representing change events + Moved Match class to org.onlab.util

Change-Id: I08e8cd8dd92983bd2764e83016b1abc0bf29388f
/*
* Copyright 2016 Open Networking Laboratory
*
* 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.event;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
/**
* Generic representation of an update.
*
* @param <T> type of value that was updated
*/
public class Change<T> {
private final T oldValue;
private final T newValue;
public Change(T oldValue, T newValue) {
this.oldValue = oldValue;
this.newValue = newValue;
}
/**
* Returns previous value.
* @return previous value.
*/
public T oldValue() {
return oldValue;
}
/**
* Returns new or current value.
* @return new value.
*/
public T newValue() {
return newValue;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof Change)) {
return false;
}
Change<T> that = (Change<T>) other;
return Objects.equal(this.oldValue, that.oldValue) &&
Objects.equal(this.newValue, that.newValue);
}
@Override
public int hashCode() {
return Objects.hashCode(oldValue, newValue);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("oldValue", oldValue)
.add("newValue", newValue)
.toString();
}
}
package org.onosproject.event;
import org.junit.Test;
import com.google.common.testing.EqualsTester;
import static org.junit.Assert.*;
/**
* Unit tests for {@link Change}.
*/
public class ChangeTest {
@Test
public void getters() {
Change<String> change = new Change<>("a", "b");
assertEquals("a", change.oldValue());
assertEquals("b", change.newValue());
}
@Test
public void equality() {
new EqualsTester()
.addEqualityGroup(new Change<>("foo", "bar"),
new Change<>("foo", "bar"))
.addEqualityGroup(new Change<>("bar", "car"))
.testEquals();
}
}
......@@ -16,6 +16,7 @@
package org.onosproject.store.consistent.impl;
import org.onlab.util.Match;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;
......
......@@ -19,6 +19,7 @@ package org.onosproject.store.consistent.impl;
import java.nio.ByteBuffer;
import org.onlab.util.KryoNamespace;
import org.onlab.util.Match;
import org.onosproject.cluster.NodeId;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.serializers.KryoSerializer;
......
......@@ -20,6 +20,8 @@ import net.kuujo.copycat.state.Command;
import net.kuujo.copycat.state.Initializer;
import net.kuujo.copycat.state.Query;
import net.kuujo.copycat.state.StateContext;
import org.onlab.util.Match;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;
......
......@@ -22,6 +22,7 @@ import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps;
import org.onlab.util.HexString;
import org.onlab.util.Match;
import org.onlab.util.SharedExecutors;
import org.onlab.util.Tools;
import org.onosproject.core.ApplicationId;
......
......@@ -17,12 +17,15 @@
package org.onosproject.store.consistent.impl;
import com.google.common.collect.Sets;
import net.kuujo.copycat.resource.internal.AbstractResource;
import net.kuujo.copycat.resource.internal.ResourceManager;
import net.kuujo.copycat.state.StateMachine;
import net.kuujo.copycat.state.internal.DefaultStateMachine;
import net.kuujo.copycat.util.concurrent.Futures;
import net.kuujo.copycat.util.function.TriConsumer;
import org.onlab.util.Match;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;
......
......@@ -21,8 +21,11 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.kuujo.copycat.state.Initializer;
import net.kuujo.copycat.state.StateContext;
import org.onlab.util.Match;
import org.onosproject.store.service.DatabaseUpdate;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;
......
......@@ -20,9 +20,12 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.kuujo.copycat.Task;
import net.kuujo.copycat.cluster.Cluster;
import net.kuujo.copycat.resource.ResourceState;
import org.onlab.util.Match;
import org.onosproject.store.service.DatabaseUpdate;
import org.onosproject.store.service.Transaction;
import org.onosproject.store.service.Versioned;
......
......@@ -32,6 +32,7 @@ import java.util.function.Consumer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.util.Match;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.store.service.Serializer;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.store.consistent.impl;
package org.onlab.util;
import static com.google.common.base.MoreObjects.toStringHelper;
......@@ -28,16 +28,21 @@ import java.util.function.Function;
*/
public final class Match<T> {
public static final Match ANY = new Match<>();
public static final Match NULL = new Match<>(null, false);
public static final Match NOT_NULL = new Match<>(null, true);
private final boolean matchAny;
private final T value;
private final boolean negation;
/**
* Returns a Match that matches any value.
* Returns a Match that matches any value including null.
* @param <T> match type
* @return new instance
*/
public static <T> Match<T> any() {
return new Match<>();
return ANY;
}
/**
......@@ -46,27 +51,48 @@ public final class Match<T> {
* @return new instance
*/
public static <T> Match<T> ifNull() {
return ifValue(null);
return NULL;
}
/**
* Returns a Match that matches all non-null values.
* @param <T> match type
* @return new instance
*/
public static <T> Match<T> ifNotNull() {
return NOT_NULL;
}
/**
* Returns a Match that matches only specified value.
* Returns a Match that only matches the specified value.
* @param value value to match
* @param <T> match type
* @return new instance
*/
public static <T> Match<T> ifValue(T value) {
return new Match<>(value);
return new Match<>(value, false);
}
/**
* Returns a Match that matches any value except the specified value.
* @param value value to not match
* @param <T> match type
* @return new instance
*/
public static <T> Match<T> ifNotValue(T value) {
return new Match<>(value, true);
}
private Match() {
matchAny = true;
negation = false;
value = null;
}
private Match(T value) {
private Match(T value, boolean negation) {
matchAny = false;
this.value = value;
this.negation = negation;
}
/**
......@@ -79,9 +105,9 @@ public final class Match<T> {
if (matchAny) {
return any();
} else if (value == null) {
return ifNull();
return negation ? ifNotNull() : ifNull();
} else {
return ifValue(mapper.apply(value));
return negation ? ifNotValue(mapper.apply(value)) : ifValue(mapper.apply(value));
}
}
......@@ -94,21 +120,21 @@ public final class Match<T> {
if (matchAny) {
return true;
} else if (other == null) {
return value == null;
return negation ? value != null : value == null;
} else {
if (value instanceof byte[]) {
return Arrays.equals((byte[]) value, (byte[]) other);
boolean equal = Arrays.equals((byte[]) value, (byte[]) other);
return negation ? !equal : equal;
}
return Objects.equals(value, other);
return negation ? !Objects.equals(value, other) : Objects.equals(value, other);
}
}
@Override
public int hashCode() {
return Objects.hash(matchAny, value);
return Objects.hash(matchAny, value, negation);
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object other) {
if (!(other instanceof Match)) {
......@@ -116,13 +142,15 @@ public final class Match<T> {
}
Match<T> that = (Match<T>) other;
return Objects.equals(this.matchAny, that.matchAny) &&
Objects.equals(this.value, that.value);
Objects.equals(this.value, that.value) &&
Objects.equals(this.negation, that.negation);
}
@Override
public String toString() {
return toStringHelper(this)
.add("matchAny", matchAny)
.add("negation", negation)
.add("value", value)
.toString();
}
......
......@@ -54,6 +54,7 @@ import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.primitives.UnsignedLongs;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
......@@ -210,6 +211,20 @@ public abstract class Tools {
}
/**
* Returns the UTF-8 encoded byte[] representation of a String.
*/
public static byte[] getBytesUtf8(String input) {
return input.getBytes(Charsets.UTF_8);
}
/**
* Returns the String representation of UTF-8 encoded byte[].
*/
public static String toStringUtf8(byte[] input) {
return new String(input, Charsets.UTF_8);
}
/**
* Returns a copy of the input byte array.
*
* @param original input
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.store.consistent.impl;
package org.onlab.util;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
......