I am trying to extend JavaBeanValueResolver in order to prevent fields from the base class being converted to JS.
public class A extends B {
public String getName() {
return "Hello World";
}
}
public abstract class B {
public String getUnsupported() {
throw new UnsupportedOperationException();
}
}
This is a contrived example. In reality, apart from the exception, my base class has many, many properties which I don't want converted to JS, for performance reasons.
So I extended JavaBeanValueResolver like this:
public class CustomPropertyResolver extends JavaBeanValueResolver {
public static final ValueResolver INSTANCE = new SiteComPropertyResolver();
@Override
protected void members(final Class<?> clazz, final Set<Method> members) {
if (clazz != Object.class && clazz != A.class) { // < -- the only change to this method is the addtl check
// Keep backing up the inheritance hierarchy.
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (matches(method, memberName(method))) {
members.add(method);
}
}
if (clazz.getSuperclass() != null) {
members(clazz.getSuperclass(), members);
}
for (Class<?> superIfc : clazz.getInterfaces()) {
members(superIfc, members);
}
}
}
}
Regardless of my implementation above, anytime I specify a resolver for my context, the context data is not being converted at all. Even when I specify the default resolver! So when my template is executed, the helpers which require that data to be set is not there, and a JS exception is rightfully thrown:
Map<String, Object> model = new HashMap<String, Object>();
model.put("required", required);
Context context = Context.newBuilder(model).resolver(CustomPropertyResolver.INSTANCE).build();
Handlebars handlebars = new Handlebars();
TalonResource helpersResource = 'path/to/helper.js';
handlebars.registerHelpers(FilenameUtils.getName(helpersResource), helpersResource.getInputStream());
Resource htmlResource = new Resource('path/to/template');
String htmlString = IOUtils.toString(htmlResource.getInputStream(), StandardCharsets.UTF_8);
Template htmlTemplate = handlebars.compile(new StringTemplateSource(FilenameUtils.getName('path/to/template'),
String html = htmlTemplate.apply(context);
Even if I do the above but use the default Resolver:
In that case the attributes being set on the context model are attempted to convert to JS (can see from breakpoints) and the UnsupportedOperationException is thrown.
It seems to me that at the minimum, specifying the default resolver should have the same behavior as not specifying a resolver at all.
I am trying to extend
JavaBeanValueResolver
in order to prevent fields from the base class being converted to JS.This is a contrived example. In reality, apart from the exception, my base class has many, many properties which I don't want converted to JS, for performance reasons.
So I extended
JavaBeanValueResolver
like this:Regardless of my implementation above, anytime I specify a resolver for my context, the context data is not being converted at all. Even when I specify the default resolver! So when my template is executed, the helpers which require that data to be set is not there, and a JS exception is rightfully thrown:
Even if I do the above but use the default Resolver:
The same error is thrown.
It's only when I don't specify a resolver at all:
In that case the attributes being set on the context model are attempted to convert to JS (can see from breakpoints) and the
UnsupportedOperationException
is thrown.It seems to me that at the minimum, specifying the default resolver should have the same behavior as not specifying a resolver at all.