package hiro.yoshioka.util.ref;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.reflect.Field;

public class PhantomReferenceReanimator {
	private static Field referentField;

	static {
		Class klass = java.lang.ref.Reference.class;

		try {
			referentField = klass.getDeclaredField("referent");
			referentField.setAccessible(true);
		} catch (NoSuchFieldException e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	/* PhantomReference から強制的にリファレントを取り出す */
	public static Object reanimate(PhantomReference ref)
			throws IllegalAccessException {
		return referentField.get(ref);
	}

	public static String toString(Reference ref) {
		Object obj = ref.get();
		if (ref instanceof PhantomReference) {
			try {
				obj = reanimate((PhantomReference) ref);
			} catch (IllegalAccessException e) {
			}
		}
		StringBuilder buf = new StringBuilder();
		buf.append(ref.getClass().getName()).append(" ==>");
		if (obj != null) {
			buf.append(obj.getClass().getName()).append(":")
					.append(obj.hashCode());
		}
		return buf.toString();
	}
}
