Class SimpleSequence

  • All Implemented Interfaces:
    TemplateModel, TemplateSequenceModel, java.io.Serializable
    Direct Known Subclasses:
    SimpleList

    public class SimpleSequence
    extends WrappingTemplateModel
    implements TemplateSequenceModel, java.io.Serializable
    A simple implementation of the TemplateSequenceModel interface, using its own underlying List for storing the list items. If you are wrapping an already existing List or array, you should certainly use DefaultMapAdapter or DefaultArrayAdapter (see comparison below).

    This class is thread-safe if you don't call modifying methods (like add(Object)) 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.

    SimpleSequence VS DefaultListAdapter/DefaultArrayAdapter - Which to use when?

    For a List or array that exists regardless of FreeMarker, only you need to access it from templates, DefaultMapAdapter should be the default choice, as it can be unwrapped to the originally wrapped object (important when passing it to Java methods from the template). It also has more predictable performance (no spikes).

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

    It also matters if for how many times will the same List entry be read from the template(s) later, on average. If, on average, you read each entry for more than 4 times, SimpleSequence 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; SimpleSequence will shallow-copy the original List at construction time, so it won't reflect List content changes after the SimpleSequence construction, also SimpleSequence can't be unwrapped to the original wrapped instance.

    See Also:
    DefaultListAdapter, DefaultArrayAdapter, TemplateSequenceModel, Serialized Form
    • Field Detail

      • list

        protected final java.util.List list
        The List that stored the elements of this sequence. It migth contains both TemplateModel elements and non-TemplateModel elements.
    • Method Detail

      • add

        public void add​(java.lang.Object obj)
        Adds an arbitrary object to the end of this sequence. If the newly added object does not implement the TemplateModel interface, it will be wrapped into the appropriate TemplateModel interface when it's first read (lazily).
        Parameters:
        obj - The object to be added.
      • toList

        @Deprecated
        public java.util.List toList()
                              throws TemplateModelException
        Deprecated.
        No replacement exists; not a reliable way of getting back the original list elemnts.
        Builds a deep-copy of the underlying list, unwrapping any values that were already converted to TemplateModel-s. When called for the second time (or later), it just reuses the first result, unless the sequence was modified since then.
        Throws:
        TemplateModelException
      • get

        public TemplateModel get​(int index)
                          throws TemplateModelException
        Returns the item at the specified index of the list. If the item isn't yet an TemplateModel, it will wrap it to one now, and writes it back into the backing list.
        Specified by:
        get in interface TemplateSequenceModel
        Returns:
        the item at the specified index, or null if the index is out of bounds. Note that a null value is interpreted by FreeMarker as "variable does not exist", and accessing a missing variables is usually considered as an error in the FreeMarker Template Language, so the usage of a bad index will not remain hidden, unless the default value for that case was also specified in the template.
        Throws:
        TemplateModelException
      • synchronizedWrapper

        public SimpleSequence synchronizedWrapper()
        Returns:
        a synchronized wrapper for list.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object