2 * Copyright 2016-present Open Networking Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package io.atomix.utils.misc;
18 import java.util.Arrays;
19 import java.util.Objects;
20 import java.util.function.Function;
22 import static com.google.common.base.MoreObjects.toStringHelper;
25 * Utility class for checking matching values.
27 * @param <T> type of value
29 public final class Match<T> {
31 public static final Match ANY = new Match<>();
32 public static final Match NULL = new Match<>(null, false);
33 public static final Match NOT_NULL = new Match<>(null, true);
35 private final boolean matchAny;
36 private final T value;
37 private final boolean negation;
40 * Returns a Match that matches any value including null.
42 * @param <T> match type
43 * @return new instance
45 public static <T> Match<T> any() {
50 * Returns a Match that matches null values.
52 * @param <T> match type
53 * @return new instance
55 public static <T> Match<T> ifNull() {
60 * Returns a Match that matches all non-null values.
62 * @param <T> match type
63 * @return new instance
65 public static <T> Match<T> ifNotNull() {
70 * Returns a Match that only matches the specified value.
72 * @param value value to match
73 * @param <T> match type
74 * @return new instance
76 public static <T> Match<T> ifValue(T value) {
77 return new Match<>(value, false);
81 * Returns a Match that matches any value except the specified value.
83 * @param value value to not match
84 * @param <T> match type
85 * @return new instance
87 public static <T> Match<T> ifNotValue(T value) {
88 return new Match<>(value, true);
97 private Match(T value, boolean negation) {
100 this.negation = negation;
104 * Maps this instance to a Match of another type.
106 * @param mapper transformation function
107 * @param <V> new match type
108 * @return new instance
110 public <V> Match<V> map(Function<T, V> mapper) {
113 } else if (value == null) {
114 return negation ? ifNotNull() : ifNull();
116 return negation ? ifNotValue(mapper.apply(value)) : ifValue(mapper.apply(value));
121 * Checks if this instance matches specified value.
123 * @param other other value
124 * @return true if matches; false otherwise
126 public boolean matches(T other) {
129 } else if (other == null) {
130 return negation ? value != null : value == null;
132 if (value instanceof byte[]) {
133 boolean equal = Arrays.equals((byte[]) value, (byte[]) other);
134 return negation ? !equal : equal;
136 return negation ? !Objects.equals(value, other) : Objects.equals(value, other);
141 public int hashCode() {
142 return Objects.hash(matchAny, value, negation);
146 public boolean equals(Object other) {
147 if (!(other instanceof Match)) {
150 Match<T> that = (Match<T>) other;
151 return this.matchAny == that.matchAny
152 && Objects.equals(this.value, that.value)
153 && this.negation == that.negation;
157 public String toString() {
158 return toStringHelper(this)
159 .add("matchAny", matchAny)
160 .add("negation", negation)