String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
Document thisOwnerDoc, otherOwnerDoc;
// get the respective Document owners.
if (this.getNodeType() == Node.DOCUMENT_NODE)
thisOwnerDoc = (Document)this;
else
thisOwnerDoc = this.getOwnerDocument();
if (other.getNodeType() == Node.DOCUMENT_NODE)
otherOwnerDoc = (Document)other;
else
otherOwnerDoc = other.getOwnerDocument();
// If from different documents, we know they are disconnected.
// and have an implementation dependent order
if (thisOwnerDoc != otherOwnerDoc &&
thisOwnerDoc !=null &&
otherOwnerDoc !=null)
{
int otherDocNum = ((CoreDocumentImpl)otherOwnerDoc).getNodeNumber();
int thisDocNum = ((CoreDocumentImpl)thisOwnerDoc).getNodeNumber();
if (otherDocNum > thisDocNum)
return DOCUMENT_POSITION_DISCONNECTED |
DOCUMENT_POSITION_FOLLOWING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
else
return DOCUMENT_POSITION_DISCONNECTED |
DOCUMENT_POSITION_PRECEDING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
}
// Find the ancestor of each node, and the distance each node is from
// its ancestor.
// During this traversal, look for ancestor/descendent relationships
// between the 2 nodes in question.
// We do this now, so that we get this info correct for attribute nodes
// and their children.
Node node;
Node thisAncestor = this;
Node otherAncestor = other;
int thisDepth=0;
int otherDepth=0;
for (node=this; node != null; node = node.getParentNode()) {
thisDepth +=1;
if (node == other)
// The other node is an ancestor of this one.
return (DOCUMENT_POSITION_CONTAINS |
DOCUMENT_POSITION_PRECEDING);
thisAncestor = node;
}
for (node=other; node!=null; node=node.getParentNode()) {
otherDepth +=1;
if (node == this)
// The other node is a descendent of the reference node.
return (DOCUMENT_POSITION_IS_CONTAINED |
DOCUMENT_POSITION_FOLLOWING);
otherAncestor = node;
}
int thisAncestorType = thisAncestor.getNodeType();
int otherAncestorType = otherAncestor.getNodeType();
Node thisNode = this;
Node otherNode = other;
// Special casing for ENTITY, NOTATION, DOCTYPE and ATTRIBUTES
// LM: should rewrite this.
switch (thisAncestorType) {
case Node.NOTATION_NODE:
case Node.ENTITY_NODE: {
DocumentType container = thisOwnerDoc.getDoctype();
if (container == otherAncestor) return
(DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_PRECEDING);
switch (otherAncestorType) {
case Node.NOTATION_NODE:
case Node.ENTITY_NODE: {
if (thisAncestorType != otherAncestorType)
// the nodes are of different types
return ((thisAncestorType>otherAncestorType) ?
DOCUMENT_POSITION_PRECEDING:DOCUMENT_POSITION_FOLLOWING);
else {
// the nodes are of the same type. Find order.
if (thisAncestorType == Node.NOTATION_NODE)
if (((NamedNodeMapImpl)container.getNotations()).precedes(otherAncestor,thisAncestor))
return (DOCUMENT_POSITION_PRECEDING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
else
return (DOCUMENT_POSITION_FOLLOWING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
else
if (((NamedNodeMapImpl)container.getEntities()).precedes(otherAncestor,thisAncestor))
return (DOCUMENT_POSITION_PRECEDING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
else
return (DOCUMENT_POSITION_FOLLOWING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
}
}
}
thisNode = thisAncestor = thisOwnerDoc;
break;
}
case Node.DOCUMENT_TYPE_NODE: {
if (otherNode == thisOwnerDoc)
return (DOCUMENT_POSITION_PRECEDING |
DOCUMENT_POSITION_CONTAINS);
else if (thisOwnerDoc!=null && thisOwnerDoc==otherOwnerDoc)
return (DOCUMENT_POSITION_FOLLOWING);
break;
}
case Node.ATTRIBUTE_NODE: {
thisNode = ((AttrImpl)thisAncestor).getOwnerElement();
if (otherAncestorType==Node.ATTRIBUTE_NODE) {
otherNode = ((AttrImpl)otherAncestor).getOwnerElement();
if (otherNode == thisNode) {
if (((NamedNodeMapImpl)thisNode.getAttributes()).precedes(other,this))
return (DOCUMENT_POSITION_PRECEDING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
else
return (DOCUMENT_POSITION_FOLLOWING |
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
}
}
// Now, find the ancestor of the element
thisDepth=0;
for (node=thisNode; node != null; node=node.getParentNode()) {
thisDepth +=1;
if (node == otherNode)
{
// The other node is an ancestor of the owning element
return (DOCUMENT_POSITION_CONTAINS |
DOCUMENT_POSITION_PRECEDING);
}
thisAncestor = node;
}
}
}
switch (otherAncestorType) {
case Node.NOTATION_NODE:
case Node.ENTITY_NODE: {
DocumentType container = thisOwnerDoc.getDoctype();
if (container == this) return (DOCUMENT_POSITION_IS_CONTAINED |
DOCUMENT_POSITION_FOLLOWING);
otherNode = otherAncestor = thisOwnerDoc;
break;
}