Package freemarker.ext.beans
Class BeanModel
java.lang.Object
freemarker.ext.beans.BeanModel
- All Implemented Interfaces:
WrapperTemplateModel,AdapterTemplateModel,TemplateHashModel,TemplateHashModelEx,TemplateModel,TemplateModelWithAPISupport
- Direct Known Subclasses:
ArrayModel,BooleanModel,DateModel,EnumerationModel,IteratorModel,NumberModel,ResourceBundleModel,StringModel
public class BeanModel
extends Object
implements TemplateHashModelEx, AdapterTemplateModel, WrapperTemplateModel, TemplateModelWithAPISupport
A class that will wrap an arbitrary object into
TemplateHashModel
interface allowing calls to arbitrary property getters and invocation of
accessible methods on the object from a template using the
object.foo to access properties and object.bar(arg1, arg2) to
invoke methods on it. You can also use the object.foo[index] syntax to
access indexed properties. It uses Beans Introspector
to dynamically discover the properties and methods.-
Field Summary
FieldsFields inherited from interface freemarker.template.TemplateModel
NOTHING -
Constructor Summary
ConstructorsConstructorDescriptionBeanModel(Object object, BeansWrapper wrapper)Creates a new model that wraps the specified object. -
Method Summary
Modifier and TypeMethodDescriptionUses Beans introspection to locate a property or method with name matching the key name.protected TemplateModelOverride this if you want to customize the behavior ofget(String).getAdaptedObject(Class<?> hint)Returns the same asgetWrappedObject(); to ensure that, this method will be final starting from 2.4.getAPI()Returns the model that exposes the (Java) API of the value.protected TemplateModelgetBeforeMethodCall(String key)Can be overridden to be public, to implementMethodCallAwareTemplateHashModel.Retrieves the original object wrapped by this model.protected booleanWhether the model has a plain get(String) or get(Object) methodprotected TemplateModelinvokeGenericGet(Map classInfo, Class<?> clazz, String key)booleanisEmpty()Tells whether the model is empty.keys()protected SetkeySet()Helper method to support TemplateHashModelEx.intsize()toString()protected Objectunwrap(TemplateModel model)values()protected TemplateModel
-
Field Details
-
object
-
wrapper
-
-
Constructor Details
-
BeanModel
Creates a new model that wraps the specified object. Note that there are specialized subclasses of this class for wrapping arrays, collections, enumeration, iterators, and maps. Note also that the superclass can be used to wrap String objects if only scalar functionality is needed. You can also choose to delegate the choice over which model class is used for wrapping toBeansWrapper.wrap(Object).- Parameters:
object- the object to wrap into a model.wrapper- theBeansWrapperassociated with this model. Every model has to have an associatedBeansWrapperinstance. The model gains many attributes from its wrapper, including the caching behavior, method exposure level, method-over-item shadowing policy etc.
-
-
Method Details
-
get
Uses Beans introspection to locate a property or method with name matching the key name. If a method or property is found, it's wrapped intoTemplateMethodModelEx(for a method or indexed property), or evaluated on-the-fly and the return value wrapped into appropriate model (for a non-indexed property). Models for various properties and methods are cached on a per-class basis, so the costly introspection is performed only once per property or method of a class. (Side-note: this also implies that any class whose method has been called will be strongly referred to by the framework and will not become unloadable until this class has been unloaded first. Normally this is not an issue, but can be in a rare scenario where you create many classes on- the-fly. Also, as the cache grows with new classes and methods introduced to the framework, it may appear as if it were leaking memory. The framework does, however detect class reloads (if you happen to be in an environment that does this kind of things--servlet containers do it when they reload a web application) and flushes the cache. If no method or property matching the key is found, the framework will try to invoke methods with signaturenon-void-return-type get(java.lang.String), thennon-void-return-type get(java.lang.Object), or alternatively (if the wrapped object is a resource bundle)Object getObject(java.lang.String).As of 2.3.33, the default implementation of this method delegates to
get(String, boolean). It's better to override that, instead of this method. Otherwise, unwanted behavior can arise if the model class also implementsMethodCallAwareTemplateHashModel, as that will certainly callget(String, boolean)internally, and not the overridden version of this method.- Specified by:
getin interfaceTemplateHashModel- Parameters:
key- The name by which theTemplateModelis identified in the template.- Returns:
- The
TemplateModelreferred to by the key, ornullif not found. - Throws:
TemplateModelException- if there was no property nor method nor a genericgetmethod to invoke.
-
get
protected TemplateModel get(String key, boolean beforeMethodCall) throws TemplateModelException, MethodCallAwareTemplateHashModel.ShouldNotBeGetAsMethodExceptionOverride this if you want to customize the behavior ofget(String). In standard implementations at least, this is whatget(String), andMethodCallAwareTemplateHashModel.getBeforeMethodCall(String)delegates to.- Parameters:
key- Same as the parameter ofget(String).beforeMethodCall- This is a hint that tells that the returned value will be called in the template. This was added to implementBeansWrapper.MethodAppearanceDecision.setMethodInsteadOfPropertyValueBeforeCall(boolean). This parameter isfalsewhenget(String)is called, andtruewhenMethodCallAwareTemplateHashModel.getBeforeMethodCall(String)is called. If this istrue, this method should return aTemplateMethodModelEx, ornull, or fail withMethodCallAwareTemplateHashModel.ShouldNotBeGetAsMethodException.- Throws:
TemplateModelExceptionMethodCallAwareTemplateHashModel.ShouldNotBeGetAsMethodException- Since:
- 2.3.33
-
getBeforeMethodCall
protected TemplateModel getBeforeMethodCall(String key) throws TemplateModelException, MethodCallAwareTemplateHashModel.ShouldNotBeGetAsMethodExceptionCan be overridden to be public, to implementMethodCallAwareTemplateHashModel. We don't implement that inBeanModelfor backward compatibility, but the functionality is present. If you expose this method by implementingMethodCallAwareTemplateHashModel, then be sure thatget(String)is not overridden in custom subclasses; if it is, then those subclasses should be modernized to overrideget(String, boolean)instead.- Throws:
TemplateModelExceptionMethodCallAwareTemplateHashModel.ShouldNotBeGetAsMethodException- Since:
- 2.3.33
-
hasPlainGetMethod
protected boolean hasPlainGetMethod()Whether the model has a plain get(String) or get(Object) method -
invokeGenericGet
protected TemplateModel invokeGenericGet(Map classInfo, Class<?> clazz, String key) throws IllegalAccessException, InvocationTargetException, TemplateModelException -
wrap
- Throws:
TemplateModelException
-
unwrap
- Throws:
TemplateModelException
-
isEmpty
public boolean isEmpty()Tells whether the model is empty. It is empty if either the wrapped object is null, or it's a Boolean with false value.- Specified by:
isEmptyin interfaceTemplateHashModel
-
getAdaptedObject
Returns the same asgetWrappedObject(); to ensure that, this method will be final starting from 2.4. This behavior ofBeanModelis assumed by some FreeMarker code.- Specified by:
getAdaptedObjectin interfaceAdapterTemplateModel- Parameters:
hint- the desired class of the returned value. An implementation should make reasonable effort to retrieve an object of the requested class, but if that is impossible, it must at least return the underlying object as-is. As a minimal requirement, an implementation must always return the exact underlying object whenhint.isInstance(underlyingObject)holds. When called withjava.lang.Object.class, it should return a generic Java object (i.e. if the model is wrapping a scripting language object that is further wrapping a Java object, the deepest underlying Java object should be returned).- Returns:
- the underlying object, or its value accommodated for the hint class.
-
getWrappedObject
Description copied from interface:WrapperTemplateModelRetrieves the original object wrapped by this model.- Specified by:
getWrappedObjectin interfaceWrapperTemplateModel
-
size
public int size()- Specified by:
sizein interfaceTemplateHashModelEx- Returns:
- the number of key/value mappings in the hash.
-
keys
- Specified by:
keysin interfaceTemplateHashModelEx- Returns:
- a collection containing the keys in the hash. Every element of
the returned collection must implement the
TemplateScalarModel(as the keys of hashes are always strings).
-
values
- Specified by:
valuesin interfaceTemplateHashModelEx- Returns:
- a collection containing the values in the hash. The elements of the
returned collection can be any kind of
TemplateModel-s. - Throws:
TemplateModelException
-
toString
-
keySet
Helper method to support TemplateHashModelEx. Returns the Set of Strings which are available via the TemplateHashModel interface. Subclasses that overrideinvokeGenericGetto provide additional hash keys should also override this method. -
getAPI
Description copied from interface:TemplateModelWithAPISupportReturns the model that exposes the (Java) API of the value. This is usually implemented by delegating toObjectWrapperWithAPISupport.wrapAsAPI(Object).- Specified by:
getAPIin interfaceTemplateModelWithAPISupport- Throws:
TemplateModelException
-