1 package net.sf.saxon.tinytree; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.Err; 4 import net.sf.saxon.style.StandardNames; 5 import net.sf.saxon.event.Receiver; 6 import net.sf.saxon.om.*; 7 import net.sf.saxon.pattern.AnyNodeTest; 8 import net.sf.saxon.pattern.NameTest; 9 import net.sf.saxon.pattern.NodeTest; 10 import net.sf.saxon.trans.DynamicError; 11 import net.sf.saxon.trans.XPathException; 12 import net.sf.saxon.type.SchemaType; 13 import net.sf.saxon.type.Type; 14 import net.sf.saxon.value.UntypedAtomicValue; 15 import net.sf.saxon.value.Value; 16 17 import javax.xml.transform.SourceLocator ; 18 19 20 27 28 public abstract class TinyNodeImpl implements NodeInfo, FingerprintedNode, SourceLocator { 29 30 protected TinyTree tree; 31 protected int nodeNr; 32 protected TinyNodeImpl parent = null; 33 34 38 39 public static final char[] NODE_LETTER = 40 {'x', 'e', 'a', 't', 'x', 'x', 'x', 'p', 'c', 'r', 'x', 'x', 'x', 'n'}; 41 42 46 47 public CharSequence getStringValueCS() { 48 return getStringValue(); 49 } 50 51 54 55 public int getTypeAnnotation() { 56 return -1; 57 } 58 59 63 64 public int getColumnNumber() { 65 return -1; 66 } 67 68 72 73 public String getPublicId() { 74 return null; 75 } 76 77 82 83 public SequenceIterator getTypedValue() throws XPathException { 84 int annotation = getTypeAnnotation(); 85 if ((annotation & NodeInfo.IS_DTD_TYPE) != 0) { 86 annotation = StandardNames.XDT_UNTYPED_ATOMIC; 87 } 88 if (annotation==-1 || annotation==StandardNames.XDT_UNTYPED_ATOMIC || annotation==StandardNames.XDT_UNTYPED) { 89 return SingletonIterator.makeIterator(new UntypedAtomicValue(getStringValueCS())); 90 } else { 91 SchemaType stype = getConfiguration().getSchemaType(annotation); 92 if (stype == null) { 93 String typeName = getNamePool().getDisplayName(annotation); 94 throw new DynamicError("Unknown type annotation " + 95 Err.wrap(typeName) + " in document instance"); 96 } else { 97 return stype.getTypedValue(this); 98 } 99 } 100 } 101 102 112 113 public Value atomize() throws XPathException { 114 int annotation = getTypeAnnotation(); 115 if ((annotation & NodeInfo.IS_DTD_TYPE) != 0) { 116 annotation = StandardNames.XDT_UNTYPED_ATOMIC; 117 } 118 if (annotation==-1 || annotation==StandardNames.XDT_UNTYPED_ATOMIC || annotation==StandardNames.XDT_UNTYPED) { 119 return new UntypedAtomicValue(getStringValueCS()); 120 } else { 121 SchemaType stype = getConfiguration().getSchemaType(annotation); 122 if (stype == null) { 123 String typeName = getNamePool().getDisplayName(annotation); 124 throw new DynamicError("Unknown type annotation " + 125 Err.wrap(typeName) + " in document instance"); 126 } else { 127 return stype.atomize(this); 128 } 129 } 130 } 131 132 133 139 140 public void setSystemId(String uri) { 141 short type = tree.nodeKind[nodeNr]; 142 if (type==Type.ATTRIBUTE || type==Type.NAMESPACE) { 143 getParent().setSystemId(uri); 144 } else { 145 tree.setSystemId(nodeNr, uri); 146 } 147 } 148 149 154 155 protected void setParentNode(TinyNodeImpl parent) { 156 this.parent = parent; 157 } 158 159 164 165 public boolean isSameNodeInfo(NodeInfo other) { 166 if (this==other) return true; 167 if (!(other instanceof TinyNodeImpl)) return false; 168 if (this.tree != ((TinyNodeImpl)other).tree) return false; 169 if (this.nodeNr != ((TinyNodeImpl)other).nodeNr) return false; 170 if (this.getNodeKind() != other.getNodeKind()) return false; 171 return true; 172 } 173 174 177 178 public String getSystemId() { 179 return tree.getSystemId(nodeNr); 180 } 181 182 186 187 public String getBaseURI() { 188 return (getParent()).getBaseURI(); 189 } 190 191 194 195 public int getLineNumber() { 196 return tree.getLineNumber(nodeNr); 197 } 198 199 207 208 protected long getSequenceNumber() { 209 return (long)nodeNr << 32; 210 } 211 212 220 221 public final int compareOrder(NodeInfo other) { 222 long a = getSequenceNumber(); 223 if (other instanceof TinyNodeImpl) { 224 long b = ((TinyNodeImpl)other).getSequenceNumber(); 225 if (a<b) return -1; 226 if (a>b) return +1; 227 return 0; 228 } else { 229 return 0 - other.compareOrder(this); 231 } 232 } 233 234 237 238 public int getFingerprint() { 239 int nc = getNameCode(); 240 if (nc==-1) return -1; 241 return nc & 0xfffff; 242 } 243 244 247 248 public int getNameCode() { 249 return tree.nameCode[nodeNr]; 251 } 252 253 257 258 public String getPrefix() { 259 int code = tree.nameCode[nodeNr]; 260 if (code<0) return ""; 261 if ((code>>20 & 0xff) == 0) return ""; 262 return tree.getNamePool().getPrefix(code); 263 } 264 265 271 272 public String getURI() { 273 int code = tree.nameCode[nodeNr]; 274 if (code<0) return ""; 275 return tree.getNamePool().getURI(code); 276 } 277 278 284 285 public String getDisplayName() { 286 int code = tree.nameCode[nodeNr]; 287 if (code<0) return ""; 288 return tree.getNamePool().getDisplayName(code); 289 } 290 291 296 297 public String getLocalPart() { 298 int code = tree.nameCode[nodeNr]; 299 if (code<0) return ""; 300 return tree.getNamePool().getLocalName(code); 301 } 302 303 308 309 public AxisIterator iterateAxis(byte axisNumber) { 310 if (axisNumber == Axis.CHILD) { 312 if (hasChildNodes()) { 313 return new SiblingEnumeration(tree, this, null, true); 314 } else { 315 return EmptyIterator.getInstance(); 316 } 317 } else { 318 return iterateAxis(axisNumber, AnyNodeTest.getInstance()); 319 } 320 } 321 322 328 329 public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) { 330 331 int type = getNodeKind(); 332 switch (axisNumber) { 333 case Axis.ANCESTOR: 334 return new AncestorEnumeration(this, nodeTest, false); 335 336 case Axis.ANCESTOR_OR_SELF: 337 return new AncestorEnumeration(this, nodeTest, true); 338 339 case Axis.ATTRIBUTE: 340 if (type!=Type.ELEMENT) { 341 return EmptyIterator.getInstance(); 342 } 343 if (tree.alpha[nodeNr]<0) { 344 return EmptyIterator.getInstance(); 345 } 346 return new AttributeEnumeration(tree, nodeNr, nodeTest); 347 348 case Axis.CHILD: 349 if (hasChildNodes()) { 350 return new SiblingEnumeration(tree, this, nodeTest, true); 351 } else { 352 return EmptyIterator.getInstance(); 353 } 354 355 case Axis.DESCENDANT: 356 if (type==Type.DOCUMENT && 357 nodeTest instanceof NameTest && 358 nodeTest.getPrimitiveType()==Type.ELEMENT) { 359 return ((TinyDocumentImpl)this).getAllElements(nodeTest.getFingerprint()); 360 } else if (hasChildNodes()) { 361 return new DescendantEnumeration(tree, this, nodeTest, false); 362 } else { 363 return EmptyIterator.getInstance(); 364 } 365 366 case Axis.DESCENDANT_OR_SELF: 367 if (hasChildNodes()) { 368 return new DescendantEnumeration(tree, this, nodeTest, true); 369 } else { 370 if (nodeTest.matches(this)) { 371 return SingletonIterator.makeIterator(this); 372 } else { 373 return EmptyIterator.getInstance(); 374 } 375 } 376 377 case Axis.FOLLOWING: 378 if (type==Type.ATTRIBUTE || type==Type.NAMESPACE) { 379 return new FollowingEnumeration(tree, (TinyNodeImpl)getParent(), nodeTest, true); 380 } else if (tree.depth[nodeNr] == 0) { 381 return EmptyIterator.getInstance(); 382 } else { 383 return new FollowingEnumeration(tree, this, nodeTest, false); 384 } 385 386 case Axis.FOLLOWING_SIBLING: 387 if (type==Type.ATTRIBUTE || type==Type.NAMESPACE || tree.depth[nodeNr] == 0) { 388 return EmptyIterator.getInstance(); 389 } else { 390 return new SiblingEnumeration(tree, this, nodeTest, false); 391 } 392 393 case Axis.NAMESPACE: 394 if (type!=Type.ELEMENT) { 395 return EmptyIterator.getInstance(); 396 } 397 return new NamespaceIterator(this, nodeTest); 398 399 case Axis.PARENT: 400 NodeInfo parent = getParent(); 401 if (parent==null) return EmptyIterator.getInstance(); 402 if (nodeTest.matches(parent)) { 403 return SingletonIterator.makeIterator(parent); 404 } 405 return EmptyIterator.getInstance(); 406 407 case Axis.PRECEDING: 408 if (type==Type.ATTRIBUTE || type==Type.NAMESPACE) { 409 return new PrecedingEnumeration(tree, (TinyNodeImpl)getParent(), nodeTest, false); 410 } else if (tree.depth[nodeNr] == 0) { 411 return EmptyIterator.getInstance(); 412 } else { 413 return new PrecedingEnumeration(tree, this, nodeTest, false); 414 } 415 416 case Axis.PRECEDING_SIBLING: 417 if (type==Type.ATTRIBUTE || type==Type.NAMESPACE || tree.depth[nodeNr] == 0) { 418 return EmptyIterator.getInstance(); 419 } else { 420 return new PrecedingSiblingEnumeration(tree, this, nodeTest); 421 } 422 423 case Axis.SELF: 424 if (nodeTest.matches(this)) { 425 return SingletonIterator.makeIterator(this); 426 } 427 return EmptyIterator.getInstance(); 428 429 case Axis.PRECEDING_OR_ANCESTOR: 430 if (type==Type.DOCUMENT) { 431 return EmptyIterator.getInstance(); 432 } else if (type==Type.ATTRIBUTE || type==Type.NAMESPACE) { 433 TinyNodeImpl el = (TinyNodeImpl)getParent(); 435 return new PrependIterator(el, new PrecedingEnumeration(tree, el, nodeTest, true)); 436 } else { 437 return new PrecedingEnumeration(tree, this, nodeTest, true); 438 } 439 440 default: 441 throw new IllegalArgumentException ("Unknown axis number " + axisNumber); 442 } 443 } 444 445 449 450 public NodeInfo getParent() { 451 if (parent != null) { 452 return parent; 453 } 454 int p = getParentNodeNr(tree, nodeNr); 455 if (p == -1) { 456 parent = null; 457 } else { 458 parent = tree.getNode(p); 459 } 460 return parent; 461 } 462 463 470 471 static final int getParentNodeNr(TinyTree tree, int nodeNr) { 472 473 if (tree.depth[nodeNr] == 0) { 474 return -1; 475 } 476 477 int p = tree.next[nodeNr]; 480 while (p > nodeNr) { 481 if (tree.nodeKind[p] == Type.PARENT_POINTER) { 482 return tree.alpha[p]; 483 } 484 p = tree.next[p]; 485 } 486 return p; 487 } 488 489 494 495 public boolean hasChildNodes() { 496 return false; 498 } 499 500 505 506 public String getAttributeValue(int fingerprint) { 507 return null; 509 } 510 511 515 516 public NodeInfo getRoot() { 517 if (tree.depth[nodeNr] == 0) { 518 return this; 519 } 520 if (parent != null) { 521 return parent.getRoot(); 522 } 523 return tree.getNode(tree.getRootNode(nodeNr)); 524 } 525 526 530 531 public DocumentInfo getDocumentRoot() { 532 NodeInfo root = getRoot(); 533 if (root instanceof DocumentInfo) { 534 return (DocumentInfo)root; 535 } else { 536 return null; 537 } 538 } 539 540 543 544 public Configuration getConfiguration() { 545 return tree.getConfiguration(); 546 } 547 548 552 553 public NamePool getNamePool() { 554 return tree.getNamePool(); 555 } 556 557 563 564 public void sendNamespaceDeclarations(Receiver out, boolean includeAncestors) 565 throws XPathException 566 {} 567 568 583 584 public int[] getDeclaredNamespaces(int[] buffer) { 585 return null; 586 } 587 588 592 593 public String generateId() { 594 return "d" + tree.getDocumentNumber() + 595 NODE_LETTER[getNodeKind()] + 596 nodeNr; 597 } 598 599 603 604 public final int getDocumentNumber() { 605 return tree.getDocumentNumber(); 606 } 607 608 } 609 610 | Popular Tags |