2 * Copyright (c) 2019 PANTHEON.tech, 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.util;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ForwardingObject;
14 import java.util.concurrent.ConcurrentHashMap;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.eclipse.jdt.annotation.NonNullByDefault;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.concepts.Delegator;
21 * A {@link ForwardingObject} which additionally masks {@link #hashCode()}/{@link #equals(Object)} of a delegate object,
22 * so that it can be a data transfer object with data-dependent implementations of those contracts can be use in
23 * collections and maps which need to work on identity. This is useful in situations where identity equality needs to
24 * be used with the conjunction with the collections library, for example {@link ConcurrentHashMap}. All instances are
25 * considered equal if they refer to the same delegate object.
28 * Note this class forms its own equality domain, and its use may lead to surprising results, especially where
29 * {@link #toString()} is involved. For example a {@code Map.toString()} may end up emitting two keys which have the
30 * same String representation.
32 * @param <T> Type of wrapped object
33 * @author Robert Varga
37 public abstract class ForwardingIdentityObject<T> extends ForwardingObject implements Delegator<T> {
38 protected ForwardingIdentityObject() {
39 // Mask public constructor
42 public static <T> ForwardingIdentityObject<T> of(final T obj) {
43 return checkedOf(requireNonNull(obj));
47 public final @NonNull T getDelegate() {
52 public final int hashCode() {
53 return System.identityHashCode(delegate());
57 public final boolean equals(final @Nullable Object obj) {
58 return obj == this || obj instanceof ForwardingIdentityObject
59 && delegate() == ((ForwardingIdentityObject<?>) obj).delegate();
63 protected abstract @NonNull T delegate();
65 private static <T> ForwardingIdentityObject<T> checkedOf(final @NonNull T delegate) {
66 return new ForwardingIdentityObject<T>() {
68 protected @NonNull T delegate() {