Java Code Examples for org.w3c.dom.Node#insertBefore()

The following examples show how to use org.w3c.dom.Node#insertBefore() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may want to check out the right sidebar which shows the related API usage.
Example 1
private void marshal(Node parent, Element kiElem, Node nextSibling,
                     String dsPrefix, DOMCryptoContext context)
    throws MarshalException
{
    // create and append KeyInfoType elements
    for (XMLStructure kiType : keyInfoTypes) {
        if (kiType instanceof DOMStructure) {
            ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
        } else {
            DOMUtils.appendChild(kiElem,
                ((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
        }
    }

    // append id attribute
    DOMUtils.setAttributeID(kiElem, "Id", id);

    parent.insertBefore(kiElem, nextSibling);
}
 
Example 2
private void marshal(Node parent, Element kiElem, Node nextSibling,
                     String dsPrefix, DOMCryptoContext context)
    throws MarshalException
{
    // create and append KeyInfoType elements
    for (XMLStructure kiType : keyInfoTypes) {
        if (kiType instanceof DOMStructure) {
            ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
        } else {
            DOMUtils.appendChild(kiElem,
                ((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
        }
    }

    // append id attribute
    DOMUtils.setAttributeID(kiElem, "Id", id);

    parent.insertBefore(kiElem, nextSibling);
}
 
Example 3
private void marshal(Node parent, Element kiElem, Node nextSibling,
                     String dsPrefix, DOMCryptoContext context)
    throws MarshalException
{
    // create and append KeyInfoType elements
    for (XMLStructure kiType : keyInfoTypes) {
        if (kiType instanceof DOMStructure) {
            ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
        } else {
            DOMUtils.appendChild(kiElem,
                ((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
        }
    }

    // append id attribute
    DOMUtils.setAttributeID(kiElem, "Id", id);

    parent.insertBefore(kiElem, nextSibling);
}
 
Example 4
Source Project: JsDroidCmd   File: XmlNode.java    License: Mozilla Public License 2.0 5 votes vote down vote up
void insertChildAt(int index, XmlNode node) {
    Node parent = this.dom;
    Node child = parent.getOwnerDocument().importNode( node.dom, true );
    if (parent.getChildNodes().getLength() < index) {
        //    TODO    Check ECMA for what happens here
        throw new IllegalArgumentException("index=" + index + " length=" + parent.getChildNodes().getLength());
    }
    if (parent.getChildNodes().getLength() == index) {
        parent.appendChild(child);
    } else {
        parent.insertBefore(child, parent.getChildNodes().item(index));
    }
}
 
Example 5
protected final void expandEntityRef (Node parent, Node reference){
    Node kid, next;
    for (kid = reference.getFirstChild(); kid != null; kid = next) {
        next = kid.getNextSibling();
        parent.insertBefore(kid, reference);
    }
}
 
Example 6
private void appendTextNode() {
    if (_textBuffer.length() > 0) {
        final Node last = (Node)_nodeStk.peek();
        if (last == _root && _nextSiblingCache != null) {
            _lastSibling = last.insertBefore(_document.createTextNode(_textBuffer.toString()), _nextSiblingCache);
        }
        else {
            _lastSibling = last.appendChild(_document.createTextNode(_textBuffer.toString()));
        }
        _textBuffer.setLength(0);
    }
}
 
Example 7
protected final void expandEntityRef (Node parent, Node reference){
    Node kid, next;
    for (kid = reference.getFirstChild(); kid != null; kid = next) {
        next = kid.getNextSibling();
        parent.insertBefore(kid, reference);
    }
}
 
Example 8
Source Project: jdk8u60   File: SAX2DOM.java    License: GNU General Public License v2.0 5 votes vote down vote up
private void appendTextNode() {
    if (_textBuffer.length() > 0) {
        final Node last = (Node)_nodeStk.peek();
        if (last == _root && _nextSiblingCache != null) {
            _lastSibling = last.insertBefore(_document.createTextNode(_textBuffer.toString()), _nextSiblingCache);
        }
        else {
            _lastSibling = last.appendChild(_document.createTextNode(_textBuffer.toString()));
        }
        _textBuffer.setLength(0);
    }
}
 
Example 9
Source Project: caja   File: DOMTreeBuilder.java    License: Apache License 2.0 5 votes vote down vote up
@Override protected void insertFosterParentedCharacters(String text,
        Element table, Element stackParent) throws SAXException {
    try {
        Node child = document.createTextNode(text);
        Node parent = table.getParentNode();
        if (parent != null) { // always an element if not null
            parent.insertBefore(child, table);
        } else {
            stackParent.appendChild(child);
        }
    } catch (DOMException e) {
        fatal(e);
    }
}
 
Example 10
/**
 * Break a text node into two sibling nodes. (Note that if the current node
 * has no parent, they won't wind up as "siblings" -- they'll both be
 * orphans.)
 *
 * @param offset
 *            The offset at which to split. If offset is at the end of the
 *            available data, the second node will be empty.
 *
 * @return A reference to the new node (containing data after the offset
 *         point). The original node will contain data up to that point.
 *
 * @throws DOMException(INDEX_SIZE_ERR)
 *             if offset is <0 or >length.
 *
 * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR)
 *             if node is read-only.
 */
public Text splitText(int offset)
    throws DOMException {

    if (isReadOnly()) {
        throw new DOMException(
        DOMException.NO_MODIFICATION_ALLOWED_ERR,
            DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
    }

    if (needsSyncData()) {
        synchronizeData();
    }
    if (offset < 0 || offset > data.length() ) {
        throw new DOMException(DOMException.INDEX_SIZE_ERR,
            DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null));
    }

    // split text into two separate nodes
    Text newText =
        getOwnerDocument().createTextNode(data.substring(offset));
    setNodeValue(data.substring(0, offset));

    // insert new text node
    Node parentNode = getParentNode();
    if (parentNode != null) {
        parentNode.insertBefore(newText, nextSibling);
    }

    return newText;

}
 
Example 11
private static int insertSourceMarker(@NonNull Node parent, @NonNull Node node,
        @NonNull File file, boolean after) {
    int insertCount = 0;
    Document doc = parent.getNodeType() ==
            Node.DOCUMENT_NODE ? (Document) parent : parent.getOwnerDocument();

    String comment;
    try {
        comment = SdkUtils.createPathComment(file, true);
    } catch (MalformedURLException e) {
        return insertCount;
    }

    Node prev = node.getPreviousSibling();
    String newline;
    if (prev != null && prev.getNodeType() == Node.TEXT_NODE) {
        // Duplicate indentation from previous line. Once we switch the merger
        // over to using the XmlPrettyPrinter, we won't need this.
        newline = prev.getNodeValue();
        int index = newline.lastIndexOf('\n');
        if (index != -1) {
            newline = newline.substring(index);
        }
    } else {
        newline = "\n";
    }

    if (after) {
        node = node.getNextSibling();
    }

    parent.insertBefore(doc.createComment(comment), node);
    insertCount++;

    // Can't add text nodes at the document level in Xerces, even though
    // it will happily parse these
    if (parent.getNodeType() != Node.DOCUMENT_NODE) {
        parent.insertBefore(doc.createTextNode(newline), node);
        insertCount++;
    }

    return insertCount;
}
 
Example 12
/**
 * Append a node to the current container.
 *
 * @param newNode New node to append
 */
protected void append(Node newNode) throws org.xml.sax.SAXException
{

  Node currentNode = m_currentNode;

  if (null != currentNode)
  {
    if (currentNode == m_root && m_nextSibling != null)
      currentNode.insertBefore(newNode, m_nextSibling);
    else
      currentNode.appendChild(newNode);

    // System.out.println(newNode.getNodeName());
  }
  else if (null != m_docFrag)
  {
    if (m_nextSibling != null)
      m_docFrag.insertBefore(newNode, m_nextSibling);
    else
      m_docFrag.appendChild(newNode);
  }
  else
  {
    boolean ok = true;
    short type = newNode.getNodeType();

    if (type == Node.TEXT_NODE)
    {
      String data = newNode.getNodeValue();

      if ((null != data) && (data.trim().length() > 0))
      {
        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null));  //"Warning: can't output text before document element!  Ignoring...");
      }

      ok = false;
    }
    else if (type == Node.ELEMENT_NODE)
    {
      if (m_doc.getDocumentElement() != null)
      {
        ok = false;

        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null));  //"Can't have more than one root on a DOM!");
      }
    }

    if (ok)
    {
      if (m_nextSibling != null)
        m_doc.insertBefore(newNode, m_nextSibling);
      else
        m_doc.appendChild(newNode);
    }
  }
}
 
Example 13
Source Project: openjdk-8   File: SAX2DOM.java    License: GNU General Public License v2.0 4 votes vote down vote up
public void startElement(String namespace, String localName, String qName,
        Attributes attrs)
    {
        appendTextNode();
        if (needToSetDocumentInfo) {
            setDocumentInfo();
            needToSetDocumentInfo = false;
        }

        final Element tmp = (Element)_document.createElementNS(namespace, qName);

        // Add namespace declarations first
        if (_namespaceDecls != null) {
            final int nDecls = _namespaceDecls.size();
            for (int i = 0; i < nDecls; i++) {
                final String prefix = (String) _namespaceDecls.elementAt(i++);

                if (prefix == null || prefix.equals(EMPTYSTRING)) {
                    tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX,
                        (String) _namespaceDecls.elementAt(i));
                }
                else {
                    tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix,
                        (String) _namespaceDecls.elementAt(i));
                }
            }
            _namespaceDecls.clear();
        }

        // Add attributes to element
/*      final int nattrs = attrs.getLength();
        for (int i = 0; i < nattrs; i++) {
            if (attrs.getLocalName(i) == null) {
                tmp.setAttribute(attrs.getQName(i), attrs.getValue(i));
            }
            else {
                tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i),
                    attrs.getValue(i));
            }
        } */


        // Add attributes to element
        final int nattrs = attrs.getLength();
        for (int i = 0; i < nattrs; i++) {
            // checking if Namespace processing is being done
            String attQName = attrs.getQName(i);
            String attURI = attrs.getURI(i);
            if (attrs.getLocalName(i).equals("")) {
                tmp.setAttribute(attQName, attrs.getValue(i));
                if (attrs.getType(i).equals("ID")) {
                    tmp.setIdAttribute(attQName, true);
                }
            } else {
                tmp.setAttributeNS(attURI, attQName, attrs.getValue(i));
                if (attrs.getType(i).equals("ID")) {
                    tmp.setIdAttributeNS(attURI, attrs.getLocalName(i), true);
                }
            }
        }


        // Append this new node onto current stack node
        Node last = (Node)_nodeStk.peek();

        // If the SAX2DOM is created with a non-null next sibling node,
        // insert the result nodes before the next sibling under the root.
        if (last == _root && _nextSibling != null)
            last.insertBefore(tmp, _nextSibling);
        else
            last.appendChild(tmp);

        // Push this node onto stack
        _nodeStk.push(tmp);
        _lastSibling = null;
    }
 
Example 14
Source Project: jdk8u60   File: DOMBuilder.java    License: GNU General Public License v2.0 4 votes vote down vote up
/**
 * Append a node to the current container.
 *
 * @param newNode New node to append
 */
protected void append(Node newNode) throws org.xml.sax.SAXException
{

  Node currentNode = m_currentNode;

  if (null != currentNode)
  {
    if (currentNode == m_root && m_nextSibling != null)
      currentNode.insertBefore(newNode, m_nextSibling);
    else
      currentNode.appendChild(newNode);

    // System.out.println(newNode.getNodeName());
  }
  else if (null != m_docFrag)
  {
    if (m_nextSibling != null)
      m_docFrag.insertBefore(newNode, m_nextSibling);
    else
      m_docFrag.appendChild(newNode);
  }
  else
  {
    boolean ok = true;
    short type = newNode.getNodeType();

    if (type == Node.TEXT_NODE)
    {
      String data = newNode.getNodeValue();

      if ((null != data) && (data.trim().length() > 0))
      {
        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null));  //"Warning: can't output text before document element!  Ignoring...");
      }

      ok = false;
    }
    else if (type == Node.ELEMENT_NODE)
    {
      if (m_doc.getDocumentElement() != null)
      {
        ok = false;

        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null));  //"Can't have more than one root on a DOM!");
      }
    }

    if (ok)
    {
      if (m_nextSibling != null)
        m_doc.insertBefore(newNode, m_nextSibling);
      else
        m_doc.appendChild(newNode);
    }
  }
}
 
