freemarker.ext.beans
Class BeanModel

java.lang.Object
  |
  +--freemarker.ext.beans.BeanModelBase
        |
        +--freemarker.ext.beans.BeanModel
All Implemented Interfaces:
TemplateHashModel, TemplateModel, TemplateScalarModel
Direct Known Subclasses:
ArrayModel, BooleanScalar, CollectionModel, EnumerationModel, IteratorModel, MapModel, NumberModel, ResourceBundleModel

public class BeanModel
extends freemarker.ext.beans.BeanModelBase
implements TemplateHashModel

A class that will wrap an arbitrary object into TemplateHashModel interface allowing calls to arbitrary property getters and invokation 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 dinamically discover the properties and methods. The models are cached (meaning requesting a model for same object twice will return the same model instance) unless the system property freemarker.beans.nocache is set to true.

Version:
1.0
Author:
Attila Szegedi, szegedia@freemail.hu

Field Summary
static int TYPE_ARRAY
          Returned from BeanModelBase.getType() if the object is a ArrayModel
static int TYPE_COLLECTION
          Returned from BeanModelBase.getType() if the object is a CollectionModel
static int TYPE_ENUMERATION
          Returned from BeanModelBase.getType() if the object is a EnumerationModel
static int TYPE_ITERATOR
          Returned from BeanModelBase.getType() if the object is a IteratorModel
static int TYPE_MAP
          Returned from BeanModelBase.getType() if the object is a MapModel
static int TYPE_OBJECT
          Returned from BeanModelBase.getType() if the object is a BeanModel
static int TYPE_OBJECT_BASE
          Returned from BeanModelBase.getType() if the object is a BeanModelBase
static int TYPE_RESOURCE_BUNDLE
          Returned from BeanModelBase.getType() if the object is a ResourceBundleModel
 
Constructor Summary
BeanModel(java.lang.Object object)
          Creates a new model that wraps the specified object.
 
Method Summary
 TemplateModel get(java.lang.String key)
          Uses Beans introspection to locate a property or method with name matching the key name.
 java.lang.String getAsString(java.util.Locale l)
          Returns either the toString() of the wrapped object or the string "null", if the wrapped object is null.
static BeanModel getInstance(java.lang.Object object)
          Returns a model wrapping the specified object.
static freemarker.ext.beans.BeanModelBase getInstance(java.lang.String object)
          Returns a model wrapping the specified String object.
 java.lang.Object getObject()
          Returns the wrapped object.
 int getType()
          Returns the type of this object (which is TYPE_OBJECT)
protected  TemplateModel invokeGenericGet(java.util.Map keyMap, java.lang.Class clazz, java.lang.String key)
           
 boolean isEmpty()
          Tells whether the model is empty.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface freemarker.template.TemplateModel
isEmpty
 

Field Detail

TYPE_OBJECT_BASE

public static final int TYPE_OBJECT_BASE
Returned from BeanModelBase.getType() if the object is a BeanModelBase

TYPE_OBJECT

public static final int TYPE_OBJECT
Returned from BeanModelBase.getType() if the object is a BeanModel

TYPE_ARRAY

public static final int TYPE_ARRAY
Returned from BeanModelBase.getType() if the object is a ArrayModel

TYPE_COLLECTION

public static final int TYPE_COLLECTION
Returned from BeanModelBase.getType() if the object is a CollectionModel

TYPE_MAP

public static final int TYPE_MAP
Returned from BeanModelBase.getType() if the object is a MapModel

TYPE_ITERATOR

public static final int TYPE_ITERATOR
Returned from BeanModelBase.getType() if the object is a IteratorModel

TYPE_ENUMERATION

public static final int TYPE_ENUMERATION
Returned from BeanModelBase.getType() if the object is a EnumerationModel

TYPE_RESOURCE_BUNDLE

public static final int TYPE_RESOURCE_BUNDLE
Returned from BeanModelBase.getType() if the object is a ResourceBundleModel
Constructor Detail

BeanModel

public BeanModel(java.lang.Object object)
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 to BeansWrapper.wrap(Object).
Parameters:
object - the object to wrap into a model.
Method Detail

getInstance

public static BeanModel getInstance(java.lang.Object object)
Returns a model wrapping the specified object. If there is already a cached model instance for this object, returns the cached model instance. Models are cached using WeakReference objects. The caching can be turned off by setting the freemarker.beans.nocache system property to true. In this case calling this method is equivalent to constructing a new model. 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 to BeansWrapper.wrap(Object).
Parameters:
object - the object to wrap into a model.
Returns:
the model for the object.

getType

public int getType()
Returns the type of this object (which is TYPE_OBJECT)
Overrides:
getType in class freemarker.ext.beans.BeanModelBase

get

public TemplateModel get(java.lang.String key)
                  throws TemplateModelException
Uses Beans introspection to locate a property or method with name matching the key name. If a method or property is found, it is wrapped into SimpleMethodModel (for a method or indexed property), or evaluated on the fly and the return value wrapped into appropriate model (for a simple 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. (Sidenote: 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 propery matching the key is found, the framework will try to invoke methods with signature get(java.lang.String), then get(java.lang.Object), or alternatively (if the wrapped object is a resource bundle) getObject(java.lang.String).
Specified by:
get in interface TemplateHashModel
Throws:
TemplateModelException - if there was no property nor method nor a generic get method to invoke.

invokeGenericGet

protected TemplateModel invokeGenericGet(java.util.Map keyMap,
                                         java.lang.Class clazz,
                                         java.lang.String key)
                                  throws java.lang.IllegalAccessException,
                                         java.lang.reflect.InvocationTargetException,
                                         TemplateModelException

getInstance

public static final freemarker.ext.beans.BeanModelBase getInstance(java.lang.String object)
Returns a model wrapping the specified String object. If there is already a cached model instance for this String, returns the cached model instance. Models are cached using WeakReference objects. The caching can be turned off by setting the freemarker.beans.nocache system property to true. In this case calling this method is equivalent to constructing a new model. Note that since the only Freemarker-specific method in this class is getAsString there is no sense in creating an object of this class directly with anything except a String. If you need to wrap an object of another class, use one of specialized subclasses, or delegate the choice to BeansWrapper.wrap(Object).
Parameters:
object - the String to wrap into a model.
Returns:
the model for the String

getObject

public java.lang.Object getObject()
Returns the wrapped object.

getAsString

public java.lang.String getAsString(java.util.Locale l)
Returns either the toString() of the wrapped object or the string "null", if the wrapped object is null.
Specified by:
getAsString in interface TemplateScalarModel
Parameters:
l - unused

isEmpty

public boolean isEmpty()
Tells whether the model is empty. It is empty if either the wrapped object is null, or it is a Boolean with false value.
Specified by:
isEmpty in interface TemplateModel
Following copied from interface: freemarker.template.TemplateModel
Returns:
true if this object is empty.