BeansWrapper (FreeMarker 2.3.35 API)
Description: declaration: package: freemarker.ext.beans, class: BeansWrapper

Package freemarker.ext.beans

# Class BeansWrapper

java.lang.Object
freemarker.ext.beans.BeansWrapper

All Implemented Interfaces:
  `ObjectWrapper`, `ObjectWrapperAndUnwrapper`, `ObjectWrapperWithAPISupport`, `RichObjectWrapper`, `WriteProtectable`

Direct Known Subclasses:
  `DefaultObjectWrapper`, `RhinoWrapper`

public class BeansWrapper extends Object implements RichObjectWrapper, WriteProtectable
`ObjectWrapper` that is able to expose the Java API of arbitrary Java objects. This is also the superclass of `DefaultObjectWrapper`. Note that instances of this class generally should be created with a `BeansWrapperBuilder`, not with its public constructors.

As of 2.3.22, using `BeansWrapper` unextended is not recommended. Instead, `DefaultObjectWrapper` with its `incompatibleImprovements` property set to 2.3.22 (or higher) is the recommended `ObjectWrapper`.

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. Using `BeansWrapperBuilder` also guarantees thread safety.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `BeansWrapper.MethodAppearanceDecision`
  Used for `MethodAppearanceFineTuner.process(freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput, freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision)` to store the results; see there.
  `static class`
  `BeansWrapper.MethodAppearanceDecisionInput`
  Used for `MethodAppearanceFineTuner.process(freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput, freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision)` as input parameter; see there.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static int`
  `EXPOSE_ALL`
  At this level of exposure, all methods and properties of the wrapped objects are exposed to the template, and even the `MemberAccessPolicy` is ignored.
  `static int`
  `EXPOSE_NOTHING`
  At this level of exposure, no Java Bean properties, and no methods are exposed.
  `static int`
  `EXPOSE_PROPERTIES_ONLY`
  At this level of exposure, only Java Bean properties 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 by the `MemberAccessPolicy`.

  ### 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
  ``
  `BeansWrapper()`
  Deprecated.
  Use `BeansWrapperBuilder` or, in rare cases, `BeansWrapper(Version)` instead.
  `protected`
  `BeansWrapper​(BeansWrapperConfiguration bwConf, boolean writeProtected)`
  Same as `BeansWrapper(BeansWrapperConfiguration, boolean, boolean)` with `true` `finalizeConstruction` argument.
  `protected`
  `BeansWrapper​(BeansWrapperConfiguration bwConf, boolean writeProtected, boolean finalizeConstruction)`
  Initializes the instance based on the `BeansWrapperConfiguration` specified.
  ``
  `BeansWrapper​(Version incompatibleImprovements)`
  Use `BeansWrapperBuilder` instead of the public constructors if possible.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected void`
  `checkModifiable()`
  If this object is already read-only according to `WriteProtectable`, throws `IllegalStateException`, otherwise does nothing.
  `void`
  `clearClassIntrospecitonCache()`
  Deprecated.
  There's a typo in this method name, so use `clearClassIntrospectionCache()` instead.
  `void`
  `clearClassIntrospectionCache()`
  Removes all class introspection data from the cache.
  `static Object`
  `coerceBigDecimal​(BigDecimal bd, Class<?> formalType)`
  Converts `BigDecimal` to the class given in the `formalType` argument if that's a known numerical type, returns the `BigDecimal` as is otherwise.
  `static void`
  `coerceBigDecimals​(Class<?>[] formalTypes, Object[] args)`
  Converts any `BigDecimal`-s in the passed array to the type of the corresponding formal argument of the method via `coerceBigDecimal(BigDecimal, Class)`.
  `static void`
  `coerceBigDecimals​(AccessibleObject callable, Object[] args)`
  Converts any `BigDecimal`s in the passed array to the type of the corresponding formal argument of the method.
  `protected void`
  `finalizeConstruction​(boolean writeProtected)`
  Meant to be called after `BeansWrapper(BeansWrapperConfiguration, boolean, boolean)` when its last argument was `false`; makes the instance read-only if necessary, then registers the model factories in the class introspector.
  `protected void`
  `finetuneMethodAppearance​(Class<?> clazz, Method m, BeansWrapper.MethodAppearanceDecision decision)`
  Deprecated.
  Use `setMethodAppearanceFineTuner(MethodAppearanceFineTuner)`; no need to extend this class anymore.
  `int`
  `getDefaultDateType()`
  Returns the default date type.
  `static BeansWrapper`
  `getDefaultInstance()`
  Deprecated.
  Use `BeansWrapperBuilder` instead.
  `ZeroArgumentNonVoidMethodPolicy`
  `getDefaultZeroArgumentNonVoidMethodPolicy()`
  See `setDefaultZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)`.
  `TemplateHashModel`
  `getEnumModels()`
  Returns a hash model that represents the so-called class enum models.
  `int`
  `getExposureLevel()`
  `Version`
  `getIncompatibleImprovements()`
  Returns the version given with `BeansWrapper(Version)`, normalized to the lowest version where a change has occurred.
  `protected TemplateModel`
  `getInstance​(Object object, ModelFactory factory)`
  Deprecated.
  override `getModelFactory(Class)` instead.
  `MemberAccessPolicy`
  `getMemberAccessPolicy()`
  `MethodAppearanceFineTuner`
  `getMethodAppearanceFineTuner()`
  `protected ModelFactory`
  `getModelFactory​(Class<?> clazz)`
  `ObjectWrapper`
  `getOuterIdentity()`
  By default returns `this`.
  `boolean`
  `getPreferIndexedReadMethod()`
  Getter pair of `setPreferIndexedReadMethod(boolean)`
  `ZeroArgumentNonVoidMethodPolicy`
  `getRecordZeroArgumentNonVoidMethodPolicy()`
  See `setRecordZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)`.
  `TemplateHashModel`
  `getStaticModels()`
  Returns a hash model that represents the so-called class static models.
  `boolean`
  `getTreatDefaultMethodsAsBeanMembers()`
  See `setTreatDefaultMethodsAsBeanMembers(boolean)`.
  `boolean`
  `getUseCache()`
  `protected TemplateModel`
  `invokeMethod​(Object object, Method method, Object[] args)`
  Invokes the specified method, wrapping the return value.
  `boolean`
  `isClassIntrospectionCacheRestricted()`
  Tells if this instance acts like if its class introspection cache is sharable with other `BeansWrapper`-s.
  `boolean`
  `isExposeFields()`
  Returns whether exposure of public instance fields of classes is enabled.
  `boolean`
  `isSimpleMapWrapper()`
  Tells whether Maps are exposed as simple maps, without access to their method.
  `boolean`
  `isStrict()`
  `boolean`
  `isWriteProtected()`
  `Object`
  `newInstance​(Class<?> clazz, List arguments)`
  Creates a new instance of the specified class using the method call logic of this object wrapper for calling the constructor.
  `protected static Version`
  `normalizeIncompatibleImprovementsVersion​(Version incompatibleImprovements)`
  Returns the lowest version number that is equivalent with the parameter version.
  `protected TemplateModel`
  `readField​(Object object, Field field)`
  Reads the specified field, returns its value as `TemplateModel`.
  `void`
  `removeFromClassIntrospectionCache​(Class<?> clazz)`
  Removes the introspection data for a class from the cache.
  `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`
  `setDefaultZeroArgumentNonVoidMethodPolicy​(ZeroArgumentNonVoidMethodPolicy defaultZeroArgumentNonVoidMethodPolicy)`
  Sets the `ZeroArgumentNonVoidMethodPolicy` for classes that are not Java records; defaults to `ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY`.
  `void`
  `setExposeFields​(boolean exposeFields)`
  Controls whether public instance fields of classes are exposed to templates.
  `void`
  `setExposureLevel​(int exposureLevel)`
  Sets the method exposure level.
  `void`
  `setMemberAccessPolicy​(MemberAccessPolicy memberAccessPolicy)`
  Sets the `MemberAccessPolicy`; default is `DefaultMemberAccessPolicy.getInstance(Version)`, which is not appropriate if template editors aren't trusted.
  `void`
  `setMethodAppearanceFineTuner​(MethodAppearanceFineTuner methodAppearanceFineTuner)`
  Used to tweak certain aspects of how methods appear in the data-model; see `MethodAppearanceFineTuner` for more.
  `void`
  `setMethodsShadowItems​(boolean methodsShadowItems)`
  Sets whether methods shadow items in beans.
  `void`
  `setNullModel​(TemplateModel nullModel)`
  Deprecated.
  Changing the `null` model can cause a lot of confusion; don't do it.
  `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`
  `setPreferIndexedReadMethod​(boolean preferIndexedReadMethod)`
  Sets if when a JavaBean property has both a normal read method (like `String[] getFoos()`) and an indexed read method (like `String getFoos(int index)`), and the Java `Introspector` exposes both (which only happens since Java 8, apparently), which read method will be used when the property is accessed with the shorthand syntax (like `myObj.foos`).
  `void`
  `setRecordZeroArgumentNonVoidMethodPolicy​(ZeroArgumentNonVoidMethodPolicy recordZeroArgumentNonVoidMethodPolicy)`
  Sets the `ZeroArgumentNonVoidMethodPolicy` for classes that are Java records; if the `BeansWrapper#BeansWrapper(Version) incompatibleImprovements` of the object wrapper is at least 2.3.33, then this defaults to `ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD`, otherwise this defaults to `ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY`.
  `void`
  `setSimpleMapWrapper​(boolean simpleMapWrapper)`
  When set to `true`, the keys in `Map`-s won't mix with the method names when looking at them from templates.
  `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`
  `setTreatDefaultMethodsAsBeanMembers​(boolean treatDefaultMethodsAsBeanMembers)`
  Controls whether Java 8 default methods that weren't overridden in a class will be recognized as bean property accessors and/or bean actions, and thus will be visible from templates.
  `void`
  `setUseCache​(boolean useCache)`
  Sets whether this wrapper caches the `TemplateModel`-s created for the Java objects that has wrapped with this object wrapper.
  `protected String`
  `toPropertiesString()`
  Returns the name-value pairs that describe the configuration of this `BeansWrapper`; called from `toString()`.
  `String`
  `toString()`
  Returns the exact class name and the identity hash, also the values of the most often used `BeansWrapper` configuration properties, also if which (if any) shared class introspection cache it uses.
  `Object`
  `tryUnwrapTo​(TemplateModel model, Class<?> targetClass)`
  Attempts to unwrap a `TemplateModel` to a plain Java object that's the instance of the given class (or is `null`).
  `Object`
  `unwrap​(TemplateModel model)`
  Attempts to unwrap a model into underlying object.
  `Object`
  `unwrap​(TemplateModel model, Class<?> targetClass)`
  Attempts to unwrap a model into an object of the desired class.
  `TemplateModel`
  `wrap​(Object object)`
  Wraps the object with a template model that is most specific for the object's class.
  `TemplateMethodModelEx`
  `wrap​(Object object, Method method)`
  Wraps a Java method so that it can be called from templates, without wrapping its parent ("this") object.
  `TemplateHashModel`
  `wrapAsAPI​(Object obj)`
  Wraps an object to a `TemplateModel` that exposes the object's "native" (usually, Java) API.
  `void`
  `writeProtect()`
  Makes the configuration properties (settings) of this `BeansWrapper` object read-only.

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

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