Example 15
/**
 * Append a node to the current container.
 *
 * @param newNode New node to append
 */
protected void append(Node newNode) throws org.xml.sax.SAXException
{

  Node currentNode = m_currentNode;

  if (null != currentNode)
  {
    if (currentNode == m_root && m_nextSibling != null)
      currentNode.insertBefore(newNode, m_nextSibling);
    else
      currentNode.appendChild(newNode);

    // System.out.println(newNode.getNodeName());
  }
  else if (null != m_docFrag)
  {
    if (m_nextSibling != null)
      m_docFrag.insertBefore(newNode, m_nextSibling);
    else
      m_docFrag.appendChild(newNode);
  }
  else
  {
    boolean ok = true;
    short type = newNode.getNodeType();

    if (type == Node.TEXT_NODE)
    {
      String data = newNode.getNodeValue();

      if ((null != data) && (data.trim().length() > 0))
      {
        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null));  //"Warning: can't output text before document element!  Ignoring...");
      }

      ok = false;
    }
    else if (type == Node.ELEMENT_NODE)
    {
      if (m_doc.getDocumentElement() != null)
      {
        ok = false;

        throw new org.xml.sax.SAXException(
          XMLMessages.createXMLMessage(
            XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null));  //"Can't have more than one root on a DOM!");
      }
    }

    if (ok)
    {
      if (m_nextSibling != null)
        m_doc.insertBefore(newNode, m_nextSibling);
      else
        m_doc.appendChild(newNode);
    }
  }
}
 
