/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation 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
*
* Contributors:
* IBM Corporation - initial API and implementation
* C. Sean Young <csyoung@google.com> - Bug 436645
******************************************************************************/
package org.eclipse.ui.internal.navigator.extensions;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
/**
* A reference meant to be a key for an evaluation cache.
*
* Should only be used to point to objects that are immutable.
*
* @param <T>
* The type of object this reference points to.
*
* @since 3.3
*/
public class EvaluationReference<T> extends SoftReference<T> {
private final int hashCode;
/**
* @param referent
* The object to be referenced, must be non-null
*/
public EvaluationReference(T referent) {
super(referent);
hashCode = referent.hashCode();
}
/**
*
* @param referent
* The object to be referenced, must be non-null
* @param queue
* The ReferenceQueue to register this instance in
*/
public EvaluationReference(T referent, ReferenceQueue<? super T> queue) {
super(referent, queue);
hashCode = referent.hashCode();
}
@Override
public int hashCode() {
return hashCode;
}
/**
* Returns true if the Object given is also an EvaluationReference and if the
* referents are equal, or if the referent is null (implying clearing or collection),
* if the given Object is exactly this EvaluationReference object.
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj == this) {
return true;
} else if (obj instanceof EvaluationReference) {
// Don't get if not given an evaluation reference to prevent
// unnecessary accesses keeping the SoftReference "fresh".
Object myObj = get();
// If the inner object is null, then the only EvaluationReference
// that is equal is itself (checked above).
if (myObj == null) return false;
EvaluationReference<?> otherRef = (EvaluationReference<?>) obj;
if (hashCode != otherRef.hashCode) return false;
// Not comparing type; it is valid for two objects of different
// types to be equal.
Object otherObj = otherRef.get();
if (otherObj == null) return false;
return myObj == otherObj || myObj.equals(otherObj);
}
return false;
}
@Override
public String toString() {
Object referent = get();
return "Evalutation[" + (referent == null ? "(collected)" : "referent=" + referent) + ']'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}