diff options
author | Jean Michel-Lemieux | 2003-02-20 22:35:37 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2003-02-20 22:35:37 +0000 |
commit | a5e50bccff2e6411caad6da6941c050486ee93a1 (patch) | |
tree | 117db731155c54f77b8e91a0df6ca8bb6346a243 | |
parent | e8dee70b179d3991919c4eb1bf73c5a208dfbcf3 (diff) | |
download | eclipse.platform.team-decoratorRefactoring20030220.tar.gz eclipse.platform.team-decoratorRefactoring20030220.tar.xz eclipse.platform.team-decoratorRefactoring20030220.zip |
*** empty log message ***decoratorRefactoring20030220
9 files changed, 292 insertions, 177 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java index df51bc1ce..eb25afbbb 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java @@ -126,6 +126,7 @@ public class CVSProviderPlugin extends Plugin { private static final int REPOSITORIES_STATE_FILE_VERSION_2 = -1; private Map repositories = new HashMap(); private List repositoryListeners = new ArrayList(); + private static List decoratorEnablementListeners = new ArrayList(); /** * The identifier for the CVS nature @@ -450,6 +451,21 @@ public class CVSProviderPlugin extends Plugin { } } + public static void broadcastDecoratorEnablementChanged(final boolean enabled) { + for(Iterator it=decoratorEnablementListeners.iterator(); it.hasNext();) { + final ICVSDecoratorEnablementListener listener = (ICVSDecoratorEnablementListener)it.next(); + ISafeRunnable code = new ISafeRunnable() { + public void run() throws Exception { + listener.decoratorEnablementChanged(enabled); + } + public void handleException(Throwable e) { + // don't log the exception....it is already being logged in Platform#run + } + }; + Platform.run(code); + } + } + public static void broadcastModificationStateChanges(final IResource[] resources) { for(Iterator it=listeners.iterator(); it.hasNext();) { final IResourceStateChangeListener listener = (IResourceStateChangeListener)it.next(); @@ -639,6 +655,15 @@ public class CVSProviderPlugin extends Plugin { } /** + * Register to receive notification of enablement of sync info decoration requirements. This + * can be useful for providing lazy initialization of caches that are only required for decorating + * resource with CVS information. + */ + public void addDecoratorEnablementListener(ICVSDecoratorEnablementListener listener) { + repositoryListeners.add(listener); + } + + /** * De-register a listener */ public void removeRepositoryListener(ICVSListener listener) { @@ -646,6 +671,13 @@ public class CVSProviderPlugin extends Plugin { } /** + * De-register the decorator enablement listener. + */ + public void removeDecoratorEnablementListener(ICVSDecoratorEnablementListener listener) { + repositoryListeners.remove(listener); + } + + /** * Create a repository instance from the given properties. * The supported properties are: * diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSDecoratorEnablementListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSDecoratorEnablementListener.java new file mode 100644 index 000000000..563e07fc5 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSDecoratorEnablementListener.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM - Initial implementation + ******************************************************************************/ +package org.eclipse.team.internal.ccvs.core; + +/** + * A decorator enablement listener is notified of changes to the enablement + * of CVS state decorators. + * <p> + * Clients may implement this interface. + * </p> + * @see CVSProviderPlugin#addDecoratorEnablementListener(ICVSDecoratorEnablementListener) + */ +public interface ICVSDecoratorEnablementListener { + /** + * Called when CVS decoration is enabled or disabled. Implementers can use the + * decorator enablement change as a chance to create or destroy cached CVS information + * that would help decorate CVS elements. + * + * @param enabled a flag indicating the enablement state of the decorators. + */ + void decoratorEnablementChanged(boolean enabled); +} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java index 374d1ff98..c62346d4a 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java @@ -508,7 +508,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile { EclipseSynchronizer.getInstance().markFileAsUpdated(getIFile()); } - public void handleModification(boolean forAddition) throws CVSException { + public boolean handleModification(boolean forAddition) throws CVSException { if (isIgnored()) { // Special case handling for when a resource passes from the un-managed state // to the ignored state (e.g. ignoring the ignore file). Parent dirty state must be @@ -519,13 +519,14 @@ public class EclipseFile extends EclipseResource implements ICVSFile { if(! resource.isDerived()) { setModified(false); } - return; + return true; } - if (EclipseSynchronizer.getInstance().contentsChangedByUpdate(getIFile())) - return; - - // set the modification state to what it really is and return true if the modification state changed - setModified(computeModified(getSyncInfo())); + if(!EclipseSynchronizer.getInstance().contentsChangedByUpdate(getIFile(), true /* clear update state */)) { + // set the modification state to what it really is and return true if the modification state changed + setModified(computeModified(getSyncInfo())); + return true; + } + return false; } /** diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java index 5beb59fff..c03109c06 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java @@ -358,9 +358,9 @@ class EclipseFolder extends EclipseResource implements ICVSFolder { return indicator == EclipseSynchronizer.IS_DIRTY_INDICATOR; } - public void handleModification(boolean forAddition) throws CVSException { + public boolean handleModification(boolean forAddition) throws CVSException { // For non-additions, we are only interested in sync info changes - if (isIgnored() || !forAddition) return; + if (isIgnored() || !forAddition) return false; // the folder is an addition. FolderSyncInfo info = getFolderSyncInfo(); @@ -368,7 +368,9 @@ class EclipseFolder extends EclipseResource implements ICVSFolder { // otherwise, flush the ancestors to recalculate if (info == null) { setModified((IContainer)getIResource(), EclipseSynchronizer.IS_DIRTY_INDICATOR); + return true; } + return false; } /** diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java index 7aa031c36..de6092a93 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java @@ -292,7 +292,7 @@ abstract class EclipseResource implements ICVSResource, Comparable { return resource; } - public abstract void handleModification(boolean forAddition) throws CVSException; + public abstract boolean handleModification(boolean forAddition) throws CVSException; /** * Method created is invoked after a resource is created diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java index a98fa2c04..ac5ab32c9 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java @@ -827,7 +827,8 @@ public class EclipseSynchronizer { } /*** broadcast events ***/ - changedResources.addAll(changedFolders); + changedResources.addAll(changedFolders); + changedResources.addAll(dirtyParents); IResource[] resources = (IResource[]) changedResources.toArray( new IResource[changedResources.size()]); broadcastResourceStateChanges(resources); @@ -859,7 +860,10 @@ public class EclipseSynchronizer { for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; try { - internalSetDirtyIndicator(resource, RECOMPUTE_INDICATOR); + if((resource.getType() == IResource.FILE && !contentsChangedByUpdate((IFile)resource, false /* don't clear */)) || + resource.getType() != IResource.FILE) { + adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR); + } } catch (CVSException e) { CVSProviderPlugin.log(e); } @@ -1230,35 +1234,36 @@ public class EclipseSynchronizer { return SyncFileWriter.isEdited(resource); } - private void internalSetDirtyIndicator(IResource resource, String indicator) throws CVSException { - adjustDirtyStateRecursively(resource, indicator); - } - - public void adjustDirtyStateRecursively(IResource resource, String indicator) throws CVSException { + private void adjustDirtyStateRecursively(IResource resource, String indicator) throws CVSException { if (resource.getType() == IResource.ROOT) return; - try { - beginOperation(null); - try { - if (Policy.DEBUG_DIRTY_CACHING) { - debug(resource, indicator, "adjusting dirty state"); - } - getSyncInfoCacheFor(resource).setDirtyIndicator(resource, indicator); - } finally { - IContainer parent = resource.getParent(); - String parentIndicator = getDirtyIndicator(parent); - if(indicator == RECOMPUTE_INDICATOR) { - adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); - } else if(indicator == IS_DIRTY_INDICATOR && parentIndicator == NOT_DIRTY_INDICATOR) { - adjustDirtyStateRecursively(parent, indicator); - } else if(indicator == NOT_DIRTY_INDICATOR && parentIndicator == IS_DIRTY_INDICATOR) { - adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); - } else { - // parents are already in the good state - } - } - } finally { - endOperation(null); + try { + beginOperation(null); + + if (indicator == getDirtyIndicator(resource)) { + return; + } + + if (Policy.DEBUG_DIRTY_CACHING) { + debug(resource, indicator, "adjusting dirty state"); } + + getSyncInfoCacheFor(resource).setDirtyIndicator(resource, indicator); + + IContainer parent = resource.getParent(); + if(indicator == NOT_DIRTY_INDICATOR) { + adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); + } + + if(indicator == RECOMPUTE_INDICATOR) { + adjustDirtyStateRecursively(parent, RECOMPUTE_INDICATOR); + } + + if(indicator == IS_DIRTY_INDICATOR) { + adjustDirtyStateRecursively(parent, indicator); + } + } finally { + endOperation(null); + } } protected String getDirtyIndicator(IResource resource) throws CVSException { @@ -1279,11 +1284,6 @@ public class EclipseSynchronizer { try { beginOperation(null); String indicator = modified ? IS_DIRTY_INDICATOR : NOT_DIRTY_INDICATOR; - - if (indicator == getDirtyIndicator(resource)) { - return; - } - // set the dirty indicator and adjust the parent accordingly adjustDirtyStateRecursively(resource, indicator); } finally { @@ -1302,8 +1302,12 @@ public class EclipseSynchronizer { sessionPropertyCache.markFileAsUpdated(file); } - protected boolean contentsChangedByUpdate(IFile file) throws CVSException { - return sessionPropertyCache.contentsChangedByUpdate(file); + protected boolean contentsChangedByUpdate(IFile file, boolean clear) throws CVSException { + if(file.exists()) { + return sessionPropertyCache.contentsChangedByUpdate(file, clear); + } else { + return false; + } } /** diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java index e3ee64989..13eb413ca 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java @@ -43,6 +43,14 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa private Set modifiedResources = new HashSet(); + // consider the following changes types and ignore the others (e.g. marker and description changes are ignored) + protected int INTERESTING_CHANGES = IResourceDelta.CONTENT | + IResourceDelta.MOVED_FROM | + IResourceDelta.MOVED_TO | + IResourceDelta.OPEN | + IResourceDelta.REPLACED | + IResourceDelta.TYPE; + /** * Listen for file modifications and fire modification state changes * @@ -68,7 +76,10 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa } if (resource.getType()==IResource.FILE && delta.getKind() == IResourceDelta.CHANGED && resource.exists()) { - contentsChanged((IFile)resource); + int flags = delta.getFlags(); + if((flags & INTERESTING_CHANGES) != 0) { + contentsChanged((IFile)resource); + } } else if (delta.getKind() == IResourceDelta.ADDED) { resourceAdded(resource); } else if (delta.getKind() == IResourceDelta.REMOVED) { @@ -143,7 +154,6 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa try { EclipseFile cvsFile = (EclipseFile)CVSWorkspaceRoot.getCVSFileFor(file); cvsFile.handleModification(false /* addition */); - // add all files to the modified list modifiedResources.add(file); } catch (CVSException e) { throw e.toCoreException(); diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java index 71e16141c..80eeb1ff3 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java @@ -14,17 +14,20 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.ISaveContext; import org.eclipse.core.resources.ISaveParticipant; import org.eclipse.core.resources.ISynchronizer; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; +import org.eclipse.team.internal.ccvs.core.ICVSDecoratorEnablementListener; import org.eclipse.team.internal.ccvs.core.Policy; import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; @@ -35,7 +38,8 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * state for all cvs managed folders are persisted using the resource's plugin * synchronizer. */ -/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache implements ISaveParticipant { +/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache + implements ISaveParticipant, ICVSDecoratorEnablementListener { // key used on a folder to indicate that the resource sync has been cahced for it's children private static final QualifiedName RESOURCE_SYNC_CACHED_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync-cached"); //$NON-NLS-1$ @@ -44,10 +48,17 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; /*package*/ static final String[] NULL_IGNORES = new String[0]; private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("", "", null, false); //$NON-NLS-1$ //$NON-NLS-2$ + private QualifiedName FOLDER_DIRTY_STATE_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-dirty-state-cached"); //$NON-NLS-1$ + private boolean isDecoratorEnabled = true; + /*package*/ SessionPropertySyncInfoCache() { try { // this save participant is removed when the plugin is shutdown. ResourcesPlugin.getWorkspace().addSaveParticipant(CVSProviderPlugin.getPlugin(), this); + CVSProviderPlugin.getPlugin().addDecoratorEnablementListener(this); + + final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); + synchronizer.add(FOLDER_DIRTY_STATE_KEY); } catch (CoreException e) { CVSProviderPlugin.log(e.getStatus()); } @@ -61,43 +72,27 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @return the folder ignore patterns, or an empty array if none */ /*package*/ String[] cacheFolderIgnores(IContainer container) throws CVSException { - try { - // don't try to load if the information is already cached - String[] ignores = (String[])container.getSessionProperty(IGNORE_SYNC_KEY); - if (ignores == null) { - // read folder ignores and remember it - ignores = SyncFileWriter.readCVSIgnoreEntries(container); - if (ignores == null) ignores = NULL_IGNORES; - container.setSessionProperty(IGNORE_SYNC_KEY, ignores); - } - return ignores; - } catch (CoreException e) { - throw CVSException.wrapException(e); + // don't try to load if the information is already cached + String[] ignores = (String[])safeGetSessionProperty(container, IGNORE_SYNC_KEY); + if (ignores == null) { + // read folder ignores and remember it + ignores = SyncFileWriter.readCVSIgnoreEntries(container); + if (ignores == null) ignores = NULL_IGNORES; + safeSetSessionProperty(container, IGNORE_SYNC_KEY, ignores); } + return ignores; } /*package*/ boolean isFolderSyncInfoCached(IContainer container) throws CVSException { - try { - return container.getSessionProperty(FOLDER_SYNC_KEY) != null; - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + return safeGetSessionProperty(container, FOLDER_SYNC_KEY) != null; } /*package*/ boolean isResourceSyncInfoCached(IContainer container) throws CVSException { - try { - return container.getSessionProperty(RESOURCE_SYNC_CACHED_KEY) != null; - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + return safeGetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY) != null; } /*package*/ void setResourceSyncInfoCached(IContainer container) throws CVSException { - try { - container.setSessionProperty(RESOURCE_SYNC_CACHED_KEY, RESOURCE_SYNC_CACHED); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, RESOURCE_SYNC_CACHED); } /** @@ -110,18 +105,13 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @see #cacheFolderSync */ /*package*/ FolderSyncInfo getCachedFolderSync(IContainer container) throws CVSException { - if (!container.exists()) return null; - try { - FolderSyncInfo info = (FolderSyncInfo)container.getSessionProperty(FOLDER_SYNC_KEY); - if (info == null) { - // There should be sync info but it was missing. Report the error - throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$ - } - if (info == NULL_FOLDER_SYNC_INFO) return null; - return info; - } catch (CoreException e) { - throw CVSException.wrapException(e); + FolderSyncInfo info = (FolderSyncInfo)safeGetSessionProperty(container, FOLDER_SYNC_KEY); + if (info == null) { + // There should be sync info but it was missing. Report the error + throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$ } + if (info == NULL_FOLDER_SYNC_INFO) return null; + return info; } /** @@ -132,9 +122,9 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; if (! container.exists()) return; try { if (container.getType() != IResource.ROOT) { - container.setSessionProperty(IGNORE_SYNC_KEY, null); - container.setSessionProperty(FOLDER_SYNC_KEY, null); - container.setSessionProperty(RESOURCE_SYNC_CACHED_KEY, null); + safeSetSessionProperty(container, IGNORE_SYNC_KEY, null); + safeSetSessionProperty(container, FOLDER_SYNC_KEY, null); + safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, null); } IResource[] members = container.members(); for (int i = 0; i < members.length; i++) { @@ -150,11 +140,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; } /* package*/ void purgeResourceSyncCache(IResource resource) throws CVSException { - try { - resource.setSessionProperty(RESOURCE_SYNC_KEY, null); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, null); } /** @@ -165,11 +151,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @param ignores the array of ignore patterns */ /*package*/ void setCachedFolderIgnores(IContainer container, String[] ignores) throws CVSException { - try { - container.setSessionProperty(IGNORE_SYNC_KEY, ignores); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(container, IGNORE_SYNC_KEY, ignores); } @@ -183,12 +165,10 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; */ /*package*/ void setCachedFolderSync(IContainer container, FolderSyncInfo info) throws CVSException { if (!container.exists()) return; - try { - if (info == null) info = NULL_FOLDER_SYNC_INFO; - container.setSessionProperty(FOLDER_SYNC_KEY, info); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + if (info == null) { + info = NULL_FOLDER_SYNC_INFO; + } + safeSetSessionProperty(container, FOLDER_SYNC_KEY, info); } /*package*/ void setDirtyIndicator(IResource resource, String indicator) throws CVSException { @@ -205,40 +185,32 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; return internalGetDirtyIndicator((IContainer)resource); } } + private void internalSetDirtyIndicator(IFile file, String indicator) throws CVSException { - try { - file.setSessionProperty(IS_DIRTY, indicator); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(file, IS_DIRTY, indicator); } + private String internalGetDirtyIndicator(IFile file) throws CVSException { - try { - String di = (String)file.getSessionProperty(IS_DIRTY); - if(di == null) { - di = RECOMPUTE_INDICATOR; - } - return di; - } catch (CoreException e) { - throw CVSException.wrapException(e); + String di = (String)safeGetSessionProperty(file, IS_DIRTY); + if(di == null) { + di = RECOMPUTE_INDICATOR; } + return di; } + private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException { - try { - container.setSessionProperty(IS_DIRTY, indicator); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(container, IS_DIRTY, indicator); } + private String internalGetDirtyIndicator(IContainer container) throws CVSException { try { - String di = (String)container.getSessionProperty(IS_DIRTY); + String di = (String)safeGetSessionProperty(container, IS_DIRTY); // if the session property is not available then restore from persisted sync info. At this // time the sync info is not flushed because we don't want the workspace to generate // a delta. if(di == null) { - byte [] diBytes = ResourcesPlugin.getWorkspace().getSynchronizer().getSyncInfo(RESOURCE_SYNC_KEY, container); + byte [] diBytes = ResourcesPlugin.getWorkspace().getSynchronizer().getSyncInfo(FOLDER_DIRTY_STATE_KEY, container); if(diBytes != null) { di = new String(diBytes); if(di.equals(NOT_DIRTY_INDICATOR)) { @@ -264,15 +236,11 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; */ /*package*/ void flushDirtyCache(IResource resource) throws CVSException { if (resource.exists()) { - try { - if (resource.getType() == IResource.FILE) { - resource.setSessionProperty(IS_DIRTY, RECOMPUTE_INDICATOR); - resource.setSessionProperty(CLEAN_UPDATE, null); - } else { - resource.setSessionProperty(IS_DIRTY, RECOMPUTE_INDICATOR); - } - } catch (CoreException e) { - throw CVSException.wrapException(e); + if (resource.getType() == IResource.FILE) { + safeSetSessionProperty(resource, IS_DIRTY, RECOMPUTE_INDICATOR); + safeSetSessionProperty(resource, CLEAN_UPDATE, null); + } else { + safeSetSessionProperty(resource, IS_DIRTY, RECOMPUTE_INDICATOR); } } } @@ -285,31 +253,21 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @param mFile */ /*package*/ void markFileAsUpdated(IFile file) throws CVSException { - try { - file.setSessionProperty(CLEAN_UPDATE, UPDATED_INDICATOR); - - // update dirty state so that decorators don't have to recompute after - // an update is completed. - contentsChangedByUpdate(file); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(file, CLEAN_UPDATE, UPDATED_INDICATOR); } - /*package*/ boolean contentsChangedByUpdate(IFile file) throws CVSException { - try { - Object indicator = file.getSessionProperty(CLEAN_UPDATE); - boolean updated = false; - if (indicator == UPDATED_INDICATOR) { - // the file was changed due to a clean update (i.e. no local mods) so skip it - file.setSessionProperty(CLEAN_UPDATE, null); - file.setSessionProperty(IS_DIRTY, NOT_DIRTY_INDICATOR); - updated = true; + /*package*/ boolean contentsChangedByUpdate(IFile file, boolean clear) throws CVSException { + Object indicator = safeGetSessionProperty(file, CLEAN_UPDATE); + boolean updated = false; + if (indicator == UPDATED_INDICATOR) { + // the file was changed due to a clean update (i.e. no local mods) so skip it + if(clear) { + safeSetSessionProperty(file, CLEAN_UPDATE, null); + safeSetSessionProperty(file, IS_DIRTY, NOT_DIRTY_INDICATOR); } - return updated; - } catch (CoreException e) { - throw CVSException.wrapException(e); + updated = true; } + return updated; } /** @@ -321,18 +279,13 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @return boolean */ /*package*/ boolean isSyncInfoLoaded(IContainer parent) throws CVSException { - try { - if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) { - if (parent.getSessionProperty(RESOURCE_SYNC_CACHED_KEY) == null) - return false; - if (parent.getSessionProperty(FOLDER_SYNC_KEY) == null) - return false; + if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) { + if (safeGetSessionProperty(parent, RESOURCE_SYNC_CACHED_KEY) == null) + return false; + if (safeGetSessionProperty(parent, FOLDER_SYNC_KEY) == null) + return false; // if (parent.getSessionProperty(IGNORE_SYNC_KEY) == null) // return false; - } - } catch (CoreException e) { - // let future operations surface the error - return false; } return true; } @@ -341,21 +294,51 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#getCachedSyncBytes(org.eclipse.core.resources.IResource) */ /*package*/ byte[] getCachedSyncBytes(IResource resource) throws CVSException { + return (byte[])safeGetSessionProperty(resource, RESOURCE_SYNC_KEY); + } + + Object safeGetSessionProperty(IResource resource, QualifiedName key) throws CVSException { try { - return (byte[])resource.getSessionProperty(RESOURCE_SYNC_KEY); + return resource.getSessionProperty(key); } catch (CoreException e) { + IStatus status = e.getStatus(); + if(status != null) { + int code = e.getStatus().getCode(); + if(code != IResourceStatus.RESOURCE_NOT_LOCAL || + code != IResourceStatus.RESOURCE_NOT_FOUND) { + // ignore error since a phantom would of been created + // and we can safely ignore these cases + return null; + } + } + // some other error we did not expect throw CVSException.wrapException(e); } } + + void safeSetSessionProperty(IResource resource, QualifiedName key, Object value) throws CVSException { + try { + resource.setSessionProperty(key, value); + } catch (CoreException e) { + IStatus status = e.getStatus(); + if(status != null) { + int code = e.getStatus().getCode(); + if(code == IResourceStatus.RESOURCE_NOT_LOCAL || + code == IResourceStatus.RESOURCE_NOT_FOUND) { + // ignore error since a phantom would of been created + // and we can safely ignore these cases + } + // some other error we did not expect + throw CVSException.wrapException(e); + } + } + } + /** * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#setCachedSyncBytes(org.eclipse.core.resources.IResource, byte[]) */ /*package*/ void setCachedSyncBytes(IResource resource, byte[] syncBytes) throws CVSException { - try { - resource.setSessionProperty(RESOURCE_SYNC_KEY, syncBytes); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } + safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, syncBytes); } /* (non-Javadoc) @@ -396,10 +379,9 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; boolean fullSave = (context.getKind() == ISaveContext.FULL_SAVE); boolean projectSave = (context.getKind() == ISaveContext.PROJECT_SAVE); - if(projectSave || fullSave) { + if(isDecoratorEnabled && (projectSave || fullSave)) { // persist all session properties for folders into sync info. final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); - synchronizer.add(RESOURCE_SYNC_KEY); // traverse the workspace looking for CVS managed projects or just the // specific projects being closed @@ -430,7 +412,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; CVSProviderPlugin.log(e); } if(di != null) { - synchronizer.setSyncInfo(RESOURCE_SYNC_KEY, resource, di.getBytes()); + synchronizer.setSyncInfo(FOLDER_DIRTY_STATE_KEY, resource, di.getBytes()); } } return true; @@ -440,4 +422,41 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; } } } + + /* (non-Javadoc) + * @see ICVSDecoratorEnablementListener#decoratorEnablementChanged(boolean) + */ + public void decoratorEnablementChanged(boolean enabled) { + // DECORATOR enable this code once PR 32354 is fixed. + // In addition, try and remove any code paths that are not required if the decorators + // are turned off. +// isDecoratorEnabled = enabled; +// if(!enabled) { +// flushDirtyStateFromDisk(); +// } + } + + /* + * Called to clear the folder dirty state from the resource sync tree and stop persisting + * these values to disk. + */ + private void flushDirtyStateFromDisk() { + final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); + + IProject[] projects; + projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + + for (int i = 0; i < projects.length; i++) { + IProject project = projects[i]; + RepositoryProvider provider = RepositoryProvider.getProvider( + project, + CVSProviderPlugin.getTypeId()); + + try { + synchronizer.flushSyncInfo(FOLDER_DIRTY_STATE_KEY, project, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + CVSProviderPlugin.log(e.getStatus()); + } + } + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java index 1eda04cf6..5d707e8da 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java @@ -50,6 +50,15 @@ import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; * See: http://dev.eclipse.org/bugs/show_bug.cgi?id=12386 */ public class SyncFileChangeListener implements IResourceChangeListener { + + // consider the following changes types and ignore the others (e.g. marker and description changes are ignored) + protected int INTERESTING_CHANGES = IResourceDelta.CONTENT | + IResourceDelta.MOVED_FROM | + IResourceDelta.MOVED_TO | + IResourceDelta.OPEN | + IResourceDelta.REPLACED | + IResourceDelta.TYPE; + /* * When a resource changes this method will detect if the changed resources is a meta file that has changed * by a 3rd party. For example, if the command line tool was run and then the user refreshed from local. To @@ -75,9 +84,17 @@ public class SyncFileChangeListener implements IResourceChangeListener { if (!resource.isAccessible()) return false; if ((delta.getFlags() & IResourceDelta.OPEN) != 0) return false; } - + String name = resource.getName(); int kind = delta.getKind(); + + // if the file has changed but not in a way that we care + // then ignore the change (e.g. marker changes to files). + if(kind == IResourceDelta.CHANGED && + (delta.getFlags() & INTERESTING_CHANGES) == 0) { + return true; + } + IResource[] toBeNotified = new IResource[0]; if(name.equals(SyncFileWriter.CVS_DIRNAME)) { @@ -92,7 +109,7 @@ public class SyncFileChangeListener implements IResourceChangeListener { } } } - + if(isMetaFile(resource)) { toBeNotified = handleChangedMetaFile(resource, kind); } else if(name.equals(SyncFileWriter.IGNORE_FILE)) { |