Example 16
Source Project: cxf   File: CustomizationParser.java    License: Apache License 2.0 4 votes vote down vote up
protected void copyAllJaxbDeclarations(final Node schemaNode, final Element jaxwsBindingNode) {
    if (isSchemaElement(schemaNode)) {
        appendJaxbVersion((Element)schemaNode);
    }

    Node[] embededNodes = getAnnotationNodes(schemaNode);
    Node annotationNode = embededNodes[0];
    Node appinfoNode = embededNodes[1];

    for (Node childNode = jaxwsBindingNode.getFirstChild();
        childNode != null;
        childNode = childNode.getNextSibling()) {

        if (isSchemaElement(schemaNode)) {
            copyJaxbAttributes(childNode, (Element)schemaNode);
        }

        //TODO: check for valid extension namespaces
        if (!(childNode instanceof Element)) { //!isJaxbBindings(childNode)) {
            continue;
        }

        Element childEl = (Element)childNode;
        if (isJaxbBindings(childNode) && isJaxbBindingsElement(childEl)) {

            NodeList nlist = nodeSelector.queryNodes(schemaNode, childEl.getAttribute("node"));
            for (int i = 0; i < nlist.getLength(); i++) {
                Node node = nlist.item(i);
                copyAllJaxbDeclarations(node, childEl);
            }

        } else {
            Element cloneNode = (Element)ProcessorUtil.cloneNode(schemaNode.getOwnerDocument(),
                                                                 childEl, true);

            NamedNodeMap atts = cloneNode.getAttributes();
            for (int x = 0; x < atts.getLength(); x++) {
                Attr attr = (Attr)atts.item(x);
                if (ToolConstants.NS_JAXB_BINDINGS.equals(attr.getNamespaceURI())) {
                    cloneNode.removeAttributeNode(attr);
                    atts = cloneNode.getAttributes();
                    x = -1;
                }
            }
            appinfoNode.appendChild(cloneNode);
        }
    }

    if (schemaNode.getFirstChild() != null) {
        schemaNode.insertBefore(annotationNode, schemaNode.getFirstChild());
    } else {
        schemaNode.appendChild(annotationNode);
    }
}
 
