1 21 package oracle.toplink.essentials.internal.sessions; 23 24 import java.util.*; 25 import oracle.toplink.essentials.mappings.*; 26 import oracle.toplink.essentials.internal.helper.*; 27 import oracle.toplink.essentials.queryframework.*; 28 import oracle.toplink.essentials.exceptions.*; 29 import oracle.toplink.essentials.internal.localization.*; 30 import oracle.toplink.essentials.descriptors.ClassDescriptor; 31 32 35 public class CommitManager { 36 protected Vector commitOrder; 37 38 43 protected IdentityHashtable processedCommits; 44 protected IdentityHashtable pendingCommits; 45 protected IdentityHashtable preModifyCommits; 46 protected IdentityHashtable postModifyCommits; 47 protected IdentityHashtable completedCommits; 48 protected IdentityHashtable shallowCommits; 49 protected AbstractSession session; 50 protected boolean isActive; 51 protected Hashtable dataModifications; 52 protected Vector objectsToDelete; 53 54 58 public CommitManager(AbstractSession session) { 59 this.session = session; 60 this.commitOrder = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(); 61 this.isActive = false; 62 63 } 71 72 76 public void addDataModificationEvent(DatabaseMapping mapping, Object [] event) { 77 if (!getDataModifications().containsKey(mapping)) { 79 getDataModifications().put(mapping, new Vector()); 80 } 81 82 ((Vector)getDataModifications().get(mapping)).addElement(event); 83 } 84 85 88 public void addObjectToDelete(Object objectToDelete) { 89 getObjectsToDelete().addElement(objectToDelete); 90 } 91 92 95 protected void addProcessedCommit(Object domainObject) { 96 getProcessedCommits().put(domainObject, domainObject); 97 } 98 99 103 public void commitAllObjects(IdentityHashtable domainObjects) throws RuntimeException , DatabaseException, OptimisticLockException { 104 reinitialize(); 105 setPendingCommits(domainObjects); 106 107 setIsActive(true); 108 getSession().beginTransaction(); 109 try { 110 for (Enumeration classesEnum = getCommitOrder().elements(); 112 classesEnum.hasMoreElements();) { 113 Class theClass = (Class )classesEnum.nextElement(); 114 115 for (Enumeration pendingEnum = getPendingCommits().elements(); 116 pendingEnum.hasMoreElements();) { 117 Object objectToWrite = pendingEnum.nextElement(); 118 if (objectToWrite.getClass() == theClass) { 119 removePendingCommit(objectToWrite); 121 WriteObjectQuery commitQuery = new WriteObjectQuery(); 122 commitQuery.setObject(objectToWrite); 123 if (getSession().isUnitOfWork()) { 124 commitQuery.cascadeOnlyDependentParts(); 125 } else { 126 commitQuery.cascadeAllParts(); } 128 getSession().executeQuery(commitQuery); 129 } 130 } 131 } 132 133 for (Enumeration mappingsEnum = getDataModifications().keys(), mappingEventsEnum = getDataModifications().elements(); 134 mappingEventsEnum.hasMoreElements();) { 135 Vector events = (Vector)mappingEventsEnum.nextElement(); 136 DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement(); 137 for (Enumeration eventsEnum = events.elements(); eventsEnum.hasMoreElements();) { 138 Object [] event = (Object [])eventsEnum.nextElement(); 139 mapping.performDataModificationEvent(event, getSession()); 140 } 141 } 142 143 Vector objects = getObjectsToDelete(); 144 reinitialize(); 145 for (Enumeration objectsToDeleteEnum = objects.elements(); 146 objectsToDeleteEnum.hasMoreElements();) { 147 getSession().deleteObject(objectsToDeleteEnum.nextElement()); 148 } 149 } catch (RuntimeException exception) { 150 getSession().rollbackTransaction(); 151 throw exception; 152 } finally { 153 reinitialize(); 154 setIsActive(false); 155 } 156 157 getSession().commitTransaction(); 158 } 159 160 164 public void commitAllObjectsWithChangeSet(UnitOfWorkChangeSet uowChangeSet) throws RuntimeException , DatabaseException, OptimisticLockException { 165 reinitialize(); 166 setIsActive(true); 167 getSession().beginTransaction(); 168 try { 169 if ((uowChangeSet.getObjectChanges().size() + uowChangeSet.getNewObjectChangeSets().size()) <= 1) { 172 Enumeration classes = uowChangeSet.getNewObjectChangeSets().keys(); 173 if (classes.hasMoreElements()) { 174 Class theClass = (Class )classes.nextElement(); 175 commitNewObjectsForClassWithChangeSet(uowChangeSet, theClass); 176 } 177 Enumeration classNames = uowChangeSet.getObjectChanges().keys(); 178 if (classNames.hasMoreElements()) { 179 String className = (String )classNames.nextElement(); 180 commitChangedObjectsForClassWithChangeSet(uowChangeSet, className); 181 } 182 } else { 183 for (Enumeration classesEnum = getCommitOrder().elements(); 185 classesEnum.hasMoreElements();) { 186 Class theClass = (Class )classesEnum.nextElement(); 187 commitAllObjectsForClassWithChangeSet(uowChangeSet, theClass); 188 } 189 } 190 191 if (hasDataModifications()) { 192 for (Enumeration mappingsEnum = getDataModifications().keys(), mappingEventsEnum = getDataModifications().elements(); 194 mappingEventsEnum.hasMoreElements();) { 195 Vector events = (Vector)mappingEventsEnum.nextElement(); 196 DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement(); 197 for (Enumeration eventsEnum = events.elements(); eventsEnum.hasMoreElements();) { 198 Object [] event = (Object [])eventsEnum.nextElement(); 199 mapping.performDataModificationEvent(event, getSession()); 200 } 201 } 202 } 203 204 if (hasObjectsToDelete()) { 205 Vector objects = getObjectsToDelete(); 206 reinitialize(); 207 for (Enumeration objectsToDeleteEnum = objects.elements(); 208 objectsToDeleteEnum.hasMoreElements();) { 209 getSession().deleteObject(objectsToDeleteEnum.nextElement()); 210 } 211 } 212 } catch (RuntimeException exception) { 213 getSession().rollbackTransaction(); 214 throw exception; 215 } finally { 216 reinitialize(); 217 setIsActive(false); 218 } 219 220 getSession().commitTransaction(); 221 } 222 223 227 protected void commitAllObjectsForClassWithChangeSet(UnitOfWorkChangeSet uowChangeSet, Class theClass) { 228 commitChangedObjectsForClassWithChangeSet(uowChangeSet, theClass.getName()); 231 commitNewObjectsForClassWithChangeSet(uowChangeSet, theClass); 232 } 233 234 238 protected void commitNewObjectsForClassWithChangeSet(UnitOfWorkChangeSet uowChangeSet, Class theClass) { 239 IdentityHashtable newObjectChangesList = (IdentityHashtable)uowChangeSet.getNewObjectChangeSets().get(theClass); 240 if (newObjectChangesList != null) { ClassDescriptor descriptor = getSession().getDescriptor(theClass); 242 for (Enumeration pendingEnum = newObjectChangesList.elements(); 243 pendingEnum.hasMoreElements();) { 244 ObjectChangeSet changeSetToWrite = (ObjectChangeSet)pendingEnum.nextElement(); 245 Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); 246 if ((!getProcessedCommits().containsKey(changeSetToWrite)) && (!getProcessedCommits().containsKey(objectToWrite))) { 247 addProcessedCommit(changeSetToWrite); 248 InsertObjectQuery commitQuery = new InsertObjectQuery(); 249 commitQuery.setObjectChangeSet(changeSetToWrite); 250 commitQuery.setObject(objectToWrite); 251 commitQuery.cascadeOnlyDependentParts(); 252 getSession().executeQuery(commitQuery); 255 } 256 ((UnitOfWorkImpl)getSession()).updateChangeTrackersIfRequired(objectToWrite, changeSetToWrite, (UnitOfWorkImpl)getSession(), descriptor); 257 258 } 261 } 262 } 263 264 268 protected void commitChangedObjectsForClassWithChangeSet(UnitOfWorkChangeSet uowChangeSet, String className) { 269 Hashtable objectChangesList = (Hashtable)uowChangeSet.getObjectChanges().get(className); 270 if (objectChangesList != null) { ClassDescriptor descriptor = null; 272 for (Enumeration pendingEnum = objectChangesList.elements(); 273 pendingEnum.hasMoreElements();) { 274 ObjectChangeSet changeSetToWrite = (ObjectChangeSet)pendingEnum.nextElement(); 275 if (descriptor == null) { 276 descriptor = getSession().getDescriptor(changeSetToWrite.getClassType(getSession())); 278 } 279 Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); 280 if ((!getProcessedCommits().containsKey(changeSetToWrite)) && (!getProcessedCommits().containsKey(objectToWrite))) { 281 addProcessedCommit(changeSetToWrite); 282 WriteObjectQuery commitQuery = null; 284 if (changeSetToWrite.isNew()) { 285 commitQuery = new InsertObjectQuery(); 286 } else { 287 commitQuery = new UpdateObjectQuery(); 288 } 289 commitQuery.setObjectChangeSet(changeSetToWrite); 290 commitQuery.setObject(objectToWrite); 291 commitQuery.cascadeOnlyDependentParts(); 292 getSession().executeQuery(commitQuery); 295 } 296 ((UnitOfWorkImpl)getSession()).updateChangeTrackersIfRequired(objectToWrite, changeSetToWrite, (UnitOfWorkImpl)getSession(), descriptor); 297 298 } 301 } 302 } 303 304 308 public void deleteAllObjects(Vector objectsForDeletion) throws RuntimeException , DatabaseException, OptimisticLockException { 309 setIsActive(true); 310 getSession().beginTransaction(); 311 312 try { 313 for (int index = getCommitOrder().size() - 1; index >= 0; index--) { 314 Class theClass = (Class )getCommitOrder().elementAt(index); 315 316 for (Enumeration objectsForDeletionEnum = objectsForDeletion.elements(); 317 objectsForDeletionEnum.hasMoreElements();) { 318 Object objectToDelete = objectsForDeletionEnum.nextElement(); 319 if (objectToDelete.getClass() == theClass) { 320 DeleteObjectQuery deleteQuery = new DeleteObjectQuery(); 321 deleteQuery.setObject(objectToDelete); 322 getSession().executeQuery(deleteQuery); 323 } 324 } 325 } 326 } catch (RuntimeException exception) { 327 try { 328 getSession().rollbackTransaction(); 329 } catch (Exception ignore) { 330 } 331 throw exception; 332 } finally { 333 setIsActive(false); 334 } 335 336 getSession().commitTransaction(); 337 } 338 339 345 public Vector getCommitOrder() { 346 return commitOrder; 347 } 348 349 352 protected IdentityHashtable getCompletedCommits() { 353 if (completedCommits == null) { 354 completedCommits = new IdentityHashtable(); 356 } 357 return completedCommits; 358 } 359 360 protected boolean hasDataModifications() { 361 return ((dataModifications != null) && (!dataModifications.isEmpty())); 362 } 363 364 368 protected Hashtable getDataModifications() { 369 if (dataModifications == null) { 370 dataModifications = new Hashtable(10); 371 } 372 return dataModifications; 373 } 374 375 protected boolean hasObjectsToDelete() { 376 return ((objectsToDelete != null) && (!objectsToDelete.isEmpty())); 377 } 378 379 382 protected Vector getObjectsToDelete() { 383 if (objectsToDelete == null) { 384 objectsToDelete = new Vector(5); 385 } 386 return objectsToDelete; 387 } 388 389 392 protected IdentityHashtable getProcessedCommits() { 393 if (processedCommits == null) { 394 processedCommits = new IdentityHashtable(); 396 } 397 return processedCommits; 398 } 399 400 403 protected IdentityHashtable getPendingCommits() { 404 if (pendingCommits == null) { 405 pendingCommits = new IdentityHashtable(); 407 } 408 return pendingCommits; 409 } 410 411 415 protected IdentityHashtable getPostModifyCommits() { 416 if (postModifyCommits == null) { 417 postModifyCommits = new IdentityHashtable(); 419 } 420 return postModifyCommits; 421 } 422 423 427 protected IdentityHashtable getPreModifyCommits() { 428 if (preModifyCommits == null) { 429 preModifyCommits = new IdentityHashtable(); 431 } 432 return preModifyCommits; 433 } 434 435 438 protected AbstractSession getSession() { 439 return session; 440 } 441 442 445 protected IdentityHashtable getShallowCommits() { 446 if (shallowCommits == null) { 447 shallowCommits = new IdentityHashtable(); 449 } 450 return shallowCommits; 451 } 452 453 461 public void initializeCommitOrder() { 462 Vector descriptors = Helper.buildVectorFromMapElements(getSession().getDescriptors()); 463 464 descriptors = Helper.addAllUniqueToVector(new Vector(descriptors.size()), descriptors); 466 Object [] descriptorsArray = new Object [descriptors.size()]; 467 for (int index = 0; index < descriptors.size(); index++) { 468 descriptorsArray[index] = descriptors.elementAt(index); 469 } 470 TOPSort.quicksort(descriptorsArray, new DescriptorCompare()); 471 descriptors = new Vector(descriptors.size()); 472 for (int index = 0; index < descriptorsArray.length; index++) { 473 descriptors.addElement(descriptorsArray[index]); 474 } 475 476 CommitOrderCalculator calculator = new CommitOrderCalculator(getSession()); 477 calculator.addNodes(descriptors); 478 calculator.calculateMappingDependencies(); 479 calculator.orderCommits(); 480 descriptors = calculator.getOrderedDescriptors(); 481 482 calculator = new CommitOrderCalculator(getSession()); 483 calculator.addNodes(descriptors); 484 calculator.calculateSpecifiedDependencies(); 485 calculator.orderCommits(); 486 487 setCommitOrder(calculator.getOrderedClasses()); 488 } 489 490 493 public boolean isActive() { 494 return isActive; 495 } 496 497 502 public boolean isCommitCompleted(Object domainObject) { 503 return getCompletedCommits().containsKey(domainObject); 504 } 505 506 511 public boolean isCommitInPostModify(Object domainObject) { 512 return getPostModifyCommits().containsKey(domainObject); 513 } 514 515 520 public boolean isCommitInPreModify(Object domainObject) { 521 return getPreModifyCommits().containsKey(domainObject); 522 } 523 524 528 public boolean isShallowCommitted(Object domainObject) { 529 return getShallowCommits().containsKey(domainObject); 530 } 531 532 536 public void markCommitCompleted(Object domainObject) { 537 getPreModifyCommits().remove(domainObject); 538 getPostModifyCommits().remove(domainObject); 539 if ((!isActive()) && getPostModifyCommits().isEmpty() && getPreModifyCommits().isEmpty()) { 541 reinitialize(); 542 return; 543 } 544 getCompletedCommits().put(domainObject, domainObject); } 546 547 551 public void markPostModifyCommitInProgress(Object domainObject) { 552 getPreModifyCommits().remove(domainObject); 553 getPostModifyCommits().put(domainObject, domainObject); } 555 556 560 public void markPreModifyCommitInProgress(Object domainObject) { 561 removePendingCommit(domainObject); 562 addProcessedCommit(domainObject); 563 getPreModifyCommits().put(domainObject, domainObject); } 565 566 570 public void markShallowCommit(Object domainObject) { 571 getShallowCommits().put(domainObject, domainObject); } 573 574 578 public void reinitialize() { 579 setPendingCommits(null); 580 setProcessedCommits(null); 581 setPreModifyCommits(null); 582 setPostModifyCommits(null); 583 setCompletedCommits(null); 584 setShallowCommits(null); 585 setObjectsToDelete(null); 586 setDataModifications(null); 587 } 588 589 592 protected void removePendingCommit(Object domainObject) { 593 getPendingCommits().remove(domainObject); 594 } 595 596 602 public void setCommitOrder(Vector commitOrder) { 603 this.commitOrder = commitOrder; 604 } 605 606 609 protected void setCompletedCommits(IdentityHashtable completedCommits) { 610 this.completedCommits = completedCommits; 611 } 612 613 617 protected void setDataModifications(Hashtable dataModifications) { 618 this.dataModifications = dataModifications; 619 } 620 621 624 public void setIsActive(boolean isActive) { 625 this.isActive = isActive; 626 } 627 628 631 protected void setObjectsToDelete(Vector objectsToDelete) { 632 this.objectsToDelete = objectsToDelete; 633 } 634 635 638 protected void setPendingCommits(IdentityHashtable pendingCommits) { 639 this.pendingCommits = pendingCommits; 640 } 641 642 645 protected void setProcessedCommits(IdentityHashtable processedCommits) { 646 this.processedCommits = processedCommits; 647 } 648 649 653 protected void setPostModifyCommits(IdentityHashtable postModifyCommits) { 654 this.postModifyCommits = postModifyCommits; 655 } 656 657 661 protected void setPreModifyCommits(IdentityHashtable preModifyCommits) { 662 this.preModifyCommits = preModifyCommits; 663 } 664 665 668 protected void setSession(AbstractSession session) { 669 this.session = session; 670 } 671 672 675 protected void setShallowCommits(IdentityHashtable shallowCommits) { 676 this.shallowCommits = shallowCommits; 677 } 678 679 682 public String toString() { 683 int size = 0; 684 if (preModifyCommits != null) { 685 size += getPreModifyCommits().size(); 686 } 687 if (postModifyCommits != null) { 688 size += getPostModifyCommits().size(); 689 } 690 Object [] args = { new Integer (size) }; 691 return Helper.getShortClassName(getClass()) + ToStringLocalization.buildMessage("commit_depth", args); 692 } 693 } 694 | Popular Tags |