1 package net.sf.saxon.dom; 2 import net.sf.saxon.functions.DeepEqual; 3 import net.sf.saxon.om.*; 4 import net.sf.saxon.pattern.NodeKindTest; 5 import net.sf.saxon.sort.AtomicComparer; 6 import net.sf.saxon.sort.CodepointCollator; 7 import net.sf.saxon.style.StandardNames; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.Type; 10 import org.w3c.dom.*; 11 12 import java.util.ArrayList ; 13 import java.util.List ; 14 15 16 19 20 public abstract class NodeOverNodeInfo implements Node { 21 22 protected NodeInfo node; 23 24 public NodeInfo getUnderlyingNodeInfo() { 25 return node; 26 } 27 28 public void setUnderlyingNodeInfo(NodeInfo node) { 29 this.node = node; 30 } 31 32 public static NodeOverNodeInfo wrap(NodeInfo node) { 33 NodeOverNodeInfo n = null; 34 if (node == null) { 35 return null; 36 } 37 switch (node.getNodeKind()) { 38 case Type.DOCUMENT: 39 n = new DocumentOverNodeInfo(); 40 break; 41 case Type.ELEMENT: 42 n = new ElementOverNodeInfo(); 43 break; 44 case Type.ATTRIBUTE: 45 n = new AttrOverNodeInfo(); 46 break; 47 case Type.TEXT: 48 case Type.COMMENT: 49 n = new TextOverNodeInfo(); 50 break; 51 case Type.PROCESSING_INSTRUCTION: 52 n = new PIOverNodeInfo(); 53 break; 54 case Type.NAMESPACE: 55 throw new IllegalArgumentException ("Cannot wrap a namespace node as a DOM Node"); 56 } 57 n.node = node; 58 return n; 59 } 60 61 62 67 68 public final boolean isSameNode(Node other) { 69 if (other instanceof NodeOverNodeInfo) { 70 return node.isSameNodeInfo(((NodeOverNodeInfo)other).node); 71 } else { 72 return false; 73 } 74 } 75 76 80 81 public String getBaseURI() { 82 return node.getBaseURI(); 83 } 84 85 91 92 public String getNodeName() { 93 switch (node.getNodeKind()) { 94 case Type.DOCUMENT: 95 return "#document"; 96 case Type.ELEMENT: 97 return node.getDisplayName(); 98 case Type.ATTRIBUTE: 99 return node.getDisplayName(); 100 case Type.TEXT: 101 return "#text"; 102 case Type.COMMENT: 103 return "#comment"; 104 case Type.PROCESSING_INSTRUCTION: 105 return node.getLocalPart(); 106 case Type.NAMESPACE: 107 return node.getLocalPart(); 108 default: 109 return "#unknown"; 110 } 111 } 112 113 119 120 public String getLocalName() { 121 switch (node.getNodeKind()) { 122 case Type.ELEMENT: 123 case Type.ATTRIBUTE: 124 return node.getLocalPart(); 125 case Type.DOCUMENT: 126 case Type.TEXT: 127 case Type.COMMENT: 128 case Type.PROCESSING_INSTRUCTION: 129 case Type.NAMESPACE: 130 default: 131 return null; 132 } 133 } 134 135 140 141 public boolean isId() { 142 return (node.getTypeAnnotation() & NamePool.FP_MASK) == StandardNames.XS_ID; 143 } 144 145 150 151 public boolean hasChildNodes() { 152 return node.iterateAxis(Axis.CHILD).next() != null; 153 } 154 155 161 162 public boolean hasAttributes() { 163 return node.iterateAxis(Axis.ATTRIBUTE).next() != null; 164 } 165 166 170 171 public short getNodeType() { 172 return (short)node.getNodeKind(); 173 } 174 175 179 180 public Node getParentNode() { 181 return wrap(node.getParent()); 182 } 183 184 189 190 public Node getPreviousSibling() { 191 return wrap((NodeInfo)node.iterateAxis(Axis.PRECEDING_SIBLING).next()); 192 } 193 194 199 200 public Node getNextSibling() { 201 return wrap((NodeInfo)node.iterateAxis(Axis.FOLLOWING_SIBLING).next()); 202 } 203 204 208 209 public Node getFirstChild() { 210 return wrap((NodeInfo)node.iterateAxis(Axis.CHILD).next()); 211 } 212 213 217 218 public Node getLastChild() { 219 AxisIterator children = node.iterateAxis(Axis.CHILD); 220 NodeInfo last = null; 221 while (true) { 222 NodeInfo next = (NodeInfo)children.next(); 223 if (next == null) { 224 return wrap(last); 225 } else { 226 last = next; 227 } 228 } 229 } 230 231 232 238 239 public Element getDocumentElement() { 240 NodeInfo root = node.getDocumentRoot(); 241 if (root==null) { 242 return null; 243 } 244 AxisIterator children = 245 root.iterateAxis(Axis.CHILD, NodeKindTest.ELEMENT); 246 return (Element)wrap((NodeInfo)children.next()); 247 } 248 249 250 254 255 public String getNodeValue() { 256 switch (node.getNodeKind()) { 257 case Type.DOCUMENT: 258 case Type.ELEMENT: 259 return null; 260 case Type.ATTRIBUTE: 261 case Type.TEXT: 262 case Type.COMMENT: 263 case Type.PROCESSING_INSTRUCTION: 264 case Type.NAMESPACE: 265 return node.getStringValue(); 266 default: 267 return null; 268 } 269 } 270 271 274 275 public void setNodeValue(String nodeValue) throws DOMException { 276 disallowUpdate(); 277 } 278 279 284 285 public NodeList getChildNodes() { 286 try { 287 List nodes = new ArrayList (10); 288 SequenceIterator iter = node.iterateAxis(Axis.CHILD); 289 while (true) { 290 NodeInfo node = (NodeInfo)iter.next(); 291 if (node == null) break; 292 nodes.add(NodeOverNodeInfo.wrap(node)); 293 } 294 return new DOMNodeList(nodes); 295 } catch (XPathException err) { 296 return null; 297 } 299 } 300 301 305 306 public NamedNodeMap getAttributes() { 307 if (node.getNodeKind()==Type.ELEMENT) { 308 return new DOMAttributeMap(node); 309 } else { 310 return null; 311 } 312 } 313 314 317 318 public Document getOwnerDocument() { 319 return (Document)wrap(node.getDocumentRoot()); 320 } 321 322 332 333 public Node insertBefore(Node newChild, 334 Node refChild) 335 throws DOMException { 336 disallowUpdate(); 337 return null; 338 } 339 340 350 351 public Node replaceChild(Node newChild, 352 Node oldChild) 353 throws DOMException{ 354 disallowUpdate(); 355 return null; 356 } 357 358 366 367 public Node removeChild(Node oldChild) throws DOMException { 368 disallowUpdate(); 369 return null; 370 } 371 372 380 381 public Node appendChild(Node newChild) throws DOMException { 382 disallowUpdate(); 383 return null; 384 } 385 386 396 397 public Node cloneNode(boolean deep) { 398 return null; 400 } 401 402 411 412 public void normalize() { 413 } 415 416 430 431 public boolean isSupported(String feature, 432 String version) { 433 return feature.equalsIgnoreCase("xml"); 434 } 435 436 439 440 public boolean supports(String feature, 441 String version) { 442 return isSupported(feature, version); 443 } 444 445 461 462 public String getNamespaceURI() { 463 String uri = node.getURI(); 464 return ("".equals(uri) ? null : uri); 465 } 466 467 477 478 public String getPrefix() { 479 String p = node.getNamePool().getPrefix(node.getNameCode()); 480 return ("".equals(p) ? null : p); 481 } 482 483 486 487 public void setPrefix(String prefix) 488 throws DOMException { 489 disallowUpdate(); 490 } 491 492 499 500 public short compareDocumentPosition(Node other) throws DOMException { 501 final short DOCUMENT_POSITION_DISCONNECTED = 0x01; 502 final short DOCUMENT_POSITION_PRECEDING = 0x02; 503 final short DOCUMENT_POSITION_FOLLOWING = 0x04; 504 final short DOCUMENT_POSITION_CONTAINS = 0x08; 505 final short DOCUMENT_POSITION_CONTAINED_BY = 0x10; 506 if (!(other instanceof NodeOverNodeInfo)) { 507 return DOCUMENT_POSITION_DISCONNECTED; 508 } 509 int c = node.compareOrder(((NodeOverNodeInfo)other).node); 510 if (c==0) { 511 return (short)0; 512 } else if (c==-1) { 513 short d = compareDocumentPosition(other.getParentNode()); 514 short result = DOCUMENT_POSITION_FOLLOWING; 515 if (d==0 || (d&DOCUMENT_POSITION_CONTAINED_BY) != 0) { 516 d |= DOCUMENT_POSITION_CONTAINED_BY; 517 } 518 return result; 519 } else if (c==+1) { 520 short d = ((NodeOverNodeInfo)getParentNode()).compareDocumentPosition(other); 521 short result = DOCUMENT_POSITION_PRECEDING; 522 if (d==0 || (d&DOCUMENT_POSITION_CONTAINS) != 0) { 523 d |= DOCUMENT_POSITION_CONTAINS; 524 } 525 return result; 526 } else { 527 throw new AssertionError (); 528 } 529 } 530 531 538 539 public String getTextContent() throws DOMException { 540 if (node.getNodeKind() == Type.DOCUMENT) { 541 return null; 542 } else { 543 return node.getStringValue(); 544 } 545 } 546 547 552 553 public void setTextContent(String textContent) throws DOMException { 554 disallowUpdate(); 555 } 556 557 563 564 public String lookupPrefix(String namespaceURI){ 565 AxisIterator iter = node.iterateAxis(Axis.NAMESPACE); 566 while (true) { 567 NodeInfo ns = (NodeInfo)iter.next(); 568 if (ns==null) { 569 return null; 570 } 571 if (ns.getStringValue().equals(namespaceURI)) { 572 return ns.getLocalPart(); 573 } 574 } 575 } 576 577 583 584 public boolean isDefaultNamespace(String namespaceURI) { 585 return namespaceURI.equals(lookupNamespaceURI("")); 586 } 587 588 594 595 public String lookupNamespaceURI(String prefix) { 596 AxisIterator iter = node.iterateAxis(Axis.NAMESPACE); 597 while (true) { 598 NodeInfo ns = (NodeInfo)iter.next(); 599 if (ns==null) { 600 return null; 601 } 602 if (ns.getLocalPart().equals(prefix)) { 603 return ns.getStringValue(); 604 } 605 } 606 } 607 608 614 615 public boolean isEqualNode(Node arg) { 616 if (!(arg instanceof NodeOverNodeInfo)) { 617 throw new IllegalArgumentException ("Other Node must wrap a Saxon NodeInfo"); 618 } 619 return DeepEqual.deepEquals( 620 SingletonIterator.makeIterator(node), 621 SingletonIterator.makeIterator(((NodeOverNodeInfo)arg).node), 622 new AtomicComparer(CodepointCollator.getInstance(), node.getConfiguration()), 623 node.getConfiguration()); 624 } 625 626 632 633 public Object getFeature(String feature, String version) { 634 return null; 635 } 636 637 644 645 public Object setUserData(String key, Object data, UserDataHandler handler) { 646 disallowUpdate(); 647 return null; 648 } 649 650 656 public Object getUserData(String key) { 657 return null; 658 } 659 660 663 664 protected static void disallowUpdate() throws DOMException { 665 throw new UnsupportedOperationException ("The Saxon DOM cannot be updated"); 666 } 667 668 } 669 670 | Popular Tags |