package org.dynjs.runtime.linker;
import org.projectodd.rephract.ContextualLinker;
import org.projectodd.rephract.Invocation;
import org.projectodd.rephract.Link;
import org.projectodd.rephract.Linker;
import java.lang.invoke.MethodHandle;
/**
* @author Bob McWhirter
*/
public class CachingLinker extends ContextualLinker {
private static final Link NO_LINK = new Link() {
@Override
public MethodHandle guard() throws Exception {
return null;
}
@Override
public MethodHandle target() throws Exception {
return null;
}
};
private final Linker delegate;
private Link getProperty;
private Link setProperty;
private Link getMethod;
private Link call;
private Link construct;
public CachingLinker(Linker delegate) {
this.delegate = delegate;
}
@Override
public Link preLinkGetProperty(Invocation invocation) throws Exception {
if (this.getProperty == null) {
this.getProperty = populate(this.delegate.preLinkGetProperty(invocation));
}
return retrieve( this.getProperty );
}
@Override
public Link preLinkSetProperty(Invocation invocation) throws Exception {
if ( this.setProperty == null ) {
this.setProperty = populate( this.delegate.preLinkSetProperty(invocation));
}
return retrieve( this.setProperty );
}
@Override
public Link preLinkGetMethod(Invocation invocation) throws Exception {
if ( this.getMethod == null ) {
this.getMethod = populate( this.delegate.preLinkGetMethod(invocation) );
}
return retrieve( this.getMethod );
}
@Override
public Link preLinkCall(Invocation invocation) throws Exception {
if ( this.call == null ) {
this.call = populate(this.delegate.preLinkCall(invocation));
}
return retrieve( this.call );
}
@Override
public Link preLinkConstruct(Invocation invocation) throws Exception {
if ( this.construct == null ) {
this.construct = populate( this.delegate.preLinkConstruct(invocation) );
}
return retrieve(this.construct);
}
protected Link populate(Link inbound) {
if ( inbound == null ) {
return NO_LINK;
}
return new CachedLink(inbound);
}
protected Link retrieve(Link inbound) {
if ( inbound == NO_LINK ) {
return null;
}
return inbound;
}
}