⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodeimpl.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    appendChild( newChildX );
                    newChildX = nextChild;
                }
                return newChild;
            }

            // Node becomes child of this parent and part of this document.
            // Note that this code comes after the test for a DocumentFragment.
            // A fragment does not become part of this node, only its children.
            // The fragment becomes parent-less and child-less.
            // newChildX._parent = this;
            newChildX.setParentNode( this );
            if (_ownerDocument != null) {
                newChildX.setOwnerDocument( _ownerDocument );
            }

            // If the list has no end (it is empty) then newChild is added as the
            // only child in it.
            if (_lastChild == null) {
                _lastChild = newChildX;
                _firstChild = newChildX;
                newChildX.setPreviousSibling( null );
                newChildX.setNextSibling( null );
            } else {
                // newChild becomes the new end of the list, adjusting the previous
                // last child.
                _lastChild.setNextSibling( newChildX );
                newChildX.setPreviousSibling( _lastChild );
                newChildX.setNextSibling( null );
                _lastChild = newChildX;
            }
            // Keep this count accurate at all times.
            ++_childsCount;
        }
        return newChild;
    }


    /**
     * Remove <TT>oldChild</TT> from this parent. If <TT>oldChild</TT> is not
     * a direct child of this parent, or childern are not supported by this node
     * type, an exception is thrown.
     *
     * @param oldChild The child to remove
     * @return The removed child
     * @throws org.w3c.dom.DOMException <TT>NO_MODIFICATION_ALLOWED_ERR</TT>
     *  Node is read-only and cannot be modified
     * @throws org.w3c.dom.DOMException <TT>HIERARCHY_REQUEST_ERR</TT>
     *  Children are not supported by this node type
     * @throws org.w3c.dom.DOMException <TT>NOT_FOUND_ERR</TT>
     *  <TT>oldChild</TT> is not a direct child of this node
     * @see #castOldChild
     */
    public synchronized final Node removeChild( Node oldChild ) throws DOMException {
        NodeProxy oldChildX;

        // Make sure the node is not read-only.
        // Throw exception if children not supported by derived class.
        if (isReadOnly()) {
            throw new DOMExceptionImpl( DOMException.NO_MODIFICATION_ALLOWED_ERR );
        }
        if (!supportsChildern()) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR,
                    "No childern supported by this node type." );
        }

        // Cast refChild to NodeImpl, making sure it is a child of this node.
        oldChildX = (NodeProxy)castOldChild( oldChild );

        // We're going to mess with this child node, so make sure no other thread
        // is touching it
        synchronized (oldChild) {
            // Need to tell all the iterators that might be observing the
            // child node that the child node is removed from the current
            // tree. The iterators will reflect the changed by selecting
            // a different child to point to. Interesting iterators are
            // those the observer the tree underneath this node and all its
            // parents.
            notifyIterators( oldChild );

            // Child becomes orphan. It is no longer first or last child of this
            // node. Removed from linked list.
            oldChildX.setParentNode( null );

            if (_firstChild != null && _firstChild.equals( oldChildX )) {
                _firstChild = (NodeProxy)oldChildX.getNextSibling();
            }

            if (_lastChild != null && _lastChild.equals( oldChildX )) {
                _lastChild = (NodeProxy)oldChildX.getPreviousSibling();
            }

            if (oldChildX.getPreviousSibling() != null) {
                ((NodeProxy)oldChildX.getPreviousSibling()).setNextSibling( oldChildX.getNextSibling() );
            }

            if (oldChildX.getNextSibling() != null) {
                ((NodeProxy)oldChildX.getNextSibling()).setPreviousSibling( oldChildX.getPreviousSibling() );
            }

            oldChildX.setPreviousSibling( null );
            oldChildX.setNextSibling( null );

            // Keep this count accurate at all times.
            --_childsCount;

        }
        return oldChild;
    }


    /**
     * Replace <TT>oldChild</TT> with <TT>newChild</TT>, adding the new child and
     * removing the old one.
     * <P>
     * If <TT>newChild</TT> does not belong to this DOM, <TT>oldChild</TT> is not
     * a direct child of this parent, or childern are not supported by this node
     * type, an exception is thrown.
     * <P>
     * <TT>newChild</TT> is removed from its original parent before adding to this
     * parent. If <TT>newChild</TT> is a {@link org.w3c.dom.DocumentFragment}, all
     * its children are inserted one by one into this parent.
     *
     * @param newChild The new child to add
     * @param oldChild The old child to take away
     * @return The old child
     * @throws org.w3c.dom.DOMException <TT>NO_MODIFICATION_ALLOWED_ERR</TT>
     *  Node is read-only and cannot be modified
     * @throws org.w3c.dom.DOMException <TT>HIERARCHY_REQUEST_ERR</TT>
     *  Children are not supported by this node type, or <TT>newChild</TT> is not
     *  a compatible type for this node
     * @throws org.w3c.dom.DOMException <TT>NOT_FOUND_ERR</TT>
     *  <TT>oldChild</TT> is not a direct child of this node
     * @see #castNewChild
     * @see #castOldChild
     */
    public synchronized final Node replaceChild( Node newChild, Node oldChild ) throws DOMException {
        // Node arguments must be casted to NodeEx in order to operate on them.
        NodeProxy newChildX;
        NodeProxy oldChildX;

        // Make sure the node is not read-only.
        // Throw exception if children not supported by derived class.
        if (isReadOnly()) {
            throw new DOMExceptionImpl( DOMException.NO_MODIFICATION_ALLOWED_ERR );
        }
        if (!supportsChildern()) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR,
                    "No childern supported by this node type." );
        }

        // Cast newChild to NodeImpl and make sure it can be inserted to this node.
        // Cast oldChild to NodeImpl, making sure it is a child of this node.
        if (newChild != null) {
            newChildX = (NodeProxy)castNewChild( newChild );
        }
        oldChildX = (NodeProxy)castOldChild( oldChild );

        // We're going to mess with this child node, so make sure no other thread
        // is touching it
        synchronized (oldChild) {
            if (newChild != null) {
                // .. or this
                synchronized (newChild) {
                    // Lazy implementation adds newChild before oldChild and then takes
                    // oldChild away. Might be a touch slowed, but is way more reliable.
                    insertBefore( newChild, oldChild );
                    removeChild( oldChild );
                }
            } else {
                // The case of just removing the old child, when the new one
                // is null.
                removeChild( oldChild );
            }
        }
        return oldChild;
    }


    /**
     * Insert <TT>newChild</TT> in this parent, before the existing child
     * <TT>refChild</TT>. If <TT>refChild</TT> is null, insert <TT>newChild</TT>
     * as the last child of this parent, akin to calling {@link #appendChild}.
     * <P>
     * If <TT>newChild</TT> is null, <TT>newChild</TT> does not belong to this DOM,
     * <TT>refChild</TT> is not a direct child of this node, or childern are not
     * supported by this node type, an exception is thrown.
     * <P>
     * <TT>newChild</TT> is removed from its original parent before adding to this
     * parent. If <TT>newChild</TT> is a {@link org.w3c.dom.DocumentFragment}, all
     * its children are inserted one by one into this parent.
     *
     * @param newChild The new child to add
     * @param refChild Insert new child before this child, or insert at the end
     *  if this child is null
     * @return The newly inserted child
     * @throws org.w3c.dom.DOMException <TT>NO_MODIFICATION_ALLOWED_ERR</TT>
     *  Node is read-only and cannot be modified
     * @throws org.w3c.dom.DOMException <TT>HIERARCHY_REQUEST_ERR</TT>
     *  Children are not supported by this node type, or <TT>newChild</TT> is not
     *  a compatible type for this node
     * @throws org.w3c.dom.DOMException <TT>NOT_FOUND_ERR</TT>
     *  <TT>oldChild</TT> is not null and not a direct child of this node
     * @see #castNewChild
     * @see #castOldChild
     */
    public synchronized final Node insertBefore( Node newChild, Node refChild ) throws DOMException {
        // Node arguments must be casted to NodeEx in order to operate on them.
        NodeProxy newChildX;
        NodeProxy refChildX;

        // Make sure the node is not read-only.
        // Throw exception if children not supported by derived class.
        if (isReadOnly()) {
            throw new DOMExceptionImpl( DOMException.NO_MODIFICATION_ALLOWED_ERR );
        }
        if (!supportsChildern()) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR,
                    "No childern supported by this node type." );
        }

        // If refChild is null, act as if appendChild was called.
        if (refChild == null) {
            return appendChild( newChild );
        }

        // Cast newChild to NodeImpl and make sure it can be inserted to this node.
        // Cast refChild to NodeImpl, making sure it is a child of this node.
        newChildX = (NodeProxy)castNewChild( newChild );
        refChildX = (NodeProxy)castOldChild( refChild );

        // We're going to mess with this child node, so make sure no other thread
        // is touching it
        synchronized (newChild) {
            // .. or this
            synchronized (refChild) {
                // If the newChild is already a child or some node, remove it first
                // before becoming child of this node. Make sure that parent is not
                // read-only.
                if (newChildX.getParentNode() != null) {
                    if (((NodeProxy)newChildX.getParentNode()).isReadOnly()) {
                        throw new DOMExceptionImpl( DOMException.NO_MODIFICATION_ALLOWED_ERR );
                    }
                    newChildX.getParentNode().removeChild( newChildX );
                }

                // Special case: newChild is a DocumentFragment and instead of
                // inserting itself, all of its childs are inserted one by one.
                if (newChildX instanceof DocumentFragment) {
                    NodeProxy nextChild;

                    newChildX = (NodeProxy)newChildX.getFirstChild();
                    while (newChildX != null) {
                        nextChild = (NodeProxy)newChildX.getNextSibling();
                        insertBefore( newChildX, refChild );
                        newChildX = nextChild;
                    }
                    return newChild;
                }

                // Node becomes child of this parent and part of this document.
                // Note that this code comes after the test for a DocumentFragment.
                // A fragment does not become part of this node, only its children.
                // The fragment becomes parent-less and child-less.
                newChildX.setParentNode( this );
                newChildX.setOwnerDocument( _ownerDocument );

                // If refChild is the first child, newChild becomes the first
                // child on the list.
                if (_firstChild.equals( refChildX )) {
                    _firstChild = newChildX;
                }
                // refChild is not the first child, so adjust the previous child
                // to point at newChild instead.
                if (refChildX.getPreviousSibling() != null) {
                    newChildX.setPreviousSibling( refChildX.getPreviousSibling() );
                    ((NodeProxy)refChildX.getPreviousSibling()).setNextSibling( newChildX );
                }
                // Adjust the refChild to point at this child and vice versa.
                refChildX.setPreviousSibling( newChildX );
                newChildX.setNextSibling( refChildX );
                // Keep this count accurate at all times.
                ++_childsCount;
            }
        }
        return newChild;
    }


    /**
     * Checks whether <TT>newChild</TT> can be added to this node as a child, and
     * if so, performs a necessary cast. <TT>newChild</TT> cannot be null and must
     * belong to this DOM. It is impossible to transfer nodes between different
     * DOM implementations.
     * <P>
     * The following rules govern the allowed <TT>newChild</TT> types:
     * <UL>
     * <LI>Parent is an {@link org.w3c.dom.Attr}, <TT>newChild</TT> must be either
     *  a {@link org.w3c.dom.Text} or an {@link org.w3c.dom.EntityReference}
     * <LI>Parent is a {@link org.w3c.dom.DocumentType}, <TT>newChild</TT> must be
     *  either an {@link org.w3c.dom.Entity} or a {@link org.w3c.dom.Notation}.
     * <LI>Parnet is any other node type, <TT>newChild</TT> must be an {@link
     *  org.w3c.dom.Element}, a {@link org.w3c.dom.CharacterData} derived type,
     *  a {@link org.w3c.dom.DocumentFragment}, an {@link
     *  org.w3c.dom.EntityReference} or a {@link org.w3c.dom.ProcessingInstruction}.
     * </UL>
     * Any deviation will throw an exception.
     *
     * @param newChild New child node
     * @return <TT>newChild</TT> cast to type {@link NodeImpl}
     * @throws org.w3c.dom.DOMException <TT>HIERARCHY_REQUEST_ERR</TT>
     *  <TT>newChild</TT> is null, does not belong to this DOM, or its node type
     *  is not supported for this parent
     */
    protected Node castNewChild( Node newChild ) throws DOMException {
        if (newChild == null) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR, "Child reference is null." );
        }

        // newChild must be Element, CDATASection, Text, Comment (all three
        // derived from CharacterData), DocumentFragment, EntityReference,
        // or ProcessingInstruction.
        if (!(newChild instanceof Node)) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR,
                    "Child is not a compatible type for this node." );
        }
        if (!(newChild instanceof Element || newChild instanceof CharacterData || newChild instanceof DocumentFragment
                || newChild instanceof EntityReference || newChild instanceof ProcessingInstruction)) {
            throw new DOMExceptionImpl( DOMException.HIERARCHY_REQUEST_ERR,
                    "Child is not a compatible type for this node." );
        }
        return newChild;
    }


    /**
     * Checks whether <TT>oldChild</TT> is a direct child of this node, and if so,
     * performs a necessary cast. <TT>oldChild</TT> cannot be null.
     *
     * @param oldChild Old child node
     * @return <T>oldChild</TT> cast to type {@link NodeImpl}
     * @throws org.w3c.dom.DOMException <TT>NOT_FOUND_ERR</TT>
     *  <TT>oldChild</TT> is null, or not a direct child of this node
     */
    protected final Node castOldChild( Node oldChild ) throws DOMException {
        if (oldChild == null || !(oldChild instanceof NodeProxy)
                || !((OzoneProxy)oldChild.getParentNode()).remoteID().equals( container().id() )) {
            throw new DOMExceptionImpl( DOMException.NOT_FOUND_ERR, "Not a direct child of this node." );
        }
        return oldChild;
    }


    /**
     * This clone method is called after a new node has been constructed to copy
     * the contents of this node into the new one. It clones in contents but not
     * in context, and guarantees that the cloned node will pass the equality
     * test (see {@link #equals}).
     * <P>
     * <TT>into</TT> must be a valid node of the exact same class as this one.
     * <TT>deep</TT> is true if deep cloning (includes all children nodes) is to
     * be performed. If <TT>deep</TT> is false, the clone might not pass the
     * equality test.
     * <P>
     * Derived classes override and call this method to add per-class variable
     * copying. This method is called by {@link #cloneNode} and the default
     * {@link java.lang.Object#clone} method.
     * <P>
     * Contents cloning duplicates the node's name and value, and its children.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -