Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java46
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java6
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java10
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java93
4 files changed, 107 insertions, 48 deletions
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 9fb627e63..ac4a27d1b 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
@@ -101,11 +101,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
} else {
time = date.getTime();
}
- try {
- EclipseSynchronizer.getInstance().setTimeStamp(getIFile(), time);
- } finally {
- setModified(false);
- }
+ EclipseSynchronizer.getInstance().setTimeStamp(getIFile(), time);
}
/*
@@ -136,27 +132,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
ResourceSyncInfo info = getSyncInfo();
if (info == null && isIgnored()) return false;
// unmanaged files are reported as modified
- boolean dirty = computeModified(info);
- setModified(dirty);
- return dirty;
- }
-
- /*
- * Deteremine if the receiver is modified when compared with the given sync
- * info.
- */
- private boolean computeModified(ResourceSyncInfo info) throws CVSException {
- // if there is no sync info and it doesn't exist then it is a phantom we don't care
- // about.
- if (info == null) {
- return exists();
- }
-
- // isMerged() must be called because when a file is updated and merged by the cvs server the timestamps
- // are equal. Merged files should however be reported as dirty because the user should take action and commit
- // or review the merged contents.
- if(info.isAdded() || info.isMerged() || !exists()) return true;
- return !getTimeStamp().equals(info.getTimeStamp());
+ return EclipseSynchronizer.getInstance().setModified(getIFile(), info, getTimeStamp(), UNKNOWN);
}
/*
@@ -406,7 +382,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
setSyncInfo(newInfo, ICVSFile.CLEAN);
} else {
// an unedited file is no longer modified
- setModified(false);
+ EclipseSynchronizer.getInstance().setModified(getIFile(), null, null, CLEAN);
}
} else {
// We still need to report a state change
@@ -520,16 +496,16 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
private void setSyncBytes(byte[] syncBytes, ResourceSyncInfo info, int modificationState) throws CVSException {
Assert.isNotNull(syncBytes);
setSyncBytes(syncBytes);
- boolean modified;
+ Date timestamp = null;
if (modificationState == UNKNOWN) {
+ // The sync info is only need if the modification state is unknown
if (info == null) {
info = new ResourceSyncInfo(syncBytes);
}
- modified = computeModified(info);
- } else {
- modified = modificationState == DIRTY;
- }
- setModified(modified);
+ // The timesatmp is only need if the modification state is unknown
+ timestamp = getTimeStamp();
+ }
+ EclipseSynchronizer.getInstance().setModified(getIFile(), info, timestamp, modificationState);
}
public void handleModification(boolean forAddition) throws CVSException {
@@ -541,12 +517,12 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
// There may be a better was of handling resources that transition from un-managed to
// ignored but for now this seems like the safest change.
if(! resource.isDerived()) {
- setModified(false);
+ EclipseSynchronizer.getInstance().setModified(getIFile(), null, null, CLEAN);
}
return;
}
// set the modification state to what it really is and return true if the modification state changed
- setModified(computeModified(getSyncInfo()));
+ EclipseSynchronizer.getInstance().setModified(getIFile(), getSyncInfo(), getTimeStamp(), UNKNOWN);
}
/**
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 17be9e028..e388633b0 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
@@ -340,7 +340,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
IContainer container = (IContainer)getIResource();
- // TODO: Added optimization to avoid loading sync info if possible
+ // Added optimization to avoid loading sync info if possible
// This will place a modified indicator on non-cvs folders
// (i.e. the call to getModifiedState will cache a session property)
int state = EclipseSynchronizer.getInstance().getModificationState(getIResource());
@@ -356,7 +356,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
// caching as go. This will recursively determined the modified state
// for all child resources until a modified child is found.
modified = calculateAndSaveChildModificationStates(monitor);
- setModified(modified);
+ EclipseSynchronizer.getInstance().setModified(this, modified);
} else {
modified = (state == ICVSFile.DIRTY);
}
@@ -375,7 +375,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
// if the folder has sync info, it was handled is setFolderInfo
// otherwise, flush the ancestors to recalculate
if (info == null) {
- setModified(true);
+ EclipseSynchronizer.getInstance().setDirtyIndicator(getIResource(), true);
}
}
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 9a0bee1ce..6818ea96b 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
@@ -260,14 +260,4 @@ abstract class EclipseResource implements ICVSResource, Comparable {
* lock
*/
protected abstract void run(final ICVSRunnable job, IProgressMonitor monitor) throws CVSException;
-
- /**
- * Sets the modified status of the receiver. This is done to ensure that any
- * cached state kept by it or its parents is updated properly. The invoked method
- * (setDirtyIndicator) will adjust the parent dirty state if the modification
- * state of the resource has changed.
- */
- protected void setModified(boolean modified) throws CVSException {
- EclipseSynchronizer.getInstance().setDirtyIndicator(getIResource(), modified);
- }
}
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 b758d310a..a17356945 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
@@ -13,6 +13,7 @@ package org.eclipse.team.internal.ccvs.core.resources;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -42,6 +43,8 @@ import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSStatus;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
+import org.eclipse.team.internal.ccvs.core.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.ICVSResource;
import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.syncinfo.BaserevInfo;
@@ -1548,6 +1551,14 @@ public class EclipseSynchronizer implements IFlushOperation {
return resourceLock.isWithinActiveOperationScope(resource);
}
+ /**
+ * Set the timestamp of the given file and set it to be CLEAN. It is
+ * assumed that this method is only invoked to reset the file timestamp
+ * to the timestamp that is in the CVS/Entries file.
+ * @param file
+ * @param time
+ * @throws CVSException
+ */
public void setTimeStamp(IFile file, long time) throws CVSException {
ISchedulingRule rule = null;
try {
@@ -1556,6 +1567,7 @@ public class EclipseSynchronizer implements IFlushOperation {
beginOperation();
try {
file.setLocalTimeStamp(time);
+ setModified(file, null, null, ICVSFile.CLEAN);
} catch (CoreException e) {
throw CVSException.wrapException(e);
}
@@ -1634,4 +1646,85 @@ public class EclipseSynchronizer implements IFlushOperation {
monitor.done();
}
}
+
+ /**
+ * Compute the modification state for the given file. If the modificationState is
+ * ICVSFile.UNKNOWN, it is computed. However, if it is CLEAN or DIRTY,
+ * it is set accordingly. CLEAN or DIRTY can only be used if the caller is protected
+ * from resource modifications (either by a scheduling rule or inside a delta handler).
+ * The info and modificationTime are only used if the modificationType is UNKNOWN.
+ * Otherwise, they can be null.
+ * @param file
+ * @param info
+ * @param modificationTime
+ * @param modificationState
+ * @return true if the file is dirty
+ */
+ public boolean setModified(IFile file, ResourceSyncInfo info, Date modificationTime, int modificationState) throws CVSException {
+ try {
+ beginOperation();
+ boolean dirty;
+ if (modificationState == ICVSFile.UNKNOWN) {
+ // if there is no sync info and it doesn't exist then it is a phantom we don't care about.
+ if (info == null) {
+ dirty = file.exists();
+ } else {
+ // isMerged() must be called because when a file is updated and merged by the cvs server the timestamps
+ // are equal. Merged files should however be reported as dirty because the user should take action and commit
+ // or review the merged contents.
+ if(info.isAdded() || info.isMerged() || !file.exists()) {
+ dirty = true;
+ } else {
+ dirty = !modificationTime.equals(info.getTimeStamp());
+ }
+ }
+ } else {
+ dirty = modificationState == ICVSFile.DIRTY;
+ }
+ setDirtyIndicator(file, dirty);
+ return dirty;
+ } finally {
+ endOperation();
+ }
+
+ }
+
+ /**
+ * Set the modified state of the folder. This method can be called when no resource locks are
+ * held. It will check the cached modification state of all the folder's children before setting.
+ * If the states of the children do not match, the state for the folder is not cached.
+ * @param folder
+ * @param modified
+ */
+ public void setModified(ICVSFolder cvsFolder, boolean modified) throws CVSException {
+ try {
+ beginOperation();
+ IContainer folder = (IContainer)cvsFolder.getIResource();
+ // The drop out condition for clean or dirty are the opposite.
+ // (i.e. if modified and a dirty is found we can set the indicator
+ // and if not modified and a dirty or unknown is found we cannot set the indicator)
+ boolean okToSet = !modified;
+ // Obtain the children while we're locked to ensure some were not added or changed
+ ICVSResource[] children = cvsFolder.members(ICVSFolder.ALL_UNIGNORED_MEMBERS);
+ for (int i = 0; i < children.length; i++) {
+ IResource resource = children[i].getIResource();
+ if (modified) {
+ if (getDirtyIndicator(resource) == IS_DIRTY_INDICATOR) {
+ okToSet = true;
+ break;
+ }
+ } else {
+ if (getDirtyIndicator(resource) != NOT_DIRTY_INDICATOR) {
+ okToSet = false;
+ break;
+ }
+ }
+ }
+ if (okToSet) {
+ setDirtyIndicator(folder, modified);
+ }
+ } finally {
+ endOperation();
+ }
+ }
}

Back to the top