Class SimpleHash

All Implemented Interfaces:
TemplateHashModel, TemplateHashModelEx, TemplateHashModelEx2, TemplateModel, Serializable
Direct Known Subclasses:
AllHttpScopesHashModel, AllHttpScopesHashModel, Environment.Namespace

public class SimpleHash extends WrappingTemplateModel implements TemplateHashModelEx2, Serializable
A simple implementation of the TemplateHashModelEx interface, using its own underlying Map or SortedMap for storing the hash entries. If you are wrapping an already existing Map, you should certainly use DefaultMapAdapter instead (see comparison below).

This class is thread-safe if you don't call modifying methods (like put(String, Object), remove(String), etc.) after you have made the object available for multiple threads (assuming you have published it safely to the other threads; see JSR-133 Java Memory Model). These methods aren't called by FreeMarker, so it's usually not a concern.

SimpleHash VS DefaultMapAdapter - Which to use when?

For a Map that exists regardless of FreeMarker, only you need to access it from templates, DefaultMapAdapter should be the default choice, as it reflects the exact behavior of the underlying Map (no surprises), can be unwrapped to the originally wrapped object (important when passing it to Java methods from the template), and has more predictable performance (no spikes).

For a hash that's made specifically to be used from templates, creating an empty SimpleHash then filling it with put(String, Object) is usually the way to go, as the resulting hash is significantly faster to read from templates than a DefaultMapAdapter (though it's somewhat slower to read from a plain Java method to which it had to be passed adapted to a Map).

It also matters if for how many times will the same Map entry be read from the template(s) later, on average. If, on average, you read each entry for more than 4 times, SimpleHash will be most certainly faster, but if for 2 times or less (and especially if not at all) then DefaultMapAdapter will be faster. Before choosing based on performance though, pay attention to the behavioral differences; SimpleHash will shallow-copy the original Map at construction time, so key order will be lost in some cases, and it won't reflect Map content changes after the SimpleHash construction, also SimpleHash can't be unwrapped to the original Map instance.

See Also:
DefaultMapAdapter, TemplateHashModelEx, Serialized Form
  • Constructor Details

  • Method Details

    • copyMap

      protected Map copyMap(Map map)
    • put

      public void put(String key, Object value)
      Adds a key-value entry to this hash.
      Parameters:
      key - The name by which the object is identified in the template.
      value - The value to which the name will be associated. This will only be wrapped to TemplateModel lazily when it's first read.
    • put

      public void put(String key, boolean b)
      Puts a boolean in the map
      Parameters:
      key - the name by which the resulting TemplateModel is identified in the template.
      b - the boolean to store.
    • get

      public TemplateModel get(String key) throws TemplateModelException
      Description copied from interface: TemplateHashModel
      Gets a TemplateModel from the hash.
      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
    • containsKey

      public boolean containsKey(String key)
      Tells if the map contains a key or not, regardless if the associated value is null or not.
      Since:
      2.3.20
    • remove

      public void remove(String key)
      Removes the given key from the underlying map.
      Parameters:
      key - the key to be removed
    • putAll

      public void putAll(Map m)
      Adds all the key/value entries in the map
      Parameters:
      m - the map with the entries to add, the keys are assumed to be strings.
    • toMap

      public Map toMap() throws TemplateModelException
      Note that this method creates and returns a deep-copy of the underlying hash used internally. This could be a gotcha for some people at some point who want to alter something in the data model, but we should maintain our immutability semantics (at least using default SimpleXXX wrappers) for the data model. It will recursively unwrap the stuff in the underlying container.
      Throws:
      TemplateModelException
    • toString

      public String toString()
      Returns the toString() of the underlying Map.
      Overrides:
      toString in class Object
    • size

      public int size()
      Specified by:
      size in interface TemplateHashModelEx
      Returns:
      the number of key/value mappings in the hash.
    • isEmpty

      public boolean isEmpty()
      Specified by:
      isEmpty in interface TemplateHashModel
    • 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()
      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.
    • keyValuePairIterator

      public TemplateHashModelEx2.KeyValuePairIterator keyValuePairIterator()
      Specified by:
      keyValuePairIterator in interface TemplateHashModelEx2
      Returns:
      The iterator that walks through the key-value pairs in the hash. Not null.
    • synchronizedWrapper

      public SimpleHash synchronizedWrapper()