1 11 package org.eclipse.team.internal.ccvs.core.resources; 12 13 import java.util.Arrays ; 14 import java.util.HashSet ; 15 import java.util.Set ; 16 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.runtime.*; 19 import org.eclipse.osgi.util.NLS; 20 import org.eclipse.team.core.RepositoryProvider; 21 import org.eclipse.team.internal.ccvs.core.*; 22 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 23 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 24 import org.eclipse.team.internal.ccvs.core.util.FileNameMatcher; 25 import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; 26 27 33 class SessionPropertySyncInfoCache extends SyncInfoCache implements ISaveParticipant { 34 35 private static final QualifiedName RESOURCE_SYNC_CACHED_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync-cached"); private static final Object RESOURCE_SYNC_CACHED = new Object (); 38 39 static final FileNameMatcher NULL_IGNORES = new FileNameMatcher(); 40 private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("dummy-repo", "dummy-root", null, false); 42 private QualifiedName FOLDER_DIRTY_STATE_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-dirty-state-cached"); 44 private SynchronizerSyncInfoCache synchronizerCache; 47 48 SessionPropertySyncInfoCache(SynchronizerSyncInfoCache synchronizerCache) { 49 this.synchronizerCache = synchronizerCache; 50 try { 51 ResourcesPlugin.getWorkspace().addSaveParticipant(CVSProviderPlugin.getPlugin(), this); 53 ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); 54 synchronizer.add(FOLDER_DIRTY_STATE_KEY); 55 } catch (CoreException e) { 56 CVSProviderPlugin.log(e); 57 } 58 } 59 60 67 FileNameMatcher getFolderIgnores(IContainer container, boolean threadSafeAccess) throws CVSException { 68 FileNameMatcher matcher = (FileNameMatcher)safeGetSessionProperty(container, IGNORE_SYNC_KEY); 70 if (threadSafeAccess && matcher == null) { 71 String [] ignores = SyncFileWriter.readCVSIgnoreEntries(container); 73 if (ignores == null) { 74 matcher = NULL_IGNORES; 75 } else { 76 matcher = new FileNameMatcher(ignores); 77 } 78 safeSetSessionProperty(container, IGNORE_SYNC_KEY, matcher); 79 } 80 return matcher; 81 } 82 83 boolean isIgnoresCached(IContainer container) throws CVSException { 84 return safeGetSessionProperty(container, IGNORE_SYNC_KEY) != null; 85 } 86 87 boolean isFolderSyncInfoCached(IContainer container) throws CVSException { 88 Object info = safeGetSessionProperty(container, FOLDER_SYNC_KEY); 89 if (info == null){ 90 info = synchronizerCache.getCachedFolderSync(container, true); 92 } 93 return info != null; 94 } 95 96 boolean isResourceSyncInfoCached(IContainer container) throws CVSException { 97 return safeGetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY) != null; 98 } 99 100 void setResourceSyncInfoCached(IContainer container) throws CVSException { 101 safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, RESOURCE_SYNC_CACHED); 102 } 103 104 113 FolderSyncInfo getCachedFolderSync(IContainer container, boolean threadSafeAccess) throws CVSException { 114 FolderSyncInfo info = (FolderSyncInfo)safeGetSessionProperty(container, FOLDER_SYNC_KEY); 115 if (!threadSafeAccess) 117 return info == NULL_FOLDER_SYNC_INFO ? null : info; 118 if (info == null) { 119 info = synchronizerCache.getCachedFolderSync(container, true); 121 if (info != null) { 122 safeSetSessionProperty(container, FOLDER_SYNC_KEY, info); 123 } 124 } 125 if (info == null) { 126 if (container.exists() && !container.isDerived()){ 129 IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSMessages.EclipseSynchronizer_folderSyncInfoMissing, new String [] { container.getFullPath().toString() }), container); 130 throw new CVSException(status); 131 } 132 } 133 if (info == NULL_FOLDER_SYNC_INFO) return null; 134 return info; 135 } 136 137 142 IResource[] purgeCache(IContainer container, boolean deep) throws CVSException { 143 if (! container.exists()) return new IResource[0]; 144 try { 145 Set flushed = new HashSet (); 146 if (container.getType() != IResource.ROOT) { 147 safeSetSessionProperty(container, IGNORE_SYNC_KEY, null); 148 safeSetSessionProperty(container, FOLDER_SYNC_KEY, null); 149 safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, null); 150 flushed.add(container); 151 EclipseSynchronizer.getInstance().adjustDirtyStateRecursively(container, RECOMPUTE_INDICATOR); 152 } 153 IResource[] members = container.members(); 154 for (int i = 0; i < members.length; i++) { 155 IResource resource = members[i]; 156 purgeResourceSyncCache(resource); 157 flushed.add(resource); 158 if (deep && resource.getType() != IResource.FILE) { 159 IResource[] flushedChildren = purgeCache((IContainer) resource, deep); 160 flushed.addAll(Arrays.asList(flushedChildren)); 161 } 162 } 163 return (IResource[]) flushed.toArray(new IResource[flushed.size()]); 164 } catch (CoreException e) { 165 throw CVSException.wrapException(e); 166 } 167 } 168 169 void purgeResourceSyncCache(IResource resource) throws CVSException { 170 safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, null); 171 EclipseSynchronizer.getInstance().adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR); 172 } 173 174 181 void setCachedFolderIgnores(IContainer container, String [] ignores) throws CVSException { 182 safeSetSessionProperty(container, IGNORE_SYNC_KEY, new FileNameMatcher(ignores)); 183 } 184 185 186 194 void setCachedFolderSync(IContainer container, FolderSyncInfo info, boolean canModifyWorkspace) throws CVSException { 195 if (!container.exists()) return; 196 if (info == null) { 197 info = NULL_FOLDER_SYNC_INFO; 198 } 199 safeSetSessionProperty(container, FOLDER_SYNC_KEY, info); 200 if (canModifyWorkspace && synchronizerCache.getCachedFolderSync(container, true) != null) { 202 synchronizerCache.setCachedFolderSync(container, null, true); 203 } 204 } 205 206 void setDirtyIndicator(IResource resource, String indicator) throws CVSException { 207 if (resource.getType() == IResource.FILE) { 208 internalSetDirtyIndicator((IFile)resource, indicator); 209 } else { 210 internalSetDirtyIndicator((IContainer)resource, indicator); 211 } 212 } 213 String getDirtyIndicator(IResource resource, boolean threadSafeAccess) throws CVSException { 214 if (resource.getType() == IResource.FILE) { 215 return internalGetDirtyIndicator((IFile)resource, threadSafeAccess); 216 } else { 217 return internalGetDirtyIndicator((IContainer)resource, threadSafeAccess); 218 } 219 } 220 221 private void internalSetDirtyIndicator(IFile file, String indicator) throws CVSException { 222 safeSetSessionProperty(file, IS_DIRTY, indicator); 223 } 224 225 private String internalGetDirtyIndicator(IFile file, boolean threadSafeAccess) throws CVSException { 226 String di = (String )safeGetSessionProperty(file, IS_DIRTY); 227 if(di == null) { 228 di = RECOMPUTE_INDICATOR; 229 } 230 return di; 231 } 232 233 private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException { 234 safeSetSessionProperty(container, IS_DIRTY, indicator); 235 } 236 237 private String internalGetDirtyIndicator(IContainer container, boolean threadSafeAccess) throws CVSException { 238 try { 239 String di = (String )safeGetSessionProperty(container, IS_DIRTY); 240 241 if(di == null) { 245 byte [] diBytes = ResourcesPlugin.getWorkspace().getSynchronizer().getSyncInfo(FOLDER_DIRTY_STATE_KEY, container); 246 if(diBytes != null && !CVSProviderPlugin.getPlugin().crashOnLastRun()) { 247 di = new String (diBytes); 248 if(di.equals(NOT_DIRTY_INDICATOR)) { 249 di = NOT_DIRTY_INDICATOR; 250 } else if(di.equals(IS_DIRTY_INDICATOR)) { 251 di = IS_DIRTY_INDICATOR; 252 } else { 253 di = RECOMPUTE_INDICATOR; 254 } 255 } else { 256 di = RECOMPUTE_INDICATOR; 257 } 258 if (threadSafeAccess) { 260 setDirtyIndicator(container, di); 261 } 262 } 263 return di; 264 } catch (CoreException e) { 265 throw CVSException.wrapException(e); 266 } 267 } 268 269 272 void flushDirtyCache(IResource resource) throws CVSException { 273 if (resource.exists()) { 274 if (resource.getType() == IResource.FILE) { 275 safeSetSessionProperty(resource, IS_DIRTY, null); 276 } else { 277 safeSetSessionProperty(resource, IS_DIRTY, null); 278 flushDirtyStateFromDisk((IContainer)resource); 279 } 280 } 281 } 282 283 291 boolean isSyncInfoLoaded(IContainer parent) throws CVSException { 292 if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) { 293 if (safeGetSessionProperty(parent, RESOURCE_SYNC_CACHED_KEY) == null) 294 return false; 295 if (safeGetSessionProperty(parent, FOLDER_SYNC_KEY) == null) 296 return false; 297 } 300 return true; 301 } 302 303 306 byte[] getCachedSyncBytes(IResource resource, boolean threadSafeAccess) throws CVSException { 307 byte[] bytes = (byte[])safeGetSessionProperty(resource, RESOURCE_SYNC_KEY); 308 if (!threadSafeAccess) 310 return bytes; 311 if (bytes == null) { 312 bytes = synchronizerCache.getCachedSyncBytes(resource, true); 314 if (bytes != null) { 315 boolean genderChange = false; 316 if (resource.getType() == IResource.FILE) { 317 if (ResourceSyncInfo.isFolder(bytes)) { 318 genderChange = true; 319 } 320 } else if (!ResourceSyncInfo.isFolder(bytes)) { 321 genderChange = true; 322 } 323 if (genderChange) { 324 bytes = null; 326 } else { 327 safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, ResourceSyncInfo.convertFromDeletion(bytes)); 328 } 329 } 330 } 331 return bytes; 332 } 333 334 Object safeGetSessionProperty(IResource resource, QualifiedName key) throws CVSException { 335 try { 336 return resource.getSessionProperty(key); 337 } catch (CoreException e) { 338 IStatus status = e.getStatus(); 339 if(status != null) { 340 int code = e.getStatus().getCode(); 341 if(code != IResourceStatus.RESOURCE_NOT_LOCAL || 342 code != IResourceStatus.RESOURCE_NOT_FOUND) { 343 return null; 346 } 347 } 348 throw CVSException.wrapException(e); 350 } 351 } 352 353 void safeSetSessionProperty(IResource resource, QualifiedName key, Object value) throws CVSException { 354 try { 355 resource.setSessionProperty(key, value); 356 } catch (CoreException e) { 357 throw CVSException.wrapException(e); 358 } 359 } 360 361 364 void setCachedSyncBytes(IResource resource, byte[] syncBytes, boolean canModifyWorkspace) throws CVSException { 365 if (syncBytes != null && ResourceSyncInfo.isDeletion(syncBytes)) { 367 syncBytes = ResourceSyncInfo.convertFromDeletion(syncBytes); 368 } 369 safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, syncBytes); 371 if (canModifyWorkspace && synchronizerCache.getCachedSyncBytes(resource, true) != null) { 373 synchronizerCache.setCachedSyncBytes(resource, null, canModifyWorkspace); 374 } 375 } 376 377 380 public void doneSaving(ISaveContext context) { 381 } 382 383 386 public void prepareToSave(ISaveContext context) throws CoreException { 387 } 388 389 392 public void rollback(ISaveContext context) { 393 } 394 395 401 public void saving(ISaveContext context) throws CoreException { 402 boolean fullSave = (context.getKind() == ISaveContext.FULL_SAVE); 403 boolean projectSave = (context.getKind() == ISaveContext.PROJECT_SAVE); 404 405 if((projectSave || fullSave)) { 406 final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); 408 409 IProject[] projects; 412 if(projectSave) { 413 projects = new IProject[1]; 414 projects[0] = context.getProject(); 415 } else { 416 projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); 417 } 418 for (int i = 0; i < projects.length; i++) { 419 IProject project = projects[i]; 420 RepositoryProvider provider = RepositoryProvider.getProvider( 421 project, 422 CVSProviderPlugin.getTypeId()); 423 424 if (provider != null) { 427 project.accept(new IResourceVisitor() { 428 public boolean visit(IResource resource) throws CoreException { 429 if(resource.getType() != IResource.FILE) { 430 String di = null; 431 try { 432 di = getDirtyIndicator(resource, true); 433 } catch (CVSException e) { 434 CVSProviderPlugin.log(e); 436 } 437 if(di != null) { 438 synchronizer.setSyncInfo(FOLDER_DIRTY_STATE_KEY, resource, di.getBytes()); 439 } 440 } 441 return true; 442 } 443 }); 444 } 445 } 446 } 447 } 448 449 453 private void flushDirtyStateFromDisk(IContainer container) { 454 final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); 455 try { 456 synchronizer.flushSyncInfo(FOLDER_DIRTY_STATE_KEY, container, IResource.DEPTH_INFINITE); 457 } catch (CoreException e) { 458 CVSProviderPlugin.log(e); 459 } 460 } 461 462 465 void purgeDirtyCache(IResource resource) throws CVSException { 466 if (! resource.exists()) return; 467 try { 468 if (resource.getType() != IResource.ROOT) { 469 safeSetSessionProperty(resource, IS_DIRTY, null); 470 } 471 if (resource.getType() != IResource.FILE) { 472 ResourcesPlugin.getWorkspace().getSynchronizer().flushSyncInfo(FOLDER_DIRTY_STATE_KEY, resource, IResource.DEPTH_INFINITE); 473 IResource[] members = ((IContainer)resource).members(); 474 for (int i = 0; i < members.length; i++) { 475 purgeDirtyCache(members[i]); 476 } 477 } 478 } catch (CoreException e) { 479 throw CVSException.wrapException(e); 480 } 481 } 482 483 486 public boolean cachesDirtyState() { 487 return true; 488 } 489 } 490 | Popular Tags |