1 16 19 20 package org.apache.xalan.xsltc.dom; 21 22 import org.apache.xalan.xsltc.DOM; 23 import org.apache.xalan.xsltc.StripFilter; 24 import org.apache.xml.serializer.SerializationHandler; 25 import org.apache.xalan.xsltc.TransletException; 26 import org.apache.xalan.xsltc.runtime.BasisLibrary; 27 import org.apache.xalan.xsltc.runtime.Hashtable; 28 import org.apache.xml.dtm.DTM; 29 import org.apache.xml.dtm.DTMAxisIterator; 30 import org.apache.xml.dtm.DTMManager; 31 import org.apache.xml.dtm.ref.DTMAxisIteratorBase; 32 import org.apache.xml.dtm.ref.DTMDefaultBase; 33 import org.apache.xml.utils.SuballocatedIntVector; 34 35 import org.w3c.dom.Node ; 36 import org.w3c.dom.NodeList ; 37 38 43 public final class MultiDOM implements DOM { 44 45 private static final int NO_TYPE = DOM.FIRST_TYPE - 2; 46 private static final int INITIAL_SIZE = 4; 47 48 private DOM[] _adapters; 49 private DOMAdapter _main; 50 private DTMManager _dtmManager; 51 private int _free; 52 private int _size; 53 54 private Hashtable _documents = new Hashtable(); 55 56 private final class AxisIterator extends DTMAxisIteratorBase { 57 private final int _axis; 59 private final int _type; 60 private DTMAxisIterator _source; 62 private int _dtmId = -1; 63 64 public AxisIterator(final int axis, final int type) { 65 _axis = axis; 66 _type = type; 67 } 68 69 public int next() { 70 if (_source == null) { 71 return(END); 72 } 73 return _source.next(); 74 } 75 76 77 public void setRestartable(boolean flag) { 78 if (_source != null) { 79 _source.setRestartable(flag); 80 } 81 } 82 83 public DTMAxisIterator setStartNode(final int node) { 84 if (node == DTM.NULL) { 85 return this; 86 } 87 88 int dom = node >>> DTMManager.IDENT_DTM_NODE_BITS; 89 90 if (_source == null || _dtmId != dom) { 92 if (_type == NO_TYPE) { 93 _source = _adapters[dom].getAxisIterator(_axis); 94 } else if (_axis == Axis.CHILD) { 95 _source = _adapters[dom].getTypedChildren(_type); 96 } else { 97 _source = _adapters[dom].getTypedAxisIterator(_axis, _type); 98 } 99 } 100 101 _dtmId = dom; 102 _source.setStartNode(node); 103 return this; 104 } 105 106 public DTMAxisIterator reset() { 107 if (_source != null) { 108 _source.reset(); 109 } 110 return this; 111 } 112 113 public int getLast() { 114 if (_source != null) { 115 return _source.getLast(); 116 } 117 else { 118 return END; 119 } 120 } 121 122 public int getPosition() { 123 if (_source != null) { 124 return _source.getPosition(); 125 } 126 else { 127 return END; 128 } 129 } 130 131 public boolean isReverse() { 132 return Axis.isReverse[_axis]; 133 } 134 135 public void setMark() { 136 if (_source != null) { 137 _source.setMark(); 138 } 139 } 140 141 public void gotoMark() { 142 if (_source != null) { 143 _source.gotoMark(); 144 } 145 } 146 147 public DTMAxisIterator cloneIterator() { 148 final AxisIterator clone = new AxisIterator(_axis, _type); 149 if (_source != null) { 150 clone._source = _source.cloneIterator(); 151 } 152 clone._dtmId = _dtmId; 153 return clone; 154 } 155 } 157 158 162 private final class NodeValueIterator extends DTMAxisIteratorBase { 163 164 private DTMAxisIterator _source; 165 private String _value; 166 private boolean _op; 167 private final boolean _isReverse; 168 private int _returnType = RETURN_PARENT; 169 170 public NodeValueIterator(DTMAxisIterator source, int returnType, 171 String value, boolean op) { 172 _source = source; 173 _returnType = returnType; 174 _value = value; 175 _op = op; 176 _isReverse = source.isReverse(); 177 } 178 179 public boolean isReverse() { 180 return _isReverse; 181 } 182 183 public DTMAxisIterator cloneIterator() { 184 try { 185 NodeValueIterator clone = (NodeValueIterator)super.clone(); 186 clone._source = _source.cloneIterator(); 187 clone.setRestartable(false); 188 return clone.reset(); 189 } 190 catch (CloneNotSupportedException e) { 191 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 192 e.toString()); 193 return null; 194 } 195 } 196 197 198 public void setRestartable(boolean isRestartable) { 199 _isRestartable = isRestartable; 200 _source.setRestartable(isRestartable); 201 } 202 203 public DTMAxisIterator reset() { 204 _source.reset(); 205 return resetPosition(); 206 } 207 208 public int next() { 209 210 int node; 211 while ((node = _source.next()) != END) { 212 String val = getStringValueX(node); 213 if (_value.equals(val) == _op) { 214 if (_returnType == RETURN_CURRENT) 215 return returnNode(node); 216 else 217 return returnNode(getParent(node)); 218 } 219 } 220 return END; 221 } 222 223 public DTMAxisIterator setStartNode(int node) { 224 if (_isRestartable) { 225 _source.setStartNode(_startNode = node); 226 return resetPosition(); 227 } 228 return this; 229 } 230 231 public void setMark() { 232 _source.setMark(); 233 } 234 235 public void gotoMark() { 236 _source.gotoMark(); 237 } 238 } 239 240 public MultiDOM(DOM main) { 241 _size = INITIAL_SIZE; 242 _free = 1; 243 _adapters = new DOM[INITIAL_SIZE]; 244 DOMAdapter adapter = (DOMAdapter)main; 245 _adapters[0] = adapter; 246 _main = adapter; 247 DOM dom = adapter.getDOMImpl(); 248 if (dom instanceof DTMDefaultBase) { 249 _dtmManager = ((DTMDefaultBase)dom).getManager(); 250 } 251 252 addDOMAdapter(adapter, false); 267 } 268 269 public int nextMask() { 270 return _free; 271 } 272 273 public void setupMapping(String [] names, String [] uris, int[] types, String [] namespaces) { 274 } 276 277 public int addDOMAdapter(DOMAdapter adapter) { 278 return addDOMAdapter(adapter, true); 279 } 280 281 private int addDOMAdapter(DOMAdapter adapter, boolean indexByURI) { 282 DOM dom = adapter.getDOMImpl(); 284 285 int domNo = 1; 286 int dtmSize = 1; 287 SuballocatedIntVector dtmIds = null; 288 if (dom instanceof DTMDefaultBase) { 289 DTMDefaultBase dtmdb = (DTMDefaultBase)dom; 290 dtmIds = dtmdb.getDTMIDs(); 291 dtmSize = dtmIds.size(); 292 domNo = dtmIds.elementAt(dtmSize-1) >>> DTMManager.IDENT_DTM_NODE_BITS; 293 } 294 else if (dom instanceof SimpleResultTreeImpl) { 295 SimpleResultTreeImpl simpleRTF = (SimpleResultTreeImpl)dom; 296 domNo = simpleRTF.getDocument() >>> DTMManager.IDENT_DTM_NODE_BITS; 297 } 298 299 if (domNo >= _size) { 300 int oldSize = _size; 301 do { 302 _size *= 2; 303 } while (_size <= domNo); 304 305 final DOMAdapter[] newArray = new DOMAdapter[_size]; 306 System.arraycopy(_adapters, 0, newArray, 0, oldSize); 307 _adapters = newArray; 308 } 309 310 _free = domNo + 1; 311 312 if (dtmSize == 1) { 313 _adapters[domNo] = adapter; 314 } 315 else if (dtmIds != null) { 316 int domPos = 0; 317 for (int i = dtmSize - 1; i >= 0; i--) { 318 domPos = dtmIds.elementAt(i) >>> DTMManager.IDENT_DTM_NODE_BITS; 319 _adapters[domPos] = adapter; 320 } 321 domNo = domPos; 322 } 323 324 if (indexByURI) { 326 String uri = adapter.getDocumentURI(0); 327 _documents.put(uri, new Integer (domNo)); 328 } 329 330 if (dom instanceof AdaptiveResultTreeImpl) { 334 AdaptiveResultTreeImpl adaptiveRTF = (AdaptiveResultTreeImpl)dom; 335 DOM nestedDom = adaptiveRTF.getNestedDOM(); 336 if (nestedDom != null) { 337 DOMAdapter newAdapter = new DOMAdapter(nestedDom, 338 adapter.getNamesArray(), 339 adapter.getUrisArray(), 340 adapter.getTypesArray(), 341 adapter.getNamespaceArray()); 342 addDOMAdapter(newAdapter); 343 } 344 } 345 346 return domNo; 347 } 348 349 public int getDocumentMask(String uri) { 350 Integer domIdx = (Integer )_documents.get(uri); 351 if (domIdx == null) { 352 return(-1); 353 } else { 354 return domIdx.intValue(); 355 } 356 } 357 358 public DOM getDOMAdapter(String uri) { 359 Integer domIdx = (Integer )_documents.get(uri); 360 if (domIdx == null) { 361 return(null); 362 } else { 363 return(_adapters[domIdx.intValue()]); 364 } 365 } 366 367 public int getDocument() 368 { 369 return _main.getDocument(); 370 } 371 372 public DTMManager getDTMManager() { 373 return _dtmManager; 374 } 375 376 379 public DTMAxisIterator getIterator() { 380 return _main.getIterator(); 382 } 383 384 public String getStringValue() { 385 return _main.getStringValue(); 386 } 387 388 public DTMAxisIterator getChildren(final int node) { 389 return _adapters[getDTMId(node)].getChildren(node); 390 } 391 392 public DTMAxisIterator getTypedChildren(final int type) { 393 return new AxisIterator(Axis.CHILD, type); 394 } 395 396 public DTMAxisIterator getAxisIterator(final int axis) { 397 return new AxisIterator(axis, NO_TYPE); 398 } 399 400 public DTMAxisIterator getTypedAxisIterator(final int axis, final int type) 401 { 402 return new AxisIterator(axis, type); 403 } 404 405 public DTMAxisIterator getNthDescendant(int node, int n, 406 boolean includeself) 407 { 408 return _adapters[getDTMId(node)].getNthDescendant(node, n, includeself); 409 } 410 411 public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator, 412 int type, String value, 413 boolean op) 414 { 415 return(new NodeValueIterator(iterator, type, value, op)); 416 } 417 418 public DTMAxisIterator getNamespaceAxisIterator(final int axis, 419 final int ns) 420 { 421 DTMAxisIterator iterator = _main.getNamespaceAxisIterator(axis, ns); 422 return(iterator); 423 } 424 425 public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) { 426 return _adapters[getDTMId(node)].orderNodes(source, node); 427 } 428 429 public int getExpandedTypeID(final int node) { 430 if (node != DTM.NULL) { 431 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getExpandedTypeID(node); 432 } 433 else { 434 return DTM.NULL; 435 } 436 } 437 438 public int getNamespaceType(final int node) { 439 return _adapters[getDTMId(node)].getNamespaceType(node); 440 } 441 442 public int getNSType(int node) 443 { 444 return _adapters[getDTMId(node)].getNSType(node); 445 } 446 447 public int getParent(final int node) { 448 if (node == DTM.NULL) { 449 return DTM.NULL; 450 } 451 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getParent(node); 452 } 453 454 public int getAttributeNode(final int type, final int el) { 455 if (el == DTM.NULL) { 456 return DTM.NULL; 457 } 458 return _adapters[el >>> DTMManager.IDENT_DTM_NODE_BITS].getAttributeNode(type, el); 459 } 460 461 public String getNodeName(final int node) { 462 if (node == DTM.NULL) { 463 return ""; 464 } 465 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeName(node); 466 } 467 468 public String getNodeNameX(final int node) { 469 if (node == DTM.NULL) { 470 return ""; 471 } 472 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeNameX(node); 473 } 474 475 public String getNamespaceName(final int node) { 476 if (node == DTM.NULL) { 477 return ""; 478 } 479 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNamespaceName(node); 480 } 481 482 public String getStringValueX(final int node) { 483 if (node == DTM.NULL) { 484 return ""; 485 } 486 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getStringValueX(node); 487 } 488 489 public void copy(final int node, SerializationHandler handler) 490 throws TransletException 491 { 492 if (node != DTM.NULL) { 493 _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].copy(node, handler); 494 } 495 } 496 497 public void copy(DTMAxisIterator nodes, SerializationHandler handler) 498 throws TransletException 499 { 500 int node; 501 while ((node = nodes.next()) != DTM.NULL) { 502 _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].copy(node, handler); 503 } 504 } 505 506 507 public String shallowCopy(final int node, SerializationHandler handler) 508 throws TransletException 509 { 510 if (node == DTM.NULL) { 511 return ""; 512 } 513 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].shallowCopy(node, handler); 514 } 515 516 public boolean lessThan(final int node1, final int node2) { 517 if (node1 == DTM.NULL) { 518 return true; 519 } 520 if (node2 == DTM.NULL) { 521 return false; 522 } 523 final int dom1 = getDTMId(node1); 524 final int dom2 = getDTMId(node2); 525 return dom1 == dom2 ? _adapters[dom1].lessThan(node1, node2) 526 : dom1 < dom2; 527 } 528 529 public void characters(final int textNode, SerializationHandler handler) 530 throws TransletException 531 { 532 if (textNode != DTM.NULL) { 533 _adapters[textNode >>> DTMManager.IDENT_DTM_NODE_BITS].characters(textNode, handler); 534 } 535 } 536 537 public void setFilter(StripFilter filter) { 538 for (int dom=0; dom<_free; dom++) { 539 if (_adapters[dom] != null) { 540 _adapters[dom].setFilter(filter); 541 } 542 } 543 } 544 545 public Node makeNode(int index) { 546 if (index == DTM.NULL) { 547 return null; 548 } 549 return _adapters[getDTMId(index)].makeNode(index); 550 } 551 552 public Node makeNode(DTMAxisIterator iter) { 553 return _main.makeNode(iter); 555 } 556 557 public NodeList makeNodeList(int index) { 558 if (index == DTM.NULL) { 559 return null; 560 } 561 return _adapters[getDTMId(index)].makeNodeList(index); 562 } 563 564 public NodeList makeNodeList(DTMAxisIterator iter) { 565 return _main.makeNodeList(iter); 567 } 568 569 public String getLanguage(int node) { 570 return _adapters[getDTMId(node)].getLanguage(node); 571 } 572 573 public int getSize() { 574 int size = 0; 575 for (int i=0; i<_size; i++) { 576 size += _adapters[i].getSize(); 577 } 578 return(size); 579 } 580 581 public String getDocumentURI(int node) { 582 if (node == DTM.NULL) { 583 node = DOM.NULL; 584 } 585 return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getDocumentURI(0); 586 } 587 588 public boolean isElement(final int node) { 589 if (node == DTM.NULL) { 590 return false; 591 } 592 return(_adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].isElement(node)); 593 } 594 595 public boolean isAttribute(final int node) { 596 if (node == DTM.NULL) { 597 return false; 598 } 599 return(_adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].isAttribute(node)); 600 } 601 602 public int getDTMId(int nodeHandle) 603 { 604 if (nodeHandle == DTM.NULL) 605 return 0; 606 607 int id = nodeHandle >>> DTMManager.IDENT_DTM_NODE_BITS; 608 while (id >= 2 && _adapters[id] == _adapters[id-1]) { 609 id--; 610 } 611 return id; 612 } 613 614 public int getNodeIdent(int nodeHandle) 615 { 616 return _adapters[nodeHandle >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeIdent(nodeHandle); 617 } 618 619 public int getNodeHandle(int nodeId) 620 { 621 return _main.getNodeHandle(nodeId); 622 } 623 624 public DOM getResultTreeFrag(int initSize, int rtfType) 625 { 626 return _main.getResultTreeFrag(initSize, rtfType); 627 } 628 629 public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager) 630 { 631 return _main.getResultTreeFrag(initSize, rtfType, addToManager); 632 } 633 634 public DOM getMain() 635 { 636 return _main; 637 } 638 639 642 public SerializationHandler getOutputDomBuilder() 643 { 644 return _main.getOutputDomBuilder(); 645 } 646 647 public String lookupNamespace(int node, String prefix) 648 throws TransletException 649 { 650 return _main.lookupNamespace(node, prefix); 651 } 652 653 public String getUnparsedEntityURI(String entity) { 655 return _main.getUnparsedEntityURI(entity); 656 } 657 658 public Hashtable getElementsWithIDs() { 660 return _main.getElementsWithIDs(); 661 } 662 } 663 | Popular Tags |