package com.hubspot.jinjava.el.ext;
import java.lang.reflect.InvocationTargetException;
import javax.el.ELContext;
import javax.el.ELException;
import com.google.common.collect.ImmutableMap;
import com.hubspot.jinjava.interpret.CallStack;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.MacroTagCycleException;
import com.hubspot.jinjava.interpret.TemplateError;
import com.hubspot.jinjava.interpret.errorcategory.BasicTemplateErrorCategory;
import com.hubspot.jinjava.lib.fn.MacroFunction;
import de.odysseus.el.misc.LocalMessages;
import de.odysseus.el.tree.Bindings;
import de.odysseus.el.tree.impl.ast.AstFunction;
import de.odysseus.el.tree.impl.ast.AstParameters;
public class AstMacroFunction extends AstFunction {
public AstMacroFunction(String name, int index, AstParameters params, boolean varargs) {
super(name, index, params, varargs);
}
@Override
public Object eval(Bindings bindings, ELContext context) {
JinjavaInterpreter interpreter = (JinjavaInterpreter) context.getELResolver().getValue(context, null, ExtendedParser.INTERPRETER);
MacroFunction macroFunction = interpreter.getContext().getGlobalMacro(getName());
if (macroFunction != null) {
CallStack macroStack = interpreter.getContext().getMacroStack();
if (!macroFunction.isCaller()) {
try {
if (interpreter.getConfig().isEnableRecursiveMacroCalls()) {
macroStack.pushWithoutCycleCheck(getName());
} else {
macroStack.push(getName(), -1);
}
} catch (MacroTagCycleException e) {
interpreter.addError(new TemplateError(TemplateError.ErrorType.WARNING,
TemplateError.ErrorReason.EXCEPTION,
TemplateError.ErrorItem.TAG,
"Cycle detected for macro '" + getName() + "'",
null,
-1,
e,
BasicTemplateErrorCategory.CYCLE_DETECTED,
ImmutableMap.of("name", getName())));
return "";
}
}
try {
return super.invoke(bindings, context, macroFunction, AbstractCallableMethod.EVAL_METHOD);
} catch (IllegalAccessException e) {
throw new ELException(LocalMessages.get("error.function.access", getName()), e);
} catch (InvocationTargetException e) {
throw new ELException(LocalMessages.get("error.function.invocation", getName()), e.getCause());
} finally {
macroStack.pop();
}
}
return super.eval(bindings, context);
}
}