- ## 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, and even the `MemberAccessPolicy` is ignored.
    See Also:
      Constant Field Values

  - ### 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 by the `MemberAccessPolicy`.

    Note that the `MemberAccessPolicy` will further restrict what's visible. That mechanism was introduced much later than "exposure levels", and it's the primary place to look at if you are concerned with safety.

    See Also:
      Constant Field Values

  - ### EXPOSE_PROPERTIES_ONLY

    public static final int EXPOSE_PROPERTIES_ONLY
    At this level of exposure, only Java Bean properties are exposed. For example, if you have `public int getX()` in a public class, then you can access that in templates like `obj.x` (but not as `obj.getX()`).

    Note that the `MemberAccessPolicy` will further restricts what's visible. Java Bean properties (like `obj.x` earlier) whose read method (like `getX()` earlier) is not accessible according the policy will not be visible.

    See Also:
      Constant Field Values

  - ### EXPOSE_NOTHING

    public static final int EXPOSE_NOTHING
    At this level of exposure, no Java Bean properties, and no methods are exposed. Only map items, resource bundle items, and objects retrieved through the generic get method (on objects of classes that have a generic get method) can be retrieved through the `TemplateHashModel` interface. You might want to call `setMethodsShadowItems(boolean)` with `false` value to speed up map item retrieval.
    See Also:
      Constant Field Values

