1 22 23 package org.xquark.extractor.algebra; 24 25 import java.io.DataOutputStream ; 26 import java.util.ArrayList ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 30 import org.xquark.extractor.common.Debug; 31 import org.xquark.xquery.parser.QName; 32 import org.xquark.xquery.parser.XQueryExpression; 33 import org.xquark.xquery.typing.QType; 34 import org.xquark.xquery.typing.QTypeElement; 35 import org.xquark.xquery.typing.QTypeSequence; 36 37 public final class Mapper implements Cloneable { 38 private static final String RCSRevision = "$Revision: 1.6 $"; 39 private static final String RCSName = "$Name: $"; 40 41 List _mapItemList = new ArrayList (); 42 43 List _keyNameList = null; 44 List _sortAttributeList; 45 46 Expression _partAttribute = null; 47 long _commonPartBitMap = -1; 49 50 List _idList = null; 51 List _mapItemAddedForId = null; 52 53 Numbering _numbering; 54 55 boolean _optimized = false; 56 57 public Mapper() { 58 59 } 60 61 public Object clone() throws CloneNotSupportedException { 62 Mapper retVal = (Mapper) super.clone(); 63 64 65 if (null != _mapItemList) { 66 retVal._mapItemList = new ArrayList (); 67 retVal._mapItemList.addAll(_mapItemList); 68 } 69 if (null != _idList) { 70 retVal._idList = new ArrayList (); 71 retVal._idList.addAll(_idList); 72 } 73 if (null != _mapItemAddedForId) { 74 retVal._mapItemAddedForId = new ArrayList (); 75 retVal._mapItemAddedForId.addAll(_mapItemAddedForId); 76 } 77 82 return retVal; 83 } 84 85 89 public void createMap(List itemList) { 90 92 if (itemList != null) { 93 Iterator iter = itemList.iterator(); 94 Expression item; 95 while (iter.hasNext()) { 96 item = (Expression) iter.next(); 97 createMapItem(item); 98 } 99 } 100 101 103 } 105 106 protected MapItem createMapItem(Expression expression) { 107 109 MapItem retVal = null; 110 if (expression instanceof TupleExpression) 111 retVal = createMapItem((TupleExpression) expression); 112 else if (expression instanceof AttributeExpression) 113 retVal = createMapItem((AttributeExpression) expression); 114 else if (expression instanceof RenameItem) 115 retVal = createMapItem((RenameItem) expression); 116 else { 117 MapItem mapItem = new MapItem(); 118 119 XQueryExpression xExpr = expression.getOrginalXExpr(); 120 mapItem.setPath(xExpr.toString()); 121 122 mapItem.setQName(null); 123 124 mapItem.setItemName(expression.getName()); 125 mapItem.setRelatedExpression(expression); 126 127 addMapItem(mapItem); 128 129 retVal = mapItem; 130 } 131 return retVal; 133 } 134 135 protected MapItem createMapItem(TupleExpression tuple) { 136 138 MapItem mapItem = new MapItem(); 139 140 XQueryExpression xExpr = tuple.getOrginalXExpr(); 141 mapItem.setPath(xExpr.toString()); 142 143 144 QType qtype = xExpr.getQType(); 145 if (qtype instanceof QTypeElement) { 146 QTypeElement qte = (QTypeElement) qtype; 147 mapItem.setQName(((QName) qte.getName())); 148 } else if (qtype instanceof QTypeSequence) { 149 mapItem.setQName(null); 150 } else { 151 Debug.assertTrue(false, "NYI!!"); 152 } 153 154 mapItem.setRelatedExpression(tuple); 155 156 List children = new ArrayList (); 157 List subExprs = tuple.getItemList(); 158 for (int i = 0; i < subExprs.size(); i++) { 159 xExpr = ((Expression) subExprs.get(i)).getOrginalXExpr(); 160 children.add(xExpr.toString()); 161 } 162 mapItem.setChildren(children); 163 addMapItem(mapItem); 164 165 return mapItem; 167 168 } 169 170 177 public List getIdentifierList() { 178 return _idList; 181 } 182 183 public List getMapItemsForId() { 184 return _mapItemAddedForId; 187 } 188 189 public void setPartAttribute(Expression part) { 190 _partAttribute = part; 191 } 192 193 public String getPartAttributeName() { 194 return _partAttribute.getName(); 195 } 196 197 public Expression getPartAttribute() { 198 return _partAttribute; 199 } 200 201 public int[] getEliminationGuide() { 202 return _numbering.getEliminationGuide(); 203 } 204 205 public boolean isMultiPart() { 206 return _partAttribute != null; 207 } 208 209 public List getCommonIdentifierAttributeNames() { 210 List retVal = null; 212 if (null != _partAttribute) { 213 List commonIdentifierMapItems = getCommonIdentifierMapItems(); 214 Debug.assertTrue(null != commonIdentifierMapItems, "null!=commonIdentifierMapItems"); 215 retVal = new ArrayList (); 216 for (int i = 0; i < commonIdentifierMapItems.size(); i++) { 217 MapItem mapItem = (MapItem) commonIdentifierMapItems.get(i); 218 if (mapItem.isLeafPath()) { 219 retVal.add(mapItem.getItemName()); 220 } else { 221 List chidren = getChildren(mapItem); 222 for (int j = 0; j < chidren.size(); j++) { 223 MapItem child = (MapItem) chidren.get(j); 224 retVal.add(child.getItemName()); 225 } 226 227 } 228 } 229 } 230 return retVal; 232 } 233 234 public List getCommonIdentifierAttributes() { 235 List retVal = null; 237 if (null != _partAttribute) { 238 List commonIdentifierMapItems = getCommonIdentifierMapItems(); 239 Debug.assertTrue(null != commonIdentifierMapItems, "null!=commonIdentifierMapItems"); 240 retVal = new ArrayList (); 241 for (int i = 0; i < commonIdentifierMapItems.size(); i++) { 242 MapItem mapItem = (MapItem) commonIdentifierMapItems.get(i); 243 if (mapItem.isLeafPath()) { 244 retVal.add(mapItem.getRelatedExpression()); 245 } else { 246 List chidren = getChildren(mapItem); 247 for (int j = 0; j < chidren.size(); j++) { 248 MapItem child = (MapItem) chidren.get(j); 249 retVal.add(child.getRelatedExpression()); 250 } 251 252 } 253 } 254 } 255 return retVal; 257 } 258 259 private List getCommonIdentifierMapItems() { 260 List retVal = null; 262 if (null != _partAttribute) { 263 retVal = new ArrayList (); 264 for (int i = 0; i < _idList.size(); i++) { 265 MapItem mapItem = (MapItem) _idList.get(i); 266 long part = mapItem.getPart(); 267 if (isCommon(part)) { 268 retVal.add(mapItem); 269 } 270 } 271 } 272 273 return retVal; 275 } 276 277 private boolean isCommon(long part) { 278 280 boolean retVal = false; 281 int count = 0; 282 long ruler = 1; 283 long tmp = 0; 284 for (int i = 0; i < 64; i++) { 285 tmp = (part >> i); 286 tmp = tmp & ruler; 287 count += tmp; 288 } 289 retVal = count > 1; 290 291 return retVal; 293 } 294 295 309 public long getCommonPartNumber() { 310 long retVal = -1; 312 if (null != _partAttribute) { 313 long maxPart = 0; 314 for (int i = 0; i < _idList.size(); i++) { 315 long part = ((MapItem) _idList.get(i)).getPart(); 316 if (maxPart < part) { 317 maxPart = part; 318 } 319 } 320 retVal = maxPart; 321 } 322 return retVal; 324 } 325 326 public List getNonCommonIdentifierAttributeNames() { 327 List retVal = null; 329 if (null != _partAttribute) { 330 List commonNonIdentifierMapItems = getNonCommonIdentifierMapItems(); 331 Debug.assertTrue(null != commonNonIdentifierMapItems, "null!=commonNonIdentifierMapItems"); 332 retVal = new ArrayList (); 333 for (int i = 0; i < commonNonIdentifierMapItems.size(); i++) { 334 MapItem mapItem = (MapItem) commonNonIdentifierMapItems.get(i); 335 if (mapItem.isLeafPath()) { 336 retVal.add(mapItem.getItemName()); 337 } else { 338 List chidren = getChildren(mapItem); 339 for (int j = 0; j < chidren.size(); j++) { 340 MapItem child = (MapItem) chidren.get(j); 341 retVal.add(child.getItemName()); 342 } 343 344 } 345 } 346 } 347 348 return retVal; 350 } 351 352 public List getNonCommonIdentifierAttributes() { 353 List retVal = null; 355 if (null != _partAttribute) { 356 List commonNonIdentifierMapItems = getNonCommonIdentifierMapItems(); 357 Debug.assertTrue(null != commonNonIdentifierMapItems, "null!=commonNonIdentifierMapItems"); 358 retVal = new ArrayList (); 359 for (int i = 0; i < commonNonIdentifierMapItems.size(); i++) { 360 MapItem mapItem = (MapItem) commonNonIdentifierMapItems.get(i); 361 if (mapItem.isLeafPath()) { 362 retVal.add(mapItem.getRelatedExpression()); 363 } else { 364 List chidren = getChildren(mapItem); 365 for (int j = 0; j < chidren.size(); j++) { 366 MapItem child = (MapItem) chidren.get(j); 367 retVal.add(child.getRelatedExpression()); 368 } 369 370 } 371 } 372 } 373 374 return retVal; 376 } 377 378 private List getNonCommonIdentifierMapItems() { 379 List retVal = null; 381 if (null != _partAttribute) { 382 retVal = new ArrayList (); 383 for (int i = 0; i < _idList.size(); i++) { 384 MapItem mapItem = (MapItem) _idList.get(i); 385 long part = mapItem.getPart(); 386 if (!isCommon(part)) { 387 retVal.add(mapItem); 388 } 389 } 390 } 391 392 return retVal; 394 } 395 396 public List getAllIdentifierAttributeNames() { 397 List retVal = null; 399 400 if (null != _idList) { 401 retVal = new ArrayList (); 402 for (int i = 0; i < _idList.size(); i++) { 403 MapItem mapItem = (MapItem) _idList.get(i); 404 if (mapItem.isLeafPath()) { 405 retVal.add(mapItem.getItemName()); 406 } else { 407 List chidren = getChildren(mapItem); 408 for (int j = 0; j < chidren.size(); j++) { 409 MapItem child = (MapItem) chidren.get(j); 410 retVal.add(child.getItemName()); 411 } 412 413 } 414 } 415 } 416 417 return retVal; 419 } 420 421 public List getAllIdentifierAttributes() { 422 List retVal = null; 424 425 if (null != _idList) { 426 retVal = new ArrayList (); 427 for (int i = 0; i < _idList.size(); i++) { 428 MapItem mapItem = (MapItem) _idList.get(i); 429 if (mapItem.isLeafPath()) { 430 retVal.add(mapItem.getRelatedExpression()); 431 } else { 432 List chidren = getChildren(mapItem); 433 for (int j = 0; j < chidren.size(); j++) { 434 MapItem child = (MapItem) chidren.get(j); 435 retVal.add(child.getRelatedExpression()); 436 } 437 438 } 439 } 440 } 441 442 return retVal; 444 } 445 446 451 public void addIdentifier(String path, List attributeList) { 452 454 if (null == _idList) { 455 _idList = new ArrayList (); 456 } 457 458 if (null == _mapItemAddedForId) { 459 _mapItemAddedForId = new ArrayList (); 460 } 461 462 if (1 < attributeList.size()) { 463 464 List children = new ArrayList (); 465 for (int i = 0; i < attributeList.size(); i++) { 466 Expression attrbute = (Expression) attributeList.get(i); 467 MapItem mapItem = findMapItem(attrbute.getName()); 468 if (null == mapItem) { 469 mapItem = new MapItem(path + "/" + Integer.toString(i), null, attrbute.getName(), null); 470 mapItem.setRelatedExpression(attrbute); 471 _mapItemList.add(mapItem); 472 _mapItemAddedForId.add(mapItem); 473 } 474 children.add(mapItem.getPath()); 475 } 476 MapItem mapItem = new MapItem(path, null, null, children); 477 _idList.add(mapItem); 478 _mapItemAddedForId.add(mapItem); 479 _mapItemList.add(mapItem); 480 } else { 481 Expression attrbute = (Expression) attributeList.get(0); 482 addIdentifier(path, attrbute); 483 } 484 485 return; 487 } 488 489 495 public MapItem addIdentifier(String path, Expression attrbute) { 496 MapItem retVal = null; 498 499 if (null == _idList) { 500 _idList = new ArrayList (); 501 } 502 503 if (null == _mapItemAddedForId) { 504 _mapItemAddedForId = new ArrayList (); 505 } 506 507 MapItem mapItem = findMapItem(attrbute.getName()); 508 if (null == mapItem) { 509 mapItem = new MapItem(path, null, attrbute.getName(), null); 510 mapItem.setRelatedExpression(attrbute); 511 _mapItemList.add(mapItem); 512 _mapItemAddedForId.add(mapItem); 513 } 514 _idList.add(mapItem); 515 retVal = mapItem; 516 517 return retVal; 519 } 520 521 542 549 public List getMapItemList() { 550 return _mapItemList; 553 } 554 555 public void setMapItemList(List mapItemList) { 556 _mapItemList = mapItemList; 559 } 560 561 public void setNumbering(Numbering numbering) { 562 _numbering = numbering; 563 } 564 565 public List getSortList() { 566 Debug.assertTrue(null != _numbering, "null != _numbering"); 567 return _numbering.getSortList(); 568 } 569 570 public MapItem map(String path) { 571 573 MapItem retVal = null; 574 for (int i = 0; i < _mapItemList.size(); i++) { 575 MapItem mapItem = (MapItem) _mapItemList.get(i); 576 if (path.equals(mapItem.getPath())) { 577 retVal = mapItem; 578 break; 579 } 580 } 581 582 return retVal; 584 } 585 586 public MapItem findMapItem(String itemName) { 587 589 MapItem retVal = null; 590 for (int i = 0; i < _mapItemList.size(); i++) { 591 MapItem mapItem = (MapItem) _mapItemList.get(i); 592 if (itemName.equals(mapItem.getItemName())) { 593 retVal = mapItem; 594 break; 595 } 596 } 597 598 return retVal; 600 } 601 602 public List getChildren(MapItem mapItem) { 603 List retVal = null; 605 606 optimize(); 607 retVal = mapItem.getChildItemList(); 608 609 return retVal; 611 } 612 613 protected MapItem createMapItem(AttributeExpression attribute) { 614 616 MapItem mapItem = new MapItem(); 617 618 XQueryExpression xExpr = attribute.getOrginalXExpr(); 619 mapItem.setPath(xExpr.getStringValue()); 620 621 QType qtype = xExpr.getQType(); 622 if (qtype instanceof QTypeElement) { 623 QTypeElement qte = (QTypeElement) xExpr.getQType(); 624 mapItem.setQName((QName) qte.getName()); 625 } 626 627 629 mapItem.setItemName(attribute.getName()); 630 mapItem.setRelatedExpression(attribute); 631 632 addMapItem(mapItem); 633 634 return mapItem; 636 } 637 638 protected MapItem createMapItem(RenameItem rename) { 639 641 MapItem mapItem = new MapItem(); 642 643 XQueryExpression xExpr = rename.getOrginalXExpr(); 644 mapItem.setPath(xExpr.toString()); 645 646 QType qtype = xExpr.getQType(); 647 if (qtype instanceof QTypeElement) { 648 QTypeElement qte = (QTypeElement) xExpr.getQType(); 649 mapItem.setQName((QName) qte.getName()); 650 } 651 652 mapItem.setItemName(rename.getName()); 653 mapItem.setRelatedExpression(rename); 654 655 addMapItem(mapItem); 656 657 return mapItem; 659 } 660 661 public void write(DataOutputStream dos) throws java.io.IOException { 662 664 String newLine = System.getProperty("line.separator"); 665 666 MapItem mapItem = null; 667 668 dos.writeBytes("<Mapper>"); 669 dos.writeBytes(newLine); 670 dos.writeBytes("<MapItemList>"); 671 dos.writeBytes(newLine); 672 for (int i = 0; i < _mapItemList.size(); i++) { 673 mapItem = (MapItem) _mapItemList.get(i); 674 mapItem.write(dos); 675 } 676 dos.writeBytes("</MapItemList>"); 677 dos.writeBytes(newLine); 678 679 if (null != _idList) { 680 dos.writeBytes("<IdList>"); 681 dos.writeBytes(newLine); 682 for (int i = 0; i < _idList.size(); i++) { 683 mapItem = (MapItem) _idList.get(i); 684 mapItem.write(dos); 685 } 686 dos.writeBytes("</IdList>"); 687 dos.writeBytes(newLine); 688 } 689 690 if (null != _mapItemAddedForId) { 691 dos.writeBytes("<MapItemAddedForId>"); 692 dos.writeBytes(newLine); 693 for (int i = 0; i < _mapItemAddedForId.size(); i++) { 694 mapItem = (MapItem) _mapItemAddedForId.get(i); 695 mapItem.write(dos); 696 } 697 dos.writeBytes("</MapItemAddedForId>"); 698 dos.writeBytes(newLine); 699 } 700 701 if (null != _partAttribute) { 702 dos.writeBytes("<PartAttribute>"); 703 dos.writeChars(_partAttribute.getName()); 704 dos.writeBytes("</PartAttribute>"); 705 dos.writeBytes(newLine); 706 } 707 708 dos.writeBytes("</Mapper>"); 709 dos.writeBytes(newLine); 710 711 } 713 714 public String pprint() { 715 StringBuffer retVal = new StringBuffer (); 717 718 retVal.append("\n===================== mapper ==========================================================\n"); 719 retVal.append("No. path, tag, item name, part children,\n"); 720 retVal.append("\n-------------------------------------------------------------------------------------------------\n"); 721 for (int i = 0; i < _mapItemList.size(); i++) { 722 MapItem mapItem = (MapItem) _mapItemList.get(i); 723 retVal.append(Integer.toString(i + 1)); 724 retVal.append("\t"); 725 retVal.append(mapItem.pprint()); 726 retVal.append("\n"); 727 728 } 729 retVal.append("\n_mapItemAddedForId-----------------------------------------------------------------------------------\n"); 730 if (null != _mapItemAddedForId) { 731 for (int i = 0; i < _mapItemAddedForId.size(); i++) { 732 MapItem mapItem = (MapItem) _mapItemAddedForId.get(i); 733 retVal.append(Integer.toString(i + 1)); 734 retVal.append("\t"); 735 retVal.append(mapItem.pprint()); 736 retVal.append("\n"); 737 } 738 } 739 retVal.append("\n_idList-------------------------------------------------------------------------------------------\n"); 740 if (null != _mapItemAddedForId) { 741 for (int i = 0; i < _idList.size(); i++) { 742 MapItem mapItem = (MapItem) _idList.get(i); 743 retVal.append(Integer.toString(i + 1)); 744 retVal.append("\t"); 745 retVal.append(mapItem.pprint()); 746 retVal.append("\n"); 747 } 748 } 749 retVal.append("\n=================================================================================================\n"); 750 return retVal.toString(); 752 } 753 754 protected void addMapItem(MapItem mapItem) { 755 757 String path = mapItem.getPath(); 758 MapItem mapItemB = map(path); 759 if (null != mapItemB) { 760 } else { 761 _mapItemList.add(mapItem); 762 } 763 764 } 766 767 public void setPart(long part) { 768 770 for (int i = 0; i < _mapItemList.size(); i++) { 771 MapItem mapItem = (MapItem) _mapItemList.get(i); 772 mapItem.setPart(part); 773 } 774 775 } 777 778 public void merge(Mapper mapper) { 779 if (null != mapper) { 781 782 List mapItemList = mapper.getMapItemList(); 783 for (int i = 0; i < mapItemList.size(); i++) { 784 MapItem mapItemToBeMerged = (MapItem) mapItemList.get(i); 785 MapItem mapItem = map(mapItemToBeMerged.getPath()); 786 if (null != mapItem) { 787 788 long mapItemPart = mapItem.getPart(); 789 long mapItemToBeMergedPart = mapItemToBeMerged.getPart(); 790 mapItem.setPart(mapItemToBeMergedPart | mapItemPart); 791 } else { 792 _mapItemList.add(mapItemToBeMerged); 793 } 794 } 795 796 797 List idList = mapper.getIdentifierList(); 798 if (null != idList) { 799 for (int i = 0; i < idList.size(); i++) { 800 MapItem mapItemToBeMerged = (MapItem) idList.get(i); 801 int index = _idList.indexOf(mapItemToBeMerged); 802 if (-1 == index) { 803 804 _idList.add(mapItemToBeMerged); 805 806 807 808 index = mapper._mapItemAddedForId.indexOf(mapItemToBeMerged); 809 if (-1 != index) { 810 811 _mapItemAddedForId.add(mapItemToBeMerged); 812 813 } 814 if (!mapItemToBeMerged.isLeafPath()) { 815 List childrenItem = mapper.getChildren(mapItemToBeMerged); 816 for (int j = 0; j < childrenItem.size(); j++) { 817 MapItem childItem = (MapItem) childrenItem.get(j); 818 index = mapper._mapItemAddedForId.indexOf(childItem); 819 if (-1 != index) { 820 821 _mapItemAddedForId.add(childItem); 822 } 823 } 824 } 825 } else { 826 827 MapItem mapItem = (MapItem) _idList.get(index); 828 long mapItemPart = mapItem.getPart(); 829 long mapItemToBeMergedPart = mapItemToBeMerged.getPart(); 830 long combinedParts = mapItemToBeMergedPart | mapItemPart; 831 mapItem.setPart(combinedParts); 832 833 834 835 if (!mapItem.isLeafPath()) { 836 List chidrenItem = getChildren(mapItem); 837 for (int k = 0; k < chidrenItem.size(); k++) { 838 MapItem child = (MapItem) chidrenItem.get(k); 839 child.setPart(combinedParts); 840 } 841 } 842 843 } 844 } 845 } else { 846 } 848 849 850 _mapItemList.removeAll(_mapItemAddedForId); 851 _mapItemList.addAll(_mapItemAddedForId); 852 } 853 } 855 856 860 public void optimize() { 861 if (!_optimized) { 862 MapItem mapItem = null; 863 for (int i = 0; i < _mapItemList.size(); i++) { 864 mapItem = (MapItem) _mapItemList.get(i); 865 if (!mapItem.isLeafPath()) { 866 List childItemList = new ArrayList (); 867 MapItem childItem = null; 868 List childPathList = mapItem.getChildren(); 869 String path = null; 870 for (int j = 0; j < childPathList.size(); j++) { 871 path = (String ) childPathList.get(j); 872 childItem = (MapItem) map(path); 873 Debug.assertTrue(null != childItem, "null!=child"); 874 childItemList.add(childItem); 875 } 876 mapItem.setChildItemLis(childItemList); 877 } 878 } 879 _optimized = true; 880 } 881 } 882 } 883 | Popular Tags |