- All Implemented Interfaces:
-
Cloneable
- Direct Known Subclasses:
-
DomElement
,DomFragment
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 Summary
Modifier and TypeMethodDescriptionadd
(DomContent child) Adds new child node to the list of children.Adds literal text to the list of children.<C extends DomContent>
DomContaineradd
(Collection<C> children) Adds all nodes in aCollection
to the list of children.<C extends DomContent>
DomContainerAdds all nodes in aStream
to the list of children.children()
Lists all children in this element or fragment.abstract DomContainer
clone()
Creates mutable deep clone of this element or fragment.Enumerates descendant elements.Finds element with given tagname.elements()
Enumerates element children.Enumerates elements with given tagname.boolean
Compares content of twoDomContainer
nodes.freeze()
Protects this element or fragment from further modification.int
hashCode()
Computes hash code of this container.int
Gets number of child nodes.Gets child node buffer.void
rawChildren
(int count, DomContent[] children) Sets child node buffer.void
Marks the element or fragment as frozen.text()
Gets concatenated text content of this node.Methods inherited from class com.machinezoo.pushmode.dom.DomContent
toString
-
Method Details
-
rawChildCount
Gets number of child nodes. This is a raw API equivalent to callingchildren().size()
.- Returns:
- number of child nodes
- See Also:
-
rawChildren
Gets child node buffer. This is a raw API returning essentially the same information aschildren()
.The buffer may be larger than the number of child nodes actually present. Extra entries are filled with
null
s. If there are no children, the buffer may benull
.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 ornull
- See Also:
-
rawChildren
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 manyadd()
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
andDomText
instances and there must be no consecutive text nodes and nonull
nodes. Ifcount
is smaller than the size of the buffer, unused entries at the end of the buffer must benull
. The buffer itself may benull
ifcount
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 ornull
- See Also:
-
add
Adds new child node to the list of children. Fragments will be inlined,null
s ignored, and text concatenated.- Parameters:
-
child
- node to add (ignored ifnull
) - Returns:
-
this
- Throws:
-
IllegalStateException
- if this element or fragment is frozen - See Also:
-
add
Adds all nodes in aCollection
to the list of children. Fragments will be inlined,null
s ignored, and text concatenated.- Type Parameters:
-
C
- item type - Parameters:
-
children
- collection of child nodes to add (ignored ifnull
) - Returns:
-
this
- Throws:
-
IllegalStateException
- if this element or fragment is frozen - See Also:
-
add
Adds all nodes in aStream
to the list of children. Fragments will be inlined,null
s ignored, and text concatenated.- Type Parameters:
-
C
- item type - Parameters:
-
children
-Stream
of child nodes to add (ignored ifnull
) - Returns:
-
this
- Throws:
-
IllegalStateException
- if this element or fragment is frozen - See Also:
-
add
Adds literal text to the list of children. Consecutive text nodes will be concatenated.- Parameters:
-
text
- text to add (ignored ifnull
or empty) - Returns:
-
this
- Throws:
-
IllegalStateException
- if this element or fragment is frozen - See Also:
-
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 forList.clear()
.All methods of the returned
List
have time complexity like methods ofArrayList
exceptList.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
Enumerates element children. This is a convenience filter applied tochildren()
.- Returns:
-
stream of children of type
DomElement
- See Also:
-
descendants
Enumerates descendant elements. Elements are traversed in pre-order depth-first manner. The returned stream is constructed incrementally as it is consumed.DomElement
provides methodDomElement.descendantsAndSelf()
.- Returns:
- stream of descendant elements
- See Also:
-
elements
Enumerates elements with given tagname. This is a convenience filter applied tochildren()
.- Parameters:
-
name
- tagname to look for - Returns:
- stream of elements with the tagname
- See Also:
-
element
Finds element with given tagname. This is a convenience filter applied tochildren()
.- Parameters:
-
name
- tagname to look for - Returns:
-
element with the tagname or an empty
Optional
- See Also:
-
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 classDomContent
- Returns:
- all text content in this node
-
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 likefreeze()
. -
freeze
Protects this element or fragment from further modification. For more information, use cases, and thread safety, seeDomContent.freeze()
.- Specified by:
-
freeze
in classDomContent
- Returns:
-
this
-
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 classDomContent
- Returns:
- deep mutable clone
-
equals
Compares content of twoDomContainer
nodes. If the two nodes are of different type (i.e. one isDomElement
and the other oneDomFragment
), 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 theirDomContent.equals(Object)
methods.- Overrides:
-
equals
in classDomContent
- 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 classDomContent
- Returns:
- container's hash code
-