freemarker.ext.beans

Class BeansWrapper

Implemented Interfaces:
ObjectWrapper
Known Direct Subclasses:
DefaultObjectWrapper, RhinoWrapper

public class BeansWrapper
extends java.lang.Object
implements ObjectWrapper

Utility class that provides generic services to reflection classes. It handles all polymorphism issues in the wrap(Object) and unwrap(TemplateModel) methods.
Version:
$Id: BeansWrapper.java,v 1.91.2.13 2007/04/02 13:08:59 szegedia Exp $
Author:
Attila Szegedi

Field Summary

static int
EXPOSE_ALL
At this level of exposure, all methods and properties of the wrapped objects are exposed to the template.
static int
EXPOSE_NOTHING
At this level of exposure, no bean properties and methods are exposed.
static int
EXPOSE_PROPERTIES_ONLY
At this level of exposure, only property getters are exposed.
static int
EXPOSE_SAFE
At this level of exposure, all methods and properties of the wrapped objects are exposed to the template except methods that are deemed not safe.

Fields inherited from interface freemarker.template.ObjectWrapper

BEANS_WRAPPER, DEFAULT_WRAPPER, SIMPLE_WRAPPER

Constructor Summary

BeansWrapper()
Creates a new instance of BeansWrapper.

Method Summary

static void
coerceBigDecimals(AccessibleObject callable, Object[] args)
Converts any BigDecimals in the passed array to the type of the corresponding formal argument of the method.
protected TemplateModel
create(Object object, Object factory)
protected int
getDefaultDateType()
static BeansWrapper
getDefaultInstance()
Returns the default instance of the wrapper.
TemplateHashModel
getEnumModels()
Returns a hash model that represents the so-called class enum models.
protected TemplateModel
getInstance(Object object, ModelFactory factory)
ObjectWrapper
getOuterIdentity()
By default returns this.
TemplateHashModel
getStaticModels()
Returns a hash model that represents the so-called class static models.
boolean
isExposeFields()
boolean
isSimpleMapWrapper()
boolean
isStrict()
Object
newInstance(Class clazz, List arguments)
void
setDefaultDateType(int defaultDateType)
Sets the default date type to use for date models that result from a plain java.util.Date instead of java.sql.Date or java.sql.Time or java.sql.Timestamp.
void
setExposeFields(boolean exposeFields)
void
setExposureLevel(int exposureLevel)
Sets the method exposure level.
void
setMethodsShadowItems(boolean methodsShadowItems)
Sets whether methods shadow items in beans.
void
setNullModel(TemplateModel nullModel)
Sets the null model.
void
setOuterIdentity(ObjectWrapper outerIdentity)
When wrapping an object, the BeansWrapper commonly needs to wrap "sub-objects", for example each element in a wrapped collection.
void
setSimpleMapWrapper(boolean simpleMapWrapper)
By default the BeansWrapper wraps classes implementing java.util.Map using MapModel.
void
setStrict(boolean strict)
Specifies if an attempt to read a bean property that doesn't exist in the wrapped object should throw an InvalidPropertyException.
void
setUseCache(boolean useCache)
Sets whether this wrapper caches model instances.
Object
unwrap(TemplateModel model)
Attempts to unwrap a model into underlying object.
Object
unwrap(TemplateModel model, Class hint)
TemplateModel
wrap(Object object)
Wraps the object with a template model that is most specific for the object's class.

Field Details

EXPOSE_ALL

public static final int EXPOSE_ALL
At this level of exposure, all methods and properties of the wrapped objects are exposed to the template.
Field Value:
0

EXPOSE_NOTHING

public static final int EXPOSE_NOTHING
Field Value:
3

EXPOSE_PROPERTIES_ONLY

public static final int EXPOSE_PROPERTIES_ONLY
At this level of exposure, only property getters are exposed. Additionally, property getters that map to unsafe methods are not exposed (i.e. Class.classLoader and Thread.contextClassLoader).
Field Value:
2

EXPOSE_SAFE

public static final int EXPOSE_SAFE
At this level of exposure, all methods and properties of the wrapped objects are exposed to the template except methods that are deemed not safe. The not safe methods are java.lang.Object methods wait() and notify(), java.lang.Class methods getClassLoader() and newInstance(), java.lang.reflect.Method and java.lang.reflect.Constructor invoke() and newInstance() methods, all java.lang.reflect.Field set methods, all java.lang.Thread and java.lang.ThreadGroup methods that can change its state, as well as the usual suspects in java.lang.System and java.lang.Runtime.
Field Value:
1

Constructor Details

BeansWrapper

public BeansWrapper()

Method Details

coerceBigDecimals

public static void coerceBigDecimals(AccessibleObject callable,
                                     Object[] args)
Converts any BigDecimals in the passed array to the type of the corresponding formal argument of the method.

create

protected TemplateModel create(Object object,
                               Object factory)

getDefaultDateType

protected int getDefaultDateType()

getDefaultInstance

public static final BeansWrapper getDefaultInstance()
Returns the default instance of the wrapper. This instance is used when you construct various bean models without explicitly specifying a wrapper. It is also returned by ObjectWrapper.BEANS_WRAPPER and this is the sole instance that is used by the JSP adapter. You can modify the properties of the default instance (caching, exposure level, null model) to affect its operation. By default, the default instance is not caching, uses the EXPOSE_SAFE exposure level, and uses null reference as the null model.

getEnumModels

