1 package com.icl.saxon.tinytree; 2 import com.icl.saxon.om.*; 3 import com.icl.saxon.om.Axis; 4 import com.icl.saxon.Controller; 5 import com.icl.saxon.Context; 6 import com.icl.saxon.PreparedStyleSheet; 7 import com.icl.saxon.PIGrabber; 8 import com.icl.saxon.KeyManager; 9 import com.icl.saxon.expr.NodeSetExtent; 10 import com.icl.saxon.expr.XPathException; 11 import com.icl.saxon.output.Outputter; 12 import com.icl.saxon.sort.LocalOrderComparer; 13 import com.icl.saxon.pattern.Pattern; 14 import com.icl.saxon.pattern.AnyNodeTest; 15 import com.icl.saxon.tree.LineNumberMap; 16 import com.icl.saxon.tree.SystemIdMap; 17 import java.util.Hashtable ; 18 import java.net.URL ; 19 20 import org.w3c.dom.*; 21 import javax.xml.transform.TransformerException ; 22 23 24 30 31 public final class TinyDocumentImpl extends TinyParentNodeImpl 32 implements DocumentInfo, Document { 33 34 private Hashtable idTable = null; 35 private NamePool namePool; 36 private Hashtable elementList = null; 37 private boolean usesNamespaces = false; 38 private Hashtable entityTable = null; 39 40 42 protected char[] charBuffer = new char[4000]; 43 protected int charBufferLength = 0; 44 protected StringBuffer commentBuffer = new StringBuffer (500); 45 46 protected int numberOfNodes = 0; protected int lastLevelOneNode = -1; 48 49 protected byte[] nodeType = new byte[4000]; 50 protected short[] depth = new short[4000]; 51 protected int[] next = new int[4000]; 52 protected int[] offset = new int[4000]; 53 protected int[] length = new int[4000]; 54 protected int[] nameCode = new int[4000]; 55 protected int[] prior = null; 57 58 protected int numberOfAttributes = 0; 59 protected int[] attParent = new int[100]; 60 protected int[] attCode = new int[100]; 61 protected String [] attValue = new String [100]; 62 63 protected int numberOfNamespaces = 0; 64 protected int[] namespaceParent = new int[20]; 65 protected int[] namespaceCode = new int[20]; 66 67 private LineNumberMap lineNumberMap; 68 private SystemIdMap systemIdMap = new SystemIdMap(); 69 70 73 private Object [] index = new Object [30]; 74 private int indexEntriesUsed = 0; 75 76 77 public TinyDocumentImpl() { 78 nodeNr = 0; 79 document = this; 80 } 81 82 85 86 public void setNamePool(NamePool pool) { 87 namePool = pool; 88 addNamespace(0, pool.getNamespaceCode("xml", Namespace.XML)); 89 } 90 91 94 95 public NamePool getNamePool() { 96 return namePool; 97 } 98 99 protected void ensureNodeCapacity() { 100 if (nodeType.length < numberOfNodes+1) { 101 int k = numberOfNodes*2; 102 103 byte[] nodeType2 = new byte[k]; 104 int[] next2 = new int[k]; 105 short[] depth2 = new short[k]; 106 int[] offset2 = new int[k]; 107 int[] length2 = new int[k]; 108 int[] nameCode2 = new int[k]; 109 110 System.arraycopy(nodeType, 0, nodeType2, 0, numberOfNodes); 111 System.arraycopy(next, 0, next2, 0, numberOfNodes); 112 System.arraycopy(depth, 0, depth2, 0, numberOfNodes); 113 System.arraycopy(offset, 0, offset2, 0, numberOfNodes); 114 System.arraycopy(length, 0, length2, 0, numberOfNodes); 115 System.arraycopy(nameCode, 0, nameCode2, 0, numberOfNodes); 116 117 nodeType = nodeType2; 118 next = next2; 119 depth = depth2; 120 offset = offset2; 121 length = length2; 122 nameCode = nameCode2; 123 } 124 } 125 126 protected void ensureAttributeCapacity() { 127 if (attParent.length < numberOfAttributes+1) { 128 int k = numberOfAttributes*2; 129 130 int[] attParent2 = new int[k]; 131 int[] attCode2 = new int[k]; 132 String [] attValue2 = new String [k]; 134 135 136 System.arraycopy(attParent, 0, attParent2, 0, numberOfAttributes); 137 System.arraycopy(attCode, 0, attCode2, 0, numberOfAttributes); 138 System.arraycopy(attValue, 0, attValue2, 0, numberOfAttributes); 140 141 attParent = attParent2; 142 attCode = attCode2; 143 attValue = attValue2; 145 } 146 } 147 148 protected void ensureNamespaceCapacity() { 149 if (namespaceParent.length < numberOfNamespaces+1) { 150 int k = numberOfNamespaces*2; 151 152 int[] namespaceParent2 = new int[k]; 153 int[] namespaceCode2 = new int[k]; 154 155 System.arraycopy(namespaceParent, 0, namespaceParent2, 0, numberOfNamespaces); 156 System.arraycopy(namespaceCode, 0, namespaceCode2, 0, numberOfNamespaces); 157 158 namespaceParent = namespaceParent2; 159 namespaceCode = namespaceCode2; 160 } 161 } 162 163 protected void addNode(short type0, int depth0, int offset0, int length0, int nameCode0) { 164 ensureNodeCapacity(); 165 nodeType[numberOfNodes] = (byte)type0; 166 depth[numberOfNodes] = (short)depth0; 167 offset[numberOfNodes] = offset0; 168 length[numberOfNodes] = length0; 169 nameCode[numberOfNodes] = nameCode0; 170 next[numberOfNodes] = -1; 172 if (depth0 == 1) lastLevelOneNode = numberOfNodes; 173 174 numberOfNodes++; 175 } 176 177 protected void appendChars(char[] chars, int start, int length) { 178 while (charBuffer.length < charBufferLength + length) { 179 char[] ch2 = new char[charBuffer.length * 2]; 180 System.arraycopy(charBuffer, 0, ch2, 0, charBufferLength); 181 charBuffer = ch2; 182 } 183 System.arraycopy(chars, start, charBuffer, charBufferLength, length); 184 charBufferLength += length; 185 } 186 187 191 192 protected void truncate(int nodes) { 193 194 if (nodes==numberOfNodes) return; 195 196 for (int i=nodes; i<numberOfNodes; i++) { 198 if (nodeType[i]==NodeInfo.TEXT) { 199 charBufferLength = offset[i]; 200 break; 201 } 202 } 203 204 for (int i=nodes; i<numberOfNodes; i++) { 206 if (nodeType[i]==NodeInfo.ELEMENT && offset[i]>=0) { 207 numberOfAttributes = offset[i]; 208 break; 209 } 210 } 211 212 for (int i=nodes; i<numberOfNodes; i++) { 214 if (nodeType[i]==NodeInfo.ELEMENT && length[i]>=0) { 215 numberOfNamespaces = length[i]; 216 break; 217 } 218 } 219 220 222 numberOfNodes = nodes; 224 225 prior = null; 227 228 231 nodeType[nodes] = (byte)NodeInfo.ROOT; 232 depth[nodes] = 0; 233 } 235 236 239 240 protected void ensurePriorIndex() { 241 if (prior==null) { 242 makePriorIndex(); 243 } 244 } 245 246 private synchronized void makePriorIndex() { 247 prior = new int[numberOfNodes]; 248 for (int i=0; i<numberOfNodes; i++) { 249 prior[i] = -1; 250 } 251 for (int i=0; i<numberOfNodes; i++) { 252 int nextNode = next[i]; 253 if (nextNode!=-1) { 254 prior[nextNode] = i; 255 } 256 } 257 } 258 259 260 protected void addAttribute(int parent0, int code0, String type0, String value0) { 261 ensureAttributeCapacity(); 262 attParent[numberOfAttributes] = parent0; 263 attCode[numberOfAttributes] = code0; 264 attValue[numberOfAttributes] = value0; 265 numberOfAttributes++; 266 267 if (type0.equals("ID")) { 268 if (idTable==null) { 269 idTable = new Hashtable (); 270 } 271 NodeInfo e = getNode(parent0); 272 registerID(e, value0); 273 } 274 } 275 276 protected void addNamespace(int parent0, int nscode0 ) { 277 usesNamespaces = true; 278 ensureNamespaceCapacity(); 279 namespaceParent[numberOfNamespaces] = parent0; 280 namespaceCode[numberOfNamespaces] = nscode0; 281 numberOfNamespaces++; 282 } 283 284 public TinyNodeImpl getNode(int nr) { 285 switch ((short)nodeType[nr]) { 286 case NodeInfo.ROOT: 287 return this; 288 case NodeInfo.ELEMENT: 289 return new TinyElementImpl(this, nr); 290 case NodeInfo.TEXT: 291 return new TinyTextImpl(this, nr); 292 case NodeInfo.COMMENT: 293 return new TinyCommentImpl(this, nr); 294 case NodeInfo.PI: 295 return new TinyProcInstImpl(this, nr); 296 } 297 return null; 298 } 299 300 304 305 public long getSequenceNumber() { 306 return 0; 307 } 308 309 312 313 protected TinyAttributeImpl getAttributeNode(int nr) { 314 return new TinyAttributeImpl(this, nr); 315 } 316 317 320 321 protected boolean isUsingNamespaces() { 322 return usesNamespaces; 323 } 324 325 328 329 protected TinyNamespaceImpl getNamespaceNode(int nr) { 330 return new TinyNamespaceImpl(this, nr); 331 } 332 333 336 337 public void setSystemId(String uri) { 338 if (uri==null) { 342 uri = ""; 343 } 344 systemIdMap.setSystemId(nodeNr, uri); 345 } 346 347 350 351 public String getSystemId() { 352 return systemIdMap.getSystemId(nodeNr); 353 } 354 355 359 360 public String getBaseURI() { 361 return getSystemId(); 362 } 363 364 367 368 protected void setSystemId(int seq, String uri) { 369 if (uri==null) { 373 uri = ""; 374 } 375 systemIdMap.setSystemId(seq, uri); 376 } 377 378 379 382 383 protected String getSystemId(int seq) { 384 return systemIdMap.getSystemId(seq); 385 } 386 387 388 391 392 public void setLineNumbering() { 393 lineNumberMap = new LineNumberMap(); 394 lineNumberMap.setLineNumber(0, 0); 395 } 396 397 400 401 protected void setLineNumber(int sequence, int line) { 402 if (lineNumberMap != null) { 403 lineNumberMap.setLineNumber(sequence, line); 404 } 405 } 406 407 410 411 protected int getLineNumber(int sequence) { 412 if (lineNumberMap != null) { 413 return lineNumberMap.getLineNumber(sequence); 414 } 415 return -1; 416 } 417 418 422 423 public int getLineNumber() { 424 return 0; 425 } 426 427 431 432 public final short getNodeType() { 433 return ROOT; 434 } 435 436 440 441 public NodeInfo getParent() { 442 return null; 443 } 444 445 449 450 public DocumentInfo getDocumentRoot() { 451 return this; 452 } 453 454 458 459 public String generateId() { 460 return ""; 461 } 462 463 466 467 471 476 477 protected AxisEnumeration getAllElements(int fingerprint) { 478 Integer key = new Integer (fingerprint); 479 if (elementList==null) { 480 elementList = new Hashtable (); 481 } 482 NodeSetExtent list = (NodeSetExtent)elementList.get(key); 483 if (list==null) { 484 list = new NodeSetExtent(LocalOrderComparer.getInstance()); 485 list.setSorted(true); 486 for (int i=1; i<numberOfNodes; i++) { 487 if (nodeType[i]==NodeInfo.ELEMENT && 488 (nameCode[i] & 0xfffff ) == fingerprint) { 489 list.append(getNode(i)); 490 } 491 } 492 elementList.put(key, list); 493 } 494 return (AxisEnumeration)list.enumerate(); 495 } 496 497 502 503 private void registerID(NodeInfo e, String id) { 504 NodeInfo old = (NodeInfo)idTable.get(id); 506 if (old==null) { 507 idTable.put(id, e); 508 } 509 510 } 511 512 518 519 public NodeInfo selectID(String id) { 520 if (idTable==null) return null; return (NodeInfo)idTable.get(id); 522 } 523 524 532 533 public synchronized Hashtable getKeyIndex(KeyManager keymanager, int fingerprint) { 534 for (int k=0; k<indexEntriesUsed; k+=3) { 535 if (((KeyManager)index[k])==keymanager && 536 ((Integer )index[k+1]).intValue() == fingerprint) { 537 Object ix = index[k+2]; 538 return (Hashtable )index[k+2]; 539 } 540 } 541 return null; 542 } 543 544 553 554 public synchronized void setKeyIndex(KeyManager keymanager, int fingerprint, Hashtable keyindex) { 555 for (int k=0; k<indexEntriesUsed; k+=3) { 556 if (((KeyManager)index[k])==keymanager && 557 ((Integer )index[k+1]).intValue()==fingerprint) { 558 index[k+2] = keyindex; 559 return; 560 } 561 } 562 563 if (indexEntriesUsed+3 >= index.length) { 564 Object [] index2 = new Object [indexEntriesUsed*2]; 565 System.arraycopy(index, 0, index2, 0, indexEntriesUsed); 566 index = index2; 567 } 568 index[indexEntriesUsed++] = keymanager; 569 index[indexEntriesUsed++] = new Integer (fingerprint); 570 index[indexEntriesUsed++] = keyindex; 571 } 572 573 577 578 protected void setUnparsedEntity(String name, String uri) { 579 if (entityTable==null) { 580 entityTable = new Hashtable (); 581 } 582 entityTable.put(name, uri); 583 } 584 585 590 591 public String getUnparsedEntity(String name) { 592 if (entityTable==null) { 593 return ""; 594 } 595 String uri = (String )entityTable.get(name); 596 return (uri==null ? "" : uri); 597 } 598 599 602 603 public void copy(Outputter out) throws TransformerException { 604 605 609 611 AxisEnumeration children = 612 getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()); 613 614 while (children.hasMoreElements()) { 615 children.nextElement().copy(out); 616 } 617 } 618 619 622 623 public void diagnosticDump() { 624 System.err.println("Node\ttype\tdepth\toffset\tlength"); 625 for (int i=0; i<numberOfNodes; i++) { 626 System.err.println(i + "\t" + nodeType[i] + "\t" + depth[i] + "\t" + 627 offset[i] + "\t" + length[i] + "\t" + Navigator.getPath(getNode(i))); 628 } 629 } 630 631 } 632 633 | Popular Tags |