parentnode.java
来自「JAVA 所有包」· Java 代码 · 共 1,032 行 · 第 1/3 页
JAVA
1,032 行
/* * Copyright 1999-2002,2004,2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.sun.org.apache.xerces.internal.dom;import java.io.Serializable;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import org.w3c.dom.DOMException;import org.w3c.dom.Document;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.UserDataHandler;/** * ParentNode inherits from ChildNode and adds the capability of having child * nodes. Not every node in the DOM can have children, so only nodes that can * should inherit from this class and pay the price for it. * <P> * ParentNode, just like NodeImpl, also implements NodeList, so it can * return itself in response to the getChildNodes() query. This eliminiates * the need for a separate ChildNodeList object. Note that this is an * IMPLEMENTATION DETAIL; applications should _never_ assume that * this identity exists. On the other hand, subclasses may need to override * this, in case of conflicting names. This is the case for the classes * HTMLSelectElementImpl and HTMLFormElementImpl of the HTML DOM. * <P> * While we have a direct reference to the first child, the last child is * stored as the previous sibling of the first child. First child nodes are * marked as being so, and getNextSibling hides this fact. * <P>Note: Not all parent nodes actually need to also be a child. At some * point we used to have ParentNode inheriting from NodeImpl and another class * called ChildAndParentNode that inherited from ChildNode. But due to the lack * of multiple inheritance a lot of code had to be duplicated which led to a * maintenance nightmare. At the same time only a few nodes (Document, * DocumentFragment, Entity, and Attribute) cannot be a child so the gain in * memory wasn't really worth it. The only type for which this would be the * case is Attribute, but we deal with there in another special way, so this is * not applicable. * <p> * This class doesn't directly support mutation events, however, it notifies * the document when mutations are performed so that the document class do so. * * <p><b>WARNING</b>: Some of the code here is partially duplicated in * AttrImpl, be careful to keep these two classes in sync! * * @xerces.internal * * @author Arnaud Le Hors, IBM * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @version $Id: ParentNode.java,v 1.2.6.1 2005/08/31 12:39:32 sunithareddy Exp $ */public abstract class ParentNode extends ChildNode { /** Serialization version. */ static final long serialVersionUID = 2815829867152120872L; /** Owner document. */ protected CoreDocumentImpl ownerDocument; /** First child. */ protected ChildNode firstChild = null; // transients /** NodeList cache */ protected transient NodeListCache fNodeListCache = null; // // Constructors // /** * No public constructor; only subclasses of ParentNode should be * instantiated, and those normally via a Document's factory methods */ protected ParentNode(CoreDocumentImpl ownerDocument) { super(ownerDocument); this.ownerDocument = ownerDocument; } /** Constructor for serialization. */ public ParentNode() {} // // NodeList methods // /** * Returns a duplicate of a given node. You can consider this a * generic "copy constructor" for nodes. The newly returned object should * be completely independent of the source object's subtree, so changes * in one after the clone has been made will not affect the other. * <p> * Example: Cloning a Text node will copy both the node and the text it * contains. * <p> * Example: Cloning something that has children -- Element or Attr, for * example -- will _not_ clone those children unless a "deep clone" * has been requested. A shallow clone of an Attr node will yield an * empty Attr of the same name. * <p> * NOTE: Clones will always be read/write, even if the node being cloned * is read-only, to permit applications using only the DOM API to obtain * editable copies of locked portions of the tree. */ public Node cloneNode(boolean deep) { if (needsSyncChildren()) { synchronizeChildren(); } ParentNode newnode = (ParentNode) super.cloneNode(deep); // set owner document newnode.ownerDocument = ownerDocument; // Need to break the association w/ original kids newnode.firstChild = null; // invalidate cache for children NodeList newnode.fNodeListCache = null; // Then, if deep, clone the kids too. if (deep) { for (ChildNode child = firstChild; child != null; child = child.nextSibling) { newnode.appendChild(child.cloneNode(true)); } } return newnode; } // cloneNode(boolean):Node /** * Find the Document that this Node belongs to (the document in * whose context the Node was created). The Node may or may not * currently be part of that Document's actual contents. */ public Document getOwnerDocument() { return ownerDocument; } /** * same as above but returns internal type and this one is not overridden * by CoreDocumentImpl to return null */ CoreDocumentImpl ownerDocument() { return ownerDocument; } /** * NON-DOM * set the ownerDocument of this node and its children */ void setOwnerDocument(CoreDocumentImpl doc) { if (needsSyncChildren()) { synchronizeChildren(); } for (ChildNode child = firstChild; child != null; child = child.nextSibling) { child.setOwnerDocument(doc); } /* setting the owner document of self, after it's children makes the data of children available to the new document. */ super.setOwnerDocument(doc); ownerDocument = doc; } /** * Test whether this node has any children. Convenience shorthand * for (Node.getFirstChild()!=null) */ public boolean hasChildNodes() { if (needsSyncChildren()) { synchronizeChildren(); } return firstChild != null; } /** * Obtain a NodeList enumerating all children of this node. If there * are none, an (initially) empty NodeList is returned. * <p> * NodeLists are "live"; as children are added/removed the NodeList * will immediately reflect those changes. Also, the NodeList refers * to the actual nodes, so changes to those nodes made via the DOM tree * will be reflected in the NodeList and vice versa. * <p> * In this implementation, Nodes implement the NodeList interface and * provide their own getChildNodes() support. Other DOMs may solve this * differently. */ public NodeList getChildNodes() { if (needsSyncChildren()) { synchronizeChildren(); } return this; } // getChildNodes():NodeList /** The first child of this Node, or null if none. */ public Node getFirstChild() { if (needsSyncChildren()) { synchronizeChildren(); } return firstChild; } // getFirstChild():Node /** The last child of this Node, or null if none. */ public Node getLastChild() { if (needsSyncChildren()) { synchronizeChildren(); } return lastChild(); } // getLastChild():Node final ChildNode lastChild() { // last child is stored as the previous sibling of first child return firstChild != null ? firstChild.previousSibling : null; } final void lastChild(ChildNode node) { // store lastChild as previous sibling of first child if (firstChild != null) { firstChild.previousSibling = node; } } /** * Move one or more node(s) to our list of children. Note that this * implicitly removes them from their previous parent. * * @param newChild The Node to be moved to our subtree. As a * convenience feature, inserting a DocumentNode will instead insert * all its children. * * @param refChild Current child which newChild should be placed * immediately before. If refChild is null, the insertion occurs * after all existing Nodes, like appendChild(). * * @return newChild, in its new state (relocated, or emptied in the case of * DocumentNode.) * * @throws DOMException(HIERARCHY_REQUEST_ERR) if newChild is of a * type that shouldn't be a child of this node, or if newChild is an * ancestor of this node. * * @throws DOMException(WRONG_DOCUMENT_ERR) if newChild has a * different owner document than we do. * * @throws DOMException(NOT_FOUND_ERR) if refChild is not a child of * this node. * * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if this node is * read-only. */ public Node insertBefore(Node newChild, Node refChild) throws DOMException { // Tail-call; optimizer should be able to do good things with. return internalInsertBefore(newChild, refChild, false); } // insertBefore(Node,Node):Node /** NON-DOM INTERNAL: Within DOM actions,we sometimes need to be able * to control which mutation events are spawned. This version of the * insertBefore operation allows us to do so. It is not intended * for use by application programs. */ Node internalInsertBefore(Node newChild, Node refChild, boolean replace) throws DOMException { boolean errorChecking = ownerDocument.errorChecking; if (newChild.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) { // SLOW BUT SAFE: We could insert the whole subtree without // juggling so many next/previous pointers. (Wipe out the // parent's child-list, patch the parent pointers, set the // ends of the list.) But we know some subclasses have special- // case behavior they add to insertBefore(), so we don't risk it. // This approch also takes fewer bytecodes. // NOTE: If one of the children is not a legal child of this // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children // have been transferred. (Alternative behaviors would be to // reparent up to the first failure point or reparent all those // which are acceptable to the target node, neither of which is // as robust. PR-DOM-0818 isn't entirely clear on which it // recommends????? // No need to check kids for right-document; if they weren't, // they wouldn't be kids of that DocFrag. if (errorChecking) { for (Node kid = newChild.getFirstChild(); // Prescan kid != null; kid = kid.getNextSibling()) { if (!ownerDocument.isKidOK(this, kid)) { throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); } } } while (newChild.hasChildNodes()) { insertBefore(newChild.getFirstChild(), refChild); } return newChild; } if (newChild == refChild) { // stupid case that must be handled as a no-op triggering events... refChild = refChild.getNextSibling(); removeChild(newChild); insertBefore(newChild, refChild); return newChild; } if (needsSyncChildren()) { synchronizeChildren(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?