package com.googlecode.objectify.util; import com.googlecode.objectify.Result; import java.io.ObjectStreamException; import java.io.Serializable; /** * Caches a result value so it is only executed once * * @author Jeff Schnitzer <jeff@infohazard.org> */ abstract public class ResultCache<T> implements Result<T>, Serializable { private boolean cached; private T value; /** */ protected abstract T nowUncached(); /** */ protected boolean isExecuted() { return cached; } /** */ @Override final public T now() { if (!cached) { value = nowUncached(); cached = true; this.postExecuteHook(); } return value; } /** Executed once after the cached value is assigned. */ protected void postExecuteHook() {} /** * When this serializes, write out a simple version that doesn't hold complicated links to internal * structures. This is safe as long as nobody ever tries to cast to ResultCache directly, which should * never happen. */ protected Object writeReplace() throws ObjectStreamException { return new ResultNow<>(now()); } /** We can get away with this because the subclass almost always provides concrete types */ @Override public String toString() { //Type from = GenericTypeReflector.getTypeParameter(this.getClass(), ResultTranslator.class.getTypeParameters()[0]); //Type to = GenericTypeReflector.getTypeParameter(this.getClass(), ResultTranslator.class.getTypeParameters()[1]); //return GenericTypeReflector.getExactSuperType(this.getClass(), ResultTranslator.class).toString(); if (isExecuted()) return "ResultCache(" + value + ")"; else return "ResultCache/" + this.getClass().getName(); } }