1 10 package org.mmbase.applications.xmlimporter; 11 12 import java.io.*; 13 import java.util.*; 14 15 import org.mmbase.module.Module; 16 import org.mmbase.module.core.MMObjectBuilder; 17 import org.mmbase.module.core.MMObjectNode; 18 import org.mmbase.module.core.MMBase; 19 import org.mmbase.module.core.TemporaryNodeManager; 20 import org.mmbase.module.core.TemporaryNodeManagerInterface; 21 import org.mmbase.module.core.TransactionManager; 22 import org.mmbase.module.core.TransactionManagerException; 23 import org.mmbase.applications.xmlimporter.SimilarObjectFinder; 24 import org.mmbase.applications.xmlimporter.ObjectMerger; 25 import org.mmbase.util.logging.Logger; 26 import org.mmbase.util.logging.Logging; 27 28 40 public class Transaction implements Runnable { 41 42 43 private static Logger log = Logging.getLoggerInstance(Transaction.class.getName()); 44 45 46 private static MMBase mmbase; 47 48 49 private static TemporaryNodeManagerInterface tmpNodeManager; 50 51 52 private static TransactionManager transactionManager; 53 54 55 private static long uniqueId = System.currentTimeMillis(); 56 57 58 private UserTransactionInfo uti; 59 60 61 protected Consultant consultant; 62 63 64 private String key; 65 66 67 private HashMap namedObjectContexts = new HashMap(); 68 69 70 private HashMap tmpObjects = new HashMap(); 71 72 75 private List lstTmpObjects = new LinkedList(); 76 77 78 private String id; 79 80 81 private boolean commitOnClose; 82 83 84 private long timeOut; 85 86 87 private File reportFile; 88 89 90 private StringBuffer reportBuffer = new StringBuffer (); 91 92 93 private Map mergedObjects = new HashMap(); 94 95 96 100 private boolean resolvedDuplicates = true; 101 102 103 private Thread kicker; 104 105 106 private boolean finished = false; 107 108 121 protected Transaction(UserTransactionInfo uti, String key, String id, 122 boolean commitOnClose, long timeOut, File reportFile, Consultant consultant) { 123 124 this.uti = uti; 125 this.key = key; 126 this.id = id; 127 this.commitOnClose = commitOnClose; 128 this.timeOut = timeOut; 129 this.reportFile = reportFile; 130 this.consultant = consultant; 131 start(); 132 } 133 134 145 protected Transaction(UserTransactionInfo uti, String key, String id, 146 boolean commitOnClose, long timeOut) { 147 148 this.uti = uti; 149 this.key = key; 150 this.id = id; 151 this.commitOnClose = commitOnClose; 152 this.timeOut = timeOut; 153 start(); 154 } 155 156 162 private static synchronized TransactionManager getTransactionManager() { 163 if (transactionManager == null) { 164 mmbase=(MMBase) Module.getModule("MMBASEROOT"); 165 tmpNodeManager = new TemporaryNodeManager(mmbase); 166 transactionManager = new TransactionManager(mmbase,tmpNodeManager); 167 } 168 return transactionManager; 169 } 170 171 182 public static Transaction createTransaction(UserTransactionInfo uti, 183 String id, boolean commitOnClose, long timeOut) 184 throws TransactionHandlerException { 185 186 boolean anonymous = (id == null); 189 if (anonymous) { 190 id = "AnTr" + uniqueId++; } 192 193 if (uti.knownTransactionContexts.get(id) != null) { 195 throw new TransactionHandlerException( 196 "Transaction id already exists: id = \"" + id + "\""); 197 } 198 199 String key = null; 201 try { 202 key = getTransactionManager().create(uti.user, id); 203 } catch (TransactionManagerException e) { 204 throw new TransactionHandlerException(e.getMessage()); 205 } 206 207 Transaction transaction 208 = new Transaction(uti, key, id, commitOnClose, timeOut); 209 210 if (!anonymous) { 213 uti.knownTransactionContexts.put(id, transaction); 214 } 215 216 if (log.isDebugEnabled()) { 217 log.debug("Transaction created: " + key); 218 } 219 return transaction; 220 } 221 222 236 public static Transaction createTransaction(UserTransactionInfo uti, 237 String id, boolean commitOnClose, long timeOut, File reportFile, 238 Consultant consultant) 239 throws TransactionHandlerException { 240 241 boolean anonymous = (id == null); 244 if (anonymous) { 245 id = "AnTr" + uniqueId++; } 247 248 if (uti.knownTransactionContexts.get(id) != null) { 250 throw new TransactionHandlerException( 251 "Transaction id already exists: id = \"" + id + "\""); 252 } 253 254 String key = null; 256 try { 257 key = getTransactionManager().create(uti.user, id); 258 } catch (TransactionManagerException e) { 259 throw new TransactionHandlerException(e.getMessage()); 260 } 261 262 Transaction transaction; 263 if (consultant != null && consultant.interactive()) { 264 transaction = new InteractiveTransaction(uti, key, id, commitOnClose, 265 timeOut, reportFile, consultant); 266 } else { 267 transaction = new Transaction(uti, key, id, commitOnClose, 268 timeOut, reportFile, consultant); 269 } 270 271 if (!anonymous) { 274 uti.knownTransactionContexts.put(id, transaction); 275 } 276 277 if (log.isDebugEnabled()) { 278 log.debug("Transaction created: " + key); 279 } 280 return transaction; 281 } 282 283 294 public static Transaction openTransaction(UserTransactionInfo uti, 295 String id, boolean commitOnClose) throws TransactionHandlerException { 296 297 if (!uti.knownTransactionContexts.containsKey(id)) { 299 throw new TransactionHandlerException( 300 "Transaction id does not exist: id = \"" + id + "\""); 301 } 302 303 Transaction tr = (Transaction) uti.knownTransactionContexts.get(id); 305 tr.commitOnClose = commitOnClose; 306 return tr; 307 } 308 309 315 public void leave() throws TransactionHandlerException { 316 317 if (log.isDebugEnabled()) { 318 log.debug("About to leave transaction: " + key); 319 } 320 321 if (commitOnClose) { 322 commit(); 323 } 324 } 325 326 336 public void commit() throws TransactionHandlerException { 337 if (consultant != null 338 && consultant.getImportStatus() == Consultant.IMPORT_TIMED_OUT) { 339 throw new TransactionHandlerException("Transaction with id=" 340 + id + " is timed out after " + timeOut + " seconds."); 341 } 342 343 try { 345 if (resolvedDuplicates) { 346 transactionManager.commit(uti.user, id); 348 if (log.isDebugEnabled()) { 349 log.debug("transaction committed: " + key 350 + "\n" + reportBuffer.toString()); 351 } 352 } else { 353 356 log.warn("transaction not committed: " + key 357 + "\n" + reportBuffer.toString()); 358 359 if (reportFile != null) { 361 Writer out = null; 362 try { 363 out = new BufferedWriter(new OutputStreamWriter( 364 new FileOutputStream(reportFile.getPath(),true))); 365 out.write(reportBuffer.toString()); 366 } catch (Exception e) { 367 throw new TransactionHandlerException( 368 "Failed to append reportfile "+reportFile+": "+e); 369 } finally { 370 if (out != null) { 371 try { 372 out.close(); 373 } catch (IOException e) { 374 throw new TransactionHandlerException( 375 "Failed to close reportfile "+reportFile+": "+e); 376 } 377 } 378 } 379 } 380 else { 381 if (log.isDebugEnabled()) { 382 log.debug("reportFile NULL"); 383 } 384 } 385 386 } 387 } catch (TransactionManagerException e) { 388 throw new TransactionHandlerException(e.getMessage()); 389 } finally { 390 stop(); 391 } 392 393 uti.knownTransactionContexts.remove(id); 395 } 396 397 405 public void delete() throws TransactionHandlerException { 406 if (consultant != null 407 && consultant.getImportStatus() == Consultant.IMPORT_TIMED_OUT) { 408 throw new TransactionHandlerException("Transaction with id=" 409 + id + " is timed out after " + timeOut + " seconds."); 410 } 411 try { 413 transactionManager.cancel(uti.user, id); 414 } catch (TransactionManagerException e) { 415 throw new TransactionHandlerException(e.getMessage()); 416 } finally { 417 stop(); 418 } 419 420 uti.knownTransactionContexts.remove(id); 422 423 if (log.isDebugEnabled()) { 424 log.debug("Transaction deleted: " + key); 425 } 426 } 427 428 441 public TmpObject createObject(String objectId, String type, 442 boolean disposeWhenNotReferenced) 443 throws TransactionHandlerException { 444 445 boolean anonymous = (objectId == null); 448 if (anonymous) { 449 objectId = "AnOb" + uniqueId++; } 451 452 if (namedObjectContexts.get(objectId) != null) { 454 throw new TransactionHandlerException( 455 "Object id already exists: id = \"" + objectId + "\""); 456 } 457 458 tmpNodeManager.createTmpNode(type, uti.user.getName(), objectId); 460 TmpObject tmpObject = 461 new TmpObject(uti, objectId, false, disposeWhenNotReferenced); 462 463 try { 465 transactionManager.addNode(key, uti.user.getName(), objectId); 466 } catch (TransactionManagerException e) { 467 tmpNodeManager.deleteTmpNode(uti.user.getName(), objectId); 468 throw new TransactionHandlerException(e.getMessage()); 469 } 470 tmpObjects.put(tmpObject.getKey(), tmpObject); 471 lstTmpObjects.add(tmpObject); 472 473 if (!anonymous) { 476 namedObjectContexts.put(objectId, tmpObject); 477 } 478 479 if (log.isDebugEnabled()) { 480 log.debug("Object created: " + tmpObject); 481 } 482 return tmpObject; 483 } 484 485 501 public TmpObject createRelation(String objectId, String type, String source, 502 String destination) throws TransactionHandlerException { 503 504 boolean anonymous = (objectId == null); 507 if (anonymous) { 508 objectId = "AnRel" + uniqueId++; } 510 511 if (namedObjectContexts.get(objectId) != null) { 513 throw new TransactionHandlerException( 514 "Object id already exists: id = \"" + objectId + "\""); 515 } 516 517 if (namedObjectContexts.get(source) == null) { 519 throw new TransactionHandlerException( 520 "Unknown source object id: id = \"" + source + "\""); 521 } 522 523 if (namedObjectContexts.get(destination) == null) { 524 throw new TransactionHandlerException( 525 "Unknown destination object id: id = \"" + destination + "\""); 526 } 527 528 try { 530 tmpNodeManager.createTmpRelationNode( 531 type, uti.user.getName(), objectId, source, destination); 532 } catch (Exception e) { 533 throw new TransactionHandlerException( 534 "Type \"" + type + "\" is not a proper relation."); 535 } 536 TmpObject tmpObject = new TmpObject(uti, objectId, true, false); 537 538 try { 540 transactionManager.addNode(key, uti.user.getName(), objectId); 541 } catch (TransactionManagerException e) { 542 tmpNodeManager.deleteTmpNode(uti.user.getName(), objectId); 543 throw new TransactionHandlerException(e.getMessage()); 544 } 545 tmpObjects.put(tmpObject.getKey(), tmpObject); 546 lstTmpObjects.add(tmpObject); 547 548 if (!anonymous) { 551 namedObjectContexts.put(objectId, tmpObject); 552 } 553 554 if (log.isDebugEnabled()) { 555 log.debug("Relation created: " + tmpObject); 556 } 557 return tmpObject; 558 } 559 560 567 public TmpObject openObject(String objectId) 568 throws TransactionHandlerException { 569 570 if (namedObjectContexts.get(objectId) == null) { 572 throw new TransactionHandlerException( 573 "Object id does not exist: id = \"" + objectId + "\""); 574 } 575 576 TmpObject tmpObj = (TmpObject) namedObjectContexts.get(objectId); 577 578 if (log.isDebugEnabled()) { 579 log.debug("Opened object: " + tmpObj); 580 } 581 582 return tmpObj; 583 } 584 585 600 public TmpObject accessObject(String objectId, int mmbaseId) 601 throws TransactionHandlerException { 602 boolean anonymous = (objectId == null); 605 if (anonymous) { 606 objectId = "AnOb_" + uniqueId++; } 608 609 if (namedObjectContexts.get(objectId) != null) { 614 TmpObject namedObject 615 = (TmpObject) namedObjectContexts.get(objectId); 616 if (namedObject.getMMBaseId() == mmbaseId) { 617 return namedObject; 620 } 621 622 throw new TransactionHandlerException( 624 "Object id already used for another object: id = \"" 625 + objectId + "\""); 626 } 627 628 TmpObject tmpObject = null; 630 try { 631 tmpNodeManager.getObject( 632 uti.user.getName(), objectId, Integer.toString(mmbaseId)); 633 tmpObject = new TmpObject(uti, objectId, mmbaseId); 634 } catch (Exception e) { 635 throw new TransactionHandlerException( 637 "Can't find object with mmbase id " + mmbaseId + " - " 638 + e.getMessage()); 639 } 640 641 try { 643 transactionManager.addNode(key, uti.user.getName(), objectId); 644 } catch (TransactionManagerException e) { 645 tmpNodeManager.deleteTmpNode(uti.user.getName(), objectId); 646 throw new TransactionHandlerException(e.getMessage()); 647 } 648 tmpObjects.put(tmpObject.getKey(), tmpObject); 649 lstTmpObjects.add(tmpObject); 650 651 if (!anonymous) { 654 namedObjectContexts.put(objectId, tmpObject); 655 } 656 657 if (log.isDebugEnabled()) { 658 log.debug("Access object created: " + tmpObject); 659 } 660 return tmpObject; 661 } 662 663 675 public void deleteObject(TmpObject tmpObject) 676 throws TransactionHandlerException { 677 678 try { 680 transactionManager.removeNode( 681 key, uti.user.getName(), tmpObject.getId()); 682 } catch (TransactionManagerException e) { 683 throw new TransactionHandlerException(e.getMessage()); 684 } 685 tmpNodeManager.deleteTmpNode(uti.user.getName(), tmpObject.getId()); 686 tmpObjects.remove(tmpObject.getKey()); 687 lstTmpObjects.remove(tmpObject); 688 689 namedObjectContexts.remove(tmpObject.getId()); 691 692 Iterator i = getRelations(tmpObject).iterator(); 694 while (i.hasNext()) { 695 TmpObject relation = (TmpObject) i.next(); 696 if (stillExists(relation)) { 697 if (log.isDebugEnabled()) { 698 log.debug("About to delete relation " + relation 699 + " because the referenced object " 700 + tmpObject.getKey() + " is deleted."); 701 } 702 deleteObject(relation); 703 } 704 } 705 706 if (tmpObject.isRelation()) { 708 Object _snumber = tmpObject.getField(TmpObject._SNUMBER); 711 if (!_snumber.equals("")) { 712 TmpObject source = (TmpObject) tmpObjects.get(_snumber); 713 dropIfRequested(source); 714 } 715 716 Object _dnumber = tmpObject.getField(TmpObject._DNUMBER); 719 if (!_dnumber.equals("")) { 720 TmpObject destination = (TmpObject) tmpObjects.get(_dnumber); 721 dropIfRequested(destination); 722 } 723 } 724 725 if (log.isDebugEnabled()) { 726 log.debug("Object deleted: " + tmpObject); 727 } 728 } 729 730 736 public void markDeleteObject(TmpObject tmpObject, boolean deleteRelations) 737 throws TransactionHandlerException { 738 try { 740 transactionManager.deleteObject( 741 key, uti.user.getName(), tmpObject.getId()); 742 } catch (TransactionManagerException e) { 743 throw new TransactionHandlerException(e.getMessage()); 744 } 745 746 Iterator iRelations = getRelations(tmpObject).iterator(); 748 while (iRelations.hasNext()) { 749 TmpObject relation = (TmpObject) iRelations.next(); 750 if (relation.isAccessObject()) { 751 if (!deleteRelations) { 753 throw new TransactionHandlerException( 756 "Object has relation(s) attached to it " 757 + "(use deleteRelations=\"true\")."); 758 } else { 759 markDeleteObject(relation, true); 761 } 762 } 763 } 764 765 tmpNodeManager.deleteTmpNode(uti.user.getName(), tmpObject.getId()); 767 tmpObjects.remove(tmpObject.getKey()); 768 lstTmpObjects.remove(tmpObject); 769 770 namedObjectContexts.remove(tmpObject.getId()); 772 773 if (log.isDebugEnabled()) { 774 log.debug("Access object marked for deletion: " 775 + tmpObject); 776 } 777 } 778 779 788 public void mergeObjects(String objectType, SimilarObjectFinder finder, 789 ObjectMerger merger) throws TransactionHandlerException { 790 791 MMObjectBuilder builder = mmbase.getMMObject(objectType); 792 793 TmpObject[] objects = (TmpObject[])lstTmpObjects.toArray(new TmpObject[0]); 795 796 for (int i = 0; i < objects.length; i++) { 798 TmpObject tempObj1 = objects[i]; 799 800 if ( stillExists(tempObj1) && 802 tempObj1.getNode().getName().equals(objectType)) { 803 804 List similarObjects = finder.findSimilarObject(this, tempObj1); 806 807 if (similarObjects.size() == 1) { 808 TmpObject tempObj2 = (TmpObject) similarObjects.get(0); 810 merge(tempObj2, tempObj1, merger); 814 } else if (similarObjects.size() > 1) { 815 log.warn("More than one similar object found: " + similarObjects); 817 818 resolvedDuplicates = resolvedDuplicates && handleDuplicates( 819 tempObj1, similarObjects, merger); 820 if (!resolvedDuplicates) { 821 break; 822 } 823 } else if (similarObjects.size() == 0) { 824 if (!merger.isAllowedToAdd(tempObj1)) { 826 deleteObject(tempObj1); 827 } 828 } 829 } 830 } 831 832 if (log.isDebugEnabled()) { 833 log.debug("All objects of type " + objectType + " merged."); 834 } 835 } 836 837 852 protected boolean handleDuplicates(TmpObject tempObj, List similarObjects, 853 ObjectMerger merger) throws TransactionHandlerException { 854 if (consultant != null ) { 856 consultant.setDuplicatesFound(true); 857 } 858 appendReportBuffer("\n"+"<!-- *** DUPLICATES FOUND START *** -->\n"); 859 appendReportBuffer("what follows:\n"); 860 appendReportBuffer("- the original object\n"); 861 appendReportBuffer("- similar object blocks\n"); 862 appendReportBuffer("where a similar object block holds: " + 863 "a mergecandidate and a mergeresult\n"); 864 appendReportBuffer("and a mergeresult is thew result of a merge of " + 865 "original object and mergecandidate -->\n\n"); 866 867 appendReportBuffer("<!-- *** original object *** -->\n"); 868 appendReportBuffer(tempObj.toXML()+"\n"); 869 870 Iterator iter = similarObjects.iterator(); 871 while (iter.hasNext() ) { 872 TmpObject similarObject = (TmpObject)iter.next(); 873 appendReportBuffer("<!-- *** start similar object block *** -->\n\n"); 874 appendReportBuffer("<!-- *** mergeCandidate *** -->\n"); 875 appendReportBuffer(similarObject.toXML() + "\n"); 876 appendReportBuffer("<!-- *** mergeResult *** -->\n"); 877 appendReportBuffer(caculateMerge(similarObject, tempObj, merger).toXML() + "\n"); 878 appendReportBuffer("<!-- *** end similar object block *** -->\n\n"); 879 } 880 appendReportBuffer("<!-- *** DUPLICATES FOUND END *** -->\n\n"); 881 return false; 882 } 883 884 896 protected TmpObject caculateMerge(TmpObject tempObj1, TmpObject tempObj2, ObjectMerger merger){ 897 if (!tempObj1.isAccessObject() && tempObj2.isAccessObject()) { 902 TmpObject to = tempObj1; 903 tempObj1 = tempObj2; 904 tempObj2 = to; 905 } 906 907 if (log.isDebugEnabled()) { 908 log.debug("About to calculate merge objects: " + tempObj1.getKey() 909 + "(target) and " + tempObj2.getKey()); 910 } 911 912 Iterator fieldNames = tempObj1.getNode().getBuilder().getFieldNames().iterator(); 914 while (fieldNames.hasNext()) { 915 String fieldName = (String ) fieldNames.next(); 916 917 if (!fieldName.equals("number") && !fieldName.equals("owner")) { 919 merger.mergeField(tempObj1, tempObj2, fieldName); 920 } 921 } 922 923 if (log.isDebugEnabled()) { 924 log.debug("Calculate merge finished for objects:\n target: " + tempObj1.getKey() 925 + " with object: " + tempObj2.getKey()); 926 } 927 return tempObj1; 928 } 929 930 942 public void merge(TmpObject tempObj1, TmpObject tempObj2, ObjectMerger merger) throws TransactionHandlerException { 943 if (!tempObj1.isAccessObject() && tempObj2.isAccessObject()) { 949 TmpObject to = tempObj1; 950 tempObj1 = tempObj2; 951 tempObj2 = to; 952 } 953 954 if (log.isDebugEnabled()) { 955 log.debug("About to merge objects: " + tempObj1.getKey() 956 + "(target) and " + tempObj2.getKey()); 957 } 958 959 Iterator fieldNames = tempObj1.getNode().getBuilder().getFieldNames().iterator(); 961 while (fieldNames.hasNext()) { 962 String fieldName = (String ) fieldNames.next(); 963 964 if (!fieldName.equals("number") && !fieldName.equals("owner")) { 966 merger.mergeField(tempObj1, tempObj2, fieldName); 967 } 968 } 969 if (log.isDebugEnabled()) { 970 log.debug("Fields merged of objects: " + tempObj1.getKey() 971 + "(target) and " + tempObj2.getKey()); 972 } 973 974 merger.mergeRelations(tempObj1, tempObj2, 976 getRelations(tempObj1), getRelations(tempObj2)); 977 978 if (log.isDebugEnabled()) { 979 log.debug("Relations merged of objects: " + tempObj1.getKey() 980 + "(target) and " + tempObj2.getKey()); 981 } 982 List relations = getRelations(tempObj1); 984 for (int i = 0; i < relations.size(); i++) { 985 986 TmpObject relation1 = (TmpObject) relations.get(i); 988 989 if (!stillExists(relation1)) { 991 continue; 992 } 993 994 for (int i2 = i + 1; i2 < relations.size(); i2++) { 996 TmpObject relation2 = (TmpObject) relations.get(i2); 997 998 if (log.isDebugEnabled()) { 999 log.debug("Relation1: " + relation1); 1000 log.debug("Relation2: " + relation2); 1001 log.debug("equalRelations: " + equalRelations(relation1, relation2)); 1002 } 1003 1004 if (stillExists(relation2) 1005 && equalRelations(relation1, relation2) 1006 && merger.areDuplicates(relation1, relation2)) { 1007 if (!relation1.isAccessObject()) { 1010 if (log.isDebugEnabled()) { 1011 log.debug("About to delete duplicate relation: " 1012 + relation1.getKey()); 1013 } 1014 deleteObject(relation1); 1015 } else { 1016 if (relation2.isAccessObject()) { 1017 if (log.isDebugEnabled()) { 1018 log.debug("About to mark for deletion " 1019 + "duplicate relation: " 1020 + relation2.getKey()); 1021 } 1022 markDeleteObject(relation2, false); 1023 } else { 1024 if (log.isDebugEnabled()) { 1025 log.debug("About to delete duplicate relation: " 1026 + relation2.getKey()); 1027 } 1028 deleteObject(relation2); 1029 } 1030 } 1031 } 1032 } 1033 } 1034 1035 if (tempObj2.isAccessObject()) { 1037 if (log.isDebugEnabled()) { 1039 log.debug("About to mark object " + tempObj2.getKey() 1040 + "for deletion, having merged it with " 1041 + tempObj1.getKey()); 1042 } 1043 markDeleteObject(tempObj2, true); 1044 } else { 1045 if (log.isDebugEnabled()) { 1047 log.debug("About to delete object " + tempObj2.getKey() 1048 + ", having merged it with " + tempObj1.getKey()); 1049 } 1050 deleteObject(tempObj2); 1051 } 1052 1053 if (log.isDebugEnabled()) { 1054 log.debug("Objects merged: " + tempObj1.getKey() 1055 + "(target) and " + tempObj2.getKey()); 1056 } 1057 1058 mergedObjects.put(tempObj2, tempObj1); 1062 } 1063 1064 1074 public TmpObject getAccessObject(int mmbaseId) 1075 throws TransactionHandlerException { 1076 if (mmbaseId == -1) { 1078 return null; 1079 } 1080 Iterator i = lstTmpObjects.iterator(); 1082 while (i.hasNext()) { 1083 TmpObject tmpObject = (TmpObject) i.next(); 1084 if (tmpObject.getMMBaseId() == mmbaseId) { 1085 return tmpObject; 1087 } 1088 } 1089 1090 return accessObject(null, mmbaseId); 1092 } 1093 1094 1102 public List getRelations(TmpObject tmpObject) 1103 throws TransactionHandlerException { 1104 1105 List accessObjects = new ArrayList(); 1106 1107 if (tmpObject.isAccessObject()) { 1109 Vector relations = tmpObject.getRelationsInPersistentCloud(); 1110 Iterator i = relations.iterator(); 1111 while (i.hasNext()) { 1112 MMObjectNode relation = (MMObjectNode) i.next(); 1113 1114 getAccessObject(relation.getIntValue("number")); 1120 } 1121 } 1122 1123 Iterator i2 = lstTmpObjects.iterator(); 1127 while (i2.hasNext()) { 1128 TmpObject tmpObj2 = (TmpObject) i2.next(); 1129 if (tmpObj2.isRelation() 1130 && (tmpObject.isSourceOf(tmpObj2) 1131 || tmpObject.isDestinationOf(tmpObj2))) { 1132 1133 accessObjects.add(tmpObj2); 1135 } 1136 } 1137 return accessObjects; 1138 } 1139 1140 1148 void dropIfRequested(TmpObject tmpObject) 1149 throws TransactionHandlerException { 1150 if (stillExists(tmpObject) && !tmpObject.isAccessObject() && getRelations(tmpObject).size() == 0 && tmpObject.getDisposeWhenNotReferenced()) { 1155 if (log.isDebugEnabled()) { 1157 log.debug("About to delete object " + tmpObject.getKey() 1158 + " because it has become unreferenced."); 1159 } 1160 deleteObject(tmpObject); 1161 } 1162 } 1163 1164 1175 protected boolean equalRelations(TmpObject tmpObj1, TmpObject tmpObj2) { 1176 if (!tmpObj1.isRelation() || !tmpObj2.isRelation()) { 1178 return false; 1179 } 1180 1181 if (tmpObj1.getNode().getIntValue(TmpObject.RNUMBER) 1183 != tmpObj2.getNode().getIntValue(TmpObject.RNUMBER)) { 1184 return false; 1185 } 1186 1187 String sourceId = tmpObj1.getNode().getStringValue(TmpObject._SNUMBER); 1189 if (!sourceId.equals("")) { 1190 TmpObject source = (TmpObject) tmpObjects.get(sourceId); 1192 if (!source.isSourceOf(tmpObj2)) { 1193 return false; 1194 } 1195 } else { 1196 sourceId = tmpObj2.getNode().getStringValue(TmpObject._SNUMBER); 1197 if (!sourceId.equals("")) { 1198 TmpObject source = (TmpObject) tmpObjects.get(sourceId); 1200 if (!source.isSourceOf(tmpObj1)) { 1201 return false; 1202 } 1203 } else { 1204 if (!tmpObj1.getNode().getStringValue(TmpObject.SNUMBER).equals( 1206 tmpObj2.getNode().getStringValue(TmpObject.SNUMBER))) { 1207 return false; 1208 } 1209 } 1210 } 1211 1212 String destinationId 1214 = tmpObj1.getNode().getStringValue(TmpObject._DNUMBER); 1215 if (!destinationId.equals("")) { 1216 TmpObject destination = (TmpObject) tmpObjects.get(destinationId); 1218 if (!destination.isDestinationOf(tmpObj2)) { 1219 return false; 1220 } 1221 } else { 1222 destinationId = tmpObj2.getNode().getStringValue(TmpObject._DNUMBER); 1223 if (!destinationId.equals("")) { 1224 TmpObject destination = (TmpObject) tmpObjects.get(destinationId); 1226 if (!destination.isDestinationOf(tmpObj1)) { 1227 return false; 1228 } 1229 } else { 1230 if (!tmpObj1.getNode().getStringValue(TmpObject.DNUMBER).equals( 1232 tmpObj2.getNode().getStringValue(TmpObject.DNUMBER))) { 1233 return false; 1234 } 1235 } 1236 } 1237 1238 return true; 1239 } 1240 1241 1247 protected boolean stillExists(TmpObject tmpObject) { 1248 return lstTmpObjects.contains(tmpObject); 1249 } 1250 1251 1255 public String getKey() { 1256 return key; 1257 } 1258 1259 1263 HashMap getObjectContexts() { 1264 return namedObjectContexts; 1265 } 1266 1267 1271 public List getTmpObjects() { 1272 return Collections.unmodifiableList(lstTmpObjects); 1273 } 1274 1275 1283 public TmpObject getMergedObject(TmpObject tempObj1) { 1284 TmpObject tempObj2 = (TmpObject) mergedObjects.get(tempObj1); 1285 if (tempObj2 == null) { 1286 tempObj2 = tempObj1; 1287 } 1288 return tempObj2; 1289 } 1290 1291 1295 public void appendReportBuffer(String str) { 1296 reportBuffer.append(str); 1297 } 1298 1299 1303 protected void start() { 1304 if (kicker == null) { 1305 kicker = new Thread (this, "TR " + key); 1306 kicker.start(); 1307 } 1308 } 1309 1310 1313 protected synchronized void stop() { 1314 1315 kicker = null; 1316 finished = true; 1317 this.notify(); 1318 1319 log.info("Stop transaction: " + new Date().toString()); 1320 } 1321 1322 1326 public void run() { 1327 synchronized(this) { 1328 try { 1329 wait(timeOut*1000); 1330 } catch (InterruptedException e) { 1331 } 1332 uti.knownTransactionContexts.remove(id); 1333 1334 if (!finished) { 1335 if (consultant != null) { 1336 consultant.setImportStatus(Consultant.IMPORT_TIMED_OUT); 1337 } 1338 log.warn("Transaction with id=" + id + " is timed out after " 1339 + timeOut + " seconds."); 1340 } 1341 } 1342 } 1343} 1344 | Popular Tags |