io.honeybadger.com.github.mustachejava.reflect.GuardedBinding Maven / Gradle / Ivy
package com.github.mustachejava.reflect;
import com.github.mustachejava.Binding;
import com.github.mustachejava.Code;
import com.github.mustachejava.MustacheException;
import com.github.mustachejava.ObjectHandler;
import com.github.mustachejava.TemplateContext;
import com.github.mustachejava.codes.PartialCode;
import com.github.mustachejava.util.GuardException;
import com.github.mustachejava.util.Wrapper;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Logger;
import static java.util.Collections.singletonList;
/**
* Codes are bound to their variables through bindings.
*
* User: sam
* Date: 7/7/12
* Time: 6:05 PM
*/
public class GuardedBinding implements Binding {
private static final Wrapper[] EMPTY_WRAPPERS = new Wrapper[0];
// Debug callsites
private static Logger logger = Logger.getLogger("mustache");
private static boolean debug = Boolean.getBoolean("mustache.debug");
private final ObjectHandler oh;
private final TemplateContext tc;
private final String name;
private final Code code;
public GuardedBinding(ObjectHandler oh, String name, TemplateContext tc, Code code) {
this.name = name;
this.code = code;
this.oh = oh;
this.tc = tc;
}
/**
* The chances of a new guard every time is very low. Instead we will
* store previously used guards and try them all before creating a new one.
*/
private Set previousSet = new CopyOnWriteArraySet<>();
private volatile Wrapper[] prevWrappers;
/**
* Retrieve the first value in the stacks of scopes that matches
* the give name. The method wrappers are cached and guarded against
* the type or number of scopes changing.
*
* Methods will be found using the object handler, called here with
* another lookup on a guard failure and finally coerced to a final
* value based on the ObjectHandler you provide.
*
* @param scopes An array of scopes to interrogate from right to left.
* @return The value of the field or method
*/
@Override
public Object get(List