com.caucho.xml.QNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resin Show documentation
Show all versions of resin Show documentation
Resin Java Application Server
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
* Free SoftwareFoundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.xml;
// import com.caucho.xpath.pattern.NodeListIterator;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.Iterator;
/**
* QNode represents any node that can have children.
*/
public abstract class QNode extends QAbstractNode {
protected QAbstractNode _firstChild;
protected QAbstractNode _lastChild;
protected QNode()
{
}
protected QNode(QDocument owner)
{
super(owner);
}
public String getNodeValue() { return null; }
public void setNodeValue(String value) {}
/**
* Returns a node list of the children.
*/
public NodeList getChildNodes()
{
return new ChildNodeList();
}
public Node getFirstChild()
{
return _firstChild;
}
public Node getLastChild()
{
return _lastChild;
}
public Node getPreviousSibling()
{
return _previous;
}
public Node getNextSibling()
{
return _next;
}
public NamedNodeMap getAttributes() { return null; }
public Node insertBefore(Node newChild, Node refChild)
throws DOMException
{
QAbstractNode qNewChild = (QAbstractNode) newChild;
QAbstractNode qRefChild = (QAbstractNode) refChild;
if (qNewChild._owner != _owner && qNewChild._owner != this)
throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR,
"insertBefore new child from wrong document");
qNewChild.remove();
if (qRefChild != null && qRefChild._parent != this)
throw new QDOMException(DOMException.NOT_FOUND_ERR, "insertBefore has no such child");
if (qNewChild instanceof QDocumentFragment) {
QDocumentFragment frag = (QDocumentFragment) qNewChild;
QAbstractNode first = frag._firstChild;
QAbstractNode next = null;
for (QAbstractNode ptr = first; ptr != null; ptr = next) {
next = ptr._next;
insertBefore(ptr, refChild);
}
return first;
}
qNewChild._parent = this;
if (refChild == null) {
if (_firstChild == null) {
qNewChild._previous = null;
qNewChild._next = null;
_firstChild = _lastChild = qNewChild;
} else {
_lastChild._next = qNewChild;
qNewChild._previous = _lastChild;
_lastChild = qNewChild;
qNewChild._next = null;
}
return qNewChild;
}
qNewChild._previous = qRefChild._previous;
qNewChild._next = qRefChild;
if (qRefChild._previous == null)
_firstChild = qNewChild;
else
qRefChild._previous._next = qNewChild;
qRefChild._previous = qNewChild;
return qNewChild;
}
public Node replaceChild(Node newChild, Node refChild)
throws DOMException
{
QAbstractNode qNewChild = (QAbstractNode) newChild;
QAbstractNode qRefChild = (QAbstractNode) refChild;
if (qRefChild == null || qRefChild._parent != this)
throw new QDOMException(DOMException.NOT_FOUND_ERR, "ref is not child");
if (qNewChild == null || qNewChild._owner != _owner)
throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR,
"wrong document");
if (_owner != null)
_owner._changeCount++;
qNewChild._previous = qRefChild._previous;
qNewChild._next = qRefChild._next;
qNewChild._parent = this;
if (qNewChild._previous == null)
_firstChild = qNewChild;
else
qNewChild._previous._next = qNewChild;
if (qNewChild._next == null)
_lastChild = qNewChild;
else
qNewChild._next._previous = qNewChild;
qRefChild._previous = null;
qRefChild._next = null;
qRefChild._parent = null;
return qRefChild;
}
public Node removeChild(Node oldChild) throws DOMException
{
QAbstractNode qOldChild = (QAbstractNode) oldChild;
if (qOldChild != null && qOldChild._parent != this) {
throw new QDOMException(DOMException.NOT_FOUND_ERR,
"removeChild has no such child");
}
if (_owner != null)
_owner._changeCount++;
if (qOldChild._previous == null)
_firstChild = qOldChild._next;
else
qOldChild._previous._next = qOldChild._next;
if (qOldChild._next == null)
_lastChild = qOldChild._previous;
else
qOldChild._next._previous = qOldChild._previous;
qOldChild._parent = null;
qOldChild._next = null;
qOldChild._previous = null;
return qOldChild;
}
private static void setOwner(QAbstractNode node, QDocument owner)
{
if (node._owner == null) {
node._owner = owner;
String namespace = node.getNamespaceURI();
if (namespace != "")
owner.addNamespace(node.getPrefix(), namespace);
for (QAbstractNode child = (QAbstractNode) node.getFirstChild();
child != null;
child = (QAbstractNode) child.getNextSibling())
{
setOwner(child, owner);
}
}
}
public Node appendChild(Node newNode) throws DOMException
{
QAbstractNode qNewNode = (QAbstractNode) newNode;
setOwner(qNewNode, _owner);
if (qNewNode._owner != _owner && qNewNode._owner != this) {
throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR,
"can't appendChild from different document");
}
qNewNode.remove();
if (qNewNode instanceof QDocumentFragment) {
QDocumentFragment frag = (QDocumentFragment) qNewNode;
QAbstractNode first = frag._firstChild;
QAbstractNode next = null;
for (QAbstractNode ptr = first; ptr != null; ptr = next) {
next = ptr._next;
appendChild(ptr);
}
return first;
}
qNewNode._parent = this;
qNewNode._next = null;
qNewNode._previous = _lastChild;
if (_lastChild == null) {
_lastChild = qNewNode;
_firstChild = qNewNode;
}
else {
_lastChild._next = qNewNode;
_lastChild = qNewNode;
}
return qNewNode;
}
public boolean hasChildNodes()
{
return _firstChild != null;
}
public void setTextContent(String content)
{
QText text = new QText(content);
text._owner = _owner;
_firstChild = _lastChild = text;
}
public void normalize()
{
}
public boolean checkValid()
throws Exception
{
if (! super.checkValid())
throw new Exception("super bad: " + this);
if (_firstChild != null && _firstChild._previous != null)
throw new Exception("first child bad: " + this);
if (_lastChild != null && _lastChild._next != null)
throw new Exception("last child bad:" + this);
QAbstractNode ptr = _firstChild;
for (; ptr != null; ptr = ptr._next) {
if (ptr._parent != this)
throw new Exception("child parent bad:" + this + " " + ptr);
if (ptr._owner != _owner && ptr._owner != this)
throw new Exception("child owner bad:" + this + " " + ptr + " " +
ptr._owner + " " + _owner);
if (ptr._next != null && ptr._next._previous != ptr)
throw new Exception("child links bad:" + this + " " + ptr);
}
ptr = _lastChild;
for (; ptr != null; ptr = ptr._previous) {
if (ptr._parent != this)
throw new Exception("child parent bad:" + this + " " + ptr);
if (ptr._owner != _owner && ptr._owner != this)
throw new Exception("child owner bad:" + this + " " + ptr);
if (ptr._previous != null && ptr._previous._next != ptr)
throw new Exception("child links bad:" + this + " " + ptr);
}
return true;
}
public QAbstractNode getNextPreorder()
{
if (_firstChild != null)
return _firstChild;
else if (_next != null)
return _next;
for (QNode ptr = _parent; ptr != null; ptr = ptr._parent) {
if (ptr._next != null)
return ptr._next;
}
return null;
}
public boolean equals(Object arg)
{
return this == arg;
}
public boolean equals(Node arg, boolean deep)
{
return this == arg;
}
// NodeList methods
public class ChildNodeList implements NodeList {
/**
* Returns the child with the given index.
*/
public Node item(int index)
{
QAbstractNode ptr = _firstChild;
for (; ptr != null && index > 0; index--) {
ptr = ptr._next;
}
return ptr;
}
/**
* Returns the number of children.
*/
public int getLength()
{
int index = 0;
for (QAbstractNode ptr = _firstChild; ptr != null; ptr = ptr._next)
index++;
return index;
}
/*
// for quercus
public Iterator iterator()
{
return new NodeListIterator(null, this);
}
*/
}
}