blob: 21987726e913f5ec0c6d1f414a10fd7e79d8898d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package freemarker.ext.beans;
import java.beans.IndexedPropertyDescriptor;
import java.beans.PropertyDescriptor;
import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
/**
* Used for customizing how the methods are visible from templates, via
* {@link BeansWrapper#setMethodAppearanceFineTuner(MethodAppearanceFineTuner)}.
* The object that implements this should also implement {@link SingletonCustomizer} whenever possible.
*
* @since 2.3.21
*/
public interface MethodAppearanceFineTuner {
/**
* <b>Experimental method; subject to change!</b>
* Implement this to tweak certain aspects of how methods appear in the
* data-model. {@link BeansWrapper} will pass in all Java methods here that
* it intends to expose in the data-model as methods (so you can do
* <tt>obj.foo()</tt> in the template).
* With this method it you can do the following tweaks:
* <ul>
* <li>Hide a method that would be otherwise shown by calling
* {@link MethodAppearanceDecision#setExposeMethodAs(String)}
* with <tt>null</tt> parameter. Note that you can't un-hide methods
* that are not public or are considered to by unsafe
* (like {@link Object#wait()}) because
* {@link #process} is not called for those.</li>
* <li>Show the method with a different name in the data-model than its
* real name by calling
* {@link MethodAppearanceDecision#setExposeMethodAs(String)}
* with non-<tt>null</tt> parameter.
* <li>Create a fake JavaBean property for this method by calling
* {@link MethodAppearanceDecision#setExposeAsProperty(PropertyDescriptor)}.
* For example, if you have <tt>int size()</tt> in a class, but you
* want it to be accessed from the templates as <tt>obj.size</tt>,
* rather than as <tt>obj.size()</tt>, you can do that with this.
* The default is {@code null}, which means that no fake property is
* created for the method. You need not and shouldn't set this
* to non-<tt>null</tt> for the getter methods of real JavaBean
* properties, as those are automatically shown as properties anyway.
* The property name in the {@link PropertyDescriptor} can be anything,
* but the method (or methods) in it must belong to the class that
* is given as the <tt>clazz</tt> parameter or it must be inherited from
* that class, or else whatever errors can occur later.
* {@link IndexedPropertyDescriptor}-s are supported.
* If a real JavaBean property of the same name exists, it won't be
* replaced by the fake one. Also if a fake property of the same name
* was assigned earlier, it won't be replaced.
* <li>Prevent the method to hide a JavaBean property (fake or real) of
* the same name by calling
* {@link MethodAppearanceDecision#setMethodShadowsProperty(boolean)}
* with <tt>false</tt>. The default is <tt>true</tt>, so if you have
* both a property and a method called "foo", then in the template
* <tt>myObject.foo</tt> will return the method itself instead
* of the property value, which is often undesirable.
* </ul>
*
* <p>Note that you can expose a Java method both as a method and as a
* JavaBean property on the same time, however you have to chose different
* names for them to prevent shadowing.
*
* @param in Describes the method about which the decision will have to be made.
*
* @param out Stores how the method will be exposed in the
* data-model after {@link #process} returns.
* This is initialized so that it reflects the default
* behavior of {@link BeansWrapper}, so you don't have to do anything with this
* when you don't want to change the default behavior.
*/
void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out);
}