All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.dom.ParentNode Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2009 Adobe Systems Incorporated All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Adobe Systems Incorporated and its suppliers, if any. The intellectual and
 * technical concepts contained herein are proprietary to Adobe Systems
 * Incorporated and its suppliers and may be covered by U.S. and Foreign
 * Patents, patents in process, and are protected by trade secret or copyright
 * law. Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained from
 * Adobe Systems Incorporated.
 */
package com.adobe.xfa.dom;

import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This class represents any node that may be a parent of other nodes
 * (e.g., element, document).  It provides the mechanics for storing and
 * iterating through child nodes.  It also caches a reference to an XFA
 * element (since all parents in the XFA hierarchy are instances of the
 * XFA Element class).
 * @exclude from published api.
 */
abstract class ParentNode extends XFANodeHolder {
	private XFANodeHolder mFirstChild;
	private XFANodeHolder mLastChild;
	private final com.adobe.xfa.Element mXFAElement;

	ParentNode (ParentNode parent, com.adobe.xfa.Element newElement) {
		super (parent, newElement);
		mXFAElement = newElement;
	}

	public NodeList getChildNodes() {
//		debug ("getChildNodes()");
		fillAllChildren();
		NodeListImpl nodeList = new NodeListImpl (getXFAElement().getNumAttrs());
		nodeList.addNodes (getFirstChildImpl());
		return nodeList;
	}

	public Node getFirstChild() {
		fillChildrenFromStart();
//		debugReturn ("getFirstChild", mFirstChild);
		return mFirstChild;
	}

	public Node getLastChild() {
		fillChildrenToEnd();
//		debugReturn ("getLastChild", mLastChild);
		return mLastChild;
	}

	public boolean hasChildNodes() {
		return mXFAElement.getFirstXMLChild() != null;
	}

	public Node insertBefore(Node newChild, Node refChild) throws DOMException {
		throw new DOMException (DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
	}

	public boolean isEqualNode(Node other) {
		if (other == null) {
			return false;
		}
		if (! (other instanceof ParentNode)) {
			return false;
		}

		ParentNode otherParent = (ParentNode) other;
		fillAllChildren();
		otherParent.fillAllChildren();
		NodeImpl thisChild = getFirstChildImpl();
		NodeImpl otherChild = otherParent.getFirstChildImpl();
		for (;;) {
			if (thisChild == null) {
				if (otherChild == null) {
					break;
				} else {
					return false;
				}
			} else {
				if (otherChild == null) {
					return false;
				} if (! thisChild.isEqualNode (otherChild)) {
					return false;
				}
			}
			thisChild = thisChild.getNext();
			otherChild = otherChild.getNext();
		}

		return true;
	}

	public Node removeChild(Node oldCcild) throws DOMException {
		throw new DOMException (DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
	}

	public Node replaceChild(Node oldChild, Node newChild) throws DOMException {
		throw new DOMException (DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
	}

	final XFANodeHolder createNode (com.adobe.xfa.Node source) {
		return createNode (this, source);
	}

	abstract boolean testDefaultNamespace (String NamespaceURI);

	final void fillAllChildren () {
		fillChildrenFromStart();
		fillChildrenToEnd();
	}

	XFANodeHolder forcePrev (NodeImpl child) {
		assert (child == mFirstChild);
		fillChildrenFromStart();
		NodeImpl prevNode = child.getPrev();
		assert ((prevNode == null) || (prevNode instanceof XFANodeHolder));
		return (XFANodeHolder) prevNode;
	}

	XFANodeHolder forceNext (NodeImpl child) {
		assert (child == mLastChild);
		com.adobe.xfa.Node xfaChild = mLastChild.getXFANode();
		com.adobe.xfa.Node xfaNext = xfaChild.getNextXMLSibling();
		if (xfaNext == null) {
			return null;
		}
		XFANodeHolder newChild = createNode (xfaNext);
		newChild.setPrev (mLastChild);
		mLastChild.setNext (newChild);
		mLastChild = newChild;
		return mLastChild;
	}

	final XFANodeHolder getFirstChildImpl () {
		return mFirstChild;
	}

	final XFANodeHolder getLastChildImpl () {
		return mLastChild;
	}

	final com.adobe.xfa.Element getXFAElement () {
		return mXFAElement;
	}

	XFANodeHolder lookupXFAChild (com.adobe.xfa.Node xfaChild) {
		fillAllChildren();
		for (NodeImpl child = mFirstChild; child != null; child = child.getNext()) {
			assert (child instanceof XFANodeHolder);
			XFANodeHolder xfaNodeHolder = (XFANodeHolder) child;
			if (xfaNodeHolder.getXFANode() == xfaChild) {
				return xfaNodeHolder;
			}
		}
		return null;
	}

	void setOnlyChild (XFANodeHolder child) {
		assert (mFirstChild == null);
		assert (mLastChild == null);
		mFirstChild = child;
		mLastChild = child;
	}

	private void fillChildrenFromStart () {
		com.adobe.xfa.Node firstXFAChild = mXFAElement.getFirstXMLChild();
		com.adobe.xfa.Node currentFirstXFAChild = null;
		if (mFirstChild != null) {
			currentFirstXFAChild = mFirstChild.getXFANode();
		}
		if (currentFirstXFAChild == firstXFAChild) {
			return;
		}
		assert (firstXFAChild != null);
		com.adobe.xfa.Node xfaNodeToAdd = firstXFAChild;
		XFANodeHolder lastAdded = null;
		XFANodeHolder firstAdded = null;
		while (xfaNodeToAdd != currentFirstXFAChild) {
			XFANodeHolder newNode = createNode (xfaNodeToAdd);
			if (firstAdded == null) {
				firstAdded = newNode;
			} else {
				assert (lastAdded != null);
				lastAdded.setNext (newNode);
			}
			newNode.setPrev (lastAdded);
			lastAdded = newNode;
			if (mFirstChild == null) {
				break;
			}
			xfaNodeToAdd = xfaNodeToAdd.getNextXMLSibling();
			assert (xfaNodeToAdd != null);
		}

		if (mFirstChild == null) {
			mLastChild = lastAdded;
		} else {
			lastAdded.setNext (mFirstChild);
			mFirstChild.setPrev (lastAdded);
		}
		mFirstChild = firstAdded;
	}

	private void fillChildrenToEnd () {
		if (mLastChild == null) {
			fillChildrenFromStart();
			if (mLastChild == null) {
				return;
			}
		}
		while (forceNextChild() != null) {
			; // intentionally empty loop
		}
	}

	private NodeImpl forceNextChild () {
		com.adobe.xfa.Node xfaChild = mLastChild.getXFANode();
		com.adobe.xfa.Node xfaNext = xfaChild.getNextXMLSibling();
		if (xfaNext == null) {
			return null;
		}
		XFANodeHolder newChild = createNode (xfaNext);
		newChild.setPrev (mLastChild);
		mLastChild.setNext (newChild);
		mLastChild = newChild;
		return mLastChild;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy