package org.jtwig.functions.impl.java;
import com.google.common.base.Optional;
import org.jtwig.functions.FunctionRequest;
import org.jtwig.functions.SimpleJtwigFunction;
import org.jtwig.reflection.model.Value;
import org.jtwig.reflection.model.java.JavaClass;
import org.jtwig.reflection.model.java.JavaConstant;
import org.jtwig.util.ClasspathFinder;
public class ConstantFunction extends SimpleJtwigFunction {
private final ClasspathFinder classpathFinder;
public ConstantFunction(ClasspathFinder classpathFinder) {
this.classpathFinder = classpathFinder;
}
@Override
public String name() {
return "constant";
}
@Override
public Object execute(FunctionRequest request) {
request
.minimumNumberOfArguments(1)
.maximumNumberOfArguments(2);
if (request.getNumberOfArguments() == 1) {
return getConstant(request, getString(request, 0));
} else {
Object constantValue = getConstant(request, getString(request, 1));
return request.getEnvironment()
.getValueEnvironment().getValueComparator()
.compare(request, constantValue, request.get(0)) == 0;
}
}
private String getString(FunctionRequest request, int index) {
return request.getEnvironment().getValueEnvironment().getStringConverter().convert(request.get(index));
}
private Object getConstant(FunctionRequest request, String constant) {
int constantNamePosition = constant.lastIndexOf(".");
if (constantNamePosition == -1) {
throw request.exception(String.format("Invalid constant specified '%s'", constant));
}
String className = constant.substring(0, constantNamePosition);
String constantName = constant.substring(constantNamePosition + 1);
Optional<JavaClass> optional = classpathFinder.load(className);
if (optional.isPresent()) {
Optional<JavaConstant> valueOptional = optional.get().constant(constantName);
if (valueOptional.isPresent()) {
Optional<Value> value = valueOptional.get().value();
if (value.isPresent()) {
return value.get().getValue();
} else {
throw request.exception(String.format("Unable to retrieve value of constant %s in class %s", constantName, className));
}
} else {
throw request.exception(String.format("Class %s does not expose constant %s", className, constantName));
}
} else {
throw request.exception(String.format("Class %s not found", className));
}
}
}