Example 17
/**
 * Traverses the "right boundary" of this range and
 * operates on each "boundary node" according to the
 * <code>how</code> parameter.  It is a-priori assumed
 * by this method that the right boundary does
 * not contain the range's start container.
 * <p>
 * A "right boundary" is best visualized by thinking
 * of a sample tree:<pre>
 *                 A
 *                /|\
 *               / | \
 *              /  |  \
 *             B   C   D
 *            /|\     /|\
 *           E F G   H I J
 * </pre>
 * Imagine first a range that begins between the
 * "E" and "F" nodes and ends between the
 * "I" and "J" nodes.  The start container is
 * "B" and the end container is "D".  Given this setup,
 * the following applies:
 * <p>
 * Partially Selected Nodes: B, D<br>
 * Fully Selected Nodes: F, G, C, H, I
 * <p>
 * The "right boundary" is the highest subtree node
 * that contains the ending container.  The root of
 * this subtree is always partially selected.
 * <p>
 * In this example, the nodes that are traversed
 * as "right boundary" nodes are: H, I, and D.
 *
 * @param root   The node that is the root of the "right boundary" subtree.
 *
 * @param how    Specifies what type of traversal is being
 *               requested (extract, clone, or delete).
 *               Legal values for this argument are:
 *
 *               <ol>
 *               <li><code>EXTRACT_CONTENTS</code> - will produce
 *               a node containing the boundaries content.
 *               Partially selected nodes are copied, but fully
 *               selected nodes are moved.
 *
 *               <li><code>CLONE_CONTENTS</code> - will leave the
 *               context tree of the range undisturbed, but will
 *               produced cloned content.
 *
 *               <li><code>DELETE_CONTENTS</code> - will delete from
 *               the context tree of the range, all fully selected
 *               nodes within the boundary.
 *               </ol>
 *
 * @return Returns a node that is the result of visiting nodes.
 *         If the traversal operation is
 *         <code>DELETE_CONTENTS</code> the return value is null.
 */
