2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.concepts;
10 import static com.google.common.base.Verify.verifyNotNull;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.MoreObjects;
15 import com.google.common.base.MoreObjects.ToStringHelper;
16 import java.util.Objects;
17 import java.util.Optional;
18 import javax.annotation.concurrent.ThreadSafe;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
23 * Utility holder of a two-variant value. The class design treats both variants as equal.
25 * @param <T> First alternative type
26 * @param <U> Second alternative type
27 * @author Robert Varga
32 public class Variant<T, U> {
33 private final @Nullable T first;
34 private final @Nullable U second;
36 protected Variant(final T first) {
37 this.first = requireNonNull(first);
41 protected Variant(final U second, final @Nullable Void dummy) {
43 this.second = requireNonNull(second);
46 protected final T first() {
47 return verifyNotNull(first);
50 protected final U second() {
51 return verifyNotNull(second);
55 * Create a new instance containing specified value.
58 * @return A new instance
59 * @throws NullPointerException if {@code value} is null
61 public static <T, U> Variant<T, U> ofFirst(final T value) {
62 return new Variant<>(value);
66 * Create a new instance containing specified value.
69 * @return A new instance
70 * @throws NullPointerException if {@code value} is null
72 public static <T, U> Variant<T, U> ofSecond(final U value) {
73 return new Variant<>(value, null);
76 public final boolean isFirst() {
80 public final T getFirst() {
81 return tryFirst().get();
84 public final Optional<T> tryFirst() {
85 return Optional.ofNullable(first);
88 public final boolean isSecond() {
89 return second != null;
92 public final U getSecond() {
93 return trySecond().get();
96 public final Optional<U> trySecond() {
97 return Optional.ofNullable(second);
101 public final int hashCode() {
102 return Objects.hash(first, second);
106 public final boolean equals(final @Nullable Object obj) {
110 if (obj == null || !getClass().equals(obj.getClass())) {
113 final Variant<?, ?> other = (Variant<?, ?>) obj;
114 return Objects.equals(first, other.first) && Objects.equals(second, other.second);
118 public final String toString() {
119 return addToString(MoreObjects.toStringHelper(this).omitNullValues()).toString();
122 protected ToStringHelper addToString(final ToStringHelper helper) {
123 return helper.add("first", first).add("second", second);