pbwest 2004/01/28 18:53:37 Modified: src/java/org/apache/fop/datastructs Tag: FOP_0-20-0_Alt-Design Node.java Log: Added: getPrecedingSibling getFollowingSibling precedingLeaf followingLeaf to support resolution of keeps and space-specifiers. Revision Changes Path No revision No revision 1.1.2.5 +153 -12 xml-fop/src/java/org/apache/fop/datastructs/Attic/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/datastructs/Attic/Node.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- Node.java 28 Jan 2004 06:19:56 -0000 1.1.2.4 +++ Node.java 29 Jan 2004 02:53:37 -0000 1.1.2.5 @@ -181,7 +181,7 @@ } /** - * Insert a subtree at a specified index position in the child list. + * Inserts a subtree at a specified index position in the child list. * @param index position of subtree within children * @param subtree to insert * @throws IndexOutOfBoundsException @@ -194,7 +194,7 @@ } /** - * Add a subtree to the child list. + * Adds a subtree to the child list. * @param subtree to insert * @throws IndexOutOfBoundsException */ @@ -382,7 +382,7 @@ } /** - * Delete <code>this</code> subtree and return a count of the deleted + * Deletes <code>this</code> subtree and returns a count of the deleted * nodes. The deletion is effected by cutting the references between * <code>this</code> and its parent (if any). All other relationships * within the subtree are maintained. @@ -430,7 +430,7 @@ } /** - * Get the parent of this <tt>Node</tt>. + * Gets the parent of this <tt>Node</tt>. * @return the parent <tt>Node</tt>. */ public Node getParent() { @@ -443,7 +443,7 @@ } /** - * Set the <i>parent</i> field of this node. + * Sets the <i>parent</i> field of this node. * @param parent the reference to set */ public void setParent(Node parent) { @@ -457,7 +457,7 @@ } /** - * Nullify the parent <tt>Node</tt> of this node. + * Nullifies the parent <tt>Node</tt> of this node. */ public void unsetParent() { if (synchronize) { @@ -469,7 +469,7 @@ } /** - * Get the n'th child of this node. + * Gets the n'th child of this node. * @param n - the <tt>int</tt> index of the child to return. * @return the <tt>Node</tt> reference to the n'th child. */ @@ -485,7 +485,7 @@ } /** - * Get an <tt>Iterator</tt> over the children of this node. + * Gets an <tt>Iterator</tt> over the children of this node. * @return the <tt>Iterator</tt>. */ public Iterator nodeChildren() { @@ -500,7 +500,7 @@ } /** - * Get the number of children of this node. + * Gets the number of children of this node. * @return the <tt>int</tt> number of children. */ public int numChildren() { @@ -513,7 +513,148 @@ if (children == null) return 0; return children.size(); } - + + /** + * Gets the preceding sibling of this <code>Node</code>, + * or <code>null</code> if none. + * @return the sibling node + */ + public Node getPrecedingSibling() { + if (synchronize) { + synchronized (this) { + if (this.parent == null) return null; + int thisChild = parent.children.indexOf(this); + if (thisChild == 0) return null; + return parent.getChild(--thisChild); + } + } + if (this.parent == null) return null; + int thisChild = parent.children.indexOf(this); + if (thisChild == 0) return null; + return parent.getChild(--thisChild); + } + + /** + * Gets the following sibling of this <code>Node</code>, + * or <code>null</code> if none. + * @return the sibling node + */ + public Node getFollowingSibling() { + if (synchronize) { + synchronized (this) { + if (this.parent == null) return null; + int thisChild = parent.children.indexOf(this); + if (++thisChild >= parent.numChildren()) return null; + return parent.getChild(thisChild); + } + } + if (this.parent == null) return null; + int thisChild = parent.children.indexOf(this); + if (++thisChild >= parent.numChildren()) return null; + return parent.getChild(thisChild); + } + + /** + * Gets the leaf <code>Node</code> immediately preceding this node in the + * pre-order tree rooted on the <code>nominalRoot</code>, or, if the + * nominal root is not encountered, the actual root. + * In a pre-order tree, all children follow their parent. + * @param nominalRoot the root node for the purposes of this operation + * @return the preceding leaf node or <code>null</code> + */ + public Node precedingLeaf(Node nominalRoot) { + if (synchronize) { + synchronized (this) { + return getPrecedingLeaf(nominalRoot); + } + } + return getPrecedingLeaf(nominalRoot); + } + + /** + * Realizes <code>precedingLeaf()</code>. Climbs the tree rooted at + * <code>nominalRoot</code> from <code>this</code>, searching for an + * ancestor with a branch preceding this. + * If none is found, there is no preceding leaf node. + * If one is found, it is descended to the last pre-order node, + * i.e. the leaf most closely preceding <code>this</code>. + * @param nominalRoot the root node for the purposes of this operation + * @return the preceding leaf node or <code>null</code> + */ + private Node getPrecedingLeaf(Node nominalRoot) { + if (this == nominalRoot || this.parent == null) { + return null; + } + Node sibling = null; + Node pivot = this.parent; + while (pivot != nominalRoot) { + if ((sibling = pivot.getPrecedingSibling()) != null) { + break; + } + pivot = pivot.parent; + } + if (pivot == nominalRoot) { // No preceding leaf node + return null; + } + // We have the pivot preceding sibling - now descend the + // preceding subtree to the last leaf + int numChildren; + while ((numChildren = sibling.numChildren()) > 0) { + sibling = sibling.getChild(--numChildren); + } + return sibling; + } + + /** + * Gets the leaf <code>Node</code> immediately following this node in the + * post-order tree rooted on the <code>nominalRoot</code>, or, if the + * nominal root is not encountered, the actual root. + * In a post-order tree, all children precede their parent. + * @param nominalRoot the root node for the purposes of this operation + * @return the following leaf node or <code>null</code> + */ + public Node followingLeaf(Node nominalRoot) { + if (synchronize) { + synchronized (this) { + return getFollowingLeaf(nominalRoot); + } + } + return getFollowingLeaf(nominalRoot); + } + + /** + * Realizes <code>followingLeaf()</code>. Climbs the tree rooted at + * <code>nominalRoot</code> from <code>this</code>, searching for an + * ancestor with a branch following this. + * If none is found, there is no following leaf node. + * If one is found, it is descended to the first post-order node, + * i.e. the leaf most closely following <code>this</code>. + * @param nominalRoot the root node for the purposes of this operation + * @return the following leaf node or <code>null</code> + */ + private Node getFollowingLeaf(Node nominalRoot) { + if (this == nominalRoot || this.parent == null) { + return null; + } + Node sibling = null; + Node pivot = this.parent; + while (pivot != nominalRoot) { + if ((sibling = pivot.getFollowingSibling()) != null) { + break; + } + pivot = pivot.parent; + } + if (pivot == nominalRoot) { // No preceding leaf node + return null; + } + // We have the pivot following sibling - now descend the + // following subtree to the first leaf + while (sibling.numChildren() > 0) { + sibling = sibling.getChild(0); + } + return sibling; + } + /** * Class <tt>PreOrder</tt> is a member class of <tt>Node</tt>. *
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]