public TemplateHashModel getEnumModels()
Returns a hash model that represents the so-called class enum models. Every class' enum model is itself a hash through which you can access enum value declared by the specified class, assuming that class is an enumeration. To obtain an enum model for a class, get the element of this hash with the fully qualified class name. For example, if you place this hash model inside the root data model under name "enums", you can use i.e. statics["java.math.RoundingMode"].UP to access the java.math.RoundingMode.UP value.
Returns:
a hash model whose keys are fully qualified class names, and that returns hash models whose elements are the enum models of the classes.

getInstance

protected TemplateModel getInstance(Object object,
                                    ModelFactory factory)

getOuterIdentity

public ObjectWrapper getOuterIdentity()
By default returns this.

getStaticModels

public TemplateHashModel getStaticModels()
Returns a hash model that represents the so-called class static models. Every class static model is itself a hash through which you can call static methods on the specified class. To obtain a static model for a class, get the element of this hash with the fully qualified class name. For example, if you place this hash model inside the root data model under name "statics", you can use i.e. statics["java.lang. System"]. currentTimeMillis() to call the java.lang.System.currentTimeMillis() method.
Returns:
a hash model whose keys are fully qualified class names, and that returns hash models whose elements are the static models of the classes.

isExposeFields

public boolean isExposeFields()

isSimpleMapWrapper

public boolean isSimpleMapWrapper()

isStrict

public boolean isStrict()

newInstance

public Object newInstance(Class clazz,
                          List arguments)
            throws TemplateModelException

setDefaultDateType

public void setDefaultDateType(int defaultDateType)
Parameters:
defaultDateType - the new default date type.

setExposeFields

public void setExposeFields(boolean exposeFields)

setExposureLevel

public void setExposureLevel(int exposureLevel)
Sets the method exposure level. By default, set to EXPOSE_SAFE.
Parameters:
exposureLevel - can be any of the EXPOSE_xxx constants.

setMethodsShadowItems

public void setMethodsShadowItems(boolean methodsShadowItems)
Sets whether methods shadow items in beans. When true (this is the default value), ${object.name} will first try to locate a bean method or property with the specified name on the object, and only if it doesn't find it will it try to call object.get(name), the so-called "generic get method" that is usually used to access items of a container (i.e. elements of a map). When set to false, the lookup order is reversed and generic get method is called first, and only if it returns null is method lookup attempted.

setNullModel

public void setNullModel(TemplateModel nullModel)
Sets the null model. This model is returned from the wrap(Object) method whenever the underlying object reference is null. It defaults to null reference, which is dealt with quite strictly on engine level, however you can substitute an arbitrary (perhaps more lenient) model, such as TemplateScalarModel.EMPTY_STRING.

setOuterIdentity

public void setOuterIdentity(ObjectWrapper outerIdentity)
When wrapping an object, the BeansWrapper commonly needs to wrap "sub-objects", for example each element in a wrapped collection. Normally it wraps these objects using itself. However, this makes it difficult to delegate to a BeansWrapper as part of a custom aggregate ObjectWrapper. This method lets you set the ObjectWrapper which will be used to wrap the sub-objects.
Parameters:
outerIdentity - the aggregate ObjectWrapper

setSimpleMapWrapper

public void setSimpleMapWrapper(boolean simpleMapWrapper)
By default the BeansWrapper wraps classes implementing java.util.Map using MapModel. Setting this flag will cause it to use a SimpleMapModel instead. The biggest difference is that when using a SimpleMapModel, the map will be visible as TemplateHashModelEx, and the subvariables will be the content of the map, without the other methods and properties of the map object.
Parameters:
simpleMapWrapper - enable simple map wrapping

setStrict

public void setStrict(boolean strict)
Specifies if an attempt to read a bean property that doesn't exist in the wrapped object should throw an InvalidPropertyException.

If this property is false (the default) then an attempt to read a missing bean property is the same as reading an existing bean property whose value is null. The template can't tell the difference, and thus always can use ?default('something') and ?exists and similar built-ins to handle the situation.

If this property is true then an attempt to read a bean propertly in the template (like myBean.aProperty) that doesn't exist in the bean object (as opposed to just holding null value) will cause InvalidPropertyException, which can't be suppressed in the template (not even with myBean.noSuchProperty?default('something')). This way ?default('something') and ?exists and similar built-ins can be used to handle existing properties whose value is null, without the risk of hiding typos in the property names. Typos will always cause error. But mind you, it goes against the basic approach of FreeMarker, so use this feature only if you really know what are you doing.


setUseCache

public void setUseCache(boolean useCache)
Sets whether this wrapper caches model instances. Default is false. When set to true, calling wrap(Object) multiple times for the same object will likely return the same model (although there is no guarantee as the cache items can be cleared anytime).

unwrap

public Object unwrap(TemplateModel model)
            throws TemplateModelException
Attempts to unwrap a model into underlying object. Generally, this method is the inverse of the wrap(Object) method. In addition it will unwrap arbitrary TemplateNumberModel instances into a number, arbitrary TemplateDateModel instances into a date, TemplateScalarModel instances into a String, and TemplateBooleanModel instances into a Boolean. All other objects are returned unchanged.

unwrap

public Object unwrap(TemplateModel model,
                     Class hint)
            throws TemplateModelException

wrap

public TemplateModel wrap(Object object)
            throws TemplateModelException
Wraps the object with a template model that is most specific for the object's class. Specifically:
Specified by:
wrap in interface ObjectWrapper