This package contains implementation of tree and list iterators that are dependent on the DOM implementation for efficiency and liveness.
The node iterator interface is defined in {@link org.w3c.dom.fi.NodeIterator} and applies to both tree and list iterators.The interface consists of two method calls {@link org.w3c.dom.fi.NodeIterator#nextNode} and {@link org.w3c.dom.fi.NodeIterator#prevNode}. The iterator is created from {@link org.w3c.dom.Node}.
Both tree and list iterators are live, meaning that changes to the document tree must be reflected in the iterator without nullifying it. The tree iterator is recursive to all childs of the iterated node tree; the list iterator is non-recursive and only returns direct children of the iterated node tree. Neither iterator returns the tree top node, its parents or siblings.
{@link org.openxml.dom.iterator.TreeIteratorImpl} and {@link org.openxml.dom.iterator.TreeIteratorInner} are a pair of classes that implement this interface for iterating trees. TreeIteratorImpl provides an implementation of the public interface and a constructor. It functions as an adapter, delegating iteration to TreeIteratorInner. TreeIteratorInner implements the actual iteration algorithm and the NodeIteratorListener interface.
The {@link org.openxml.dom.iterator.NodeIteratorListener} interface allows the owner node to notify the iterator of changes to the document tree that might affect it, allowing the iterator to adjust accordingly. Notifications are the responsibiliy of the {@link org.openxml.dom.NodeImpl} node that created the iterator and by definition is the top node in the iterated tree. NodeImpl automatically registers new iterators as interested listeners by calling {@link org.openxml.dom.iterator.TreeIteratorImpl#asNodeIteratorListener} on the constructed TreeIteratorImpl.
The notification is required to support the liveness of the iterator. The iterator keeps tabs on two nodes, the top node of the tree (the owner) and the node currently being iterated over. The iterator is only interested in changes that occur in the tree underneath the owner node, but not to changes that occur to the owner node itself, its parents or siblings. The iterator is notified of the change through{@link org.openxml.dom.iterator.NodeIteratorListener#removeNode}.
A side effect of the notification mechanism is the iterator being referenced by the owner node long after the application ceased to reference it. To slove this issue and assure proper garbage collection, the iterator has been split into two classes. TreeIterator is referenced by the application. When the application ceases referencing TreeIteratorImpl, it is garbage collected and calls {@link org.openxml.dom.iterator.TreeIteratorInner#destroy}. TreeIteratorInner will then unregister itself with the owner NodeImpl, freeing the other reference to it and allowing it to be properly garbage collected.
{@link org.openxml.dom.iterator.ListIteratorImpl} and {@link org.openxml.dom.iterator.ListIteratorInner} use the exact same mechanism.
See {@link org.openxml.dom.iterator.TreeIteratorImpl}, {@link org.openxml.dom.iterator.TreeIteratorInner}, {@link org.openxml.dom.iterator.NodeIteratorListener}, {@link org.w3c.dom.fi.NodeIterator}, {@link org.openxml.dom.NodeImpl}
Keeper design (impl/inner class combination) has been contributed by Ray Whitmer.