package org.dynjs.runtime.linker;
import org.projectodd.rephract.Link;
import org.projectodd.rephract.PreconditionFailedException;
import org.projectodd.rephract.SmartLink;
import java.lang.invoke.MethodHandle;
/**
* @author Bob McWhirter
*/
public class CachedLink extends Link {
private final Link delegate;
private MethodHandle guard;
private MethodHandle target;
public CachedLink(Link delegate) {
this.delegate = delegate;
}
@Override
public MethodHandle test(Object... args) throws Throwable {
if (!(boolean) guard().invokeWithArguments(args)) {
return null;
}
return target();
}
@Override
public Object tryInvoke(Object... args) throws Throwable {
Class<?>[] argTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; ++i) {
argTypes[i] = args[i].getClass();
}
MethodHandle target = test(args);
if (target == null) {
throw new PreconditionFailedException();
}
return target.invokeWithArguments(args);
}
@Override
public MethodHandle guard() throws Exception {
if (this.guard == null) {
this.guard = this.delegate.guard();
}
return this.guard;
}
@Override
public MethodHandle target() throws Exception {
if ( this.target == null ) {
this.target = this.delegate.target();
}
return this.target;
}
public String toString() {
return "[CachedLink: delegate=" + this.delegate.toString() + "]";
}
}