private Node traverseRightBoundary( Node root, int how )
{
    Node next = getSelectedNode( fEndContainer, fEndOffset-1 );
    boolean isFullySelected = ( next!=fEndContainer );

    if ( next==root )
        return traverseNode( next, isFullySelected, false, how );

    Node parent = next.getParentNode();
    Node clonedParent = traverseNode( parent, false, false, how );

    while( parent!=null )
    {
        while( next!=null )
        {
            Node prevSibling = next.getPreviousSibling();
            Node clonedChild =
                traverseNode( next, isFullySelected, false, how );
            if ( how!=DELETE_CONTENTS )
            {
                clonedParent.insertBefore(
                    clonedChild,
                    clonedParent.getFirstChild()
                );
            }
            isFullySelected = true;
            next = prevSibling;
        }
        if ( parent==root )
            return clonedParent;

        next = parent.getPreviousSibling();
        parent = parent.getParentNode();
        Node clonedGrandParent = traverseNode( parent, false, false, how );
        if ( how!=DELETE_CONTENTS )
            clonedGrandParent.appendChild( clonedParent );
        clonedParent = clonedGrandParent;

    }

    // should never occur
    return null;
}
 
Example 18
/**
 * Traverses the "right boundary" of this range and
 * operates on each "boundary node" according to the
 * <code>how</code> parameter.  It is a-priori assumed
 * by this method that the right boundary does
 * not contain the range's start container.
 * <p>
 * A "right boundary" is best visualized by thinking
 * of a sample tree:<pre>
 *                 A
 *                /|\
 *               / | \
 *              /  |  \
 *             B   C   D
 *            /|\     /|\
 *           E F G   H I J
 * </pre>
 * Imagine first a range that begins between the
 * "E" and "F" nodes and ends between the
 * "I" and "J" nodes.  The start container is
 * "B" and the end container is "D".  Given this setup,
 * the following applies:
 * <p>
 * Partially Selected Nodes: B, D<br>
 * Fully Selected Nodes: F, G, C, H, I
 * <p>
 * The "right boundary" is the highest subtree node
 * that contains the ending container.  The root of
 * this subtree is always partially selected.
 * <p>
 * In this example, the nodes that are traversed
 * as "right boundary" nodes are: H, I, and D.
 *
 * @param root   The node that is the root of the "right boundary" subtree.
 *
 * @param how    Specifies what type of traversal is being
 *               requested (extract, clone, or delete).
 *               Legal values for this argument are:
 *
 *               <ol>
 *               <li><code>EXTRACT_CONTENTS</code> - will produce
 *               a node containing the boundaries content.
 *               Partially selected nodes are copied, but fully
 *               selected nodes are moved.
 *
 *               <li><code>CLONE_CONTENTS</code> - will leave the
 *               context tree of the range undisturbed, but will
 *               produced cloned content.
 *
 *               <li><code>DELETE_CONTENTS</code> - will delete from
 *               the context tree of the range, all fully selected
 *               nodes within the boundary.
 *               </ol>
 *
 * @return Returns a node that is the result of visiting nodes.
 *         If the traversal operation is
 *         <code>DELETE_CONTENTS</code> the return value is null.
 */
