Interface MethodCallAwareTemplateHashModel

All Superinterfaces:
TemplateHashModel, TemplateModel
All Known Implementing Classes:
GenericObjectModel

public interface MethodCallAwareTemplateHashModel extends TemplateHashModel
Adds an extra getter method to TemplateHashModel that can return different result than TemplateHashModel.get(String), knowing that the result of it will be called as a method. At least as of 2.3.33, this is only used by the template language for 0-argument method calls that are directly after the dot operator and the key (like in obj.m(), where the "()" is directly after the key "m"), or for the equivalent of that with square brackets (obj["m"]()).

Background knowledge needed to understand this: In the FreeMarker template language, methods/functions are first class values (just like strings, numbers,etc.). Also, unlike in Java, there's no separate namespace for methods, and for the other field-like members. When you have obj.m() in a template, first, the dot operator gets the value for the key "m", and after that, and independently of that, the method call operator tries to call that value (and if it's not a method or function, that will fail). The dot operator, before 2.3.33, was never aware of what the value it gets will be used for (like will it be called, will it be printed, etc.). Now it can be. For example, if in the template you have someRecord.someComponent(), and there someRecord was wrapped by the ObjectWrapper into a TemplateHashModel that also implements this interface, then the dot operator will call getBeforeMethodCall("someComponent"), rather than get("someComponent"). This is needed to implement subtle features like BeansWrapper.MethodAppearanceDecision.setMethodInsteadOfPropertyValueBeforeCall(boolean), which is needed to implement ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD.

While technically we could do the same for method calls with more the 0 arguments, as of 2.3.33 at least, we don't want to generalize this to that case. This is a workaround we added to address the issue with accessing components in Java records, which are 0-argument methods (see that at BeansWrapper.MethodAppearanceDecision.setMethodInsteadOfPropertyValueBeforeCall(boolean)).

Objects wrapped with BeansWrapper, and hence with DefaultObjectWrapper, will implement this interface when they are "generic" objects (that is, when they are not classes with special wrapper, like Map-s, Collection-s, Number-s, etc.).

Since:
2.3.33