1 22 23 package org.xquark.mediator.DOMUtils; 24 25 import java.io.IOException ; 26 import java.util.ArrayList ; 27 28 import org.w3c.dom.Node ; 29 import org.xml.sax.ContentHandler ; 30 import org.xml.sax.SAXException ; 31 import org.xml.sax.ext.LexicalHandler ; 32 import org.xquark.mediator.plan.Operator; 33 import org.xquark.mediator.plan.ResultSet; 34 import org.xquark.schema.SimpleType; 35 import org.xquark.util.SAXConstants; 36 import org.xquark.xpath.datamodel.TypedNode; 37 import org.xquark.xquery.parser.XQueryException; 38 import org.xquark.xquery.typing.QAtomicSerializer; 39 40 47 public class Tuple { 48 private static final String RCSRevision = "$Revision: 1.11 $"; 52 private static final String RCSName = "$Name: $"; 53 59 private int size = 0; 61 private int idsize = 0; 62 63 69 private ArrayList indexnodes = null; 70 private ArrayList identifiers = null; 71 private BufferTuple parent = null; 72 73 79 80 public Tuple(Operator algebra) { 81 this.size = algebra.getSize(); 82 this.idsize = algebra.getIdSize(); 83 if (size > 0) { 84 indexnodes = new ArrayList (size); 85 for (int i = 0; i < size; i++) 86 indexnodes.add(null); 87 } 88 if (idsize > 0) { 89 identifiers = new ArrayList (idsize); 90 for (int i = 0; i < idsize; i++) 91 identifiers.add(null); 92 } 93 } 97 98 public Tuple(int size) { 99 this.size = size; 100 if (size > 0) { 101 indexnodes = new ArrayList (size); 102 for (int i = 0; i < size; i++) 103 indexnodes.add(null); 104 } 105 } 108 109 public Tuple(int size, int idsize) { 110 this.size = size; 111 this.idsize = idsize; 112 if (size > 0) { 113 indexnodes = new ArrayList (size); 114 for (int i = 0; i < size; i++) 115 indexnodes.add(null); 116 } 117 if (idsize > 0) { 118 identifiers = new ArrayList (idsize); 119 for (int i = 0; i < idsize; i++) 120 identifiers.add(null); 121 } 122 } 126 127 public Tuple(ResultSet rs) { 128 this.size = rs.getOperator().getSize(); 129 this.idsize = rs.getOperator().getIdSize(); 130 if (size > 0) { 131 indexnodes = new ArrayList (size); 132 for (int i = 0; i < size; i++) 133 indexnodes.add(null); 134 } 135 if (idsize > 0) { 136 identifiers = new ArrayList (idsize); 137 for (int i = 0; i < idsize; i++) 138 identifiers.add(null); 139 } 140 } 144 145 public Tuple(Tuple tuple) { 146 this.size = tuple.size(); 147 this.idsize = tuple.idsize(); 148 if (size > 0) { 149 indexnodes = new ArrayList (size); 150 for (int i = 0; i < size; i++) 151 indexnodes.add(null); 152 } 153 if (idsize > 0) { 154 identifiers = new ArrayList (idsize); 155 for (int i = 0; i < idsize; i++) 156 identifiers.add(null); 157 } 158 this.fillIdentifiers(0, tuple); 159 this.appendTupleAtIndex(0, tuple); 160 } 164 165 public Object clone() throws CloneNotSupportedException { 166 return super.clone(); 167 } 168 public void setParent(BufferTuple parent) { 172 this.parent = parent; 173 } 174 public BufferTuple getParent() { 175 return parent; 176 } 177 178 184 public void addNodeAtIndex(int idx, TypedNode element) { 185 if (indexnodes.get(idx) == null) 187 indexnodes.set(idx, new ArrayList ()); 188 ((ArrayList ) indexnodes.get(idx)).add(element); 189 194 } 195 196 199 public void addNodesAtIndex(int idx, ArrayList elements) { 200 if (elements == null) 201 return; 202 if (indexnodes.get(idx) == null) 203 indexnodes.set(idx, new ArrayList ()); 204 ((ArrayList ) indexnodes.get(idx)).addAll(elements); 205 210 } 211 212 215 public ArrayList getPath(String path) { 216 int pos = parent.getPathIndex(path); 217 if (pos != -1) 219 return getNodesAtIndex(pos); 220 return null; 221 } 222 223 public ArrayList getNodesAtIndex(int idx) { 224 if (idx >= 0 && idx < indexnodes.size()) 225 return (ArrayList ) indexnodes.get(idx); 226 else 227 return null; 228 234 } 235 236 public void appendTuple(Tuple tuple) { 237 appendTupleAtIndex(0, tuple); 238 } 239 240 public void appendTupleAtIndex(int idx, Tuple tuple) { 241 for (int i = 0; i < tuple.size(); i++) 242 addNodesAtIndex(idx + i, tuple.getNodesAtIndex(i)); 243 } 244 245 248 250 253 public int size() { 254 return size; 255 } 256 257 260 public int idsize() { 261 return idsize; 262 268 } 269 270 273 public void eraseIdSize() { 274 identifiers = null; 275 idsize = 0; 276 } 277 278 282 public Tuple getPart(int index, int part, int idsiz) { 283 if (index >= size) 284 return null; 285 ArrayList tmplist = this.getNodesAtIndex(index); 286 if (tmplist == null || part >= tmplist.size()) 287 return null; 288 ArrayList reslist = new ArrayList (1); 289 reslist.add(tmplist.get(part)); 290 Tuple newtuple = new Tuple(1, idsiz); 291 newtuple.addNodesAtIndex(0, reslist); 292 newtuple.fillIdentifiers(); 293 return newtuple; 294 } 295 296 public Tuple getPart(int index, int idsiz) { 297 if (index < 0 || index >= size) 298 return null; 299 ArrayList tmplist = this.getNodesAtIndex(index); 300 Tuple newtuple = new Tuple(1, idsiz); 301 newtuple.fillIdentifiers(0,newtuple); 302 newtuple.addNodesAtIndex(0, tmplist); 303 return newtuple; 304 } 305 306 public Tuple getPart(int index) { 307 return getPart(index,0); 308 } 309 310 public Tuple getPart(String str, int idsiz) { 311 if (parent == null) 312 return null; 313 return getPart(parent.getPathIndex(str),idsiz); 314 } 315 316 public Tuple getPart(String str) { 317 return getPart(str,0); 318 } 319 320 323 public Tuple project(ArrayList steps, ArrayList idxsteps) { 324 return project(steps, idxsteps, false); 325 } 326 public Tuple project(ArrayList steps, ArrayList idxsteps, boolean erase) { 327 if (idxsteps.isEmpty()) { 330 for (int i = 0; i < steps.size(); i++) { 331 339 String stepsi = (String ) steps.get(i); 340 int tmpInt = parent.getPathIndex(stepsi); 342 if (tmpInt >= 0) 343 idxsteps.add(new Integer (tmpInt)); 344 } 345 } 346 347 Tuple newtuple = null; 348 if (erase) { newtuple = this; 350 } else { 351 newtuple = new Tuple(idxsteps.size(), idsize); 352 newtuple.fillIdentifiers(0, this); 353 int cpt = 0; 354 for (int i = 0; i < idxsteps.size(); i++) { 355 int idx = ((Integer ) idxsteps.get(i)).intValue(); 356 newtuple.addNodesAtIndex(cpt++, getNodesAtIndex(idx)); 357 } 358 } 359 return newtuple; 360 } 361 362 365 public Tuple merge(Tuple addtuple, Operator algebra) { 366 Tuple newtuple = new Tuple(algebra); 367 newtuple.appendTuple(this); 368 newtuple.fillIdentifiers(0, this); 369 int cpt = size(); 370 for (int k = 0; k < addtuple.size(); k++) { 371 newtuple.addNodesAtIndex(cpt++, addtuple.getNodesAtIndex(k)); 381 } 383 cpt = idsize; 384 385 for (int k = 0; k < addtuple.idsize(); k++) 386 newtuple.fillIdentifiers(cpt++, addtuple.getIdentifiers(k)); 388 389 return newtuple; 390 } 391 392 395 public void mergeInPlace(ArrayList nodes, Operator algebra) { 396 int oldsize = size; 397 if (size < algebra.getSize()) { 398 for (int i = size; i < algebra.getSize(); i++) 399 indexnodes.add(null); 400 size = algebra.getSize(); 401 } 402 if (idsize < algebra.getIdSize()) { 403 if (identifiers == null) 404 identifiers = new ArrayList (); 405 for (int i = idsize; i < algebra.getIdSize(); i++) 406 identifiers.add(this); 407 idsize = algebra.getIdSize(); 408 } 409 if (nodes != null) 410 addNodesAtIndex(oldsize, nodes); 411 } 412 413 416 public void mergeInPlace(TypedNode node, Operator algebra) { 417 int oldsize = size; 418 if (size < algebra.getSize()) { 419 for (int i = size; i < algebra.getSize(); i++) 420 indexnodes.add(null); 421 size = algebra.getSize(); 422 } 423 if (idsize < algebra.getIdSize()) { 424 if (identifiers == null) 425 identifiers = new ArrayList (); 426 for (int i = idsize; i < algebra.getIdSize(); i++) 427 identifiers.add(this); 428 idsize = algebra.getIdSize(); 429 } 430 if (node != null) 431 addNodeAtIndex(oldsize, node); 432 } 433 434 437 447 450 public Tuple completeTupleForLeft(int size) { 451 Tuple tuple = new Tuple(size); 452 tuple.appendTuple(this); 453 return tuple; 455 } 456 457 460 public Tuple completeTupleForRight(int size, ArrayList equivalences) { 461 Tuple tuple = new Tuple(size); 462 int cpt = 0; 463 464 467 int limit = size - size(); 468 469 for (int i = 0; i < size(); i++) { 471 tuple.addNodesAtIndex(limit + cpt, getNodesAtIndex(i)); 476 cpt++; 477 } 479 return tuple; 480 } 481 482 486 public String makeStringPath(int index, QAtomicSerializer ser) { 487 ArrayList nodes = getNodesAtIndex(index); 488 if (nodes == null) 489 return null; 490 if (nodes.size() != 1) 491 return null; 492 493 TypedNode node = (TypedNode) nodes.get(0); 494 if (node == null) 495 return null; 496 Object typedValue = node.getTypedValue(); 497 if (typedValue == null && node.getChildNodes().getLength() == 1) { 498 node = (TypedNode)node.getChildNodes().item(0) ; 499 typedValue = node.getTypedValue(); 500 } 501 if (typedValue == null) return null; 502 else try { 503 return ser.serialize((SimpleType)node.getType(), typedValue); 504 } catch (XQueryException e) { 505 return null; 506 } 507 } 508 512 public void makeEventPath(TypedDOMReader domreader, ContentHandler handler, int index) throws XQueryException { 513 if (domreader == null) 514 return; 515 ArrayList nodes = getNodesAtIndex(index); 516 if (nodes == null || nodes.isEmpty()) 517 return; 518 try { 519 for (int i = 0; i < nodes.size(); i++) { 520 TypedNode nodei = (TypedNode) nodes.get(i); 521 if (nodei == null) { 522 continue; 523 } 524 domreader.setContentHandler(handler); 525 if (handler instanceof LexicalHandler ) 526 domreader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); 527 domreader.setRoot(nodei); 528 domreader.setFeature(SAXConstants.FRAGMENT_FEATURE, true); 529 domreader.parse(""); 530 } 531 return; 532 } catch (IOException ioe) { 533 throw new XQueryException("Tuple.makeEventPath: " + ioe.getMessage()); 534 } catch (SAXException saxe) { 535 throw new XQueryException("Tuple.makeEventPath: " + saxe.getMessage()); 536 } 537 } 538 539 542 public void fillIdentifiers() { 544 if (identifiers == null) 545 return; 546 for (int i = 0; i < idsize; i++) 548 identifiers.set(i, this); 549 556 } 557 558 561 public void fillIdentifiers(int startindex, Tuple tuple) { 562 for (int i = startindex, j = 0; i < startindex + tuple.idsize(); i++, j++) 563 identifiers.set(i, tuple.getIdentifiers(j)); 564 568 } 569 570 573 public void fillIdentifiers(int startindex, Object obj) { 574 identifiers.set(startindex, obj); 575 } 577 578 581 public ArrayList retIdentifiers() { 582 return identifiers; 583 } 584 588 591 public Object getIdentifiers(int index) { 592 if (identifiers == null || idsize <= index) 593 return null; 594 return identifiers.get(index); 595 } 596 602 605 public void getIdentifiers(Object [] identifiers) { 606 if (this.identifiers == null) { 607 for (int i = 0; i < identifiers.length; i++) 608 identifiers[i] = null; 609 return; 610 } 611 for (int i = 0; i < identifiers.length; i++) 612 if (idsize > i) 613 identifiers[i] = this.identifiers.get(i); 614 else 615 identifiers[i] = null; 616 } 617 627 public boolean equals(Tuple tuple) { 628 if (tuple == null) 629 return false; 630 if (tuple.size() != this.size) 631 return false; 632 if (tuple.idsize() != this.idsize) 633 return false; 634 for (int i = 0; i < size; i++) { 635 ArrayList listi = tuple.getNodesAtIndex(i); 636 if (((ArrayList ) indexnodes.get(i)).size() != listi.size()) 637 return false; 638 for (int j = 0; j < listi.size(); j++) { 639 TypedNode nodeij1 = (TypedNode) listi.get(j); 640 TypedNode nodeij2 = (TypedNode) ((ArrayList ) indexnodes.get(i)).get(j); 641 if (!DOMUtils.compareTree(nodeij1, nodeij2)) 642 return false; 643 } 644 } 645 return true; 646 } 647 668 676 public String toCompleteString() { 677 StringBuffer sb = new StringBuffer (); 678 sb.append("\n----------- <TUPLE (" + size() + ")> -----------------\n"); 679 sb.append("INDEX \n"); 680 for (int i = 0; i < indexnodes.size(); i++) 681 sb.append(i + " - " + indexnodes.get(i) + "\n"); 682 683 if (identifiers == null) 684 sb.append("\nidentifiers is empty\n"); 685 else { 686 sb.append("\nidentifiers \n"); 687 for (int i = 0; i < identifiers.size(); i++) 688 sb.append(i + " - " + identifiers.get(i) + "\n"); 689 } 690 691 for (int i = 0; i < size; i++) { 692 sb.append("\n-------------------------------\n"); 693 ArrayList nodes = getNodesAtIndex(i); 694 if (nodes == null) { 695 sb.append("null nodes " + i + "\n"); 696 continue; 697 } 698 for (int j = 0; j < nodes.size(); j++) { 699 if (nodes.get(j) == null) 701 sb.append("null node " + i + "-" + j + "\n"); 702 else { 703 Object obj = nodes.get(j); 704 if (obj instanceof TypedNode) 705 sb.append(stringRepresentationOf((TypedNode)obj)); 706 else if (obj instanceof Node ) 707 sb.append(stringRepresentationOf((Node )obj)); 708 else 709 sb.append("unknown node type " + obj.getClass().getName()); 710 } 711 } 712 } 713 sb.append("\n----------------------------------------\n"); 714 return sb.toString(); 715 } 716 717 724 public String stringRepresentationOf(TypedNode root) { 725 return stringRepresentationOf("", root); 726 } 727 public String stringRepresentationOf(Node root) { 728 return stringRepresentationOf("", root); 729 } 730 731 738 private String stringRepresentationOf(String before, TypedNode root) { 739 if (root == null) 740 return before + "<null>"; 741 742 StringBuffer str = new StringBuffer (); 743 String newline = System.getProperty("line.separator"); 744 745 org.w3c.dom.NamedNodeMap nnm = root.getAttributes(); 747 if (nnm != null) { 748 for (int i = 0; i < nnm.getLength(); i++) 749 str.append(newline + before + "*---- [A] " + nnm.item(i).getNodeName() + " : " + nnm.item(i).getNodeValue()); 750 } 751 752 org.w3c.dom.NodeList nl = root.getChildNodes(); 754 if ((nl == null) || (nl.getLength() <= 0)) 755 str.append(newline + before + "+----" + root.getNodeName() + " : " + root.getNodeValue() + " [" + root.getNodeType() + "]"); 756 else { 757 str.append(newline + before + "+----" + root.getNodeName() + " [" + root.getNodeType() + "]"); 758 for (int i = 0; i < nl.getLength(); i++) 759 str.append(stringRepresentationOf(before + " ", nl.item(i))); 760 } 761 return str.toString(); 762 } 763 764 private String stringRepresentationOf(String before, Node root) { 765 if (root == null) 766 return before + "<null>"; 767 768 StringBuffer str = new StringBuffer (); 769 String newline = System.getProperty("line.separator"); 770 771 org.w3c.dom.NamedNodeMap nnm = root.getAttributes(); 773 if (nnm != null) { 774 for (int i = 0; i < nnm.getLength(); i++) 775 str.append(newline + before + "*---- [A] " + nnm.item(i).getNodeName() + " : " + nnm.item(i).getNodeValue()); 776 } 777 778 org.w3c.dom.NodeList nl = root.getChildNodes(); 780 if ((nl == null) || (nl.getLength() <= 0)) 781 str.append(newline + before + "+----" + root.getNodeName() + " : " + root.getNodeValue() + " [" + root.getNodeType() + "]"); 782 else { 783 str.append(newline + before + "+----" + root.getNodeName() + " [" + root.getNodeType() + "]"); 784 for (int i = 0; i < nl.getLength(); i++) 785 str.append(stringRepresentationOf(before + " ", nl.item(i))); 786 } 787 return str.toString(); 788 } 789 790 } 791 | Popular Tags |