private Node traverseRightBoundary( Node root, int how )
{
    Node next = getSelectedNode( fEndContainer, fEndOffset-1 );
    boolean isFullySelected = ( next!=fEndContainer );

    if ( next==root )
        return traverseNode( next, isFullySelected, false, how );

    Node parent = next.getParentNode();
    Node clonedParent = traverseNode( parent, false, false, how );

    while( parent!=null )
    {
        while( next!=null )
        {
            Node prevSibling = next.getPreviousSibling();
            Node clonedChild =
                traverseNode( next, isFullySelected, false, how );
            if ( how!=DELETE_CONTENTS )
            {
                clonedParent.insertBefore(
                    clonedChild,
                    clonedParent.getFirstChild()
                );
            }
            isFullySelected = true;
            next = prevSibling;
        }
        if ( parent==root )
            return clonedParent;

        next = parent.getPreviousSibling();
        parent = parent.getParentNode();
        Node clonedGrandParent = traverseNode( parent, false, false, how );
        if ( how!=DELETE_CONTENTS )
            clonedGrandParent.appendChild( clonedParent );
        clonedParent = clonedGrandParent;

    }

    // should never occur
    return null;
}
 
Example 19
Source Project: hottub   File: RangeImpl.java    License: GNU General Public License v2.0 2 votes vote down vote up
/**
 * Traverses the "right boundary" of this range and
 * operates on each "boundary node" according to the
 * <code>how</code> parameter.  It is a-priori assumed
 * by this method that the right boundary does
 * not contain the range's start container.
 * <p>
 * A "right boundary" is best visualized by thinking
 * of a sample tree:<pre>
 *                 A
 *                /|\
 *               / | \
 *              /  |  \
 *             B   C   D
 *            /|\     /|\
 *           E F G   H I J
 * </pre>
 * Imagine first a range that begins between the
 * "E" and "F" nodes and ends between the
 * "I" and "J" nodes.  The start container is
 * "B" and the end container is "D".  Given this setup,
 * the following applies:
 * <p>
 * Partially Selected Nodes: B, D<br>
 * Fully Selected Nodes: F, G, C, H, I
 * <p>
 * The "right boundary" is the highest subtree node
 * that contains the ending container.  The root of
 * this subtree is always partially selected.
 * <p>
 * In this example, the nodes that are traversed
 * as "right boundary" nodes are: H, I, and D.
 *
 * @param root   The node that is the root of the "right boundary" subtree.
 *
 * @param how    Specifies what type of traversal is being
 *               requested (extract, clone, or delete).
 *               Legal values for this argument are:
 *
 *               <ol>
 *               <li><code>EXTRACT_CONTENTS</code> - will produce
 *               a node containing the boundaries content.
 *               Partially selected nodes are copied, but fully
 *               selected nodes are moved.
 *
 *               <li><code>CLONE_CONTENTS</code> - will leave the
 *               context tree of the range undisturbed, but will
 *               produced cloned content.
 *
 *               <li><code>DELETE_CONTENTS</code> - will delete from
 *               the context tree of the range, all fully selected
 *               nodes within the boundary.
 *               </ol>
 *
 * @return Returns a node that is the result of visiting nodes.
 *         If the traversal operation is
 *         <code>DELETE_CONTENTS</code> the return value is null.
 */
