Class DomContainer

  • All Implemented Interfaces:
    Cloneable
    Direct Known Subclasses:
    DomElement, DomFragment

    @NoTests
    public abstract class DomContainer
    extends DomContent
    Base class for DomElement and DomFragment. This class provides methods common to both, which mostly includes nearly all methods for modifying and querying the list of child nodes (child elements and text).

    Since DomFragment is nothing more than a list of child nodes, DomFragment is implemented as a thin wrapper around DomContainer.

    Children are of type DomContent. They are either DomElement or DomText. When DomFragment is added to another fragment or to an element, it is inlined. Fragments cannot be children of elements or other fragments. There are never two consecutive DomText nodes in the child list. If text is appended to a child list that already ends with text node, a new DomText node is created in its place that contains both strings concatenated together.

    Due to this non-trivial manipulation of appended content, it doesn't make much sense to provide list-like functionality (set, insert, or remove children) and the whole child manipulation API is append-only. It fits the typical functional programming use case of building DOM trees from scratch. If DOM tree modification is needed, for example to expand templates, apply DOM tree filters, or to import external content, the best approach is to build new DOM tree with desired changes applied and discard the original DOM tree. The only mutating method we support is children().clear(), so that contents of this DomContainer can be replaced without replacing the whole object.

    Since using the high-level builder and query API might be too much overhead in some cases, a low-level raw access API is provided too. It is application's responsibility to use the raw API correctly.

    • Method Detail

      • rawChildCount

        @DraftApi
        public int rawChildCount()
        Gets number of child nodes. This is a raw API equivalent to calling children().size().
        Returns:
        number of child nodes
        See Also:
        rawChildren(), rawChildren(int, DomContent[])
      • rawChildren

        @DraftApi
        public DomContent[] rawChildren()
        Gets child node buffer. This is a raw API returning essentially the same information as children().

        The buffer may be larger than the number of child nodes actually present. Extra entries are filled with nulls. If there are no children, the buffer may be null.

        The returned array may be modified, but application should satisfy the same requirements as with rawChildren(int, DomContent[]).

        Returns:
        null-padded array of child nodes or null
        See Also:
        rawChildCount(), rawChildren(int, DomContent[])
      • rawChildren

        @DraftApi
        public void rawChildren​(int count,
                                DomContent[] children)
        Sets child node buffer. This is a raw API to be used under extreme circumstances. The proper high-level way to fill child node buffer is to use the many add() methods. If child list has to be modified, the high-level way to do it is to rebuild the whole element/fragment.

        The new child buffer must satisfy several requirements. It can only contain DomElement and DomText instances and there must be no consecutive text nodes and no null nodes. If count is smaller than the size of the buffer, unused entries at the end of the buffer must be null. The buffer itself may be null if count is zero. These requirements are not checked. If application fails to satisfy them, it may result in surprising behavior or exceptions.

        This method does no check whether the container is frozen. This is application's responsibility. Modifying frozen containers is unsafe.

        Parameters:
        count - new child count
        children - new child node buffer or null
        See Also:
        rawChildCount(), rawChildren(), add(DomContent)
      • add

        public <C extends DomContentDomContainer add​(Collection<C> children)
        Adds all nodes in a Collection to the list of children. Fragments will be inlined, nulls ignored, and text concatenated.
        Type Parameters:
        C - item type
        Parameters:
        children - collection of child nodes to add (ignored if null)
        Returns:
        this
        Throws:
        IllegalStateException - if this element or fragment is frozen
        See Also:
        add(DomContent)
      • add

        public <C extends DomContentDomContainer add​(Stream<C> children)
        Adds all nodes in a Stream to the list of children. Fragments will be inlined, nulls ignored, and text concatenated.
        Type Parameters:
        C - item type
        Parameters:
        children - Stream of child nodes to add (ignored if null)
        Returns:
        this
        Throws:
        IllegalStateException - if this element or fragment is frozen
        See Also:
        add(DomContent)
      • add

        public DomContainer add​(String text)
        Adds literal text to the list of children. Consecutive text nodes will be concatenated.
        Parameters:
        text - text to add (ignored if null or empty)
        Returns:
        this
        Throws:
        IllegalStateException - if this element or fragment is frozen
        See Also:
        add(DomContent)
      • children

        @DraftCode("sublists are copies instead of views")
        public List<DomContent> children()
        Lists all children in this element or fragment. The list is a live view of the internal representation of the child list. It will reflect changes made through other methods of this class. The returned list itself is unmodifiable except for List.clear().

        All methods of the returned List have time complexity like methods of ArrayList except List.subList(int, int), which is currently implemented as returning copy of the sublist rather than a view.

        Returns:
        list of all children
        See Also:
        elements(), descendants()
      • elements

        public Stream<DomElement> elements​(String name)
        Enumerates elements with given tagname. This is a convenience filter applied to children().
        Parameters:
        name - tagname to look for
        Returns:
        stream of elements with the tagname
        See Also:
        children(), elements()
      • text

        @DraftApi("see base class")
        public String text()
        Description copied from class: DomContent
        Gets concatenated text content of this node. Text is concatenated recursively in the same order in which it would appear in HTML. Attribute values are not included. No whitespace normalization is performed.
        Specified by:
        text in class DomContent
        Returns:
        all text content in this node
      • rawFreeze

        @DraftApi
        public void rawFreeze()
        Marks the element or fragment as frozen. This is a raw API that merely marks the container as frozen without performing any other tasks like freeze().
      • clone

        public abstract DomContainer clone()
        Creates mutable deep clone of this element or fragment. All child nodes are cloned recursively. The clone is completely independent of this node.
        Specified by:
        clone in class DomContent
        Returns:
        deep mutable clone
      • equals

        public boolean equals​(Object object)
        Compares content of two DomContainer nodes. If the two nodes are of different type (i.e. one is DomElement and the other one DomFragment), this method returns false. Equality is unaffected by whether the element/fragment is frozen or not. Children of both containers are compared recursively by calling their DomContent.equals(Object) methods.
        Overrides:
        equals in class DomContent
        Parameters:
        object - object to compare this container with
        Returns:
        true if the two nodes are equal, false otherwise
      • hashCode

        public int hashCode()
        Computes hash code of this container. It is computed by combining hash codes of all children. Hash code is unaffected by whether the element/fragment is frozen or not.
        Overrides:
        hashCode in class DomContent
        Returns:
        container's hash code