blob: 7839ba6ef9eeb9bd43329e8f1971a70b7dfe19fb [file] [log] [blame]
Madan Jampani7804c992015-07-20 13:20:19 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Madan Jampani7804c992015-07-20 13:20:19 -07003 *
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 */
Madan Jampanif2f086c2016-01-13 16:15:39 -080016package org.onlab.util;
Madan Jampani7804c992015-07-20 13:20:19 -070017
18import static com.google.common.base.MoreObjects.toStringHelper;
19
20import java.util.Arrays;
21import java.util.Objects;
22import java.util.function.Function;
23
24/**
25 * Utility class for checking matching values.
26 *
27 * @param <T> type of value
28 */
29public final class Match<T> {
30
Madan Jampanif2f086c2016-01-13 16:15:39 -080031 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);
34
Madan Jampani7804c992015-07-20 13:20:19 -070035 private final boolean matchAny;
36 private final T value;
Madan Jampanif2f086c2016-01-13 16:15:39 -080037 private final boolean negation;
Madan Jampani7804c992015-07-20 13:20:19 -070038
39 /**
Madan Jampanif2f086c2016-01-13 16:15:39 -080040 * Returns a Match that matches any value including null.
Madan Jampani7804c992015-07-20 13:20:19 -070041 * @param <T> match type
42 * @return new instance
43 */
44 public static <T> Match<T> any() {
Madan Jampanif2f086c2016-01-13 16:15:39 -080045 return ANY;
Madan Jampani7804c992015-07-20 13:20:19 -070046 }
47
48 /**
49 * Returns a Match that matches null values.
50 * @param <T> match type
51 * @return new instance
52 */
53 public static <T> Match<T> ifNull() {
Madan Jampanif2f086c2016-01-13 16:15:39 -080054 return NULL;
Madan Jampani7804c992015-07-20 13:20:19 -070055 }
56
57 /**
Madan Jampanif2f086c2016-01-13 16:15:39 -080058 * Returns a Match that matches all non-null values.
59 * @param <T> match type
60 * @return new instance
61 */
62 public static <T> Match<T> ifNotNull() {
63 return NOT_NULL;
64 }
65
66 /**
67 * Returns a Match that only matches the specified value.
Madan Jampani7804c992015-07-20 13:20:19 -070068 * @param value value to match
69 * @param <T> match type
70 * @return new instance
71 */
72 public static <T> Match<T> ifValue(T value) {
Madan Jampanif2f086c2016-01-13 16:15:39 -080073 return new Match<>(value, false);
74 }
75
76 /**
77 * Returns a Match that matches any value except the specified value.
78 * @param value value to not match
79 * @param <T> match type
80 * @return new instance
81 */
82 public static <T> Match<T> ifNotValue(T value) {
83 return new Match<>(value, true);
Madan Jampani7804c992015-07-20 13:20:19 -070084 }
85
86 private Match() {
87 matchAny = true;
Madan Jampanif2f086c2016-01-13 16:15:39 -080088 negation = false;
Madan Jampani7804c992015-07-20 13:20:19 -070089 value = null;
90 }
91
Madan Jampanif2f086c2016-01-13 16:15:39 -080092 private Match(T value, boolean negation) {
Madan Jampani7804c992015-07-20 13:20:19 -070093 matchAny = false;
94 this.value = value;
Madan Jampanif2f086c2016-01-13 16:15:39 -080095 this.negation = negation;
Madan Jampani7804c992015-07-20 13:20:19 -070096 }
97
98 /**
99 * Maps this instance to a Match of another type.
100 * @param mapper transformation function
101 * @param <V> new match type
102 * @return new instance
103 */
104 public <V> Match<V> map(Function<T, V> mapper) {
105 if (matchAny) {
106 return any();
107 } else if (value == null) {
Madan Jampanif2f086c2016-01-13 16:15:39 -0800108 return negation ? ifNotNull() : ifNull();
Madan Jampani7804c992015-07-20 13:20:19 -0700109 } else {
Madan Jampanif2f086c2016-01-13 16:15:39 -0800110 return negation ? ifNotValue(mapper.apply(value)) : ifValue(mapper.apply(value));
Madan Jampani7804c992015-07-20 13:20:19 -0700111 }
112 }
113
114 /**
115 * Checks if this instance matches specified value.
116 * @param other other value
117 * @return true if matches; false otherwise
118 */
119 public boolean matches(T other) {
120 if (matchAny) {
121 return true;
122 } else if (other == null) {
Madan Jampanif2f086c2016-01-13 16:15:39 -0800123 return negation ? value != null : value == null;
Madan Jampani7804c992015-07-20 13:20:19 -0700124 } else {
125 if (value instanceof byte[]) {
Madan Jampanif2f086c2016-01-13 16:15:39 -0800126 boolean equal = Arrays.equals((byte[]) value, (byte[]) other);
127 return negation ? !equal : equal;
Madan Jampani7804c992015-07-20 13:20:19 -0700128 }
Madan Jampanif2f086c2016-01-13 16:15:39 -0800129 return negation ? !Objects.equals(value, other) : Objects.equals(value, other);
Madan Jampani7804c992015-07-20 13:20:19 -0700130 }
131 }
132
133 @Override
Madan Jampani80984052015-07-23 13:11:36 -0700134 public int hashCode() {
Madan Jampanif2f086c2016-01-13 16:15:39 -0800135 return Objects.hash(matchAny, value, negation);
Madan Jampani80984052015-07-23 13:11:36 -0700136 }
137
138 @Override
139 public boolean equals(Object other) {
140 if (!(other instanceof Match)) {
141 return false;
142 }
Madan Jampani92c64eb2015-07-23 15:37:07 -0700143 Match<T> that = (Match<T>) other;
Madan Jampani329dd1b2016-03-22 15:03:53 -0700144 return this.matchAny == that.matchAny &&
Madan Jampanif2f086c2016-01-13 16:15:39 -0800145 Objects.equals(this.value, that.value) &&
Madan Jampani329dd1b2016-03-22 15:03:53 -0700146 this.negation == that.negation;
Madan Jampani80984052015-07-23 13:11:36 -0700147 }
148
149 @Override
Madan Jampani7804c992015-07-20 13:20:19 -0700150 public String toString() {
151 return toStringHelper(this)
152 .add("matchAny", matchAny)
Madan Jampanif2f086c2016-01-13 16:15:39 -0800153 .add("negation", negation)
Madan Jampani7804c992015-07-20 13:20:19 -0700154 .add("value", value)
155 .toString();
156 }
157}