Class DefaultObjectWrapper
- All Implemented Interfaces:
ObjectWrapper,ObjectWrapperAndUnwrapper,ObjectWrapperWithAPISupport,RichObjectWrapper,WriteProtectable
- Direct Known Subclasses:
SimpleObjectWrapper
ObjectWrapper interface. Usually, you don't need to create instances of
this, as an instance of this is already the default value of the
object_wrapper setting. Then the
incompatibleImprovements of the DefaultObjectWrapper will be the same
that you have set for the Configuration itself. As of this writing, it's highly recommended to use
incompatibleImprovements 2.3.22 (or higher).
If you still need to create an instance, that should be done with an DefaultObjectWrapperBuilder (or
with Configuration.setSetting(String, String) with "object_wrapper" key), not with
its constructor, as that allows FreeMarker to reuse singletons. For new projects, it's recommended to set
forceLegacyNonListCollections to
false, and iterableSupport to true;
setting incompatibleImprovements to 2.3.22 won't do these, as they could break legacy templates too easily.
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_SAFEFields inherited from interface freemarker.template.ObjectWrapper
BEANS_WRAPPER, DEFAULT_WRAPPER, SIMPLE_WRAPPERFields inherited from interface freemarker.template.ObjectWrapperAndUnwrapper
CANT_UNWRAP_TO_TARGET_CLASS -
Constructor Summary
ConstructorsModifierConstructorDescriptionDeprecated.protectedDefaultObjectWrapper(BeansWrapperConfiguration bwCfg, boolean writeProtected)UseDefaultObjectWrapper(DefaultObjectWrapperConfiguration, boolean)instead if possible; it does the same, except that it tolerates a non-DefaultObjectWrapperConfigurationconfiguration too.protectedDefaultObjectWrapper(DefaultObjectWrapperConfiguration dowCfg, boolean writeProtected)CallsBeansWrapper(BeansWrapperConfiguration, boolean)and sets upDefaultObjectWrapper-specific fields.DefaultObjectWrapper(Version incompatibleImprovements)UseDefaultObjectWrapperBuilderinstead if possible. -
Method Summary
Modifier and TypeMethodDescriptionprotected ObjectconvertArray(Object arr)Converts an array to a java.util.List.booleanGetter pair ofsetDOMNodeSupport(boolean); see there.booleanGetter pair ofsetForceLegacyNonListCollections(boolean); see there.booleanGetter pair ofsetIterableSupport(boolean); see there.booleanGetter pair ofsetJythonSupport(boolean); see there.booleanThe getter pair ofsetUseAdaptersForContainers(boolean).protected TemplateModelhandleUnknownType(Object obj)Called for an object that isn't considered to be of a "basic" Java type, like for an application specific type, or for a W3C DOM node.protected static VersionnormalizeIncompatibleImprovementsVersion(Version incompatibleImprovements)Returns the lowest version number that is equivalent with the parameter version.voidsetDOMNodeSupport(boolean domNodeSupport)Enables wrappingNode-s on a special way (as described in the "XML Processing Guide" in the Manual); defaults totrue..voidsetForceLegacyNonListCollections(boolean forceLegacyNonListCollections)Specifies whether non-ListCollection-s (likeSet-s) must be wrapped by pre-fetching into aSimpleSequence.voidsetIterableSupport(boolean iterableSupport)Specifies whetherIterable-s (not to be confused withIterator-s) that don't implement any other recognized Java interfaces (most notablyCollection) will be recognized as listable objects (TemplateCollectionModel-s), or they will be just seen as generic objects (JavaBean-s).voidsetJythonSupport(boolean jythonSupport)Enables wrapping Jython objects in a special way; defaults totrue.voidsetUseAdaptersForContainers(boolean useAdaptersForContainers)protected StringReturns the name-value pairs that describe the configuration of thisBeansWrapper; called fromBeansWrapper.toString().Wraps the parameter object toTemplateModelinterface(s).wrapDomNode(Object obj)Methods inherited from class freemarker.ext.beans.BeansWrapper
checkModifiable, clearClassIntrospecitonCache, clearClassIntrospectionCache, coerceBigDecimal, coerceBigDecimals, coerceBigDecimals, finalizeConstruction, finetuneMethodAppearance, getDefaultDateType, getDefaultInstance, getDefaultZeroArgumentNonVoidMethodPolicy, getEnumModels, getExposureLevel, getIncompatibleImprovements, getInstance, getMemberAccessPolicy, getMethodAppearanceFineTuner, getModelFactory, getOuterIdentity, getPreferIndexedReadMethod, getRecordZeroArgumentNonVoidMethodPolicy, getStaticModels, getTreatDefaultMethodsAsBeanMembers, getUseCache, invokeMethod, isClassIntrospectionCacheRestricted, isExposeFields, isSimpleMapWrapper, isStrict, isWriteProtected, newInstance, readField, removeFromClassIntrospectionCache, setDefaultDateType, setDefaultZeroArgumentNonVoidMethodPolicy, setExposeFields, setExposureLevel, setMemberAccessPolicy, setMethodAppearanceFineTuner, setMethodsShadowItems, setNullModel, setOuterIdentity, setPreferIndexedReadMethod, setRecordZeroArgumentNonVoidMethodPolicy, setSimpleMapWrapper, setStrict, setTreatDefaultMethodsAsBeanMembers, setUseCache, toString, tryUnwrapTo, unwrap, unwrap, wrap, wrapAsAPI, writeProtect
-
Constructor Details
-
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
UseDefaultObjectWrapperBuilderinstead 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
useAdaptersForContainerschanges totrue. - 2.3.24 (or higher): When wrapping an
Iterator, operations on it that only check if the collection is empty without reading an element from it, such as?has_content, won't cause the a later iteration (or further emptiness check) to fail anymore. Earlier, in certain situations, the second operation has failed saying that the iterator "can be listed only once". - 2.3.26 (or higher):
Enumeration-s are wrapped intoDefaultEnumerationAdapterinstead of intoEnumerationModel(as far asuseAdaptersForContainersistrue, which is the default). This adapter is cleaner thanEnumerationModelas it only implements the minimally required FTL type, which avoids some ambiguous situations. (Note that Java API methods aren't exposed anymore as subvariables; if you really need them, you can use?api).
- 2.3.22 (or higher): The default value of
- Since:
- 2.3.21
-
DefaultObjectWrapper
UseDefaultObjectWrapper(DefaultObjectWrapperConfiguration, boolean)instead if possible; it does the same, except that it tolerates a non-DefaultObjectWrapperConfigurationconfiguration too.- Since:
- 2.3.21
-
DefaultObjectWrapper
CallsBeansWrapper(BeansWrapperConfiguration, boolean)and sets upDefaultObjectWrapper-specific fields.- Since:
- 2.3.22
-
-
Method Details
-
wrap
Wraps the parameter object toTemplateModelinterface(s). Simple types like numbers, strings, booleans and dates will be wrapped into the correspondingSimpleXxxclasses (likeSimpleNumber).Map-s,List-s, otherCollection-s, arrays andIterator-s will be wrapped into the correspondingSimpleXxxorDefaultXxxAdapterclasses (likeSimpleHashorDefaultMapAdapter), depending ongetUseAdaptersForContainers()andgetForceLegacyNonListCollections(). After that, the wrapping is handled byhandleUnknownType(Object), so see more there.- Specified by:
wrapin interfaceObjectWrapper- Overrides:
wrapin 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
TemplateModelwrapper of the object passed in. To support un-wrapping, you may consider the return value to implementWrapperTemplateModelandAdapterTemplateModel. The default expectation is that theTemplateModelisn't less thread safe than the wrapped object. If theObjectWrapperreturns 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
Called for an object that isn'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). However, these can be turned off with thesetDOMNodeSupport(boolean)andsetJythonSupport(boolean). Note that ifBeansWrapper.getMemberAccessPolicy()doesn't return aDefaultMemberAccessPolicyorLegacyDefaultMemberAccessPolicy, then Jython wrapper will be skipped for security reasons.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
-
convertArray
Converts an array to a java.util.List. -
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.trueis recommended, which is also the default when theincompatible_improvementsof this instance was set toConfiguration.VERSION_2_3_22or 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-
Listcollections (likeSet-s) will only be wrapped with adapter approach (withDefaultNonListCollectionAdapter) ifforceLegacyNonListCollectionswas 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-ListCollection-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 otherwiseSimpleSequencewill be used regardless of this. In new projects you should set this tofalse. At least beforeincompatible_improvements2.4.0 it defaults totrue, because of backward compatibility concerns: withTemplateSequenceModeltemplates 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)
-
getIterableSupport
public boolean getIterableSupport()Getter pair ofsetIterableSupport(boolean); see there.- Since:
- 2.3.25
-
setIterableSupport
public void setIterableSupport(boolean iterableSupport)Specifies whetherIterable-s (not to be confused withIterator-s) that don't implement any other recognized Java interfaces (most notablyCollection) will be recognized as listable objects (TemplateCollectionModel-s), or they will be just seen as generic objects (JavaBean-s). Defaults tofalsefor backward compatibility, but in new projects you should set this totrue. Before setting this totruein older projects, check if you have calledmyIterable.iterator()directly from any templates, because the Java API is only exposed to the templates if theIterableis wrapped as generic object.- Since:
- 2.3.25
-
getDOMNodeSupport
public final boolean getDOMNodeSupport()Getter pair ofsetDOMNodeSupport(boolean); see there.- Since:
- 2.3.31
-
setDOMNodeSupport
public void setDOMNodeSupport(boolean domNodeSupport)Enables wrappingNode-s on a special way (as described in the "XML Processing Guide" in the Manual); defaults totrue.. If this istrue,Node+s will be wrapped like any other generic object.- Since:
- 2.3.31
- See Also:
handleUnknownType(Object)
-
getJythonSupport
public final boolean getJythonSupport()Getter pair ofsetJythonSupport(boolean); see there.- Since:
- 2.3.31
-
setJythonSupport
public void setJythonSupport(boolean jythonSupport)Enables wrapping Jython objects in a special way; defaults totrue. If this isfalse, they will be wrapped like any other generic object. Note that Jython wrapping is legacy feature, and might by disabled by the selectedMemberAccessPolicy, even if this istrue; seehandleUnknownType(Object).- Since:
- 2.3.31
- See Also:
handleUnknownType(Object)
-
normalizeIncompatibleImprovementsVersion
protected static Version normalizeIncompatibleImprovementsVersion(Version incompatibleImprovements)Returns the lowest version number that is equivalent with the parameter version.- Since:
- 2.3.22
-
toPropertiesString
Description copied from class:BeansWrapperReturns 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:
toPropertiesStringin classBeansWrapper- Since:
- 2.3.22
-
DefaultObjectWrapperBuilder, or in rare cases,DefaultObjectWrapper(Version)instead.