- ## Constructor Details

  - ### BeansWrapper

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

  - ### BeansWrapper

    public BeansWrapper​(Version incompatibleImprovements)
    Use `BeansWrapperBuilder` instead of the public constructors if possible. The main disadvantage of using the public constructors is that the instances won't share caches. So unless having a private cache is your goal, don't use them. See
    Parameters:
      `incompatibleImprovements` - Sets which of the non-backward-compatible improvements should be enabled. Not `null`. This version number is the same as the FreeMarker version number with which the improvements were implemented.

      For new projects, it's recommended to set this to the FreeMarker version that's used during the development. For released products that are still actively developed it's a low risk change to increase the 3rd version number further as FreeMarker is updated, but of course you should always check the list of effects below. Increasing the 2nd or 1st version number possibly mean substantial changes with higher risk of breaking the application, but again, see the list of effects below.

      The reason it's separate from `Configuration.setIncompatibleImprovements(Version)` is that `ObjectWrapper` objects are sometimes shared among multiple `Configuration`-s, so the two version numbers are technically independent. But it's recommended to keep those two version numbers the same. Actually, if you leave the `object_wrapper` setting at its default (and most do), then that will be kept the same as of the `Configuration`.

      The changes enabled by `incompatibleImprovements` are (but also check the changes at `DefaultObjectWrapper(Version)`, if you are using `DefaultObjectWrapper`):

      - 2.3.0: No changes; this is the starting point, the version used in older projects.

      - 2.3.21 (or higher): Several glitches were fixed in overloaded method selection. This usually just gets rid of errors (like ambiguity exceptions and numerical precision loses due to bad overloaded method choices), still, as in some cases the method chosen can be a different one now (that was the point of the reworking after all), it can mean a change in the behavior of the application. The most important change is that the treatment of `null` arguments were fixed, as earlier they were only seen applicable to parameters of type `Object`. Now `null`-s are seen to be applicable to any non-primitive parameters, and among those the one with the most specific type will be preferred (just like in Java), which is hence never the one with the `Object` parameter type. For more details about overloaded method selection changes see the version history in the FreeMarker Manual.

      - 2.3.24 (or higher): `Iterator`-s were always said to be non-empty when using `?has_content` and such (i.e., operators that check emptiness without reading any elements). Now an `Iterator` counts as empty exactly if it has no elements left. (Note that this bug has never affected basic functionality, like `<#list ...>`.)

      - 2.3.26 (or higher): The default of `getTreatDefaultMethodsAsBeanMembers()` changes from `false` to `true`. Thus, Java 8 default methods (and the bean properties they define) are exposed, despite that `Introspector` (the official JavaBeans introspector) ignores them, at least as of Java 8.

      - 2.3.27 (or higher): The default of the `preferIndexedReadMethod` setting changes from `true` to `false`.

      - 2.3.33 (or higher): The default of `setRecordZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)` has changed to `ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD`, from `ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY`. This means that Java record public methods with 0-arguments and non-void return type are now exposed both as properties, and as methods, while earlier they were only exposed as methods. That is, if in a record you have `public String name()`, now in templates the value can be accessed both as `obj.name` (like a property), and as `obj.name()` (for better backward compatibility only - it's bad style).

      - 2.3.35 (or higher): `isFoo()` methods that return `Boolean` (the wrapper class) are now exposed as the `foo` bean property, just like `isFoo()` methods returning primitive `boolean` already were. Before this, `Introspector` (which is spec-strict) reported only primitive-`boolean` `isFoo()` methods as property readers, so `Boolean isFoo()` was accessible only as a method (`obj.isFoo()`).

      Note that the version will be normalized to the lowest version where the same incompatible `BeansWrapper` improvements were already present, so `getIncompatibleImprovements()` might return a lower version than what you have specified.

      Note again that most projects use `DefaultObjectWrapper` (which extends `BeansWrapper`), in which case see the additional changes at `DefaultObjectWrapper(Version)`!

    Since:
      2.3.21

  - ### BeansWrapper

    protected BeansWrapper​(BeansWrapperConfiguration bwConf, boolean writeProtected)
    Same as `BeansWrapper(BeansWrapperConfiguration, boolean, boolean)` with `true` `finalizeConstruction` argument.
    Since:
      2.3.21

  - ### BeansWrapper

    protected BeansWrapper​(BeansWrapperConfiguration bwConf, boolean writeProtected, boolean finalizeConstruction)
    Initializes the instance based on the `BeansWrapperConfiguration` specified.
    Parameters:
      `writeProtected` - Makes the instance's configuration settings read-only via `WriteProtectable.writeProtect()`; this way it can use the shared class introspection cache.
      `finalizeConstruction` - Decides if the construction is finalized now, or the caller will do some more adjustments on the instance and then call `finalizeConstruction(boolean)` itself.
    Since:
      2.3.22

- ## Method Details

  - ### finalizeConstruction

    protected void finalizeConstruction​(boolean writeProtected)
    Meant to be called after `BeansWrapper(BeansWrapperConfiguration, boolean, boolean)` when its last argument was `false`; makes the instance read-only if necessary, then registers the model factories in the class introspector. No further changes should be done after calling this, if `writeProtected` was `true`.
    Since:
      2.3.22

  - ### writeProtect

    public void writeProtect()
    Makes the configuration properties (settings) of this `BeansWrapper` object read-only. As changing them after the object has become visible to multiple threads leads to undefined behavior, it's recommended to call this when you have finished configuring the object.

    Consider using `BeansWrapperBuilder` instead, which gives an instance that's already write protected and also uses some shared caches/pools.

    Specified by:
      `writeProtect` in interface `WriteProtectable`
    Since:
      2.3.21

  - ### isWriteProtected

    public boolean isWriteProtected()
    Specified by:
      `isWriteProtected` in interface `WriteProtectable`
    Since:
      2.3.21

  - ### checkModifiable

    protected void checkModifiable()
    If this object is already read-only according to `WriteProtectable`, throws `IllegalStateException`, otherwise does nothing.
    Since:
      2.3.21

  - ### isStrict

    public boolean isStrict()
    See Also:
      `setStrict(boolean)`

  - ### 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 you are doing.

  - ### 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

  - ### getOuterIdentity

    public ObjectWrapper getOuterIdentity()
    By default returns `this`.
    See Also:
      `setOuterIdentity(ObjectWrapper)`

  - ### setSimpleMapWrapper

    public void setSimpleMapWrapper​(boolean simpleMapWrapper)
    When set to `true`, the keys in `Map`-s won't mix with the method names when looking at them from templates. The default is `false` for backward-compatibility, but is not recommended.

    When this is `false`, `myMap.foo` or `myMap['foo']` either returns the method `foo`, or calls `Map.get("foo")`. If both exists (the method and the `Map` key), one will hide the other, depending on the `isMethodsShadowItems()`, which default to `true` (the method wins). Some frameworks use this so that you can call `myMap.get(nonStringKey)` from templates [*], but it comes on the cost of polluting the key-set with the method names, and risking methods accidentally hiding `Map` entries (or the other way around). Thus, this setup is not recommended. (Technical note: `Map`-s will be wrapped into `MapModel` in this case.)

    When this is `true`, `myMap.foo` or `myMap['foo']` always calls `Map.get("foo")`. The methods of the `Map` object aren't visible from templates in this case. This, however, spoils the `myMap.get(nonStringKey)` workaround. But now you can use `myMap(nonStringKey)` instead, that is, you can use the map itself as the `get` method. (Technical note: `Map`-s will be wrapped into `SimpleMapModel` in this case.)

    *: For historical reasons, FreeMarker 2.3.X doesn't support non-string keys with the `[]` operator, hence the workarounds. This will be likely fixed in FreeMarker 2.4.0. Also note that the method- and the "field"-namespaces aren't separate in FreeMarker, hence `myMap.get` can return the `get` method.

  - ### isSimpleMapWrapper

    public boolean isSimpleMapWrapper()
    Tells whether Maps are exposed as simple maps, without access to their method. See `setSimpleMapWrapper(boolean)` for details.
    Returns:
      true if Maps are exposed as simple hashes, false if they're exposed as full JavaBeans.

  - ### getPreferIndexedReadMethod

    public boolean getPreferIndexedReadMethod()
    Getter pair of `setPreferIndexedReadMethod(boolean)`
    Since:
      2.3.27

  - ### setPreferIndexedReadMethod

    public void setPreferIndexedReadMethod​(boolean preferIndexedReadMethod)
    Sets if when a JavaBean property has both a normal read method (like `String[] getFoos()`) and an indexed read method (like `String getFoos(int index)`), and the Java `Introspector` exposes both (which only happens since Java 8, apparently), which read method will be used when the property is accessed with the shorthand syntax (like `myObj.foos`). Before `incompatibleImprovements` 2.3.27 it defaults to `true` for backward compatibility (although it's actually less backward compatible if you are just switching to Java 8; see later), but the recommended value and the default starting with `incompatibleImprovements` 2.3.27 is `false`. This setting has no effect on properties that only has normal read method, or only has indexed read method. In case a property has both, using the indexed reader method is disadvantageous, as then FreeMarker can't tell what the highest allowed index is, and so the property will be unlistable (`<#list foo as myObj.foos>` will fail).

    Apparently, this setting only matters since Java 8, as before that `Introspector` did not expose the indexed reader method if there was also a normal reader method. As with Java 8 the behavior of `Introspector` has changed, some old templates started to break, as the property has suddenly become unlistable (see earlier why). So setting this to `false` can be seen as a Java 8 compatibility fix.

    Since:
      2.3.27

  - ### 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. Note that `setMemberAccessPolicy(MemberAccessPolicy)` further restricts what's visible, unless this is set to `EXPOSE_ALL`.

  - ### getExposureLevel

    public int getExposureLevel()
    Since:
      2.3.21

  - ### setExposeFields

    public void setExposeFields​(boolean exposeFields)
    Controls whether public instance fields of classes are exposed to templates.
    Parameters:
      `exposeFields` - if set to true, public instance fields of classes that do not have a property getter defined can be accessed directly by their name. If there is a property getter for a property of the same name as the field (i.e. getter "getFoo()" and field "foo"), then referring to "foo" in template invokes the getter. If set to false, no access to public instance fields of classes is given. Default is false.

  - ### setTreatDefaultMethodsAsBeanMembers

    public void setTreatDefaultMethodsAsBeanMembers​(boolean treatDefaultMethodsAsBeanMembers)
    Controls whether Java 8 default methods that weren't overridden in a class will be recognized as bean property accessors and/or bean actions, and thus will be visible from templates. (We expose bean properties and bean actions, not methods in general.) Before `incompatibleImprovements` 2.3.26 this defaults to `false` for backward compatibility. Starting with `incompatibleImprovements` 2.3.26 it defaults to `true`.

    Some explanation: FreeMarker uses `Introspector` to discover the bean properties and actions of classes, for maximum conformance to the JavaBeans specification. But for some reason (perhaps just a bug in the Oracle/OpenJDK Java 8 implementation) that ignores the Java 8 default methods coming from the interfaces. When this setting is `true`, we search for non-overridden default methods ourselves, and add them to the set of discovered bean members.

    Since:
      2.3.26

  - ### setDefaultZeroArgumentNonVoidMethodPolicy

    public void setDefaultZeroArgumentNonVoidMethodPolicy​(ZeroArgumentNonVoidMethodPolicy defaultZeroArgumentNonVoidMethodPolicy)
    Sets the `ZeroArgumentNonVoidMethodPolicy` for classes that are not Java records; defaults to `ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY`.

    Note that methods in this class are inherited by `DefaultObjectWrapper`, which is what you normally use.

    Since:
      2.3.33

  - ### setRecordZeroArgumentNonVoidMethodPolicy

    public void setRecordZeroArgumentNonVoidMethodPolicy​(ZeroArgumentNonVoidMethodPolicy recordZeroArgumentNonVoidMethodPolicy)
    Sets the `ZeroArgumentNonVoidMethodPolicy` for classes that are Java records; if the `BeansWrapper#BeansWrapper(Version) incompatibleImprovements` of the object wrapper is at least 2.3.33, then this defaults to `ZeroArgumentNonVoidMethodPolicy.BOTH_METHOD_AND_PROPERTY_UNLESS_BEAN_PROPERTY_READ_METHOD`, otherwise this defaults to `ZeroArgumentNonVoidMethodPolicy.METHOD_ONLY`.

    Note that methods in this class are inherited by `DefaultObjectWrapper`, which is what you normally use.

    Since:
      2.3.33

  - ### isExposeFields

    public boolean isExposeFields()
    Returns whether exposure of public instance fields of classes is enabled. See `setExposeFields(boolean)` for details.
    Returns:
      true if public instance fields are exposed, false otherwise.
    Since:
      2.3.26

  - ### getTreatDefaultMethodsAsBeanMembers

    public boolean getTreatDefaultMethodsAsBeanMembers()
    See `setTreatDefaultMethodsAsBeanMembers(boolean)`.

  - ### getDefaultZeroArgumentNonVoidMethodPolicy

    public ZeroArgumentNonVoidMethodPolicy getDefaultZeroArgumentNonVoidMethodPolicy()
    See `setDefaultZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)`.
    Since:
      2.3.33

  - ### getRecordZeroArgumentNonVoidMethodPolicy

    public ZeroArgumentNonVoidMethodPolicy getRecordZeroArgumentNonVoidMethodPolicy()
    See `setRecordZeroArgumentNonVoidMethodPolicy(ZeroArgumentNonVoidMethodPolicy)`.
    Since:
      2.3.33

  - ### getMethodAppearanceFineTuner

    public MethodAppearanceFineTuner getMethodAppearanceFineTuner()

  - ### setMethodAppearanceFineTuner

    public void setMethodAppearanceFineTuner​(MethodAppearanceFineTuner methodAppearanceFineTuner)
    Used to tweak certain aspects of how methods appear in the data-model; see `MethodAppearanceFineTuner` for more.

  - ### getMemberAccessPolicy

    public MemberAccessPolicy getMemberAccessPolicy()
    Since:
      2.3.30

  - ### setMemberAccessPolicy

    public void setMemberAccessPolicy​(MemberAccessPolicy memberAccessPolicy)
    Sets the `MemberAccessPolicy`; default is `DefaultMemberAccessPolicy.getInstance(Version)`, which is not appropriate if template editors aren't trusted.
    Since:
      2.3.30

  - ### isClassIntrospectionCacheRestricted

    public boolean isClassIntrospectionCacheRestricted()
    Tells if this instance acts like if its class introspection cache is sharable with other `BeansWrapper`-s. A restricted cache denies certain too "antisocial" operations, like `clearClassIntrospectionCache()`. The value depends on how the instance was created; with a public constructor (then this is `false`), or with `BeansWrapperBuilder` (then it's `true`). Note that in the last case it's possible that the introspection cache will not be actually shared because there's no one to share with, but this will `true` even then.
    Since:
      2.3.21

  - ### 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.

  - ### setDefaultDateType

    public 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`. Default value is `TemplateDateModel.UNKNOWN`.
    Parameters:
      `defaultDateType` - the new default date type.

  - ### getDefaultDateType

    public int getDefaultDateType()
    Returns the default date type. See `setDefaultDateType(int)` for details.
    Returns:
      the default date type

  - ### setUseCache

    public void setUseCache​(boolean useCache)
    Sets whether this wrapper caches the `TemplateModel`-s created for the Java objects that has wrapped with this object wrapper. 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 any time).

  - ### getUseCache

    public boolean getUseCache()
    Since:
      2.3.21

  - ### setNullModel

    @Deprecated public void setNullModel​(TemplateModel nullModel)
    Deprecated.
    Changing the `null` model can cause a lot of confusion; don't do it.
    Sets the null model. This model is returned from the `wrap(Object)` method whenever the wrapped object is `null`. It defaults to `null`, which is dealt with quite strictly on engine level, however you can substitute an arbitrary (perhaps more lenient) model, like an empty string. For proper working, the `nullModel` should be an `AdapterTemplateModel` that returns `null` for `AdapterTemplateModel.getAdaptedObject(Class)`.

  - ### getIncompatibleImprovements

    public Version getIncompatibleImprovements()
    Returns the version given with `BeansWrapper(Version)`, normalized to the lowest version where a change has occurred. Thus, this is not necessarily the same version than that was given to the constructor.
    Since:
      2.3.21

  - ### normalizeIncompatibleImprovementsVersion

    protected static Version normalizeIncompatibleImprovementsVersion​(Version incompatibleImprovements)
    Returns the lowest version number that is equivalent with the parameter version.
    Since:
      2.3.21

  - ### getDefaultInstance

    @Deprecated public static final BeansWrapper getDefaultInstance()
    Deprecated.
    Use `BeansWrapperBuilder` instead. The instance returned here is not read-only, so it's dangerous to use.
    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.

  - ### 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:
    - if the object is null, returns the `null model`,
    - if the object is a Number returns a `NumberModel` for it,
    - if the object is a Date returns a `DateModel` for it,
    - if the object is a Boolean returns `TemplateBooleanModel.TRUE` or `TemplateBooleanModel.FALSE`
    - if the object is already a TemplateModel, returns it unchanged,
    - if the object is an array, returns a `ArrayModel` for it
    - if the object is a Map, returns a `MapModel` for it
    - if the object is a Collection, returns a `CollectionModel` for it
    - if the object is an Iterator, returns a `IteratorModel` for it
    - if the object is an Enumeration, returns a `EnumerationModel` for it
    - if the object is a String, returns a `StringModel` for it
    - otherwise, returns a `GenericObjectModel` for it.
    Specified by:
      `wrap` in interface `ObjectWrapper`
    Parameters:
      `object` - 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`

  - ### wrap

    public TemplateMethodModelEx wrap​(Object object, Method method)
    Wraps a Java method so that it can be called from templates, without wrapping its parent ("this") object. The result is almost the same as that you would get by wrapping the parent object then getting the method from the resulting `TemplateHashModel` by name. Except, if the wrapped method is overloaded, with this method you explicitly select an overload, while otherwise you would get a `TemplateMethodModelEx` that selects an overload each time it's called based on the argument values.
    Parameters:
      `object` - The object whose method will be called, or `null` if `method` is a static method. This object will be used "as is", like without unwrapping it if it's a `TemplateModelAdapter`.
      `method` - The method to call, which must be an (inherited) member of the class of `object`, as described by `Method.invoke(Object, Object...)`
    Since:
      2.3.22

  - ### wrapAsAPI

    public TemplateHashModel wrapAsAPI​(Object obj) throws TemplateModelException
    Description copied from interface: `ObjectWrapperWithAPISupport`
    Wraps an object to a `TemplateModel` that exposes the object's "native" (usually, Java) API.
    Specified by:
      `wrapAsAPI` in interface `ObjectWrapperWithAPISupport`
    Parameters:
      `obj` - The object for which the API model has to be returned. Shouldn't be `null`.
    Returns:
      The `TemplateModel` through which the API of the object can be accessed. Can't be `null`.
    Throws:
      `TemplateModelException`
    Since:
      2.3.22

  - ### getInstance

    @Deprecated protected TemplateModel getInstance​(Object object, ModelFactory factory)
    Deprecated.
    override `getModelFactory(Class)` instead. Using this method will now bypass wrapper caching (if it's enabled) and always result in creation of a new wrapper. This method will be removed in 2.4
    Parameters:
      `object` - The object to wrap
      `factory` - The factory that wraps the object

  - ### getModelFactory

    protected ModelFactory getModelFactory​(Class<?> clazz)

  - ### 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, arbitrary `TemplateBooleanModel` instances into a Boolean, arbitrary `TemplateHashModel` instances into a Map, arbitrary `TemplateSequenceModel` into a List, and arbitrary `TemplateCollectionModel` into a Set. All other objects are returned unchanged.
    Specified by:
      `unwrap` in interface `ObjectWrapperAndUnwrapper`
    Returns:
      The plain Java object. Can be `null`, if `null` is the appropriate Java value to represent the template model. `null` must not be used to indicate an unwrapping failure. It must NOT be `ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS`.
    Throws:
      `TemplateModelException` - if an attempted unwrapping fails.
    See Also:
      `ObjectWrapperAndUnwrapper.tryUnwrapTo(TemplateModel, Class)`

  - ### unwrap

    public Object unwrap​(TemplateModel model, Class<?> targetClass) throws TemplateModelException
    Attempts to unwrap a model into an object of the desired class. Generally, this method is the inverse of the `wrap(Object)` method. It recognizes a wide range of target classes - all Java built-in primitives, primitive wrappers, numbers, dates, sets, lists, maps, and native arrays.
    Parameters:
      `model` - the model to unwrap
      `targetClass` - the class of the unwrapped result; `Object.class` if we don't know what the expected type is.
    Returns:
      the unwrapped result of the desired class
    Throws:
      `TemplateModelException` - if an attempted unwrapping fails.
    See Also:
      `tryUnwrapTo(TemplateModel, Class)`

  - ### tryUnwrapTo

    public Object tryUnwrapTo​(TemplateModel model, Class<?> targetClass) throws TemplateModelException
    Description copied from interface: `ObjectWrapperAndUnwrapper`
    Attempts to unwrap a `TemplateModel` to a plain Java object that's the instance of the given class (or is `null`).
    Specified by:
      `tryUnwrapTo` in interface `ObjectWrapperAndUnwrapper`
      `targetClass` - The class that the return value must be an instance of (except when the return value is `null`). Can't be `null`; if the caller doesn't care, it should either use {#unwrap(TemplateModel)}, or `Object.class` as the parameter value.
    Returns:
      The unwrapped value that's either an instance of `targetClass`, or is `null` (if `null` is the appropriate Java value to represent the template model), or is `ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS` if the unwrapping can't satisfy the `targetClass` (nor the result can be `null`). However, `ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS` must not be returned if the `targetClass` parameter was `Object.class`.
    Throws:
      `TemplateModelException` - If the unwrapping fails for a reason than doesn't fit the meaning of the `ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS` return value.
    Since:
      2.3.22
    See Also:
      `ObjectWrapperAndUnwrapper.unwrap(TemplateModel)`

  - ### invokeMethod

    protected TemplateModel invokeMethod​(Object object, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException, TemplateModelException
    Invokes the specified method, wrapping the return value. All method invocations done in templates should go through this (assuming the target object was wrapped with this `ObjectWrapper`).

    This method is protected since 2.3.30; before that it was package private. The intended application of overriding this is monitoring what calls are made from templates. That can be useful to asses what will be needed in a `WhitelistMemberAccessPolicy` for example. Note that `Object.toString()` calls caused by type conversion (like when you have `${myObject}`) will not go through here, as they aren't called by the template directly (and aren't called via reflection). On the other hand, `${myObject[key]}`, if `myObject` is not a `Map`, will go through here as a `get(String|Object)` method call, if there's a such method.

    If the return value is null, and the return type of the invoked method is void, `TemplateModel.NOTHING` is returned.

    Parameters:
      `object` - the object to invoke the method on (`null` may be null for static methods)
      `method` - the method to invoke
      `args` - the arguments to the method
    Returns:
      the wrapped return value of the method.
    Throws:
      `InvocationTargetException` - if the invoked method threw an exception
      `IllegalAccessException` - if the method can't be invoked due to an access restriction.
      `TemplateModelException` - if the return value couldn't be wrapped (this can happen if the wrapper has an outer identity or is subclassed, and the outer identity or the subclass throws an exception. Plain BeansWrapper never throws TemplateModelException).
    Since:
      2.3.30
    See Also:
      `readField(Object, Field)`

  - ### readField

    protected TemplateModel readField​(Object object, Field field) throws IllegalAccessException, TemplateModelException
    Reads the specified field, returns its value as `TemplateModel`. All field reading done in templates should go through this (assuming the target object was wrapped with this `ObjectWrapper`).

    Just like in the case of `invokeMethod(Object, Method, Object[])`, overriding this can be useful if you want to monitor what members are accessed by templates. However, it has the caveat that final field values are possibly cached, so you won't see all reads. Furthermore, at least static models pre-read final fields, so they will be read even if the templates don't read them.

    Throws:
      `IllegalAccessException`
      `TemplateModelException`
    Since:
      2.3.30
    See Also:
      `invokeMethod(Object, Method, Object[])`

  - ### 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 `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.

  - ### 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. `enums["java.math.RoundingMode"].UP` to access the `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.
    Throws:
      `UnsupportedOperationException` - if this method is invoked on a pre-1.5 JRE, as Java enums aren't supported there.

  - ### newInstance

    public Object newInstance​(Class<?> clazz, List arguments) throws TemplateModelException
    Creates a new instance of the specified class using the method call logic of this object wrapper for calling the constructor. Overloaded constructors and varargs are supported. Only public constructors will be called.
    Parameters:
      `clazz` - The class whose constructor we will call.
      `arguments` - The list of `TemplateModel`-s to pass to the constructor after unwrapping them
    Returns:
      The instance created; it's not wrapped into `TemplateModel`.
    Throws:
      `TemplateModelException`

  - ### removeFromClassIntrospectionCache

    public void removeFromClassIntrospectionCache​(Class<?> clazz)
    Removes the introspection data for a class from the cache. Use this if you know that a class is not used anymore in templates. If the class will be still used, the cache entry will be silently re-created, so this isn't a dangerous operation.
    Since:
      2.3.20

  - ### clearClassIntrospecitonCache

    @Deprecated public void clearClassIntrospecitonCache()
    Deprecated.
    There's a typo in this method name, so use `clearClassIntrospectionCache()` instead.

    Removes all class introspection data from the cache.

    Use this if you want to free up memory on the expense of recreating the cache entries for the classes that will be used later in templates.

    Throws:
      `IllegalStateException` - if `isClassIntrospectionCacheRestricted()` is `true`.
    Since:
      2.3.20

  - ### clearClassIntrospectionCache

    public void clearClassIntrospectionCache()
    Removes all class introspection data from the cache.

    Use this if you want to free up memory on the expense of recreating the cache entries for the classes that will be used later in templates.

    Throws:
      `IllegalStateException` - if `isClassIntrospectionCacheRestricted()` is `true`.
    Since:
      2.3.29 (in earlier versions use `clearClassIntrospecitonCache()`)

  - ### finetuneMethodAppearance

    @Deprecated protected void finetuneMethodAppearance​(Class<?> clazz, Method m, BeansWrapper.MethodAppearanceDecision decision)
    Deprecated.
    Use `setMethodAppearanceFineTuner(MethodAppearanceFineTuner)`; no need to extend this class anymore. Soon this method will be final, so trying to override it will break your app. Note that if the `methodAppearanceFineTuner` property is set to non-`null`, this method is not called anymore.

  - ### coerceBigDecimals

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

  - ### coerceBigDecimals

    public static void coerceBigDecimals​(Class<?>[] formalTypes, Object[] args)
    Converts any `BigDecimal`-s in the passed array to the type of the corresponding formal argument of the method via `coerceBigDecimal(BigDecimal, Class)`.

  - ### coerceBigDecimal

    public static Object coerceBigDecimal​(BigDecimal bd, Class<?> formalType)
    Converts `BigDecimal` to the class given in the `formalType` argument if that's a known numerical type, returns the `BigDecimal` as is otherwise. Overflow and precision loss are possible, similarly as with casting in Java.

  - ### toString

    public String toString()
    Returns the exact class name and the identity hash, also the values of the most often used `BeansWrapper` configuration properties, also if which (if any) shared class introspection cache it uses.
    Overrides:
      `toString` in class `Object`
    Since:
      2.3.21

  - ### toPropertiesString

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