1 12 package org.eclipse.team.internal.ccvs.core.resources; 13 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 23 import org.eclipse.core.resources.*; 24 import org.eclipse.core.runtime.*; 25 import org.eclipse.core.runtime.jobs.*; 26 import org.eclipse.osgi.util.NLS; 27 import org.eclipse.team.core.TeamException; 28 import org.eclipse.team.internal.ccvs.core.*; 29 import org.eclipse.team.internal.ccvs.core.syncinfo.*; 30 import org.eclipse.team.internal.ccvs.core.syncinfo.ReentrantLock.CVSThreadInfo; 31 import org.eclipse.team.internal.ccvs.core.util.*; 32 import org.eclipse.team.internal.core.subscribers.BatchingLock.IFlushOperation; 33 import org.eclipse.team.internal.core.subscribers.BatchingLock.ThreadInfo; 34 import org.osgi.framework.Bundle; 35 36 59 public class EclipseSynchronizer implements IFlushOperation { 60 private static final String IS_DIRTY_INDICATOR = SyncInfoCache.IS_DIRTY_INDICATOR; 61 private static final String NOT_DIRTY_INDICATOR = SyncInfoCache.NOT_DIRTY_INDICATOR; 62 private static final String RECOMPUTE_INDICATOR = SyncInfoCache.RECOMPUTE_INDICATOR; 63 64 private static EclipseSynchronizer instance; 66 67 private ILock lock = Job.getJobManager().newLock(); 69 private ReentrantLock resourceLock = new ReentrantLock(); 70 71 private SynchronizerSyncInfoCache synchronizerCache = new SynchronizerSyncInfoCache(); 72 private SessionPropertySyncInfoCache sessionPropertyCache = new SessionPropertySyncInfoCache(synchronizerCache); 73 74 77 EclipseSynchronizer() { 78 } 79 80 83 public static EclipseSynchronizer getInstance() { 84 if(instance==null) { 85 instance = new EclipseSynchronizer(); 86 } 87 return instance; 88 } 89 90 public SyncInfoCache getSyncInfoCacheFor(IResource resource) { 91 if (resource.exists() && resource.isLocal(IResource.DEPTH_ZERO)) { 92 return sessionPropertyCache; 93 } else { 94 return synchronizerCache; 95 } 96 } 97 98 private boolean isValid(IResource resource) { 99 return resource.exists() || synchronizerCache.isPhantom(resource); 100 } 101 102 110 public void setFolderSync(IContainer folder, FolderSyncInfo info) throws CVSException { 111 Assert.isNotNull(info); if (folder.getType() == IResource.ROOT) return; 114 if (!isValid(folder)) { 115 if (getFolderSync(folder.getParent()) == null) { 119 IStatus status = new CVSStatus(IStatus.ERROR, TeamException.UNABLE, 120 NLS.bind(CVSMessages.EclipseSynchronizer_ErrorSettingFolderSync, new String [] { folder.getFullPath().toString() }),folder); 121 throw new CVSException(status); 122 } 123 } 124 ISchedulingRule rule = null; 125 try { 126 rule = beginBatching(folder, null); 127 try { 128 beginOperation(); 129 FolderSyncInfo oldInfo = getFolderSync(folder); 131 getSyncInfoCacheFor(folder).setCachedFolderSync(folder, info, true); 133 if (oldInfo == null) { 135 adjustDirtyStateRecursively(folder, RECOMPUTE_INDICATOR); 136 } 137 folderChanged(folder); 138 } finally { 139 endOperation(); 140 } 141 } finally { 142 if (rule != null) endBatching(rule, null); 143 } 144 } 145 146 153 public FolderSyncInfo getFolderSync(IContainer folder) throws CVSException { 154 if (folder.getType() == IResource.ROOT || !isValid(folder)) return null; 155 FolderSyncInfo info = getSyncInfoCacheFor(folder).getCachedFolderSync(folder, false ); 157 if (info != null) 158 return info; 159 try { 160 beginOperation(); 161 cacheFolderSync(folder); 162 return getSyncInfoCacheFor(folder).getCachedFolderSync(folder, true ); 163 } finally { 164 endOperation(); 165 } 166 } 167 168 175 public void deleteFolderSync(IContainer folder) throws CVSException { 176 if (folder.getType() == IResource.ROOT || !isValid(folder)) return; 177 ISchedulingRule rule = null; 178 try { 179 rule = beginBatching(folder, null); 180 try { 181 beginOperation(); 182 cacheResourceSyncForChildren(folder, true ); 185 IResource[] children = folder.members(true); 186 for (int i = 0; i < children.length; i++) { 187 IResource resource = children[i]; 188 resourceChanged(resource); 189 getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, null, true); 191 } 192 getSyncInfoCacheFor(folder).setCachedFolderSync(folder, null, true); 194 folderChanged(folder); 195 } catch (CoreException e) { 196 throw CVSException.wrapException(e); 197 } finally { 198 endOperation(); 199 } 200 } finally { 201 if (rule != null) endBatching(rule, null); 202 } 203 } 204 205 private void folderChanged(IContainer folder) { 206 resourceLock.folderChanged(folder); 207 } 208 209 private void resourceChanged(IResource resource) { 210 resourceLock.resourceChanged(resource); 211 } 212 213 221 public void setResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException { 222 Assert.isNotNull(info); IContainer parent = resource.getParent(); 224 if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) { 225 IStatus status = new CVSStatus(IStatus.ERROR, TeamException.UNABLE, 226 NLS.bind(CVSMessages.EclipseSynchronizer_ErrorSettingResourceSync, new String [] { resource.getFullPath().toString() }), resource); 227 throw new CVSException(status); 228 } 229 ISchedulingRule rule = null; 230 try { 231 rule = beginBatching(resource, null); 232 try { 233 beginOperation(); 234 cacheResourceSyncForChildren(parent, true ); 236 setCachedResourceSync(resource, info); 237 resourceChanged(resource); 238 } finally { 239 endOperation(); 240 } 241 } finally { 242 if (rule != null) endBatching(rule, null); 243 } 244 } 245 246 253 public ResourceSyncInfo getResourceSync(IResource resource) throws CVSException { 254 byte[] info = getSyncBytes(resource); 255 if (info == null) return null; 256 return new ResourceSyncInfo(info); 257 } 258 259 266 public byte[] getSyncBytes(IResource resource) throws CVSException { 267 IContainer parent = resource.getParent(); 268 if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) return null; 269 byte[] info = getSyncInfoCacheFor(resource).getCachedSyncBytes(resource, false ); 271 if (info != null) 272 return info; 273 try { 274 beginOperation(); 275 try { 277 cacheResourceSyncForChildren(parent, false ); 278 } catch (CVSException e) { 279 if (isCannotModifySynchronizer(e) || isResourceNotFound(e)) { 280 byte[] bytes = getSyncBytesFromDisk(resource); 282 if (!resource.exists() && bytes != null && !ResourceSyncInfo.isDeletion(bytes)) { 283 bytes = ResourceSyncInfo.convertToDeletion(bytes); 284 } 285 return bytes; 286 } else { 287 throw e; 288 } 289 } 290 return getCachedSyncBytes(resource); 291 } finally { 292 endOperation(); 293 } 294 } 295 296 304 public void setSyncBytes(IResource resource, byte[] syncBytes) throws CVSException { 305 Assert.isNotNull(syncBytes); IContainer parent = resource.getParent(); 307 if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) { 308 IStatus status = new CVSStatus(IStatus.ERROR, TeamException.UNABLE, 309 NLS.bind(CVSMessages.EclipseSynchronizer_ErrorSettingResourceSync, new String [] { resource.getFullPath().toString() }),resource); 310 throw new CVSException(status); 311 } 312 ISchedulingRule rule = null; 313 try { 314 rule = beginBatching(resource, null); 315 try { 316 beginOperation(); 317 cacheResourceSyncForChildren(parent, true ); 319 setCachedSyncBytes(resource, syncBytes); 320 resourceChanged(resource); 321 } finally { 322 endOperation(); 323 } 324 } finally { 325 if (rule != null) endBatching(rule, null); 326 } 327 } 328 329 335 public void deleteResourceSync(IResource resource) throws CVSException { 336 IContainer parent = resource.getParent(); 337 if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) return; 338 ISchedulingRule rule = null; 339 try { 340 rule = beginBatching(resource, null); 341 try { 342 beginOperation(); 343 cacheResourceSyncForChildren(parent, true ); 345 if (getCachedSyncBytes(resource) != null) { setCachedSyncBytes(resource, null); 347 clearDirtyIndicator(resource); 348 resourceChanged(resource); 349 } 350 } finally { 351 endOperation(); 352 } 353 } finally { 354 if (rule != null) endBatching(rule, null); 355 } 356 } 357 358 361 private void clearDirtyIndicator(IResource resource) throws CVSException { 362 getSyncInfoCacheFor(resource).flushDirtyCache(resource); 363 adjustDirtyStateRecursively(resource.getParent(), RECOMPUTE_INDICATOR); 364 } 365 366 373 public boolean isIgnored(IResource resource) throws CVSException { 374 if (resource.getType() == IResource.ROOT || 375 resource.getType() == IResource.PROJECT || 376 ! resource.exists()) { 377 return false; 378 } 379 IContainer parent = resource.getParent(); 380 FileNameMatcher matcher = sessionPropertyCache.getFolderIgnores(parent, false ); 381 if (matcher == null) { 382 try { 383 beginOperation(); 384 matcher = cacheFolderIgnores(parent); 385 } finally { 386 endOperation(); 387 } 388 } 389 return matcher.match(resource.getName()); 390 } 391 392 398 public void addIgnored(IContainer folder, String pattern) throws CVSException { 399 if (folder.getType() == IResource.ROOT || ! folder.exists()) { 400 IStatus status = new CVSStatus(IStatus.ERROR, TeamException.UNABLE, 401 NLS.bind(CVSMessages.EclipseSynchronizer_ErrorSettingIgnorePattern, new String [] { folder.getFullPath().toString() }),folder); 402 throw new CVSException(status); 403 } 404 ISchedulingRule rule = null; 405 try { 406 rule = beginBatching(folder.getFile(new Path(SyncFileWriter.IGNORE_FILE)), null); 407 try { 408 beginOperation(); 409 String [] ignores = SyncFileWriter.readCVSIgnoreEntries(folder); 410 if (ignores != null) { 411 for (int i = 0; i < ignores.length; i++) { 413 if (ignores[i].equals(pattern)) return; 414 } 415 String [] oldIgnores = ignores; 417 ignores = new String [oldIgnores.length + 1]; 418 System.arraycopy(oldIgnores, 0, ignores, 0, oldIgnores.length); 419 ignores[oldIgnores.length] = pattern; 420 } else { 421 ignores = new String [] { pattern }; 422 } 423 setCachedFolderIgnores(folder, ignores); 424 SyncFileWriter.writeCVSIgnoreEntries(folder, ignores); 425 List possibleIgnores = new ArrayList (); 427 accumulateNonManagedChildren(folder, possibleIgnores); 428 ResourceStateChangeListeners.getListener().resourceSyncInfoChanged((IResource[])possibleIgnores.toArray(new IResource[possibleIgnores.size()])); 429 } finally { 430 endOperation(); 431 } 432 } finally { 433 if (rule != null) endBatching(rule, null); 434 } 435 } 436 437 444 public IResource[] members(IContainer folder) throws CVSException { 445 if (! isValid(folder)) return new IResource[0]; 446 try { 447 beginOperation(); 448 if (folder.getType() != IResource.ROOT) { 449 cacheResourceSyncForChildren(folder, false); 451 } 452 } catch (CVSException e) { 453 if (!isCannotModifySynchronizer(e) && !isResourceNotFound(e)) { 454 throw e; 455 } 456 } finally { 457 endOperation(); 458 } 459 try { 460 461 return synchronizerCache.members(folder); 462 463 } catch (CoreException e) { 464 throw CVSException.wrapException(e); 465 } 466 } 467 468 private boolean isCannotModifySynchronizer(CVSException e) { 469 return (e.getStatus().getCode() == IResourceStatus.WORKSPACE_LOCKED 474 || e.getStatus().getCode() == CVSStatus.FAILED_TO_CACHE_SYNC_INFO); 475 } 476 477 private boolean isResourceNotFound(CVSException e) { 478 return e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND; 479 } 480 481 488 public ISchedulingRule beginBatching(ISchedulingRule resourceRule, IProgressMonitor monitor) { 489 return resourceLock.acquire(resourceRule, this , monitor); 490 } 491 492 504 public void endBatching(ISchedulingRule rule, IProgressMonitor monitor) throws CVSException { 505 try { 506 resourceLock.release(rule, monitor); 507 } catch (TeamException e) { 508 throw CVSException.wrapException(e); 509 } 510 } 511 512 519 public void flush(final ThreadInfo info, IProgressMonitor monitor) throws CVSException { 520 if (info != null && !info.isEmpty()) { 521 try { 522 ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { 523 public void run(IProgressMonitor pm) throws CoreException { 524 IStatus status = commitCache(info, pm); 525 if (!status.isOK()) { 526 throw new CVSException(status); 527 } 528 } 529 }, null, 0 , monitor); 530 } catch (CoreException e) { 531 throw CVSException.wrapException(e); 532 } 533 } 534 } 535 536 539 private void beginOperation() { 540 try { 541 if (ResourcesPlugin.getWorkspace().isTreeLocked()) return; 547 } catch (RuntimeException e) { 548 if (Platform.getBundle(CVSProviderPlugin.ID).getState() == Bundle.ACTIVE) { 551 throw e; 552 } else { 553 throw new OperationCanceledException(); 554 } 555 } 556 lock.acquire(); 557 } 558 559 562 private void endOperation() { 563 try { 564 if (ResourcesPlugin.getWorkspace().isTreeLocked()) return; 566 } catch (RuntimeException e) { 567 if (Platform.getBundle(CVSProviderPlugin.ID).getState() == Bundle.ACTIVE) { 570 throw e; 571 } else { 572 throw new OperationCanceledException(); 573 } 574 } 575 lock.release(); 576 } 577 578 592 public void flush(IContainer root, boolean deep, IProgressMonitor monitor) throws CVSException { 593 monitor = Policy.monitorFor(monitor); 594 monitor.beginTask(null, 10); 595 ISchedulingRule rule = null; 596 try { 597 rule = beginBatching(root, Policy.subMonitorFor(monitor, 1)); 598 try { 599 beginOperation(); 600 try { 601 resourceLock.flush(Policy.subMonitorFor(monitor, 8)); 603 } catch (TeamException e) { 604 throw CVSException.wrapException(e); 605 } finally { 606 sessionPropertyCache.purgeCache(root, deep); 608 } 609 } finally { 610 endOperation(); 611 } 612 } finally { 613 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 1)); 614 monitor.done(); 615 } 616 } 617 618 public void deconfigure(final IProject project, IProgressMonitor monitor) throws CVSException { 619 monitor = Policy.monitorFor(monitor); 620 monitor.beginTask(null, 100); 621 ISchedulingRule rule = null; 622 try { 623 rule = beginBatching(project, Policy.subMonitorFor(monitor, 10)); 624 flush(project, true , Policy.subMonitorFor(monitor, 80)); 626 627 purgeDirtyCache(project, Policy.subMonitorFor(monitor, 5)); 628 629 synchronizerCache.purgeCache(project, true); 632 } finally { 633 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 5)); 634 monitor.done(); 635 } 636 } 637 638 644 public void ignoreFilesChanged(IContainer[] roots) throws CVSException { 645 for (int i = 0; i < roots.length; i++) { 646 IContainer container = roots[i]; 647 if (container.exists()) { 648 ISchedulingRule rule = null; 649 try { 650 Set changed = new HashSet (); 651 rule = beginBatching(container, null); 652 try { 653 beginOperation(); 654 655 FileNameMatcher oldIgnores = null; 657 if (sessionPropertyCache.isFolderSyncInfoCached(container)) { 658 oldIgnores = cacheFolderIgnores(container); 659 } 660 661 changed.addAll(Arrays.asList( 663 sessionPropertyCache.purgeCache(container, oldIgnores == null ))); 664 665 if (oldIgnores != null) { 667 FileNameMatcher newIgnores = cacheFolderIgnores(container); 668 try { 669 IResource[] members = container.members(); 670 for (int j = 0; j < members.length; j++) { 671 IResource resource = members[j]; 672 if (resource.getType() == IResource.FOLDER) { 673 String name = resource.getName(); 674 if (oldIgnores.match(name) && !newIgnores.match(name)) { 675 changed.addAll(Arrays.asList( 676 sessionPropertyCache.purgeCache((IContainer)resource, true ))); 677 } 678 } 679 } 680 } catch (CoreException e) { 681 CVSProviderPlugin.log(e); 683 } 684 } 685 } finally { 686 endOperation(); 687 } 688 if (!changed.isEmpty()) { 689 ResourceStateChangeListeners.getListener().resourceSyncInfoChanged( 690 (IResource[]) changed.toArray(new IResource[changed.size()])); 691 } 692 } finally { 693 if (rule != null) endBatching(rule, null); 694 } 695 } 696 } 697 } 698 699 public void syncFilesChangedExternally(IContainer[] changedMetaFiles, IFile[] externalDeletions) throws CVSException { 700 List changed = new ArrayList (); 701 for (int i = 0; i < changedMetaFiles.length; i++) { 702 IContainer container = changedMetaFiles[i]; 703 if (!isWithinActiveOperationScope(container)) { 704 changed.addAll(Arrays.asList( 705 sessionPropertyCache.purgeCache(container, false ))); 706 } 707 } 708 for (int i = 0; i < externalDeletions.length; i++) { 709 IFile file = externalDeletions[i]; 710 if (!isWithinActiveOperationScope(file)) { 711 sessionPropertyCache.purgeCache(file.getParent(), false ); 712 changed.add(file); 713 } 714 } 715 if (!changed.isEmpty()) { 716 ResourceStateChangeListeners.getListener().externalSyncInfoChange( 717 (IResource[]) changed.toArray(new IResource[changed.size()])); 718 } 719 } 720 721 734 boolean prepareForDeletion(IResource resource) throws CVSException { 735 if (!resource.exists()) return false; 736 ISchedulingRule rule = null; 737 try { 738 rule = beginBatching(resource, null); 739 try { 740 beginOperation(); 741 adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR); 745 if (resource.getType() == IResource.FILE) { 746 byte[] syncBytes = getSyncBytes(resource); 747 if (syncBytes != null) { 748 if (ResourceSyncInfo.isAddition(syncBytes)) { 749 deleteResourceSync(resource); 750 } else { 751 syncBytes = convertToDeletion(syncBytes); 752 synchronizerCache.setCachedSyncBytes(resource, syncBytes, true); 753 } 754 sessionPropertyCache.purgeResourceSyncCache(resource); 755 resourceChanged(resource); 756 } 757 return false; 758 } else { 759 IContainer container = (IContainer)resource; 760 if (container.getType() == IResource.PROJECT) { 761 synchronizerCache.flush((IProject)container); 762 return false; 763 } else { 764 FolderSyncInfo info = getFolderSync(container); 766 if (info == null) return false; 767 synchronizerCache.setCachedFolderSync(container, info, true); 768 folderChanged(container); 769 byte[] syncBytes = getSyncBytes(resource); 771 synchronizerCache.setCachedSyncBytes(resource, syncBytes, true); 772 sessionPropertyCache.purgeResourceSyncCache(container); 773 sessionPropertyCache.purgeCache(container, false); 774 return true; 775 } 776 } 777 } finally { 778 endOperation(); 779 } 780 } finally { 781 if (rule != null) endBatching(rule, null); 782 } 783 } 784 785 793 protected void handleDeleted(IResource resource) throws CVSException { 794 if (resource.exists()) return; 795 try { 796 beginOperation(); 797 adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR); 798 } finally { 799 endOperation(); 800 } 801 } 802 803 815 public void prepareForDeletion(IResource resource, IProgressMonitor monitor) throws CVSException { 816 monitor = Policy.monitorFor(monitor); 818 try { 819 beginOperation(); 820 monitor.beginTask(null, 100); 821 try { 822 resource.accept(new IResourceVisitor() { 823 public boolean visit(IResource innerResource) throws CoreException { 824 try { 825 return prepareForDeletion(innerResource); 826 } catch (CVSException e) { 827 CVSProviderPlugin.log(e); 828 throw new CoreException(e.getStatus()); 829 } 830 } 831 }); 832 } catch (CoreException e) { 833 throw CVSException.wrapException(e); 834 } 835 } finally { 836 endOperation(); 837 monitor.done(); 838 } 839 } 840 841 847 private void cacheResourceSyncForChildren(IContainer container, boolean canModifyWorkspace) throws CVSException { 848 if (! getSyncInfoCacheFor(container).isResourceSyncInfoCached(container)) { 850 byte[][] infos; 852 if (isLinkedResource(container)) { 854 infos = null; 855 } else { 856 infos = SyncFileWriter.readAllResourceSync(container); 857 } 858 try { 859 if (infos != null) { 860 for (int i = 0; i < infos.length; i++) { 861 byte[] syncBytes = infos[i]; 862 IPath name = new Path(null, getName(syncBytes)); 863 IResource resource; 864 if (isFolder(syncBytes)) { 865 resource = container.getFolder(name); 866 } else { 867 resource = container.getFile(name); 868 } 869 getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, syncBytes, canModifyWorkspace); 870 } 871 } 872 getSyncInfoCacheFor(container).setResourceSyncInfoCached(container); 873 } catch (CVSException e) { 874 if (Policy.DEBUG_METAFILE_CHANGES) { 875 System.err.println("Failed to cache Entries for folder " + container.getFullPath()); } 877 throw e; 878 } 879 } 880 } 881 882 888 private void cacheFolderSync(IContainer container) throws CVSException { 889 if (! getSyncInfoCacheFor(container).isFolderSyncInfoCached(container)) { 891 FolderSyncInfo info; 893 if (isLinkedResource(container)) { 895 info = null; 896 } else { 897 info = SyncFileWriter.readFolderSync(container); 898 } 899 getSyncInfoCacheFor(container).setCachedFolderSync(container, info, false); 900 } 901 } 902 903 private boolean isLinkedResource(IResource resource) { 904 return CVSWorkspaceRoot.isLinkedResource(resource); 905 } 906 907 912 private byte[] getSyncBytesFromDisk(IResource resource) throws CVSException { 913 byte[][] infos = SyncFileWriter.readAllResourceSync(resource.getParent()); 914 if (infos == null) return null; 915 for (int i = 0; i < infos.length; i++) { 916 byte[] syncBytes = infos[i]; 917 if (resource.getName().equals(getName(syncBytes))) { 918 return syncBytes; 919 } 920 } 921 return null; 922 } 923 924 934 IStatus commitCache(ThreadInfo threadInfo, IProgressMonitor monitor) { 935 if (threadInfo.isEmpty()) { 936 return SyncInfoCache.STATUS_OK; 937 } 938 List errors = new ArrayList (); 939 try { 940 941 IResource[] changedResources = threadInfo.getChangedResources(); 943 IContainer[] changedFolders; 944 if (threadInfo instanceof CVSThreadInfo) { 945 changedFolders = ((CVSThreadInfo)threadInfo).getChangedFolders(); 946 } else { 947 changedFolders = new IContainer[0]; 948 } 949 Set dirtyParents = new HashSet (); 950 for (int i = 0; i < changedResources.length; i++) { 951 IResource resource = changedResources[i]; 952 IContainer folder = resource.getParent(); 953 dirtyParents.add(folder); 954 } 955 956 monitor = Policy.monitorFor(monitor); 957 int numDirty = dirtyParents.size(); 958 int numResources = changedFolders.length + numDirty; 959 monitor.beginTask(null, numResources); 960 if(monitor.isCanceled()) { 961 monitor.subTask(CVSMessages.EclipseSynchronizer_UpdatingSyncEndOperationCancelled); 962 } else { 963 monitor.subTask(CVSMessages.EclipseSynchronizer_UpdatingSyncEndOperation); 964 } 965 966 967 for (int i = 0; i < changedFolders.length; i++) { 969 IContainer folder = changedFolders[i]; 970 if (folder.exists() && folder.getType() != IResource.ROOT) { 971 try { 972 beginOperation(); 973 FolderSyncInfo info = sessionPropertyCache.getCachedFolderSync(folder, true); 974 if (info == null) { 976 if (!isLinkedResource(folder)) 979 SyncFileWriter.deleteFolderSync(folder); 980 dirtyParents.remove(folder); 981 } else { 982 SyncFileWriter.writeFolderSync(folder, info); 984 } 985 } catch(CVSException e) { 986 try { 987 sessionPropertyCache.purgeCache(folder, true ); 988 } catch(CVSException pe) { 989 errors.add(pe.getStatus()); 990 } 991 errors.add(e.getStatus()); 992 } finally { 993 endOperation(); 994 } 995 } 996 monitor.worked(1); 997 } 998 999 monitor.worked(numDirty - dirtyParents.size()); 1001 1002 for (Iterator it = dirtyParents.iterator(); it.hasNext();) { 1004 IContainer folder = (IContainer) it.next(); 1005 if (folder.exists() && folder.getType() != IResource.ROOT) { 1006 try { 1008 beginOperation(); 1009 List infos = new ArrayList (); 1010 IResource[] children = folder.members(true); 1011 for (int i = 0; i < children.length; i++) { 1012 IResource resource = children[i]; 1013 byte[] syncBytes = getSyncBytes(resource); 1014 if (syncBytes != null) { 1015 infos.add(syncBytes); 1016 } 1017 } 1018 if (infos.size() > 0 || !isLinkedResource(folder)) 1020 SyncFileWriter.writeAllResourceSync(folder, 1021 (byte[][]) infos.toArray(new byte[infos.size()][])); 1022 } catch(CVSException e) { 1023 try { 1024 sessionPropertyCache.purgeCache(folder, false ); 1025 } catch(CVSException pe) { 1026 errors.add(pe.getStatus()); 1027 } 1028 errors.add(e.getStatus()); 1029 } catch (CoreException e) { 1030 try { 1031 sessionPropertyCache.purgeCache(folder, false ); 1032 } catch(CVSException pe) { 1033 errors.add(pe.getStatus()); 1034 } 1035 errors.add(e.getStatus()); 1036 } finally { 1037 endOperation(); 1038 } 1039 } 1040 monitor.worked(1); 1041 } 1042 1043 1044 monitor.subTask(CVSMessages.EclipseSynchronizer_NotifyingListeners); 1045 Set allChanges = new HashSet (); 1046 allChanges.addAll(Arrays.asList(changedResources)); 1047 allChanges.addAll(Arrays.asList(changedFolders)); 1048 allChanges.addAll(dirtyParents); 1049 IResource[] resources = (IResource[]) allChanges.toArray( 1050 new IResource[allChanges.size()]); 1051 broadcastResourceStateChanges(resources); 1052 if ( ! errors.isEmpty()) { 1053 MultiStatus status = new MultiStatus(CVSProviderPlugin.ID, 1054 CVSStatus.COMMITTING_SYNC_INFO_FAILED, 1055 CVSMessages.EclipseSynchronizer_ErrorCommitting, 1056 null); 1057 for (int i = 0; i < errors.size(); i++) { 1058 status.merge((IStatus)errors.get(i)); 1059 } 1060 return status; 1061 } 1062 return SyncInfoCache.STATUS_OK; 1063 } finally { 1064 monitor.done(); 1065 } 1066 } 1067 1068 1071 void broadcastResourceStateChanges(IResource[] resources) { 1072 if (resources.length > 0) { 1073 ResourceStateChangeListeners.getListener().resourceSyncInfoChanged(resources); 1074 } 1075 } 1076 1077 1086 private byte[] getCachedSyncBytes(IResource resource) throws CVSException { 1087 return getSyncInfoCacheFor(resource).getCachedSyncBytes(resource, true); 1088 } 1089 1090 1099 private void setCachedSyncBytes(IResource resource, byte[] syncBytes) throws CVSException { 1100 getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, syncBytes, true); 1101 resourceChanged(resource); 1102 } 1103 1104 1113 private void setCachedResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException { 1114 byte[] syncBytes = null; 1116 if (info != null) syncBytes = info.getBytes(); 1117 getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, syncBytes, true); 1118 } 1119 1120 1127 private FileNameMatcher cacheFolderIgnores(IContainer container) throws CVSException { 1128 return sessionPropertyCache.getFolderIgnores(container, true); 1129 } 1130 1131 1138 private void setCachedFolderIgnores(IContainer container, String [] ignores) throws CVSException { 1139 sessionPropertyCache.setCachedFolderIgnores(container, ignores); 1140 } 1141 1142 1151 private void accumulateNonManagedChildren(IContainer folder, List possibleIgnores) throws CVSException { 1152 try { 1153 cacheResourceSyncForChildren(folder, true ); 1154 IResource[] children = folder.members(); 1155 List folders = new ArrayList (); 1156 for (int i = 0; i < children.length; i++) { 1158 IResource child = children[i]; 1159 if(getCachedSyncBytes(child)==null) { 1160 possibleIgnores.add(child); 1161 } 1162 if(child.getType()!=IResource.FILE) { 1163 folders.add(child); 1164 } 1165 } 1166 for (Iterator iter = folders.iterator(); iter.hasNext();) { 1167 IContainer child = (IContainer) iter.next(); 1168 accumulateNonManagedChildren(child, possibleIgnores); 1169 } 1170 } catch(CoreException e) { 1171 throw CVSException.wrapException(e); 1172 } 1173 } 1174 1175 1188 public void setNotifyInfo(IResource resource, NotifyInfo info) throws CVSException { 1189 NotifyInfo[] infos = SyncFileWriter.readAllNotifyInfo(resource.getParent()); 1190 if (infos == null) { 1191 if (info == null) return; 1193 infos = new NotifyInfo[] { info }; 1194 } else { 1195 Map infoMap = new HashMap (); 1196 for (int i = 0; i < infos.length; i++) { 1197 NotifyInfo notifyInfo = infos[i]; 1198 infoMap.put(notifyInfo.getName(), notifyInfo); 1199 } 1200 if (info == null) { 1201 infoMap.remove(resource.getName()); 1203 } else { 1204 infoMap.put(info.getName(), info); 1206 } 1207 1208 NotifyInfo[] newInfos = new NotifyInfo[infoMap.size()]; 1209 int i = 0; 1210 for (Iterator iter = infoMap.values().iterator(); iter.hasNext();) { 1211 newInfos[i++] = (NotifyInfo) iter.next(); 1212 } 1213 infos = newInfos; 1214 } 1215 SyncFileWriter.writeAllNotifyInfo(resource.getParent(), infos); 1216 } 1217 1218 1223 public NotifyInfo getNotifyInfo(IResource resource) throws CVSException { 1224 NotifyInfo[] infos = SyncFileWriter.readAllNotifyInfo(resource.getParent()); 1225 if (infos == null) return null; 1226 for (int i = 0; i < infos.length; i++) { 1227 NotifyInfo notifyInfo = infos[i]; 1228 if (notifyInfo.getName().equals(resource.getName())) { 1229 return notifyInfo; 1230 } 1231 } 1232 return null; 1233 } 1234 1235 1239 public void deleteNotifyInfo(IResource resource) throws CVSException { 1240 NotifyInfo[] infos = SyncFileWriter.readAllNotifyInfo(resource.getParent()); 1241 if (infos == null) return; 1242 Map infoMap = new HashMap (); 1243 for (int i = 0; i < infos.length; i++) { 1244 NotifyInfo notifyInfo = infos[i]; 1245 infoMap.put(notifyInfo.getName(), notifyInfo); 1246 } 1247 infoMap.remove(resource.getName()); 1248 NotifyInfo[] newInfos = new NotifyInfo[infoMap.size()]; 1249 int i = 0; 1250 for (Iterator iter = infoMap.values().iterator(); iter.hasNext();) { 1251 newInfos[i++] = (NotifyInfo) iter.next(); 1252 } 1253 SyncFileWriter.writeAllNotifyInfo(resource.getParent(), newInfos); 1254 } 1255 1256 1267 public void setBaserevInfo(IResource resource, BaserevInfo info) throws CVSException { 1268 BaserevInfo[] infos = SyncFileWriter.readAllBaserevInfo(resource.getParent()); 1269 if (infos == null) { 1270 infos = new BaserevInfo[] { info }; 1271 } else { 1272 Map infoMap = new HashMap (); 1273 for (int i = 0; i < infos.length; i++) { 1274 infoMap.put(infos[i].getName(), infos[i]); 1275 } 1276 infoMap.put(info.getName(), info); 1277 BaserevInfo[] newInfos = new BaserevInfo[infoMap.size()]; 1278 int i = 0; 1279 for (Iterator iter = infoMap.values().iterator(); iter.hasNext();) { 1280 newInfos[i++] = (BaserevInfo) iter.next(); 1281 } 1282 infos = newInfos; 1283 } 1284 SyncFileWriter.writeAllBaserevInfo(resource.getParent(), infos); 1285 } 1286 1287 1292 public BaserevInfo getBaserevInfo(IResource resource) throws CVSException { 1293 BaserevInfo[] infos = SyncFileWriter.readAllBaserevInfo(resource.getParent()); 1294 if (infos == null) return null; 1295 for (int i = 0; i < infos.length; i++) { 1296 BaserevInfo info = infos[i]; 1297 if (info.getName().equals(resource.getName())) { 1298 return info; 1299 } 1300 } 1301 return null; 1302 } 1303 1304 1308 public void deleteBaserevInfo(IResource resource) throws CVSException { 1309 BaserevInfo[] infos = SyncFileWriter.readAllBaserevInfo(resource.getParent()); 1310 if (infos == null) return; 1311 Map infoMap = new HashMap (); 1312 for (int i = 0; i < infos.length; i++) { 1313 infoMap.put(infos[i].getName(), infos[i]); 1314 } 1315 infoMap.remove(resource.getName()); 1316 BaserevInfo[] newInfos = new BaserevInfo[infoMap.size()]; 1317 int i = 0; 1318 for (Iterator iter = infoMap.values().iterator(); iter.hasNext();) { 1319 newInfos[i++] = (BaserevInfo) iter.next(); 1320 } 1321 SyncFileWriter.writeAllBaserevInfo(resource.getParent(), newInfos); 1322 } 1323 1324 public void copyFileToBaseDirectory(final IFile file, IProgressMonitor monitor) throws CVSException { 1325 monitor = Policy.monitorFor(monitor); 1326 monitor.beginTask(null, 100); 1327 ISchedulingRule rule = null; 1328 try { 1329 rule = beginBatching(file, Policy.subMonitorFor(monitor, 10)); 1330 ResourceSyncInfo info = getResourceSync(file); 1331 if (info == null || info.isAdded() || info.isDeleted()) 1333 return; 1334 SyncFileWriter.writeFileToBaseDirectory(file, Policy.subMonitorFor(monitor, 80)); 1335 resourceChanged(file); 1336 } finally { 1337 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 10)); 1338 monitor.done(); 1339 } 1340 } 1341 1342 public void restoreFileFromBaseDirectory(final IFile file, IProgressMonitor monitor) throws CVSException { 1343 monitor = Policy.monitorFor(monitor); 1344 monitor.beginTask(null, 100); 1345 ISchedulingRule rule = null; 1346 try { 1347 rule = beginBatching(file, Policy.subMonitorFor(monitor, 10)); 1348 ResourceSyncInfo info = getResourceSync(file); 1349 if (info == null || info.isAdded()) 1351 return; 1352 SyncFileWriter.restoreFileFromBaseDirectory(file, Policy.subMonitorFor(monitor, 80)); 1353 resourceChanged(file); 1354 } finally { 1355 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 10)); 1356 monitor.done(); 1357 } 1358 } 1359 1360 public void deleteFileFromBaseDirectory(final IFile file, IProgressMonitor monitor) throws CVSException { 1361 ResourceSyncInfo info = getResourceSync(file); 1362 if (info == null || info.isAdded()) 1364 return; 1365 SyncFileWriter.deleteFileFromBaseDirectory(file, monitor); 1366 } 1367 1368 1376 public boolean isSyncInfoLoaded(IResource[] resources, int depth) throws CVSException { 1377 IContainer[] folders = getParentFolders(resources, depth); 1379 for (int i = 0; i < folders.length; i++) { 1381 IContainer parent = folders[i]; 1382 if (!getSyncInfoCacheFor(parent).isSyncInfoLoaded(parent)) { 1383 return false; 1384 } 1385 } 1386 return true; 1387 } 1388 1389 1397 public void ensureSyncInfoLoaded(IResource[] resources, int depth) throws CVSException { 1398 IContainer[] folders = getParentFolders(resources, depth); 1400 for (int i = 0; i < folders.length; i++) { 1402 IContainer parent = folders[i]; 1403 ISchedulingRule rule = null; 1404 try { 1405 rule = beginBatching(parent, null); 1406 try { 1407 beginOperation(); 1408 cacheResourceSyncForChildren(parent, true ); 1409 cacheFolderSync(parent); 1410 cacheFolderIgnores(parent); 1411 } finally { 1412 endOperation(); 1413 } 1414 } finally { 1415 if (rule != null) endBatching(rule, null); 1416 } 1417 } 1418 } 1419 1420 1424 private IContainer[] getParentFolders(IResource[] resources, int depth) throws CVSException { 1425 final Set folders = new HashSet (); 1426 for (int i = 0; i < resources.length; i++) { 1427 IResource resource = resources[i]; 1428 folders.add(resource.getProject()); 1429 if (resource.getType() != IResource.PROJECT) { 1430 folders.add(resource.getParent()); 1431 } 1432 if (depth != IResource.DEPTH_ZERO) { 1434 try { 1435 resource.accept(new IResourceVisitor() { 1436 public boolean visit(IResource innerResource) throws CoreException { 1437 if (innerResource.getType() == IResource.FOLDER) 1438 folders.add(innerResource); 1439 return true; 1441 } 1442 }, depth, false); 1443 } catch (CoreException e) { 1444 throw CVSException.wrapException(e); 1445 } 1446 } 1447 } 1448 return (IContainer[]) folders.toArray(new IContainer[folders.size()]); 1449 } 1450 1451 1458 public void run(ISchedulingRule resourceRule, ICVSRunnable runnable, IProgressMonitor monitor) throws CVSException { 1459 monitor = Policy.monitorFor(monitor); 1460 monitor.beginTask(null, 100); 1461 ISchedulingRule rule = beginBatching(resourceRule, Policy.subMonitorFor(monitor, 1)); 1462 try { 1463 runnable.run(Policy.subMonitorFor(monitor, 98)); 1464 } finally { 1465 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 1)); 1466 monitor.done(); 1467 } 1468 } 1469 1470 1476 public boolean isEdited(IFile resource) { 1477 return SyncFileWriter.isEdited(resource); 1478 } 1479 1480 void adjustDirtyStateRecursively(IResource resource, String indicator) throws CVSException { 1481 if (resource.getType() == IResource.ROOT) return; 1482 try { 1483 beginOperation(); 1484 1485 if (getSyncInfoCacheFor(resource).cachesDirtyState()) { 1486 if (indicator == getDirtyIndicator(resource)) { 1487 return; 1488 } 1489 getSyncInfoCacheFor(resource).setDirtyIndicator(resource, indicator); 1490 } 1491 1492 if (Policy.DEBUG_DIRTY_CACHING) { 1493 debug(resource, indicator, "adjusting dirty state"); } 1495 1496 IContainer parent = resource.getParent(); 1497 if(indicator == NOT_DIRTY_INDICATOR) { 1498 adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); 1499 } 1500 1501 if(indicator == RECOMPUTE_INDICATOR) { 1502 adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); 1503 } 1504 1505 if(indicator == IS_DIRTY_INDICATOR) { 1506 adjustDirtyStateRecursively(parent, indicator); 1507 } 1508 } finally { 1509 endOperation(); 1510 } 1511 } 1512 1513 protected String getDirtyIndicator(IResource resource) throws CVSException { 1514 String indicator = getSyncInfoCacheFor(resource).getDirtyIndicator(resource, false ); 1516 if (indicator != null) 1517 return indicator; 1518 try { 1519 beginOperation(); 1520 return getSyncInfoCacheFor(resource).getDirtyIndicator(resource, true); 1521 } finally { 1522 endOperation(); 1523 } 1524 } 1525 1526 1531 protected void setDirtyIndicator(IResource resource, boolean modified) throws CVSException { 1532 String indicator = modified ? IS_DIRTY_INDICATOR : NOT_DIRTY_INDICATOR; 1533 adjustDirtyStateRecursively(resource, indicator); 1535 } 1536 1537 1541 private String getName(byte[] syncBytes) throws CVSException { 1542 return ResourceSyncInfo.getName(syncBytes); 1543 } 1544 1545 1550 private boolean isFolder(byte[] syncBytes) { 1551 return ResourceSyncInfo.isFolder(syncBytes); 1552 } 1553 1554 1559 private byte[] convertToDeletion(byte[] syncBytes) throws CVSException { 1560 return ResourceSyncInfo.convertToDeletion(syncBytes); 1561 } 1562 1563 static public void debug(IResource resource, String indicator, String string) { 1564 String di = EclipseSynchronizer.IS_DIRTY_INDICATOR; 1565 if(indicator == EclipseSynchronizer.IS_DIRTY_INDICATOR) { 1566 di = "dirty"; } else if(indicator == EclipseSynchronizer.NOT_DIRTY_INDICATOR) { 1568 di = "clean"; } else { 1570 di = "needs recomputing"; } 1572 System.out.println("["+string + ":" + di + "] " + resource.getFullPath()); } 1574 1575 1579 public int getModificationState(IResource resource) throws CVSException { 1580 String indicator = getDirtyIndicator(resource); 1581 if (Policy.DEBUG_DIRTY_CACHING) { 1582 debug(resource, indicator, "getModificationState"); } 1584 if (indicator == null || indicator == RECOMPUTE_INDICATOR) { 1585 return ICVSFile.UNKNOWN; 1586 } else if (indicator == IS_DIRTY_INDICATOR) { 1587 return ICVSFile.DIRTY; 1588 } else if (indicator == NOT_DIRTY_INDICATOR) { 1589 return ICVSFile.CLEAN; 1590 } else { 1591 return ICVSFile.UNKNOWN; 1592 } 1593 } 1594 1595 1601 public boolean isWithinActiveOperationScope(IResource resource) { 1602 return resourceLock.isWithinActiveOperationScope(resource); 1603 } 1604 1605 1613 public void setTimeStamp(EclipseFile cvsFile, long time) throws CVSException { 1614 ISchedulingRule rule = null; 1615 IFile file = (IFile)cvsFile.getIResource(); 1616 try { 1617 rule = beginBatching(file, null); 1618 try { 1619 beginOperation(); 1620 try { 1621 file.setLocalTimeStamp(time); 1622 setModified(cvsFile, ICVSFile.CLEAN); 1623 } catch (CoreException e) { 1624 throw CVSException.wrapException(e); 1625 } 1626 resourceChanged(file); 1627 } finally { 1628 endOperation(); 1629 } 1630 } finally { 1631 if (rule != null) endBatching(rule, null); 1632 } 1633 } 1634 1635 1639 public void postMove(IResource resource) throws CVSException { 1640 try { 1641 beginOperation(); 1642 if (resource.getType() == IResource.FILE) { 1643 sessionPropertyCache.purgeResourceSyncCache(resource); 1646 } else { 1647 IContainer container = (IContainer)resource; 1648 sessionPropertyCache.purgeCache(container, true ); 1650 try { 1652 container.accept(new IResourceVisitor() { 1653 public boolean visit(IResource resource) throws CoreException { 1654 if (getSyncBytes(resource) != null) { 1655 resourceChanged(resource); 1656 } 1657 if (resource.getType() != IResource.FILE) { 1658 if (getFolderSync((IContainer)resource) != null) { 1659 folderChanged((IContainer)resource); 1660 return true; 1661 } 1662 } 1663 return false; 1664 } 1665 }); 1666 } catch (CoreException e) { 1667 throw CVSException.wrapException(e); 1668 } 1669 flush(container, true , null); 1671 } 1672 } finally { 1673 endOperation(); 1674 } 1675 } 1676 1677 1685 public void performMoveDelete(ICVSRunnable runnable, IProgressMonitor monitor) throws CVSException { 1686 ISchedulingRule rule = null; 1687 try { 1688 monitor.beginTask(null, 100); 1689 rule = beginBatching(null, null); 1690 try { 1691 beginOperation(); 1692 runnable.run(Policy.subMonitorFor(monitor, 95)); 1693 } finally { 1694 endOperation(); 1695 } 1696 } finally { 1697 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 5)); 1698 monitor.done(); 1699 } 1700 } 1701 1702 1711 public boolean setModified(EclipseFile cvsFile, int modificationState) throws CVSException { 1712 try { 1713 beginOperation(); 1714 boolean dirty; 1715 if (modificationState == ICVSFile.UNKNOWN) { 1716 dirty = cvsFile.isDirty(); 1717 } else { 1718 dirty = modificationState == ICVSFile.DIRTY; 1719 } 1720 setDirtyIndicator(cvsFile.getIResource(), dirty); 1721 return dirty; 1722 } finally { 1723 endOperation(); 1724 } 1725 1726 } 1727 1728 1735 public void setModified(ICVSFolder cvsFolder, boolean modified) throws CVSException { 1736 try { 1737 beginOperation(); 1738 IContainer folder = (IContainer)cvsFolder.getIResource(); 1739 boolean okToSet = !modified; 1743 ICVSResource[] children = cvsFolder.members(ICVSFolder.ALL_UNIGNORED_MEMBERS); 1745 for (int i = 0; i < children.length; i++) { 1746 IResource resource = children[i].getIResource(); 1747 if (modified) { 1748 if (getDirtyIndicator(resource) == IS_DIRTY_INDICATOR) { 1749 okToSet = true; 1750 break; 1751 } 1752 } else { 1753 if (getDirtyIndicator(resource) != NOT_DIRTY_INDICATOR) { 1754 okToSet = false; 1755 break; 1756 } 1757 } 1758 } 1759 if (okToSet) { 1760 setDirtyIndicator(folder, modified); 1761 } 1762 } finally { 1763 endOperation(); 1764 } 1765 } 1766 1767 public boolean wasPhantom(IResource resource) { 1768 if (resource.exists()) { 1769 try { 1770 return (synchronizerCache.getCachedSyncBytes(resource, true) != null 1771 || (resource.getType() == IResource.FOLDER 1772 && synchronizerCache.hasCachedFolderSync((IContainer)resource))); 1773 } catch (CVSException e) { 1774 CVSProviderPlugin.log(e); 1776 } 1777 } 1778 return false; 1779 } 1780 1781 1787 public void resourcesRecreated(IResource[] resources, IProgressMonitor monitor) throws CVSException { 1788 if (resources.length == 0) return; 1789 ISchedulingRule rule = null; 1790 ISchedulingRule projectsRule = getProjectRule(resources); 1791 try { 1792 monitor = Policy.monitorFor(monitor); 1793 monitor.beginTask(null, 100); 1794 rule = beginBatching(projectsRule, monitor); 1795 for (int i = 0; i < resources.length; i++) { 1796 IResource resource = resources[i]; 1797 try { 1798 created(resource); 1799 } catch (CVSException e) { 1800 CVSProviderPlugin.log(e); 1801 } 1802 } 1803 } finally { 1804 if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 5)); 1805 monitor.done(); 1806 } 1807 } 1808 1809 private ISchedulingRule getProjectRule(IResource[] resources) { 1810 HashSet set = new HashSet (); 1811 for (int i = 0; i < resources.length; i++) { 1812 IResource resource = resources[i]; 1813 set.add(resource.getProject()); 1814 } 1815 IProject[] projects = (IProject[]) set.toArray(new IProject[set.size()]); 1816 if (projects.length == 1) { 1817 return projects[0]; 1818 } 1819 return new MultiRule(projects); 1820 } 1821 1822 protected void created(IResource resource) throws CVSException { 1823 try { 1824 beginOperation(); 1825 if (resource.exists()) { 1826 restoreResourceSync(resource); 1827 if (resource.getType() == IResource.FOLDER) { 1828 restoreFolderSync((IFolder)resource); 1829 } 1830 } 1831 } finally { 1832 endOperation(); 1833 } 1834 } 1835 1836 1839 private void restoreFolderSync(IFolder folder) throws CVSException { 1840 try { 1841 beginOperation(); 1843 FolderSyncInfo folderInfo = synchronizerCache.getCachedFolderSync(folder, true); 1844 if (folderInfo != null) { 1845 if (folder.getFolder(SyncFileWriter.CVS_DIRNAME).exists()) { 1847 1854 FolderSyncInfo newFolderInfo = getFolderSync(folder); 1856 if (newFolderInfo.getRoot().equals(folderInfo.getRoot()) 1857 && newFolderInfo.getRepository().equals(folderInfo.getRepository())) { 1858 } else { 1861 ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(folder); 1864 ICVSResource[] children = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS); 1865 for (int i = 0; i < children.length; i++) { 1866 ICVSResource resource = children[i]; 1867 deleteResourceSync(resource.getIResource()); 1868 } 1869 } 1870 } 1871 1872 setFolderSync(folder, folderInfo); 1874 sessionPropertyCache.purgeDirtyCache(folder); 1876 IResource[] members = members(folder); 1878 IResource changedResource = null; 1879 for (int i = 0; i < members.length; i++) { 1880 IResource resource = members[i]; 1881 if (getSyncBytes(resource) != null) { 1882 changedResource = resource; 1883 break; 1884 } 1885 } 1886 if (changedResource == null) { 1887 changedResource = folder.getFile("dummy"); } 1889 resourceChanged(changedResource); 1890 } 1891 } finally { 1892 try { 1893 endOperation(); 1894 } finally { 1895 synchronizerCache.flush(folder); 1896 } 1897 } 1898 } 1899 1900 1903 private void restoreResourceSync(IResource resource) throws CVSException { 1904 try { 1905 beginOperation(); 1906 byte[] syncBytes = synchronizerCache.getCachedSyncBytes(resource, true); 1907 if (syncBytes != null) { 1908 if (!ResourceSyncInfo.isFolder(syncBytes)) { 1909 syncBytes = ResourceSyncInfo.convertFromDeletion(syncBytes); 1910 } 1911 byte[] newBytes = getSyncBytes(resource); 1912 if (newBytes != null && !ResourceSyncInfo.isFolder(newBytes)) { 1913 newBytes = ResourceSyncInfo.convertFromDeletion(newBytes); 1914 } 1915 if (newBytes == null || Util.equals(syncBytes, newBytes)) { 1916 setSyncBytes(resource, syncBytes); 1918 } 1919 } 1920 } finally { 1921 try { 1922 endOperation(); 1923 } finally { 1924 synchronizerCache.setCachedSyncBytes(resource, null, true); 1925 } 1926 } 1927 } 1928 1929 private void purgeDirtyCache(IProject project, IProgressMonitor monitor) throws CVSException { 1930 sessionPropertyCache.purgeDirtyCache(project); 1931 } 1932} 1933 | Popular Tags |