private Node traverseRightBoundary( Node root, int how )
{
    Node next = getSelectedNode( fEndContainer, fEndOffset-1 );
    boolean isFullySelected = ( next!=fEndContainer );

    if ( next==root )
        return traverseNode( next, isFullySelected, false, how );

    Node parent = next.getParentNode();
    Node clonedParent = traverseNode( parent, false, false, how );

    while( parent!=null )
    {
        while( next!=null )
        {
            Node prevSibling = next.getPreviousSibling();
            Node clonedChild =
                traverseNode( next, isFullySelected, false, how );
            if ( how!=DELETE_CONTENTS )
            {
                clonedParent.insertBefore(
                    clonedChild,
                    clonedParent.getFirstChild()
                );
            }
            isFullySelected = true;
            next = prevSibling;
        }
        if ( parent==root )
            return clonedParent;

        next = parent.getPreviousSibling();
        parent = parent.getParentNode();
        Node clonedGrandParent = traverseNode( parent, false, false, how );
        if ( how!=DELETE_CONTENTS )
            clonedGrandParent.appendChild( clonedParent );
        clonedParent = clonedGrandParent;

    }

    // should never occur
    return null;
}
 
Example 20
/**
 * Traverses the "right boundary" of this range and
 * operates on each "boundary node" according to the
 * <code>how</code> parameter.  It is a-priori assumed
 * by this method that the right boundary does
 * not contain the range's start container.
 * <p>
 * A "right boundary" is best visualized by thinking
 * of a sample tree:<pre>
 *                 A
 *                /|\
 *               / | \
 *              /  |  \
 *             B   C   D
 *            /|\     /|\
 *           E F G   H I J
 * </pre>
 * Imagine first a range that begins between the
 * "E" and "F" nodes and ends between the
 * "I" and "J" nodes.  The start container is
 * "B" and the end container is "D".  Given this setup,
 * the following applies:
 * <p>
 * Partially Selected Nodes: B, D<br>
 * Fully Selected Nodes: F, G, C, H, I
 * <p>
 * The "right boundary" is the highest subtree node
 * that contains the ending container.  The root of
 * this subtree is always partially selected.
 * <p>
 * In this example, the nodes that are traversed
 * as "right boundary" nodes are: H, I, and D.
 *
 * @param root   The node that is the root of the "right boundary" subtree.
 *
 * @param how    Specifies what type of traversal is being
 *               requested (extract, clone, or delete).
 *               Legal values for this argument are:
 *
 *               <ol>
 *               <li><code>EXTRACT_CONTENTS</code> - will produce
 *               a node containing the boundaries content.
 *               Partially selected nodes are copied, but fully
 *               selected nodes are moved.
 *
 *               <li><code>CLONE_CONTENTS</code> - will leave the
 *               context tree of the range undisturbed, but will
 *               produced cloned content.
 *
 *               <li><code>DELETE_CONTENTS</code> - will delete from
 *               the context tree of the range, all fully selected
 *               nodes within the boundary.
 *               </ol>
 *
 * @return Returns a node that is the result of visiting nodes.
 *         If the traversal operation is
 *         <code>DELETE_CONTENTS</code> the return value is null.
 */
private Node traverseRightBoundary( Node root, int how )
{
    Node next = getSelectedNode( fEndContainer, fEndOffset-1 );
    boolean isFullySelected = ( next!=fEndContainer );

    if ( next==root )
        return traverseNode( next, isFullySelected, false, how );

    Node parent = next.getParentNode();
    Node clonedParent = traverseNode( parent, false, false, how );

    while( parent!=null )
    {
        while( next!=null )
        {
            Node prevSibling = next.getPreviousSibling();
            Node clonedChild =
                traverseNode( next, isFullySelected, false, how );
            if ( how!=DELETE_CONTENTS )
            {
                clonedParent.insertBefore(
                    clonedChild,
                    clonedParent.getFirstChild()
                );
            }
            isFullySelected = true;
            next = prevSibling;
        }
        if ( parent==root )
            return clonedParent;

        next = parent.getPreviousSibling();
        parent = parent.getParentNode();
        Node clonedGrandParent = traverseNode( parent, false, false, how );
        if ( how!=DELETE_CONTENTS )
            clonedGrandParent.appendChild( clonedParent );
        clonedParent = clonedGrandParent;

    }

    // should never occur
    return null;
}