Class DefaultObjectWrapper
- java.lang.Object
-
- freemarker.ext.beans.BeansWrapper
-
- freemarker.template.DefaultObjectWrapper
-
- All Implemented Interfaces:
ObjectWrapper
,ObjectWrapperAndUnwrapper
,ObjectWrapperWithAPISupport
,RichObjectWrapper
,WriteProtectable
- Direct Known Subclasses:
SimpleObjectWrapper
public class DefaultObjectWrapper extends BeansWrapper
The default implementation of theObjectWrapper
interface. Usually, you don't need to create instances of this, as an instance of this is already the default value of theobject_wrapper setting
. Then theincompatibleImprovements
of theDefaultObjectWrapper
will be the same that you have set for theConfiguration
itself. As of this writing, it's highly recommended to useincompatibleImprovements
2.3.22 (or higher).If you still need to create an instance, that should be done with an
DefaultObjectWrapperBuilder
, not with its constructor, as that allows FreeMarker to reuse singletons. For new projects, it's recommended to setforceLegacyNonListCollections
tofalse
- something that settingincompatibleImprovements
to 2.3.22 won't do.This class is only thread-safe after you have finished calling its setter methods, and then safely published it (see JSR 133 and related literature). When used as part of
Configuration
, of course it's enough if that was safely published and then left unmodified.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class freemarker.ext.beans.BeansWrapper
BeansWrapper.MethodAppearanceDecision, BeansWrapper.MethodAppearanceDecisionInput
-
-
Field Summary
-
Fields inherited from class freemarker.ext.beans.BeansWrapper
EXPOSE_ALL, EXPOSE_NOTHING, EXPOSE_PROPERTIES_ONLY, EXPOSE_SAFE
-
Fields inherited from interface freemarker.template.ObjectWrapper
BEANS_WRAPPER, DEFAULT_WRAPPER, SIMPLE_WRAPPER
-
Fields inherited from interface freemarker.template.ObjectWrapperAndUnwrapper
CANT_UNWRAP_TO_TARGET_CLASS
-
-
Constructor Summary
Constructors Modifier Constructor Description DefaultObjectWrapper()
Deprecated.UseDefaultObjectWrapperBuilder
, or in rare cases,DefaultObjectWrapper(Version)
instead.protected
DefaultObjectWrapper(BeansWrapperConfiguration bwCfg, boolean writeProtected)
UseDefaultObjectWrapper(DefaultObjectWrapperConfiguration, boolean)
instead if possible; it does the same, except that it tolerates a non-DefaultObjectWrapperConfiguration
configuration too.protected
DefaultObjectWrapper(DefaultObjectWrapperConfiguration dowCfg, boolean writeProtected)
CallsBeansWrapper(BeansWrapperConfiguration, boolean)
and sets upDefaultObjectWrapper
-specific fields.DefaultObjectWrapper(Version incompatibleImprovements)
UseDefaultObjectWrapperBuilder
instead if possible.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected Object
convertArray(Object arr)
Converts an array to a java.util.List.boolean
getForceLegacyNonListCollections()
Getter pair ofsetForceLegacyNonListCollections(boolean)
; see there.boolean
getUseAdaptersForContainers()
The getter pair ofsetUseAdaptersForContainers(boolean)
.protected TemplateModel
handleUnknownType(Object obj)
Called for an object that aren't considered to be of a "basic" Java type, like for an application specific type, or for a W3C DOM node.protected static Version
normalizeIncompatibleImprovementsVersion(Version incompatibleImprovements)
Returns the lowest version number that is equivalent with the parameter version.void
setForceLegacyNonListCollections(boolean forceLegacyNonListCollections)
Specifies whether non-List
Collection
-s (likeSet
-s) must be wrapped by pre-fetching into aSimpleSequence
.void
setUseAdaptersForContainers(boolean useAdaptersForContainers)
protected String
toPropertiesString()
Returns the name-value pairs that describe the configuration of thisBeansWrapper
; called fromBeansWrapper.toString()
.TemplateModel
wrap(Object obj)
Wraps the parameter object toTemplateModel
interface(s).TemplateModel
wrapDomNode(Object obj)
-
Methods inherited from class freemarker.ext.beans.BeansWrapper
checkModifiable, clearClassIntrospecitonCache, coerceBigDecimal, coerceBigDecimals, coerceBigDecimals, finalizeConstruction, finetuneMethodAppearance, getDefaultDateType, getDefaultInstance, getEnumModels, getExposureLevel, getIncompatibleImprovements, getInstance, getMethodAppearanceFineTuner, getModelFactory, getOuterIdentity, getStaticModels, getUseCache, isClassIntrospectionCacheRestricted, isExposeFields, isSimpleMapWrapper, isStrict, isWriteProtected, newInstance, removeFromClassIntrospectionCache, setDefaultDateType, setExposeFields, setExposureLevel, setMethodAppearanceFineTuner, setMethodsShadowItems, setNullModel, setOuterIdentity, setSimpleMapWrapper, setStrict, setUseCache, toString, tryUnwrapTo, unwrap, unwrap, wrap, wrapAsAPI, writeProtect
-
-
-
-
Constructor Detail
-
DefaultObjectWrapper
public DefaultObjectWrapper()
Deprecated.UseDefaultObjectWrapperBuilder
, or in rare cases,DefaultObjectWrapper(Version)
instead.Creates a new instance with the incompatible-improvements-version specified inConfiguration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS
.
-
DefaultObjectWrapper
public DefaultObjectWrapper(Version incompatibleImprovements)
UseDefaultObjectWrapperBuilder
instead if possible. Instances created with this constructor won't share the class introspection caches with other instances. SeeBeansWrapper(Version)
(the superclass constructor) for more details.- Parameters:
incompatibleImprovements
- It's the same as inBeansWrapper(Version)
, plus these changes:- 2.3.22 (or higher): The default value of
useAdaptersForContainers
changes totrue
.
- 2.3.22 (or higher): The default value of
- Since:
- 2.3.21
-
DefaultObjectWrapper
protected DefaultObjectWrapper(BeansWrapperConfiguration bwCfg, boolean writeProtected)
UseDefaultObjectWrapper(DefaultObjectWrapperConfiguration, boolean)
instead if possible; it does the same, except that it tolerates a non-DefaultObjectWrapperConfiguration
configuration too.- Since:
- 2.3.21
-
DefaultObjectWrapper
protected DefaultObjectWrapper(DefaultObjectWrapperConfiguration dowCfg, boolean writeProtected)
CallsBeansWrapper(BeansWrapperConfiguration, boolean)
and sets upDefaultObjectWrapper
-specific fields.- Since:
- 2.3.22
-
-
Method Detail
-
wrap
public TemplateModel wrap(Object obj) throws TemplateModelException
Wraps the parameter object toTemplateModel
interface(s). Simple types like numbers, strings, booleans and dates will be wrapped into the correspondingSimpleXxx
classes (likeSimpleNumber
).Map
-s,List
-s, otherCollection
-s, arrays andIterator
-s will be wrapped into the correspondingSimpleXxx
orDefaultXxxAdapter
classes (likeSimpleHash
orDefaultMapAdapter
), depending ongetUseAdaptersForContainers()
andgetForceLegacyNonListCollections()
. After that, the wrapping is handled byhandleUnknownType(Object)
, so see more there.- Specified by:
wrap
in interfaceObjectWrapper
- Overrides:
wrap
in classBeansWrapper
- Parameters:
obj
- The object to wrap into aTemplateModel
. If it already implementsTemplateModel
, it should just return the object as is. If it'snull
, the method should returnnull
(however,BeansWrapper
, has a legacy option for returning a null model object instead, but it's not a good idea).- Returns:
- a
TemplateModel
wrapper of the object passed in. To support un-wrapping, you may consider the return value to implementWrapperTemplateModel
andAdapterTemplateModel
. The default expectation is that theTemplateModel
isn't less thread safe than the wrapped object. If theObjectWrapper
returns less thread safe objects, that should be clearly documented, as it restricts how it can be used, like, then it can't be used to wrap "shared variables" (Configuration.setSharedVaribles(Map)
). - Throws:
TemplateModelException
-
handleUnknownType
protected TemplateModel handleUnknownType(Object obj) throws TemplateModelException
Called for an object that aren't considered to be of a "basic" Java type, like for an application specific type, or for a W3C DOM node. In its default implementation, W3CNode
-s will be wrapped asNodeModel
-s (allows DOM tree traversal), Jython objects will be delegated to theJythonWrapper
, others will be wrapped usingBeansWrapper.wrap(Object)
.When you override this method, you should first decide if you want to wrap the object in a custom way (and if so then do it and return with the result), and if not, then you should call the super method (assuming the default behavior is fine with you).
- Throws:
TemplateModelException
-
wrapDomNode
public TemplateModel wrapDomNode(Object obj)
-
getUseAdaptersForContainers
public boolean getUseAdaptersForContainers()
The getter pair ofsetUseAdaptersForContainers(boolean)
.- Since:
- 2.3.22
-
setUseAdaptersForContainers
public void setUseAdaptersForContainers(boolean useAdaptersForContainers)
Sets if to wrap container objects (Map
-s,List
-s, arrays and such) the legacy copying approach or the newer adapter approach should be used.true
is recommended, which is also the default when theincompatible_improvements
of this instance was set toConfiguration.VERSION_2_3_22
or higher. To understand the difference, check some of the classes that implement the two approaches:- Copying approach:
SimpleHash
,SimpleSequence
- Adapter approach:
DefaultMapAdapter
,DefaultListAdapter
,DefaultArrayAdapter
,DefaultIteratorAdapter
See also the related Version History entry under 2.3.22 in the FreeMarker Manual, which gives a breakdown of the consequences.
Attention: For backward compatibility, currently, non-
List
collections (likeSet
-s) will only be wrapped with adapter approach (withDefaultNonListCollectionAdapter
) ifforceLegacyNonListCollections
was set tofalse
. Currently the default istrue
, but in new projects you should set it tofalse
. SeesetForceLegacyNonListCollections(boolean)
for more.- Since:
- 2.3.22
- See Also:
setForceLegacyNonListCollections(boolean)
- Copying approach:
-
getForceLegacyNonListCollections
public boolean getForceLegacyNonListCollections()
Getter pair ofsetForceLegacyNonListCollections(boolean)
; see there.- Since:
- 2.3.22
-
setForceLegacyNonListCollections
public void setForceLegacyNonListCollections(boolean forceLegacyNonListCollections)
Specifies whether non-List
Collection
-s (likeSet
-s) must be wrapped by pre-fetching into aSimpleSequence
. The modern approach is wrapping into aDefaultNonListCollectionAdapter
. This setting only has effect whengetUseAdaptersForContainers()
is alsotrue
, as otherwiseSimpleSequence
will be used regardless of this. In new projects you should set this tofalse
. At least beforeincompatible_improvements
2.4.0 it defaults totrue
, because of backward compatibility concerns: withTemplateSequenceModel
templates could access the items by index if they wanted to (the index values were defined by the iteration order). This was not very useful, or was even confusing, and it conflicts with the adapter approach.- Since:
- 2.3.22
- See Also:
setUseAdaptersForContainers(boolean)
-
normalizeIncompatibleImprovementsVersion
protected static Version normalizeIncompatibleImprovementsVersion(Version incompatibleImprovements)
Returns the lowest version number that is equivalent with the parameter version.- Since:
- 2.3.22
-
toPropertiesString
protected String toPropertiesString()
Description copied from class:BeansWrapper
Returns the name-value pairs that describe the configuration of thisBeansWrapper
; called fromBeansWrapper.toString()
. The expected format is like"foo=bar, baaz=wombat"
. When overriding this, you should call the super method, and then insert the content before it with a following", "
, or after it with a preceding", "
.- Overrides:
toPropertiesString
in classBeansWrapper
- Since:
- 2.3.22
-
-