BeanModel (FreeMarker 2.3.23 API)
Date: 2015-07-05

freemarker.ext.beans

## Class BeanModel

- java.lang.Object
- - freemarker.ext.beans.BeanModel

- All Implemented Interfaces:
    WrapperTemplateModel, AdapterTemplateModel, TemplateHashModel, TemplateHashModelEx, TemplateModel, TemplateModelWithAPISupport
  Direct Known Subclasses:
    ArrayModel, BooleanModel, DateModel, EnumerationModel, IteratorModel, NumberModel, ResourceBundleModel, StringModel

      public class BeanModel
      extends Object
      implements TemplateHashModelEx, AdapterTemplateModel, WrapperTemplateModel, TemplateModelWithAPISupport

  A class that will wrap an arbitrary object into `TemplateHashModel` interface allowing calls to arbitrary property getters and invocation of accessible methods on the object from a template using the `object.foo` to access properties and `object.bar(arg1, arg2)` to invoke methods on it. You can also use the `object.foo[index]` syntax to access indexed properties. It uses Beans `Introspector` to dynamically discover the properties and methods.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected Object` | `object`
    `protected BeansWrapper` | `wrapper`

    - ### Fields inherited from interface freemarker.template.TemplateModel

      `NOTHING`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `BeanModel(Object object, BeansWrapper wrapper)` Creates a new model that wraps the specified object.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `TemplateModel` | `get(String key)` Uses Beans introspection to locate a property or method with name matching the key name.
    `Object` | `getAdaptedObject(Class hint)` Returns the same as `getWrappedObject()`; to ensure that, this method will be final starting from 2.4.
    `TemplateModel` | `getAPI()` Returns the model that exposes the (Java) API of the value.
    `Object` | `getWrappedObject()` Retrieves the original object wrapped by this model.
    `protected boolean` | `hasPlainGetMethod()` Whether the model has a plain get(String) or get(Object) method
    `protected TemplateModel` | `invokeGenericGet(Map keyMap, Class clazz, String key)`
    `boolean` | `isEmpty()` Tells whether the model is empty.
    `TemplateCollectionModel` | `keys()`
    `protected Set` | `keySet()` Helper method to support TemplateHashModelEx.
    `int` | `size()`
    `String` | `toString()`
    `protected Object` | `unwrap(TemplateModel model)`
    `TemplateCollectionModel` | `values()`
    `protected TemplateModel` | `wrap(Object obj)`

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

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

- - ### Field Detail

    - #### object

          protected final Object object

    - #### wrapper

          protected final BeansWrapper wrapper

  - ### Constructor Detail

    - #### BeanModel

          public BeanModel(Object object,
                           BeansWrapper wrapper)

      Creates a new model that wraps the specified object. Note that there are specialized subclasses of this class for wrapping arrays, collections, enumeration, iterators, and maps. Note also that the superclass can be used to wrap String objects if only scalar functionality is needed. You can also choose to delegate the choice over which model class is used for wrapping to `BeansWrapper.wrap(Object)`.
      Parameters:
        `object` - the object to wrap into a model.
        `wrapper` - the `BeansWrapper` associated with this model. Every model has to have an associated `BeansWrapper` instance. The model gains many attributes from its wrapper, including the caching behavior, method exposure level, method-over-item shadowing policy etc.

  - ### Method Detail

    - #### get

          public TemplateModel get(String key)
                            throws TemplateModelException

      Uses Beans introspection to locate a property or method with name matching the key name. If a method or property is found, it's wrapped into `TemplateMethodModelEx` (for a method or indexed property), or evaluated on-the-fly and the return value wrapped into appropriate model (for a simple property) Models for various properties and methods are cached on a per-class basis, so the costly introspection is performed only once per property or method of a class. (Side-note: this also implies that any class whose method has been called will be strongly referred to by the framework and will not become unloadable until this class has been unloaded first. Normally this is not an issue, but can be in a rare scenario where you create many classes on- the-fly. Also, as the cache grows with new classes and methods introduced to the framework, it may appear as if it were leaking memory. The framework does, however detect class reloads (if you happen to be in an environment that does this kind of things--servlet containers do it when they reload a web application) and flushes the cache. If no method or property matching the key is found, the framework will try to invoke methods with signature `non-void-return-type get(java.lang.String)`, then `non-void-return-type get(java.lang.Object)`, or alternatively (if the wrapped object is a resource bundle) `Object getObject(java.lang.String)`.
      Specified by:
        `get` in interface `TemplateHashModel`
      Parameters:
        `key` - the name by which the `TemplateModel` is identified in the template.
      Returns:
        the `TemplateModel` referred to by the key, or null if not found.
      Throws:
        `TemplateModelException` - if there was no property nor method nor a generic `get` method to invoke.

    - #### hasPlainGetMethod

          protected boolean hasPlainGetMethod()

      Whether the model has a plain get(String) or get(Object) method

    - #### invokeGenericGet

          protected TemplateModel invokeGenericGet(Map keyMap,
                                                   Class clazz,
                                                   String key)
                                            throws IllegalAccessException,
                                                   InvocationTargetException,
                                                   TemplateModelException

      Throws:
        `IllegalAccessException`
        `InvocationTargetException`
        `TemplateModelException`

    - #### wrap

          protected TemplateModel wrap(Object obj)
                                throws TemplateModelException

      Throws:
        `TemplateModelException`

    - #### unwrap

          protected Object unwrap(TemplateModel model)
                           throws TemplateModelException

      Throws:
        `TemplateModelException`

    - #### isEmpty

          public boolean isEmpty()

      Tells whether the model is empty. It is empty if either the wrapped object is null, or it's a Boolean with false value.
      Specified by:
        `isEmpty` in interface `TemplateHashModel`

    - #### getAdaptedObject

          public Object getAdaptedObject(Class hint)

      Returns the same as `getWrappedObject()`; to ensure that, this method will be final starting from 2.4. This behavior of `BeanModel` is assumed by some FreeMarker code.
      Specified by:
        `getAdaptedObject` in interface `AdapterTemplateModel`
      Parameters:
        `hint` - the desired class of the returned value. An implementation should make reasonable effort to retrieve an object of the requested class, but if that is impossible, it must at least return the underlying object as-is. As a minimal requirement, an implementation must always return the exact underlying object when `hint.isInstance(underlyingObject)` holds. When called with `java.lang.Object.class`, it should return a generic Java object (i.e. if the model is wrapping a scripting language object that is further wrapping a Java object, the deepest underlying Java object should be returned).
      Returns:
        the underlying object, or its value accommodated for the hint class.

    - #### getWrappedObject

          public Object getWrappedObject()

      Description copied from interface: `WrapperTemplateModel`
      Retrieves the original object wrapped by this model.
      Specified by:
        `getWrappedObject` in interface `WrapperTemplateModel`

    - #### size

          public int size()

      Specified by:
        `size` in interface `TemplateHashModelEx`
      Returns:
        the number of key/value mappings in the hash.

    - #### keys

          public TemplateCollectionModel keys()

      Specified by:
        `keys` in interface `TemplateHashModelEx`
      Returns:
        a collection containing the keys in the hash. Every element of the returned collection must implement the `TemplateScalarModel` (as the keys of hashes are always strings).

    - #### values

          public TemplateCollectionModel values()
                                         throws TemplateModelException

      Specified by:
        `values` in interface `TemplateHashModelEx`
      Returns:
        a collection containing the values in the hash. The elements of the returned collection can be any kind of `TemplateModel`-s.
      Throws:
        `TemplateModelException`

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`

    - #### keySet

          protected Set keySet()

      Helper method to support TemplateHashModelEx. Returns the Set of Strings which are available via the TemplateHashModel interface. Subclasses that override `invokeGenericGet` to provide additional hash keys should also override this method.

    - #### getAPI

          public TemplateModel getAPI()
                               throws TemplateModelException

      Description copied from interface: `TemplateModelWithAPISupport`
      Returns the model that exposes the (Java) API of the value. This is usually implemented by delegating to `ObjectWrapperWithAPISupport.wrapAsAPI(Object)`.
      Specified by:
        `getAPI` in interface `TemplateModelWithAPISupport`
      Throws:
        `TemplateModelException`