Package freemarker.ext.beans
Interface MethodAppearanceFineTuner
public interface MethodAppearanceFineTuner
Used for customizing how the Java methods are visible from templates, via
BeansWrapper.setMethodAppearanceFineTuner(MethodAppearanceFineTuner)
.
The object that implements this should also implement SingletonCustomizer
whenever possible, to allow reusing
the class introspection cache in more situations.- Since:
- 2.3.21
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Implement this to tweak certain aspects of how methods appear in the data-model.
-
Method Details
-
process
void process(BeansWrapper.MethodAppearanceDecisionInput in, BeansWrapper.MethodAppearanceDecision out)Implement this to tweak certain aspects of how methods appear in the data-model.BeansWrapper
will pass in all Java methods here that it intends to expose in the data-model as methods (so you can doobj.foo()
in the template). This also applies to JavaBeans property read methods, likepublic int getX()
, even if the bean property value itself is already exposed (with namex
, in this example).With this method you can do the following tweaks:
- Hide a method that would be otherwise shown by calling
BeansWrapper.MethodAppearanceDecision.setExposeMethodAs(String)
withnull
parameter. Note that you can't un-hide methods that are not public or are considered to by unsafe (likeObject.wait()
) becauseprocess(freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput, freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision)
is not called for those. - Show the method with a different name in the data-model than its
real name by calling
BeansWrapper.MethodAppearanceDecision.setExposeMethodAs(String)
with non-null
parameter. (If set tonull
, then the method won't be exposed.) The default is the real name of the method. Note that ifmethodInsteadOfPropertyValueBeforeCall
istrue
, the method is not exposed if the method name set here is the same as the name of the property set for this method withBeansWrapper.MethodAppearanceDecision.setExposeAsProperty(PropertyDescriptor)
. - Create a fake JavaBean property for this method by calling
BeansWrapper.MethodAppearanceDecision.setExposeAsProperty(PropertyDescriptor)
. For example, if you haveint size()
in a class, but you want it to be accessed from the templates asobj.size
(like a JavaBean property), rather than asobj.size()
, you can do that with this (but remember callingsetMethodShadowsProperty(false)
as well, if the method name is exactly the same as the property name). The default isnull
, which means that no fake property is created for the method. You need not, and shouldn't set this to non-null
for the property read (get/is) methods of real JavaBeans properties, as bean properties are not treated as methods (hence theMethodAppearanceFineTuner
is irrelevant), and are exposed or not regardless of this mechanism (based onBeansWrapperConfiguration.setExposureLevel(int)
). The property name in thePropertyDescriptor
can be anything, but the method (or methods) in it must belong to the class that is given as theclazz
parameter, or it must be inherited from that class, otherwise the behavior is undefined, and errors can occur later.IndexedPropertyDescriptor
-s are supported. If a real JavaBeans property of the same name exists, or a fake property of the same name was already assigned earlier, it won't be replaced by the new one by default, however this can be changed withBeansWrapper.MethodAppearanceDecision.setReplaceExistingProperty(boolean)
. - If something is exposed as property via
BeansWrapper.MethodAppearanceDecision.setExposeAsProperty(PropertyDescriptor)
(and not only because it's a real JavaBeans property), and you also want the property value to be accessible in templates as the return value of a 0-argument method of the same name, then callBeansWrapper.MethodAppearanceDecision.setMethodInsteadOfPropertyValueBeforeCall(boolean)
withtrue
. Here's an example to explain that. Let's say, you have a class that contains "public String name()", and you exposed that as a property viaBeansWrapper.MethodAppearanceDecision.setExposeAsProperty(PropertyDescriptor)
. So far, you can access the property value from templates asuser.name
, butuser.name()
will fail, saying that you try to call aString
(because you apply the()
operator on the result ofuser.name
, which is aString
). But withBeansWrapper.MethodAppearanceDecision.setMethodInsteadOfPropertyValueBeforeCall(boolean)
true
, bothuser.name
, anduser.name()
will do the same (which is possible because ifuser
is aMethodCallAwareTemplateHashModel
, "name" can be resoled to different values in the two cases). The default (initial) value ofmethodInsteadOfPropertyValueBeforeCall
depends onBeansWrapperConfiguration.setDefaultZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)
, andBeansWrapperConfiguration.setRecordZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)
. - Prevent the method to hide a JavaBeans property (fake or real) of the same name by calling
BeansWrapper.MethodAppearanceDecision.setMethodShadowsProperty(boolean)
withfalse
. The default istrue
, so if you have both a property and a method called "foo", then in the templatemyObject.foo
will return the method itself instead of the property value, which is often undesirable.
- Parameters:
in
- Describes the method about which the decision will be made.out
- Stores how the method will be exposed in the data-model afterprocess(freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput, freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision)
returns. This is initialized so that it reflects the default behavior ofBeansWrapper
, so you don't have to do anything with this when you don't want to change the default behavior.
- Hide a method that would be otherwise shown by calling
-