blob: ea179854fa8c640d1cfa3a74c16f8a82a5542e1d [file] [log] [blame]
package freemarker.core;
import java.util.List;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
/**
* A holder for builtins that deal with null left-hand values.
*/
class ExistenceBuiltins {
// Can't be instantiated
private ExistenceBuiltins() { }
private static abstract class ExistenceBuiltIn extends BuiltIn {
protected TemplateModel evalMaybeNonexistentTarget(Environment env) throws TemplateException {
TemplateModel tm;
if (target instanceof ParentheticalExpression) {
boolean lastFIRE = env.setFastInvalidReferenceExceptions(true);
try {
tm = target.eval(env);
} catch (InvalidReferenceException ire) {
tm = null;
} finally {
env.setFastInvalidReferenceExceptions(lastFIRE);
}
} else {
tm = target.eval(env);
}
return tm;
}
}
static class defaultBI extends ExistenceBuiltins.ExistenceBuiltIn {
TemplateModel _eval(final Environment env) throws TemplateException {
TemplateModel model = evalMaybeNonexistentTarget(env);
return model == null ? FIRST_NON_NULL_METHOD : new ConstantMethod(model);
}
private static class ConstantMethod implements TemplateMethodModelEx
{
private final TemplateModel constant;
ConstantMethod(TemplateModel constant) {
this.constant = constant;
}
public Object exec(List args) {
return constant;
}
}
/**
* A method that goes through the arguments one by one and returns
* the first one that is non-null. If all args are null, returns null.
*/
private static final TemplateMethodModelEx FIRST_NON_NULL_METHOD =
new TemplateMethodModelEx() {
public Object exec(List args) throws TemplateModelException {
int argCnt = args.size();
if(argCnt == 0) throw MessageUtil.newArgCntError("?default", argCnt, 1, Integer.MAX_VALUE);
for (int i = 0; i < argCnt; i++ ) {
TemplateModel result = (TemplateModel) args.get(i);
if (result != null) return result;
}
return null;
}
};
}
static class existsBI extends ExistenceBuiltins.ExistenceBuiltIn {
TemplateModel _eval(Environment env) throws TemplateException {
return evalMaybeNonexistentTarget(env) == null ? TemplateBooleanModel.FALSE : TemplateBooleanModel.TRUE;
}
boolean evalToBoolean(Environment env) throws TemplateException {
return _eval(env) == TemplateBooleanModel.TRUE;
}
}
static class has_contentBI extends ExistenceBuiltins.ExistenceBuiltIn {
TemplateModel _eval(Environment env) throws TemplateException {
return Expression.isEmpty(evalMaybeNonexistentTarget(env))
? TemplateBooleanModel.FALSE
: TemplateBooleanModel.TRUE;
}
boolean evalToBoolean(Environment env) throws TemplateException {
return _eval(env) == TemplateBooleanModel.TRUE;
}
}
static class if_existsBI extends ExistenceBuiltins.ExistenceBuiltIn {
TemplateModel _eval(Environment env)
throws TemplateException
{
TemplateModel model = evalMaybeNonexistentTarget(env);
return model == null ? TemplateModel.NOTHING : model;
}
}
}