org.opendaylight.yangtools.util.ForwardingIdentityObject Maven / Gradle / Ivy
/*
* Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.yangtools.util;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
import com.google.common.collect.ForwardingObject;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.concepts.Delegator;
/**
* A {@link ForwardingObject} which additionally masks {@link #hashCode()}/{@link #equals(Object)} of a delegate object,
* so that it can be a data transfer object with data-dependent implementations of those contracts can be use in
* collections and maps which need to work on identity. This is useful in situations where identity equality needs to
* be used with the conjunction with the collections library, for example {@link ConcurrentHashMap}. All instances are
* considered equal if they refer to the same delegate object.
*
* Note this class forms its own equality domain, and its use may lead to surprising results, especially where
* {@link #toString()} is involved. For example a {@code Map.toString()} may end up emitting two keys which have the
* same String representation.
*
* @param Type of wrapped object
*/
@Beta
@NonNullByDefault
public abstract class ForwardingIdentityObject extends ForwardingObject implements Delegator {
protected ForwardingIdentityObject() {
// Mask public constructor
}
public static ForwardingIdentityObject of(final T obj) {
return checkedOf(requireNonNull(obj));
}
@Override
public final @NonNull T getDelegate() {
return delegate();
}
@Override
public final int hashCode() {
return System.identityHashCode(delegate());
}
@Override
public final boolean equals(final @Nullable Object obj) {
return obj == this || obj instanceof ForwardingIdentityObject
&& delegate() == ((ForwardingIdentityObject>) obj).delegate();
}
@Override
protected abstract @NonNull T delegate();
private static ForwardingIdentityObject checkedOf(final @NonNull T delegate) {
return new ForwardingIdentityObject<>() {
@Override
protected @NonNull T delegate() {
return delegate;
}
};
}
}