DefaultObjectWrapper (FreeMarker 2.3.35 API)
Description: declaration: package: freemarker.template, class: DefaultObjectWrapper

Package freemarker.template

# 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 the `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_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.
  Use `DefaultObjectWrapperBuilder`, or in rare cases, `DefaultObjectWrapper(Version)` instead.
  `protected`
  `DefaultObjectWrapper​(BeansWrapperConfiguration bwCfg, boolean writeProtected)`
  Use `DefaultObjectWrapper(DefaultObjectWrapperConfiguration, boolean)` instead if possible; it does the same, except that it tolerates a non-`DefaultObjectWrapperConfiguration` configuration too.
  `protected`
  `DefaultObjectWrapper​(DefaultObjectWrapperConfiguration dowCfg, boolean writeProtected)`
  Calls `BeansWrapper(BeansWrapperConfiguration, boolean)` and sets up `DefaultObjectWrapper`-specific fields.
  ``
  `DefaultObjectWrapper​(Version incompatibleImprovements)`
  Use `DefaultObjectWrapperBuilder` instead if possible.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected Object`
  `convertArray​(Object arr)`
  Converts an array to a java.util.List.
  `boolean`
  `getDOMNodeSupport()`
  Getter pair of `setDOMNodeSupport(boolean)`; see there.
  `boolean`
  `getForceLegacyNonListCollections()`
  Getter pair of `setForceLegacyNonListCollections(boolean)`; see there.
  `boolean`
  `getIterableSupport()`
  Getter pair of `setIterableSupport(boolean)`; see there.
  `boolean`
  `getJythonSupport()`
  Getter pair of `setJythonSupport(boolean)`; see there.
  `boolean`
  `getUseAdaptersForContainers()`
  The getter pair of `setUseAdaptersForContainers(boolean)`.
  `protected TemplateModel`
  `handleUnknownType​(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 Version`
  `normalizeIncompatibleImprovementsVersion​(Version incompatibleImprovements)`
  Returns the lowest version number that is equivalent with the parameter version.
  `void`
  `setDOMNodeSupport​(boolean domNodeSupport)`
  Enables wrapping `Node`-s on a special way (as described in the "XML Processing Guide" in the Manual); defaults to `true`..
  `void`
  `setForceLegacyNonListCollections​(boolean forceLegacyNonListCollections)`
  Specifies whether non-`List` `Collection`-s (like `Set`-s) must be wrapped by pre-fetching into a `SimpleSequence`.
  `void`
  `setIterableSupport​(boolean iterableSupport)`
  Specifies whether `Iterable`-s (not to be confused with `Iterator`-s) that don't implement any other recognized Java interfaces (most notably `Collection`) will be recognized as listable objects (`TemplateCollectionModel`-s), or they will be just seen as generic objects (JavaBean-s).
  `void`
  `setJythonSupport​(boolean jythonSupport)`
  Enables wrapping Jython objects in a special way; defaults to `true`.
  `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.
  `protected String`
  `toPropertiesString()`
  Returns the name-value pairs that describe the configuration of this `BeansWrapper`; called from `BeansWrapper.toString()`.
  `TemplateModel`
  `wrap​(Object obj)`
  Wraps the parameter object to `TemplateModel` interface(s).
  `TemplateModel`
  `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`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### DefaultObjectWrapper

    @Deprecated public DefaultObjectWrapper()
    Deprecated.
    Use `DefaultObjectWrapperBuilder`, or in rare cases, `DefaultObjectWrapper(Version)` instead.
    Creates a new instance with the incompatible-improvements-version specified in `Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS`.

  - ### DefaultObjectWrapper

    public DefaultObjectWrapper​(Version incompatibleImprovements)
    Use `DefaultObjectWrapperBuilder` instead if possible. Instances created with this constructor won't share the class introspection caches with other instances. See `BeansWrapper(Version)` (the superclass constructor) for more details.
    Parameters:
      `incompatibleImprovements` - It's the same as in `BeansWrapper(Version)`, plus these changes:
      - 2.3.22 (or higher): The default value of `useAdaptersForContainers` changes to `true`.
      - 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 into `DefaultEnumerationAdapter` instead of into `EnumerationModel` (as far as `useAdaptersForContainers` is `true`, which is the default). This adapter is cleaner than `EnumerationModel` as 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`).
    Since:
      2.3.21

  - ### DefaultObjectWrapper

    protected DefaultObjectWrapper​(BeansWrapperConfiguration bwCfg, boolean writeProtected)
    Use `DefaultObjectWrapper(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)
    Calls `BeansWrapper(BeansWrapperConfiguration, boolean)` and sets up `DefaultObjectWrapper`-specific fields.
    Since:
      2.3.22

- ## Method Details

  - ### wrap

    public TemplateModel wrap​(Object obj) throws TemplateModelException
    Wraps the parameter object to `TemplateModel` interface(s). Simple types like numbers, strings, booleans and dates will be wrapped into the corresponding `SimpleXxx` classes (like `SimpleNumber`). `Map`-s, `List`-s, other `Collection`-s, arrays and `Iterator`-s will be wrapped into the corresponding `SimpleXxx` or `DefaultXxxAdapter` classes (like `SimpleHash` or `DefaultMapAdapter`), depending on `getUseAdaptersForContainers()` and `getForceLegacyNonListCollections()`. After that, the wrapping is handled by `handleUnknownType(Object)`, so see more there.
    Specified by:
      `wrap` in interface `ObjectWrapper`
    Overrides:
      `wrap` in class `BeansWrapper`
    Parameters:
      `obj` - The object to wrap into a `TemplateModel`. If it already implements `TemplateModel`, it should just return the object as is. If it's `null`, the method should return `null` (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 implement `WrapperTemplateModel` and `AdapterTemplateModel`. The default expectation is that the `TemplateModel` isn't less thread safe than the wrapped object. If the `ObjectWrapper` 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 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, W3C `Node`-s will be wrapped as `NodeModel`-s (allows DOM tree traversal), Jython objects will be delegated to the `JythonWrapper`, others will be wrapped using `BeansWrapper.wrap(Object)`. However, these can be turned off with the `setDOMNodeSupport(boolean)` and `setJythonSupport(boolean)`. Note that if `BeansWrapper.getMemberAccessPolicy()` doesn't return a `DefaultMemberAccessPolicy` or `LegacyDefaultMemberAccessPolicy`, 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

    public TemplateModel wrapDomNode​(Object obj)

  - ### convertArray

    protected Object convertArray​(Object arr)
    Converts an array to a java.util.List.

  - ### getUseAdaptersForContainers

    public boolean getUseAdaptersForContainers()
    The getter pair of `setUseAdaptersForContainers(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 the `incompatible_improvements` of this instance was set to `Configuration.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 (like `Set`-s) will only be wrapped with adapter approach (with `DefaultNonListCollectionAdapter`) if `forceLegacyNonListCollections` was set to `false`. Currently the default is `true`, but in new projects you should set it to `false`. See `setForceLegacyNonListCollections(boolean)` for more.

    Since:
      2.3.22
    See Also:
      `setForceLegacyNonListCollections(boolean)`

  - ### getForceLegacyNonListCollections

    public boolean getForceLegacyNonListCollections()
    Getter pair of `setForceLegacyNonListCollections(boolean)`; see there.
    Since:
      2.3.22

  - ### setForceLegacyNonListCollections

    public void setForceLegacyNonListCollections​(boolean forceLegacyNonListCollections)
    Specifies whether non-`List` `Collection`-s (like `Set`-s) must be wrapped by pre-fetching into a `SimpleSequence`. The modern approach is wrapping into a `DefaultNonListCollectionAdapter`. This setting only has effect when `getUseAdaptersForContainers()` is also `true`, as otherwise `SimpleSequence` will be used regardless of this. In new projects you should set this to `false`. At least before `incompatible_improvements` 2.4.0 it defaults to `true`, because of backward compatibility concerns: with `TemplateSequenceModel` 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)`

  - ### getIterableSupport

    public boolean getIterableSupport()
    Getter pair of `setIterableSupport(boolean)`; see there.
    Since:
      2.3.25

  - ### setIterableSupport

    public void setIterableSupport​(boolean iterableSupport)
    Specifies whether `Iterable`-s (not to be confused with `Iterator`-s) that don't implement any other recognized Java interfaces (most notably `Collection`) will be recognized as listable objects (`TemplateCollectionModel`-s), or they will be just seen as generic objects (JavaBean-s). Defaults to `false` for backward compatibility, but in new projects you should set this to `true`. Before setting this to `true` in older projects, check if you have called `myIterable.iterator()` directly from any templates, because the Java API is only exposed to the templates if the `Iterable` is wrapped as generic object.
    Since:
      2.3.25

  - ### getDOMNodeSupport

    public final boolean getDOMNodeSupport()
    Getter pair of `setDOMNodeSupport(boolean)`; see there.
    Since:
      2.3.31

  - ### setDOMNodeSupport

    public void setDOMNodeSupport​(boolean domNodeSupport)
    Enables wrapping `Node`-s on a special way (as described in the "XML Processing Guide" in the Manual); defaults to `true`.. If this is `true`, `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 of `setJythonSupport(boolean)`; see there.
    Since:
      2.3.31

  - ### setJythonSupport

    public void setJythonSupport​(boolean jythonSupport)
    Enables wrapping Jython objects in a special way; defaults to `true`. If this is `false`, they will be wrapped like any other generic object. Note that Jython wrapping is legacy feature, and might by disabled by the selected `MemberAccessPolicy`, even if this is `true`; see `handleUnknownType(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

    protected String toPropertiesString()
    Description copied from class: `BeansWrapper`
    Returns the name-value pairs that describe the configuration of this `BeansWrapper`; called from `BeansWrapper.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 class `BeansWrapper`
    Since:
      2.3.22