1 21 package oracle.toplink.essentials.internal.sessions; 23 24 import java.util.*; 25 import oracle.toplink.essentials.descriptors.VersionLockingPolicy; 26 import oracle.toplink.essentials.mappings.*; 27 import oracle.toplink.essentials.exceptions.*; 28 import oracle.toplink.essentials.internal.helper.*; 29 import oracle.toplink.essentials.internal.helper.linkedlist.LinkedNode; 30 import oracle.toplink.essentials.internal.queryframework.ContainerPolicy; 31 import oracle.toplink.essentials.internal.identitymaps.*; 32 import oracle.toplink.essentials.logging.SessionLog; 33 import oracle.toplink.essentials.sessions.SessionProfiler; 34 import oracle.toplink.essentials.descriptors.ClassDescriptor; 35 import oracle.toplink.essentials.internal.descriptors.ObjectBuilder; 36 import oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicy; 37 38 45 public class MergeManager { 46 47 48 protected AbstractSession session; 49 50 51 protected IdentityHashtable objectDescriptors; 52 53 54 protected IdentityHashtable objectsAlreadyMerged; 55 56 57 protected ArrayList acquiredLocks; 58 59 60 protected CacheKey writeLockQueued; 61 62 63 protected LinkedNode queueNode; 64 65 66 protected int mergePolicy; 67 protected static final int WORKING_COPY_INTO_ORIGINAL = 1; 68 protected static final int ORIGINAL_INTO_WORKING_COPY = 2; 69 protected static final int CLONE_INTO_WORKING_COPY = 3; 70 protected static final int WORKING_COPY_INTO_REMOTE = 4; 71 protected static final int REFRESH_REMOTE_OBJECT = 5; 72 protected static final int CHANGES_INTO_DISTRIBUTED_CACHE = 6; 73 protected static final int CLONE_WITH_REFS_INTO_WORKING_COPY = 7; 74 protected static final int WORKING_COPY_INTO_BACKUP = 9; 75 76 77 protected int cascadePolicy; 78 public static final int NO_CASCADE = 1; 79 public static final int CASCADE_PRIVATE_PARTS = 2; 80 public static final int CASCADE_ALL_PARTS = 3; 81 public static final int CASCADE_BY_MAPPING = 4; 82 protected long systemTime = 0; public static boolean LOCK_ON_MERGE = true; 84 85 public MergeManager(AbstractSession session) { 86 this.session = session; 87 this.objectsAlreadyMerged = new IdentityHashtable(); 88 this.cascadePolicy = CASCADE_ALL_PARTS; 89 this.mergePolicy = WORKING_COPY_INTO_ORIGINAL; 90 this.objectDescriptors = new IdentityHashtable(); 91 this.acquiredLocks = new ArrayList(); 92 } 93 94 97 protected IdentityHashtable buildIdentitySet(Object container, ContainerPolicy containerPolicy, boolean keyByTarget) { 98 IdentityHashtable result = new IdentityHashtable(containerPolicy.sizeFor(container) + 1); 100 for (Object iter = containerPolicy.iteratorFor(container); containerPolicy.hasNext(iter);) { 101 Object element = containerPolicy.next(iter, getSession()); 102 if (keyByTarget) { 103 result.put(getTargetVersionOfSourceObject(element), element); 104 } else { 105 result.put(element, element); 106 } 107 } 108 return result; 109 } 110 111 114 public void cascadeAllParts() { 115 setCascadePolicy(CASCADE_ALL_PARTS); 116 } 117 118 121 public void cascadePrivateParts() { 122 setCascadePolicy(CASCADE_PRIVATE_PARTS); 123 } 124 125 128 public void dontCascadeParts() { 129 setCascadePolicy(NO_CASCADE); 130 } 131 132 public ArrayList getAcquiredLocks() { 133 return this.acquiredLocks; 134 } 135 136 public int getCascadePolicy() { 137 return cascadePolicy; 138 } 139 140 protected int getMergePolicy() { 141 return mergePolicy; 142 } 143 144 public IdentityHashtable getObjectDescriptors() { 145 return objectDescriptors; 146 } 147 148 public IdentityHashtable getObjectsAlreadyMerged() { 150 return objectsAlreadyMerged; 151 } 152 153 public Object getObjectToMerge(Object sourceValue) { 154 if (shouldMergeOriginalIntoWorkingCopy()) { 155 return getTargetVersionOfSourceObject(sourceValue); 156 } 157 158 return sourceValue; 159 } 160 161 165 public LinkedNode getQueueNode() { 166 return this.queueNode; 167 } 168 169 public AbstractSession getSession() { 170 return session; 171 } 172 173 177 public long getSystemTime() { 178 if (systemTime == 0) { 179 systemTime = System.currentTimeMillis(); 180 } 181 return systemTime; 182 } 183 184 188 public Object getTargetVersionOfSourceObject(Object source) { 189 if (shouldMergeWorkingCopyIntoOriginal() || shouldMergeWorkingCopyIntoRemote()) { 190 return ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(source); 192 } else if (shouldMergeCloneIntoWorkingCopy() || shouldMergeOriginalIntoWorkingCopy() || shouldMergeCloneWithReferencesIntoWorkingCopy()) { 193 return registerObjectForMergeCloneIntoWorkingCopy(source); 197 } else if (shouldRefreshRemoteObject()) { 198 ClassDescriptor descriptor = getSession().getDescriptor(source); 200 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(source, getSession()); 201 return getSession().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, source.getClass(), descriptor, null); 202 } 203 204 throw ValidationException.invalidMergePolicy(); 205 } 206 207 211 public CacheKey getWriteLockQueued() { 212 return this.writeLockQueued; 213 } 214 215 219 public Object mergeChanges(Object object, ObjectChangeSet objectChangeSet) throws ValidationException { 220 if (object == null) { 221 return object; 222 } 223 224 if (getSession().isClassReadOnly(object.getClass())) { 226 return object; 227 } 228 229 if (getObjectsAlreadyMerged().containsKey(object)) { 231 return object; 232 } 233 234 getObjectsAlreadyMerged().put(object, object); 236 237 Object mergedObject; 238 if (shouldMergeWorkingCopyIntoOriginal()) { 239 mergedObject = mergeChangesOfWorkingCopyIntoOriginal(object, objectChangeSet); 240 } else if (shouldMergeCloneIntoWorkingCopy() || shouldMergeCloneWithReferencesIntoWorkingCopy()) { 241 mergedObject = mergeChangesOfCloneIntoWorkingCopy(object); 242 } else if (shouldMergeOriginalIntoWorkingCopy()) { 243 mergedObject = mergeChangesOfOriginalIntoWorkingCopy(object); 244 } else { 245 throw ValidationException.invalidMergePolicy(); 246 } 247 248 return mergedObject; 249 } 250 251 255 public void mergeChangesFromChangeSet(UnitOfWorkChangeSet uowChangeSet) { 256 getSession().startOperationProfile(SessionProfiler.DistributedMerge); 257 getSession().getIdentityMapAccessorInstance().acquireWriteLock(); 259 getSession().log(SessionLog.FINER, SessionLog.PROPAGATION, "received_updates_from_remote_server"); 260 getSession().getEventManager().preDistributedMergeUnitOfWorkChangeSet(uowChangeSet); 261 262 try { 263 getSession().getIdentityMapAccessorInstance().getWriteLockManager().acquireRequiredLocks(this, uowChangeSet); 265 Enumeration objectChangeEnum = uowChangeSet.getAllChangeSets().keys(); 266 while (objectChangeEnum.hasMoreElements()) { 267 ObjectChangeSet objectChangeSet = (ObjectChangeSet)objectChangeEnum.nextElement(); 268 Object object = objectChangeSet.getTargetVersionOfSourceObject(getSession(), false); 269 270 Object mergedObject = this.mergeChanges(object, objectChangeSet); 273 274 if (mergedObject == null) { 277 if (objectChangeSet.isNew()) { 278 mergedObject = mergeNewObjectIntoCache(objectChangeSet); 279 } 280 } 281 if (mergedObject == null) { 282 getSession().incrementProfile(SessionProfiler.ChangeSetsNotProcessed); 283 } else { 284 getSession().incrementProfile(SessionProfiler.ChangeSetsProcessed); 285 } 286 } 287 Enumeration deletedObjects = uowChangeSet.getDeletedObjects().elements(); 288 while (deletedObjects.hasMoreElements()) { 289 ObjectChangeSet changeSet = (ObjectChangeSet)deletedObjects.nextElement(); 290 changeSet.removeFromIdentityMap(getSession()); 291 getSession().incrementProfile(SessionProfiler.DeletedObject); 292 } 293 } catch (RuntimeException exception) { 294 getSession().handleException(exception); 295 } finally { 296 getSession().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(this); 297 getSession().getIdentityMapAccessorInstance().releaseWriteLock(); 298 getSession().getEventManager().postDistributedMergeUnitOfWorkChangeSet(uowChangeSet); 299 getSession().endOperationProfile(SessionProfiler.DistributedMerge); 300 } 301 } 302 303 307 public boolean mergeChangesInCollection(Object source, Object target, Object backup, DatabaseMapping mapping) { 308 ContainerPolicy containerPolicy = mapping.getContainerPolicy(); 309 310 IdentityHashtable backupSet = buildIdentitySet(backup, containerPolicy, false); 312 IdentityHashtable sourceSet = null; 313 IdentityHashtable targetToSources = null; 314 315 if (shouldMergeWorkingCopyIntoOriginal()) { 317 sourceSet = buildIdentitySet(source, containerPolicy, false); 318 } else { 319 targetToSources = buildIdentitySet(source, containerPolicy, true); 320 } 321 322 boolean changeOccured = false; 323 324 if (backup == target) { 326 backup = containerPolicy.cloneFor(backup); 327 } 328 329 for (Object backupIter = containerPolicy.iteratorFor(backup); 331 containerPolicy.hasNext(backupIter);) { 332 Object backupElement = containerPolicy.next(backupIter, getSession()); 333 334 if (shouldMergeWorkingCopyIntoOriginal()) { if (!sourceSet.containsKey(backupElement)) { 337 changeOccured = true; 338 containerPolicy.removeFrom((Object )null, getTargetVersionOfSourceObject(backupElement), target, getSession()); 339 340 if (mapping.isPrivateOwned()) { 343 registerRemovedNewObjectIfRequired(backupElement); 344 } 345 } 346 } else { if (!targetToSources.containsKey(backupElement)) { changeOccured = true; 349 containerPolicy.removeFrom((Object )null, backupElement, target, getSession()); } 351 } 352 } 353 354 for (Object sourceIter = containerPolicy.iteratorFor(source); 356 containerPolicy.hasNext(sourceIter);) { 357 Object sourceElement = containerPolicy.next(sourceIter, getSession()); 358 359 mapping.cascadeMerge(sourceElement, this); 362 if (shouldMergeWorkingCopyIntoOriginal()) { if (!backupSet.containsKey(sourceElement)) { 365 changeOccured = true; 366 containerPolicy.addInto(getTargetVersionOfSourceObject(sourceElement), target, getSession()); 367 } else { 368 containerPolicy.validateElementAndRehashIfRequired(sourceElement, target, getSession(), getTargetVersionOfSourceObject(sourceElement)); 369 } 370 } else { Object targetVersionOfSourceElement = getTargetVersionOfSourceObject(sourceElement); 372 if (!backupSet.containsKey(targetVersionOfSourceElement)) { changeOccured = true; 374 containerPolicy.addInto(targetVersionOfSourceElement, target, getSession()); 375 } 376 } 377 } 378 379 return changeOccured; 380 } 381 382 386 protected Object mergeChangesOfCloneIntoWorkingCopy(Object rmiClone) { 387 ClassDescriptor descriptor = getSession().getDescriptor(rmiClone); 388 Object registeredObject = registerObjectForMergeCloneIntoWorkingCopy(rmiClone); 389 390 if (registeredObject == rmiClone) { 391 return rmiClone; 393 } 394 395 boolean changeTracked = false; 396 try { 397 ObjectBuilder builder = descriptor.getObjectBuilder(); 398 399 if (descriptor.usesVersionLocking()) { 400 VersionLockingPolicy policy = (VersionLockingPolicy) descriptor.getOptimisticLockingPolicy(); 401 if (policy.isStoredInObject()) { 402 Object currentValue = builder.extractValueFromObjectForField(registeredObject, policy.getWriteLockField(), session); 403 404 if (policy.isNewerVersion(currentValue, rmiClone, session.keyFromObject(rmiClone), session)) { 405 throw OptimisticLockException.objectChangedSinceLastMerge(rmiClone); 406 } 407 } 408 } 409 410 descriptor.getObjectChangePolicy().dissableEventProcessing(registeredObject); 412 413 builder.mergeIntoObject(registeredObject, false, rmiClone, this); 415 } finally { 416 descriptor.getObjectChangePolicy().enableEventProcessing(registeredObject); 417 } 418 419 return registeredObject; 420 } 421 422 426 protected Object mergeChangesOfOriginalIntoWorkingCopy(Object clone) { 427 ClassDescriptor descriptor = getSession().getDescriptor(clone); 428 429 Object original = ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObjectOrNull(clone); 431 432 if (original == null) { 433 return clone; 434 } 435 436 descriptor.getObjectBuilder().mergeIntoObject(clone, false, original, this); 438 439 descriptor.getObjectChangePolicy().revertChanges(clone, descriptor, (UnitOfWorkImpl)this.getSession(), ((UnitOfWorkImpl)this.getSession()).getCloneMapping()); 441 Vector primaryKey = getSession().keyFromObject(clone); 442 if (descriptor.usesOptimisticLocking()) { 443 descriptor.getOptimisticLockingPolicy().mergeIntoParentCache((UnitOfWorkImpl)getSession(), primaryKey, clone); 444 } 445 446 CacheKey parentCacheKey = ((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, clone.getClass(), descriptor); 447 CacheKey uowCacheKey = getSession().getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, clone.getClass(), descriptor); 448 449 if ((parentCacheKey != null) && (uowCacheKey != null)) { 451 uowCacheKey.setReadTime(parentCacheKey.getReadTime()); 452 } 453 454 return clone; 455 } 456 457 461 protected Object mergeChangesOfWorkingCopyIntoOriginal(Object clone, ObjectChangeSet objectChangeSet) { 462 UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)getSession(); 463 464 Object original = unitOfWork.getOriginalVersionOfObjectOrNull(clone); 467 468 ClassDescriptor descriptor = unitOfWork.getDescriptor(clone.getClass()); 469 470 try { 472 if (original == null) { 473 original = unitOfWork.buildOriginal(clone); 475 if (objectChangeSet == null) { 476 descriptor.getObjectBuilder().mergeIntoObject(original, true, clone, this); 477 } else if (!objectChangeSet.isNew()) { 478 AbstractSession parent = unitOfWork.getParent(); 483 original = parent.getIdentityMapAccessorInstance().getWriteLockManager().appendLock(objectChangeSet.getPrimaryKeys(), original, descriptor, this, parent); 484 descriptor.getObjectBuilder().mergeIntoObject(original, true, clone, this); 485 } else { 486 descriptor.getObjectBuilder().mergeChangesIntoObject(original, objectChangeSet, clone, this); 487 } 488 } else if (objectChangeSet == null) { 489 descriptor.getObjectBuilder().mergeIntoObject(original, false, clone, this); 491 } else { 492 if (!objectChangeSet.isNew()) { 494 AbstractSession parent = unitOfWork.getParent(); 495 if(objectChangeSet.shouldInvalidateObject(original, parent)) { 496 parent.getIdentityMapAccessor().invalidateObject(original); 497 return clone; 498 } 499 } 500 descriptor.getObjectBuilder().mergeChangesIntoObject(original, objectChangeSet, clone, this); 501 } 502 } catch (QueryException exception) { 503 if (unitOfWork.shouldPerformNoValidation() || (descriptor.hasWrapperPolicy())) { 508 if ((exception.getErrorCode() != QueryException.BACKUP_CLONE_DELETED) && (exception.getErrorCode() != QueryException.BACKUP_CLONE_IS_ORIGINAL_FROM_PARENT) && (exception.getErrorCode() != QueryException.BACKUP_CLONE_IS_ORIGINAL_FROM_SELF)) { 509 throw exception; 510 } 511 return clone; 512 } else { 513 throw exception; 514 } 515 } 516 517 if (!unitOfWork.isNestedUnitOfWork()) { 518 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(clone, unitOfWork); 519 520 CacheKey cacheKey = unitOfWork.getParent().getIdentityMapAccessorInstance().acquireLock(primaryKey, original.getClass(), descriptor); 523 try { 524 if (descriptor.usesOptimisticLocking()) { 525 if (descriptor.getOptimisticLockingPolicy().isChildWriteLockValueGreater(unitOfWork, primaryKey, original.getClass())) { 526 cacheKey.setWriteLockValue(unitOfWork.getIdentityMapAccessor().getWriteLockValue(original)); 527 } 528 } 529 530 cacheKey.setObject(original); 532 if (descriptor.getCacheInvalidationPolicy().shouldUpdateReadTimeOnUpdate() || ((objectChangeSet != null) && objectChangeSet.isNew())) { 533 cacheKey.setReadTime(getSystemTime()); 534 } 535 } finally { 536 cacheKey.updateAccess(); 537 cacheKey.release(); 538 } 539 } 540 return clone; 541 } 542 543 546 public void mergeCloneIntoWorkingCopy() { 547 setMergePolicy(CLONE_INTO_WORKING_COPY); 548 } 549 550 554 public void mergeCloneWithReferencesIntoWorkingCopy() { 555 setMergePolicy(CLONE_WITH_REFS_INTO_WORKING_COPY); 556 } 557 558 561 public void mergeIntoDistributedCache() { 562 setMergePolicy(CHANGES_INTO_DISTRIBUTED_CACHE); 563 } 564 565 570 public Object mergeNewObjectIntoCache(ObjectChangeSet changeSet) { 571 if (changeSet.isNew()) { 572 Class objectClass = changeSet.getClassType(session); 573 ClassDescriptor descriptor = getSession().getDescriptor(objectClass); 574 Object object = changeSet.getTargetVersionOfSourceObject(getSession(), false); 576 if (object == null) { 577 if (!getObjectsAlreadyMerged().containsKey(changeSet)) { 578 object = descriptor.getObjectBuilder().buildNewInstance(); 581 getObjectsAlreadyMerged().put(changeSet, object); 583 } else { 584 object = getObjectsAlreadyMerged().get(changeSet); 587 } 588 } else { 589 object = changeSet.getTargetVersionOfSourceObject(getSession(), true); 590 } 591 mergeChanges(object, changeSet); 592 Object implementation = descriptor.getObjectBuilder().unwrapObject(object, getSession()); 593 594 return getSession().getIdentityMapAccessorInstance().putInIdentityMap(implementation, descriptor.getObjectBuilder().extractPrimaryKeyFromObject(implementation, getSession()), changeSet.getWriteLockValue(), getSystemTime(), descriptor); 595 } 596 return null; 597 } 598 599 602 public void mergeOriginalIntoWorkingCopy() { 603 setMergePolicy(ORIGINAL_INTO_WORKING_COPY); 604 } 605 606 609 public void mergeWorkingCopyIntoBackup() { 610 setMergePolicy(WORKING_COPY_INTO_BACKUP); 611 } 612 613 616 public void mergeWorkingCopyIntoOriginal() { 617 setMergePolicy(WORKING_COPY_INTO_ORIGINAL); 618 } 619 620 623 public void mergeWorkingCopyIntoRemote() { 624 setMergePolicy(WORKING_COPY_INTO_REMOTE); 625 } 626 627 631 public void refreshRemoteObject() { 632 setMergePolicy(REFRESH_REMOTE_OBJECT); 633 } 634 635 640 protected Object registerObjectForMergeCloneIntoWorkingCopy(Object clone) { 641 ClassDescriptor descriptor = getSession().getDescriptor(clone.getClass()); 642 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(clone, getSession()); 643 644 Object objectFromCache = getSession().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, descriptor.getJavaClass(), descriptor, null); 647 if (objectFromCache != null) { 648 return objectFromCache; 649 } 650 651 oracle.toplink.essentials.queryframework.DoesExistQuery existQuery = descriptor.getQueryManager().getDoesExistQuery(); 652 653 if (existQuery.shouldCheckCacheForDoesExist()) { 655 return ((UnitOfWorkImpl)getSession()).internalRegisterObject(clone, descriptor); 656 } 657 658 Boolean doesExist = (Boolean )existQuery.checkEarlyReturn(clone, primaryKey, getSession(), null); 660 if (doesExist == Boolean.FALSE) { 661 return ((UnitOfWorkImpl)getSession()).internalRegisterObject(clone, descriptor); 662 } 663 664 Object object = getSession().readObject(clone); 666 if (object == null) { 667 return ((UnitOfWorkImpl)getSession()).internalRegisterObject(clone, descriptor); 668 } else { 669 return object; 670 } 671 } 672 673 677 public void registerRemovedNewObjectIfRequired(Object removedObject) { 678 if (getSession().isUnitOfWork()) { 679 UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)getSession(); 680 681 if (shouldMergeWorkingCopyIntoOriginal() && unitOfWork.getParent().isUnitOfWork() && unitOfWork.isCloneNewObject(removedObject)) { 682 Object originalVersionOfRemovedObject = unitOfWork.getOriginalVersionOfObject(removedObject); 683 unitOfWork.addRemovedObject(originalVersionOfRemovedObject); 684 } 685 } 686 } 687 688 public void setCascadePolicy(int cascadePolicy) { 689 this.cascadePolicy = cascadePolicy; 690 } 691 692 protected void setMergePolicy(int mergePolicy) { 693 this.mergePolicy = mergePolicy; 694 } 695 696 public void setObjectDescriptors(IdentityHashtable objectDescriptors) { 697 this.objectDescriptors = objectDescriptors; 698 } 699 700 protected void setObjectsAlreadyMerged(IdentityHashtable objectsAlreadyMerged) { 701 this.objectsAlreadyMerged = objectsAlreadyMerged; 702 } 703 704 708 public void setQueueNode(LinkedNode node) { 709 this.queueNode = node; 710 } 711 712 protected void setSession(AbstractSession session) { 713 this.session = session; 714 } 715 716 721 public void setWriteLockQueued(CacheKey writeLockQueued) { 722 this.writeLockQueued = writeLockQueued; 723 } 724 725 729 public boolean shouldCascadeByMapping() { 730 return getCascadePolicy() == CASCADE_BY_MAPPING; 731 } 732 733 736 public boolean shouldCascadeAllParts() { 737 return getCascadePolicy() == CASCADE_ALL_PARTS; 738 } 739 740 743 public boolean shouldCascadeParts() { 744 return getCascadePolicy() != NO_CASCADE; 745 } 746 747 750 public boolean shouldCascadePrivateParts() { 751 return (getCascadePolicy() == CASCADE_PRIVATE_PARTS) || (getCascadePolicy() == CASCADE_ALL_PARTS); 752 } 753 754 759 public boolean shouldCascadeReferences() { 760 return !shouldMergeCloneIntoWorkingCopy(); 761 } 762 763 767 public boolean shouldMergeChangesIntoDistributedCache() { 768 return getMergePolicy() == CHANGES_INTO_DISTRIBUTED_CACHE; 769 } 770 771 774 public boolean shouldMergeCloneIntoWorkingCopy() { 775 return getMergePolicy() == CLONE_INTO_WORKING_COPY; 776 } 777 778 781 public boolean shouldMergeCloneWithReferencesIntoWorkingCopy() { 782 return getMergePolicy() == CLONE_WITH_REFS_INTO_WORKING_COPY; 783 } 784 785 788 public boolean shouldMergeOriginalIntoWorkingCopy() { 789 return getMergePolicy() == ORIGINAL_INTO_WORKING_COPY; 790 } 791 792 795 public boolean shouldMergeWorkingCopyIntoBackup() { 796 return getMergePolicy() == WORKING_COPY_INTO_BACKUP; 797 } 798 799 802 public boolean shouldMergeWorkingCopyIntoOriginal() { 803 return getMergePolicy() == WORKING_COPY_INTO_ORIGINAL; 804 } 805 806 810 public boolean shouldMergeWorkingCopyIntoRemote() { 811 return getMergePolicy() == WORKING_COPY_INTO_REMOTE; 812 } 813 814 818 public boolean shouldRefreshRemoteObject() { 819 return getMergePolicy() == REFRESH_REMOTE_OBJECT; 820 } 821 } 822 | Popular Tags |