Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.team.cvs.core/src/org')
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProvider.java19
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java19
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java45
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/AbstractStructureVisitor.java5
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Add.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/CheckedInHandler.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Command.java39
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/DiffStructureVisitor.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/ResponseHandler.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Session.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StaticHandler.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StickyHandler.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/UpdatedHandler.java3
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java1
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java12
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSFolder.java2
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSResource.java1
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSSynchronizer.java112
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFile.java9
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFolder.java28
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalResource.java7
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java1
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java1
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java1
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/Synchronizer.java608
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CacheData.java44
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FileSystemSynchronizer.java402
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FolderSyncInfo.java (renamed from bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FolderSyncInfo.java)315
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICache.java28
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICacheLoader.java20
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java (renamed from bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ResourceSyncInfo.java)739
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/SimpleCache.java76
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ListFileFilter.java84
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/RemoteFolderTreeBuilder.java5
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ResourceDeltaVisitor.java84
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileUtil.java199
36 files changed, 1482 insertions, 1448 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProvider.java
index ed98b88c3..0fc89ef9f 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProvider.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProvider.java
@@ -56,11 +56,12 @@ import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree;
-import org.eclipse.team.internal.ccvs.core.resources.Synchronizer;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FileSystemSynchronizer;
import org.eclipse.team.internal.ccvs.core.util.Util;
public class CVSProvider implements ICVSProvider {
@@ -373,17 +374,11 @@ public class CVSProvider implements ICVSProvider {
/*
* @see ICVSProvider#importAndCheckout(IProject, Properties, IProgressMonitor)
*/
- public void createModule(
- IProject project,
- Properties configuration,
- IProgressMonitor monitor)
- throws TeamException {
-
+ public void createModule(IProject project, Properties configuration, IProgressMonitor monitor) throws TeamException {
CVSRepositoryLocation location = buildRepository(configuration, false);
boolean alreadyExists = isCached(location);
addToCache(location);
try {
-
// Get the import properties
String message = configuration.getProperty("message"); //$NON-NLS-1$
if (message == null)
@@ -421,7 +416,6 @@ public class CVSProvider implements ICVSProvider {
// Set the folder sync info of the project to point to the remote module
ICVSFolder folder = (ICVSFolder)Session.getManagedResource(project);
folder.setFolderSyncInfo(new FolderSyncInfo(moduleName, location.getLocation(), null, false));
- Synchronizer.getInstance().save(monitor);
// Register the project with Team
// (unless the project already has the proper nature from the project meta-information)
@@ -438,6 +432,8 @@ public class CVSProvider implements ICVSProvider {
if ( ! alreadyExists)
disposeRepository(location);
throw e;
+ } finally {
+ CVSProviderPlugin.getSynchronizer().save(project.getLocation().toFile(), Policy.subMonitorFor(monitor, 5));
}
// We succeeded so we should cache the password ...
location.updateCache();
@@ -500,7 +496,6 @@ public class CVSProvider implements ICVSProvider {
// Only set the info if there is none.
info = new FolderSyncInfo(remotePath, location.getLocation(), tag, false);
folder.setFolderSyncInfo(info);
- Synchronizer.getInstance().save(monitor);
}
// Register the project with Team
@@ -510,6 +505,8 @@ public class CVSProvider implements ICVSProvider {
TeamPlugin.getManager().setProvider(project, CVSProviderPlugin.NATURE_ID, null, monitor);
} catch (CoreException e) {
throw wrapException(e);
+ } finally {
+ CVSProviderPlugin.getSynchronizer().save(project.getLocation().toFile(), Policy.subMonitorFor(monitor, 5));
}
}
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 61ca984e8..3b3268f96 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
@@ -18,17 +18,23 @@ import org.eclipse.core.runtime.Plugin;
import org.eclipse.team.core.ITeamProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.TeamPlugin;
+import org.eclipse.team.core.sync.ISyncProvider;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProvider;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption;
-import org.eclipse.team.internal.ccvs.core.resources.Synchronizer;
+import org.eclipse.team.internal.ccvs.core.resources.ICVSSynchronizer;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FileSystemSynchronizer;
import org.eclipse.team.internal.ccvs.core.util.ProjectDescriptionManager;
import org.eclipse.team.internal.ccvs.core.util.Util;
public class CVSProviderPlugin extends Plugin {
private static CVSProviderPlugin instance;
+
+ private static ICVSSynchronizer synchronizer;
+
/**
* Int used for the communications timeout on server connections (in seconds)
*/
@@ -145,7 +151,9 @@ public class CVSProviderPlugin extends Plugin {
public void startup() throws CoreException {
super.startup();
Policy.localize("org.eclipse.team.internal.ccvs.core.messages");
- Synchronizer.startup();
+
+ synchronizer = new FileSystemSynchronizer();
+
CVSProvider.startup();
ProjectDescriptionManager.initializeChangeListener();
}
@@ -157,6 +165,13 @@ public class CVSProviderPlugin extends Plugin {
super.shutdown();
CVSProvider.shutdown();
}
+
+ /**
+ * Returns the synchronizer reponsible for managing the CVS meta information.
+ */
+ public static ICVSSynchronizer getSynchronizer() {
+ return synchronizer;
+ }
/*
* Add a resource change listener to the workspace in order to respond to
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java
index 6b5f0d98f..445b3f85c 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java
@@ -49,7 +49,6 @@ import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResource;
@@ -59,8 +58,10 @@ import org.eclipse.team.internal.ccvs.core.resources.LocalFolder;
import org.eclipse.team.internal.ccvs.core.resources.LocalResource;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
-import org.eclipse.team.internal.ccvs.core.resources.Synchronizer;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FileSystemSynchronizer;
import org.eclipse.team.internal.ccvs.core.util.Assert;
import org.eclipse.team.internal.ccvs.core.util.RemoteFolderTreeBuilder;
@@ -123,14 +124,6 @@ public class CVSTeamProvider implements ITeamNature, ITeamProvider {
* @see IProjectNature#deconfigure()
*/
public void deconfigure() throws CoreException {
- // We want to clear the sync info for the project without deleting the CVS directories
- // unmanage() does this
- try {
- managedProject.unmanage();
- } catch (CVSException e) {
- throw new CoreException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, 0, Policy.bind("CVSTeamProvider.deconfigureProblem", new Object[] {project.getName()}), e));
- }
- project.refreshLocal(IResource.DEPTH_INFINITE, null);
}
/**
@@ -550,11 +543,11 @@ public class CVSTeamProvider implements ITeamNature, ITeamProvider {
};
for (int i = 0; i < resources.length; i++) {
- getChild(resources[i]).accept(visitor);
+ IResource resource = resources[i];
+ getChild(resource).accept(visitor);
+ CVSProviderPlugin.getSynchronizer().save(resource.getLocation().toFile(), progress);
}
-
- Synchronizer.getInstance().save(progress);
-
+
// Perform an update, ignoring any local file modifications
update(resources, depth, null, true, progress);
}
@@ -880,7 +873,7 @@ public class CVSTeamProvider implements ITeamNature, ITeamProvider {
}
};
});
- Synchronizer.getInstance().save(new NullProgressMonitor());
+ CVSProviderPlugin.getSynchronizer().save(project.getLocation().toFile(), new NullProgressMonitor());
return;
}
@@ -1034,26 +1027,6 @@ public class CVSTeamProvider implements ITeamNature, ITeamProvider {
return new CVSStatus(IStatus.OK, "OK");
}
- /**
- * Call this method to refresh both the local CVS sync information (e.g. the files in the CVS subdirectories) and the
- * contents of the files. This is useful when a command line client is invoked outside of the workbench and the user
- * would like to continue working in the workbench with the modified state.
- *
- * @param resources to be refreshed deep
- * @param progress a progress monitor to indicate the duration of the operation, or <code>null</code> if
- * progress reporting is not required.
- */
- public void refreshFromLocal(IResource[] resources, IProgressMonitor monitor) throws CVSException {
- for (int i = 0; i < resources.length; i++) {
- Synchronizer.getInstance().reload(new LocalFolder(resources[i].getLocation().toFile()),monitor);
- try {
- resources[i].refreshLocal(IResource.DEPTH_INFINITE, monitor);
- } catch(CoreException e) {
- throw new CVSException("Problems encountered refreshing from the local file system", e);
- }
- }
- }
-
/*
* @see ITeamProvider#refreshState(IResource[], int, IProgressMonitor)
*/
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/AbstractStructureVisitor.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/AbstractStructureVisitor.java
index efc727920..be7f466fe 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/AbstractStructureVisitor.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/AbstractStructureVisitor.java
@@ -8,11 +8,12 @@ package org.eclipse.team.internal.ccvs.core.client;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResourceVisitor;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Add.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Add.java
index 816442620..e5e085adb 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Add.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Add.java
@@ -9,10 +9,11 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResource;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResourceVisitor;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
public class Add extends Command {
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/CheckedInHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/CheckedInHandler.java
index 80cc34f80..a9bbc8a38 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/CheckedInHandler.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/CheckedInHandler.java
@@ -9,7 +9,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
/**
* Handles a "Checked-in" response from the CVS server.
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Command.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Command.java
index 2ca78d26a..167b4a5d5 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Command.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Command.java
@@ -20,7 +20,7 @@ import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListen
import org.eclipse.team.internal.ccvs.core.resources.CVSFileNotFoundException;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResource;
-import org.eclipse.team.internal.ccvs.core.resources.Synchronizer;
+import org.eclipse.team.internal.ccvs.core.resources.LocalResource;
/**
* Abstract base class for the commands which implements the ICommand
@@ -267,7 +267,26 @@ public abstract class Command {
monitor = Policy.monitorFor(monitor);
monitor.beginTask("", 100 * resources.length);
for (int i = 0; i < resources.length; i++) {
- Synchronizer.getInstance().reload(resources[i], Policy.subMonitorFor(monitor, 100));
+ if(resources[i] instanceof LocalResource && resources[i].exists()) {
+ CVSProviderPlugin.getSynchronizer().reload(((LocalResource)resources[i]).getLocalFile(), Policy.subMonitorFor(monitor, 100));
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
+ * Reload the sync info for all arguments this command will be running on.
+ */
+ private void saveSyncInfo(ICVSResource[] resources, IProgressMonitor monitor) throws CVSException {
+ try {
+ monitor = Policy.monitorFor(monitor);
+ monitor.beginTask("", 100 * resources.length);
+ for (int i = 0; i < resources.length; i++) {
+ if(resources[i] instanceof LocalResource) {
+ CVSProviderPlugin.getSynchronizer().save(((LocalResource)resources[i]).getLocalFile(), Policy.subMonitorFor(monitor, 100));
+ }
}
} finally {
monitor.done();
@@ -280,6 +299,7 @@ public abstract class Command {
LocalOption[] localOptions, String[] arguments, ICommandOutputListener listener,
IProgressMonitor monitor)
throws CVSException {
+ ICVSResource[] resources = null;
try {
session.setNoLocalChanges(DO_NOT_CHANGE.isElementOf(globalOptions));
session.setModTime(null);
@@ -290,7 +310,7 @@ public abstract class Command {
// Ensure that the commands run with the latest contents of the CVS subdirectory sync files
// and not the cached values. Allow 10% of work.
- ICVSResource[] resources = computeWorkResources(session, arguments);
+ resources = computeWorkResources(session, arguments);
reloadSyncInfo(resources, Policy.subMonitorFor(monitor, 10));
Policy.checkCanceled(monitor);
@@ -319,15 +339,16 @@ public abstract class Command {
// Processing responses contributes 70% of work.
IStatus status = processResponses(session, listener, Policy.subMonitorFor(monitor, 70));
- // Finished adds last 10% of work.
- commandFinished(session, globalOptions, localOptions, resources, monitor,
+ // Finished adds last 5% of work.
+ commandFinished(session, globalOptions, localOptions, resources, Policy.subMonitorFor(monitor, 5),
status.getCode() != CVSException.SERVER_ERROR);
- monitor.worked(10);
+ monitor.worked(5);
return status;
} finally {
- // This will automatically persist any changes that were made to the
- // sync info while running a command.
- Synchronizer.getInstance().save(monitor);
+ // Give the synchronizer a chance to persist any pending changes.
+ if(resources!=null) {
+ saveSyncInfo(resources, Policy.subMonitorFor(monitor, 5));
+ }
monitor.done();
}
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/DiffStructureVisitor.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/DiffStructureVisitor.java
index 68ee3caca..ca5a49d1f 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/DiffStructureVisitor.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/DiffStructureVisitor.java
@@ -7,7 +7,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
/**
* The diff command needs to send a file structure to the server that differs somewhat from the canonical
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/ResponseHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/ResponseHandler.java
index e6d8fb092..6eef70936 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/ResponseHandler.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/ResponseHandler.java
@@ -8,8 +8,9 @@ package org.eclipse.team.internal.ccvs.core.client;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Util;
/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Session.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Session.java
index a070e6d90..cf030d99b 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Session.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/Session.java
@@ -22,7 +22,8 @@ import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResource;
import org.eclipse.team.internal.ccvs.core.resources.LocalFile;
import org.eclipse.team.internal.ccvs.core.resources.LocalFolder;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
public class Session {
public static final String CURRENT_LOCAL_FOLDER = ".";
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StaticHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StaticHandler.java
index 90b54ccb3..f9a2cafa0 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StaticHandler.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StaticHandler.java
@@ -7,8 +7,9 @@ package org.eclipse.team.internal.ccvs.core.client;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StickyHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StickyHandler.java
index 6672649bc..497fc207c 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StickyHandler.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/StickyHandler.java
@@ -8,8 +8,9 @@ package org.eclipse.team.internal.ccvs.core.client;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/UpdatedHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/UpdatedHandler.java
index 003c9e3f2..9e63f0250 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/UpdatedHandler.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/UpdatedHandler.java
@@ -12,7 +12,8 @@ import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
import org.eclipse.team.internal.ccvs.core.util.EntryFileDateFormat;
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java
index 7738a0d72..12e419820 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java
@@ -17,6 +17,7 @@ import org.eclipse.team.core.sync.IRemoteResource;
import org.eclipse.team.core.sync.LocalSyncElement;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProvider;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
public class CVSLocalSyncElement extends LocalSyncElement {
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java
index bfcde8d75..813d1c537 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java
@@ -7,6 +7,7 @@ package org.eclipse.team.internal.ccvs.core.resources;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.ccvs.core.CVSProviderPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.team.ccvs.core.ICVSRemoteResource;
import org.eclipse.team.core.TeamException;
@@ -18,6 +19,7 @@ import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProvider;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.client.Session;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.Assert;
public class CVSRemoteSyncElement extends RemoteSyncElement {
@@ -217,13 +219,13 @@ public class CVSRemoteSyncElement extends RemoteSyncElement {
} else {
// We have conflicting deletions. Clear the sync info
local.setSyncInfo(null);
- Synchronizer.getInstance().save(Policy.monitorFor(monitor));
+ CVSProviderPlugin.getSynchronizer().save(((LocalResource)local).getLocalFile(), Policy.monitorFor(monitor));
return;
}
}
info = new ResourceSyncInfo(info.getName(), revision, info.getTimeStamp(), info.getKeywordMode(), local.getParent().getFolderSyncInfo().getTag(), info.getPermissions());
local.setSyncInfo(info);
- Synchronizer.getInstance().save(Policy.monitorFor(monitor));
+ CVSProviderPlugin.getSynchronizer().save(((LocalResource)local).getLocalFile(), Policy.monitorFor(monitor));
}
/*
@@ -243,11 +245,9 @@ public class CVSRemoteSyncElement extends RemoteSyncElement {
} else if (outgoing) {
// For now, just unmanage the local resource so the remote change can be loaded with an update
Session.getManagedResource(getLocal()).unmanage();
- Synchronizer.getInstance().save(Policy.monitorFor(monitor));
} else {
// For now, just unmanage the local resource so the remote change can be loaded with an update
Session.getManagedResource(getLocal()).unmanage();
- Synchronizer.getInstance().save(Policy.monitorFor(monitor));
}
}
@@ -293,6 +293,6 @@ public class CVSRemoteSyncElement extends RemoteSyncElement {
FolderSyncInfo remoteInfo = remote.getFolderSyncInfo();
FolderSyncInfo localInfo = local.getParent().getFolderSyncInfo();
local.setFolderSyncInfo(new FolderSyncInfo(remoteInfo.getRepository(), remoteInfo.getRoot(), localInfo.getTag(), localInfo.getIsStatic()));
- Synchronizer.getInstance().save(Policy.monitorFor(monitor));
- }
+ CVSProviderPlugin.getSynchronizer().save(((LocalResource)local).getLocalFile(), Policy.monitorFor(monitor));
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSFolder.java
index 5da6bd914..f5dbd3ae5 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSFolder.java
@@ -6,6 +6,7 @@ package org.eclipse.team.internal.ccvs.core.resources;
*/
import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
/**
* The CVS analog of a directory. CVS folders have access to synchronization information
@@ -24,6 +25,7 @@ public interface ICVSFolder extends ICVSResource {
* <li> does not exist() but is managed (deleted folder)
* <li> exist() and isManaged() (normal registered file)
* </ul>
+ * If the folder does not exist then a zero length array is returned.
*/
ICVSFolder[] getFolders() throws CVSException;
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSResource.java
index dcfb41b95..e3c54919b 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSResource.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSResource.java
@@ -6,6 +6,7 @@ package org.eclipse.team.internal.ccvs.core.resources;
*/
import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
/**
* The CVS analog of file system files and directories. These are handles to
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSSynchronizer.java
new file mode 100644
index 000000000..603269455
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ICVSSynchronizer.java
@@ -0,0 +1,112 @@
+package org.eclipse.team.internal.ccvs.core.resources;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+
+/**
+ * A synchronizer is responsible for managing synchronization information for local
+ * CVS resources.
+ *
+ * @see ResourceSyncInfo
+ * @see FolderSyncInfo
+ */
+public interface ICVSSynchronizer {
+
+ /**
+ * Associates the provided folder sync information with the given folder. The folder
+ * must exist on the file system.
+ * <p>
+ * The workbench and team plugins are notified that the state of this resources has
+ * changed.</p>
+ *
+ * @param file the file or folder for which to associate the sync info.
+ * @param info the folder sync to set.
+ *
+ * @throws CVSException if there was a problem adding sync info.
+ */
+ public void setFolderSync(File folder, FolderSyncInfo info) throws CVSException;
+
+ /**
+ * Answers the folder sync information associated with this folder or <code>null</code>
+ * if none is available.
+ *
+ * @param folder the folder for which to return folder sync info.
+ * @throws CVSException if there was a problem adding folder sync info.
+ */
+ public FolderSyncInfo getFolderSync(File file) throws CVSException;
+
+ /**
+ * Associates the provided sync information with the given file or folder. The resource
+ * may or may not exist on the file system however the parent folder must be a cvs
+ * folder.
+ * <p>
+ * The workbench and team plugins are notified that the state of this resources has
+ * changed.</p>
+ *
+ * @param file the file or folder for which to associate the sync info.
+ * @param info to set. The name in the resource info must match the file or folder name.
+ *
+ * @throws CVSException if there was a problem adding sync info.
+ */
+ public void setResourceSync(File file, ResourceSyncInfo info) throws CVSException;
+
+ /**
+ * Answers the sync information associated with this file of folder or <code>null</code>
+ * if none is available. A resource cannot have sync information if its parent folder
+ * does not exist.
+ *
+ * @param file the file or folder for which to return sync info.
+ * @throws CVSException if there was a problem adding sync info or broadcasting
+ * the changes.
+ */
+ public ResourceSyncInfo getResourceSync(File file) throws CVSException;
+
+ /**
+ * Removes the folder's and all children's folder sync information. This will essentially remove
+ * all CVS knowledge from these resources.
+ */
+ public void deleteFolderSync(File file, IProgressMonitor monitor) throws CVSException;
+
+ /**
+ * Removes the resource's sync information.
+ */
+ public void deleteResourceSync(File file) throws CVSException;
+
+ /**
+ * Allows the synchronizer to update the workspace with changes made by an 3rd
+ * party tool to the sync info.
+ */
+ public void reload(File file, IProgressMonitor monitor) throws CVSException;
+
+ /**
+ * Call to allow the synchronizer to save any pending or buffered changes and dispatch
+ * state change notifications.
+ */
+ public void save(File file, IProgressMonitor monitor) throws CVSException;
+
+ /**
+ * Answers an array with the sync information for immediate child resources of this folder. Note
+ * that the returned sync information may be for resources that no longer exist (e.g. in the
+ * case of a pending deletion).
+ *
+ * @param folder the folder for which to return the children resource sync infos. The folder
+ * must exist.
+ *
+ * @throws CVSException if an error occurs retrieving the sync info.
+ */
+ public ResourceSyncInfo[] members(File folder) throws CVSException;
+
+ /**
+ * XXX: Should be removed. Currently only used by tests and instead the tests should be
+ * created for the different types of concrete sync classes.
+ */
+ public boolean isEmpty();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFile.java
index af91531fb..290c784b8 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFile.java
@@ -5,7 +5,6 @@ package org.eclipse.team.internal.ccvs.core.resources;
* All Rights Reserved.
*/
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -17,9 +16,10 @@ import java.text.ParseException;
import java.util.Date;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.EntryFileDateFormat;
import org.eclipse.team.internal.ccvs.core.util.Util;
@@ -264,7 +264,6 @@ public class LocalFile extends LocalResource implements ICVSFile {
* @see ICVSResource#unmanage()
*/
public void unmanage() throws CVSException {
- Synchronizer.getInstance().deleteResourceSync(ioResource);
+ CVSProviderPlugin.getSynchronizer().deleteResourceSync(ioResource);
}
-}
-
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFolder.java
index c5fafae28..f945b3cbe 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalFolder.java
@@ -10,17 +10,12 @@ import java.io.FileFilter;
import java.util.HashSet;
import java.util.Set;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
import org.eclipse.team.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSStatus;
import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.FileNameMatcher;
-import org.eclipse.team.internal.ccvs.core.util.SyncFileUtil;
/**
* Implements the ICVSFolder interface on top of an
@@ -40,10 +35,14 @@ public class LocalFolder extends LocalResource implements ICVSFolder {
*/
public ICVSFolder[] getFolders() throws CVSException {
+ if(!getLocalFile().exists()) {
+ return new ICVSFolder[0];
+ }
+
final Set folders = new HashSet();
final FileNameMatcher matcher = FileNameMatcher.getIgnoreMatcherFor(ioResource);
- ResourceSyncInfo[] syncDirs = Synchronizer.getInstance().members(ioResource);
+ ResourceSyncInfo[] syncDirs = CVSProviderPlugin.getSynchronizer().members(ioResource);
for (int i = 0; i < syncDirs.length; i++) {
if(syncDirs[i].isDirectory()) {
folders.add((new LocalFolder(new File(ioResource, syncDirs[i].getName()))));
@@ -67,10 +66,14 @@ public class LocalFolder extends LocalResource implements ICVSFolder {
*/
public ICVSFile[] getFiles() throws CVSException {
+ if(!getLocalFile().exists()) {
+ return new ICVSFile[0];
+ }
+
final Set files = new HashSet();
final FileNameMatcher matcher = FileNameMatcher.getIgnoreMatcherFor(ioResource);
- ResourceSyncInfo[] syncDirs = Synchronizer.getInstance().members(ioResource);
+ ResourceSyncInfo[] syncDirs = CVSProviderPlugin.getSynchronizer().members(ioResource);
for (int i = 0; i < syncDirs.length; i++) {
if(!syncDirs[i].isDirectory()) {
files.add((new LocalFile(new File(ioResource, syncDirs[i].getName()))));
@@ -218,14 +221,14 @@ public class LocalFolder extends LocalResource implements ICVSFolder {
* @see ICVSFolder#getFolderInfo()
*/
public FolderSyncInfo getFolderSyncInfo() throws CVSException {
- return Synchronizer.getInstance().getFolderSync(ioResource);
+ return CVSProviderPlugin.getSynchronizer().getFolderSync(ioResource);
}
/*
* @see ICVSFolder#setFolderInfo(FolderSyncInfo)
*/
public void setFolderSyncInfo(FolderSyncInfo folderInfo) throws CVSException {
- Synchronizer.getInstance().setFolderSync(ioResource, folderInfo);
+ CVSProviderPlugin.getSynchronizer().setFolderSync(ioResource, folderInfo);
}
/*
@@ -233,9 +236,8 @@ public class LocalFolder extends LocalResource implements ICVSFolder {
*/
public boolean isCVSFolder() {
try {
- return Synchronizer.getInstance().getFolderSync(ioResource) != null;
+ return CVSProviderPlugin.getSynchronizer().getFolderSync(ioResource) != null;
} catch(CVSException e) {
- CVSProviderPlugin.log(new CVSStatus(IStatus.ERROR, Path.EMPTY, "CVS error getting folder sync info", e));
return false;
}
}
@@ -244,6 +246,6 @@ public class LocalFolder extends LocalResource implements ICVSFolder {
* @see ICVSResource#unmanage()
*/
public void unmanage() throws CVSException {
- Synchronizer.getInstance().deleteFolderSync(ioResource, new NullProgressMonitor());
+ CVSProviderPlugin.getSynchronizer().deleteFolderSync(ioResource, new NullProgressMonitor());
}
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalResource.java
index 361e7f0b3..5a41bfeae 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalResource.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LocalResource.java
@@ -7,8 +7,9 @@ package org.eclipse.team.internal.ccvs.core.resources;
import java.io.File;
-import org.eclipse.core.resources.IResource;
+import org.eclipse.team.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.FileNameMatcher;
import org.eclipse.team.internal.ccvs.core.util.FileUtil;
import org.eclipse.team.internal.ccvs.core.util.Util;
@@ -143,14 +144,14 @@ public abstract class LocalResource implements ICVSResource {
* @see ICVSResource#getSyncInfo()
*/
public ResourceSyncInfo getSyncInfo() throws CVSException {
- return Synchronizer.getInstance().getResourceSync(ioResource);
+ return CVSProviderPlugin.getSynchronizer().getResourceSync(ioResource);
}
/*
* @see ICVSResource#setSyncInfo(ResourceSyncInfo)
*/
public void setSyncInfo(ResourceSyncInfo info) throws CVSException {
- Synchronizer.getInstance().setResourceSync(ioResource, info);
+ CVSProviderPlugin.getSynchronizer().setResourceSync(ioResource, info);
}
/*
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
index 129af60f0..2798e6269 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java
@@ -31,6 +31,7 @@ import org.eclipse.team.internal.ccvs.core.client.Update;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.client.listeners.LogListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.Assert;
/**
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
index 1f63a4851..7be17c5c9 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java
@@ -36,6 +36,7 @@ import org.eclipse.team.internal.ccvs.core.client.listeners.StatusListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.UpdateListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
/**
* This class provides the implementation of ICVSRemoteFolder
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
index 21fed0d4f..85192e071 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java
@@ -13,6 +13,7 @@ import org.eclipse.team.ccvs.core.ICVSRemoteResource;
import org.eclipse.team.ccvs.core.ICVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.util.Assert;
import org.eclipse.team.internal.ccvs.core.util.NullOutputStream;
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/Synchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/Synchronizer.java
deleted file mode 100644
index 28a7eff00..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/Synchronizer.java
+++ /dev/null
@@ -1,608 +0,0 @@
-package org.eclipse.team.internal.ccvs.core.resources;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.team.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.core.TeamPlugin;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-import org.eclipse.team.internal.ccvs.core.util.ResourceDeltaVisitor;
-import org.eclipse.team.internal.ccvs.core.util.SyncFileUtil;
-
-/**
- * A singleton that provides clients access to CVS synchronization information
- * about local files and folder. In addition, when sync information is modified
- * via this class, the Team plugin is notified of a state change and the resource
- * is refreshed within the workbench.
- * <p>
- * All set and delete methods on the synchronizer do not persist the sync information
- * to disk, instead clients modifying the sync info must call <code>save()</code>
- * to persist the sync information.</p>
- * <p>
- * A client may set/get resource sync info for files that don't exist on the file
- * system yet. This is mainly to support having sync info for deleted files. However,
- * to set/get folder sync info the underlying folder in the file system must exist.</p>
- *
- * [Note: it may be interesting to implement a mechanism for invalidating cache items
- * based on a LRU - least recently used, algorithm. This could potentially save a lot
- * of memory for very large workspaces.]
- *
- * @see ResourceSyncInfo
- * @see FolderSyncInfo
- */
-public class Synchronizer {
-
- // the one and only instance.
- private static Synchronizer instance;
- private static SyncResourceDeletionListener deletedListener;
-
- // cache containing ResourceSyncInfo that are created from the entry file and permission file
- // {keys = Entry File files values = SyncFile}
- // {Syncfile is keys = file name values = ResourceSyncInfo}
- private Map entriesCache = new HashMap(10);
-
- // cache containing FolderSyncInfo that are created from the CVS subdirectory folder config
- // files
- // {keys = Folder values = FolderSyncInfo}
- private Map folderConfigCache = new HashMap(10);
-
- // used to remember entry files and folders that are modified in memory but have
- // not been saved.
- private Set invalidatedEntryFiles = new HashSet(10);
- private Set invalidatedFolderConfigs = new HashSet(10);
-
- // Fields for progress monitoring algorithm. Initially, give progress for every 4 resources, double
- // this value at halfway point, then reset halfway point to be half of remaining work. (this gives an infinite
- // series that converges at total work after an infinite number of resources).
- public static final int TOTAL_WORK = 250;
- private int halfWay = TOTAL_WORK / 2;
- private int currentIncrement = 4;
- private int nextProgress = currentIncrement;
- private int worked = 0;
-
- /**
- * Data structured used in the cache tables to save information about file contents that
- * are read from disk.
- */
- private class SyncFile {
- long timestamp = 0;
- Map config = new HashMap(10);
- }
-
- /**
- * When a container resource in the workbench is deleted the Synchronizer must clear the cache so that
- * stale sync infos are removed.
- */
- public class SyncResourceDeletionListener extends ResourceDeltaVisitor {
- protected void handleAdded(IProject project, IResource resource) {
- }
- protected void handleRemoved(IProject project, IResource resource) {
- try {
- if(resource.getType()!=IResource.FILE && !resource.getName().equals("CVS")) {
- String location = new Path(project.getWorkspace().getRoot().getLocation().toString()).append(resource.getFullPath()).toString();
- Synchronizer.getInstance().deleteFolderSync(new File(location), new NullProgressMonitor());
- }
- } catch(CVSException e) {
- CVSProviderPlugin.log(new Status(IStatus.WARNING, CVSProviderPlugin.ID, 0, "Could not delete CVS folder sync info", null));
- }
- }
- protected void handleChanged(IProject project, IResource resource) {
- }
- }
-
- /**
- * Debug method that displays the contents of the cache.
- */
- public void dump() {
- System.out.println("Synchronizer:");
- System.out.println("\tEntries");
- for (Iterator it = entriesCache.keySet().iterator(); it.hasNext();) {
- File entriesFile = (File)it.next();
- SyncFile contents = (SyncFile)entriesCache.get(entriesFile);
- System.out.println(entriesFile.getAbsolutePath() + " (" + contents.config.size() +")");
- for (Iterator it2 = contents.config.keySet().iterator(); it2.hasNext();) {
- System.out.println(((String)it2.next()));
- }
- }
-
- System.out.println("\tFolders");
- for (Iterator it = folderConfigCache.keySet().iterator(); it.hasNext();) {
- File folder = (File)it.next();
- System.out.println(folder.getAbsolutePath());
- }
- }
-
- /**
- * Singleton constructor
- */
- private Synchronizer() {
- }
-
- /**
- * Answer the singleton instance of the Synchronizer.
- */
- public static Synchronizer getInstance() {
- return instance;
- }
-
- /**
- * On startup, initialize the synchronizer instance
- */
- public static void startup() {
- instance = new Synchronizer();
- deletedListener = instance.new SyncResourceDeletionListener();
- deletedListener.register();
- }
-
- /**
- * Associates the provided sync information with the given file or folder. The resource
- * may or may not exist on the file system however the parent folder must have a CVS
- * subdirectory.
- * <p>
- * The workbench and team plugins are notified that the state of this resources has
- * changed.</p>
- *
- * @param file the file or folder for which to associate the sync info.
- * @param info to set. The name in the resource info must match the file or folder name.
- *
- * @throws CVSException if there was a problem adding sync info or broadcasting
- * the changes. If the parent folder does not have a CVS subdirectory.
- */
- public synchronized void setResourceSync(File file, ResourceSyncInfo info) throws CVSException {
-
- Assert.isNotNull(file);
- Assert.isNotNull(info);
- Assert.isTrue(info.getName().equals(file.getName()));
-
- File parentCVSDir = SyncFileUtil.getCVSSubdirectory(file.getParentFile());
- File entriesFile = new File(parentCVSDir, SyncFileUtil.ENTRIES);
-
- if(!parentCVSDir.exists()) {
- throw new CVSException("Parent folder does not have a CVS directory");
- }
-
- SyncFile entriesSync = (SyncFile)entriesCache.get(entriesFile);
- if(entriesSync==null) {
- entriesSync = new SyncFile();
- entriesCache.put(entriesFile, entriesSync);
- }
- entriesSync.config.put(info.getName(), info);
- invalidatedEntryFiles.add(entriesFile);
- }
-
- /**
- * Answers the sync information associated with this file of folder or <code>null</code>
- * if none is available. A resource cannot have sync information if its parent folder
- * does not exist.
- *
- * @param file the file or folder for which to return sync info.
- * @throws CVSException if there was a problem adding sync info or broadcasting
- * the changes.
- */
- public synchronized ResourceSyncInfo getResourceSync(File file) throws CVSException {
- return getResourceSync(file, false);
- }
-
- /**
- * Remove the sync information associated with this file.
- * <p>
- * The workbench and team plugins are notified that the state of this resources has
- * changed.</p>
- *
- * @param file the file or folder for which to delete its resource sync info.
- *
- * @throws CVSException if there was a problem removing sync info or broadcasting
- * the changes.
- */
- public synchronized void deleteResourceSync(File file) throws CVSException {
- File entriesFile = new File(SyncFileUtil.getCVSSubdirectory(file.getParentFile()), SyncFileUtil.ENTRIES);
- SyncFile entriesSync = (SyncFile)entriesCache.get(entriesFile);
- if(entriesSync!=null) {
- entriesSync.config.remove(file.getName());
- invalidatedEntryFiles.add(entriesFile);
- broadcastSyncChange(new File[] {file}, true);
- }
- }
-
- /**
- * Answers the folder sync information associated with this folder or <code>null</code>
- * if none is available.
- *
- * @param folder the folder for which to return folder sync info.
- * @throws CVSException if there was a problem adding folder sync info or broadcasting
- * the changes. If the folder does not exist on the file system.
- */
- public synchronized FolderSyncInfo getFolderSync(File folder) throws CVSException {
- return getFolderSync(folder, false);
- }
-
- /**
- * Associates the provided folder sync information with the given folder. The folder
- * must exist on the file system.
- * <p>
- * The workbench and team plugins are notified that the state of this resources has
- * changed.</p>
- *
- * @param file the file or folder for which to associate the sync info.
- * @param info to set. The name in the resource info must match the file or folder name.
- *
- * @throws CVSException if there was a problem adding sync info or broadcasting
- * the changes. If the folder does not exist on the file system.
- */
- public synchronized void setFolderSync(File folder, FolderSyncInfo info) throws CVSException {
-
- Assert.isNotNull(info);
-
- if(!folder.exists()) {
- throw new CVSException("Folder must exist to set sync info");
- }
-
- File cvsDirectory = SyncFileUtil.getCVSSubdirectory(folder);
- if(!cvsDirectory.exists()) {
- cvsDirectory.mkdir();
- }
-
- // if parent has the sync folder (e.g. CVS) then ensure that the directory
- // entry for this folder is added.
- if(getFolderSync(folder.getParentFile())!=null) {
- ResourceSyncInfo resourceInfo = new ResourceSyncInfo(folder.getName());
- setResourceSync(folder, resourceInfo);
- }
-
- // there can only be one sync entry for folders, create a new one
- folderConfigCache.remove(folder);
- SyncFile folderSync = new SyncFile();
- folderSync.config.put(folder.getName(), info);
- folderConfigCache.put(folder, folderSync);
- invalidatedFolderConfigs.add(folder);
- }
-
- /**
- * Remove the folder sync information associated with this folder and all its
- * children. If a parent folder does not have folder sync (e.g. is not managed
- * by CVS) then all children must also not have sync information.
- * <p>
- * The workbench and team plugins are notified that the state of this resources has
- * changed.</p>
- *
- * @param folder the root folder at which to start deleting.
- * @param monitor the progress monitor, cannot be <code>null</code>.
- *
- * @throws CVSException if there was a problem removing sync info or broadcasting
- * the changes.
- */
- public synchronized void deleteFolderSync(File folder, IProgressMonitor monitor) throws CVSException {
- ResourceSyncInfo[] children = members(folder);
-
- for (int i = 0; i < children.length; i++) {
- if(children[i].isDirectory()) {
- deleteFolderSync(new File(folder, children[i].getName()), monitor);
- }
- }
-
- deleteFolderAndChildEntries(folder, true);
- }
-
- /**
- * The set and delete methods on the synchronizer do not persist the sync information
- * to disk, instead clients modifying the sync info must call this method to
- * persist the sync information.
- *
- * @param monitor the progress monitor, cannot be <code>null</code>.
- *
- * @throws CVSException if there was a problem persisting the changes to disk.
- */
- public synchronized void save(IProgressMonitor monitor) throws CVSException {
- List filesToUpdate = new ArrayList();
- for (Iterator it = invalidatedEntryFiles.iterator(); it.hasNext();) {
- File entryFile = (File) it.next();
- SyncFile info = (SyncFile)entriesCache.get(entryFile);
-
- // entry file may of been deleted from cache by a client calling
- // deleteFolderSync (e.g. pruning on update).
- if(info!=null) {
-
- // collect all sync infos for this entries file
- List syncInfos = new ArrayList();
- for (Iterator it2 = info.config.values().iterator(); it2.hasNext();) {
- ResourceSyncInfo element = (ResourceSyncInfo) it2.next();
- syncInfos.add(element);
- filesToUpdate.add(new File(entryFile.getParentFile().getParentFile(), element.getName()));
- }
-
- if(!entryFile.exists()) {
- try {
- entryFile.getParentFile().mkdirs();
- entryFile.createNewFile();
- } catch(IOException e) {
- throw new CVSException("Error creating " + entryFile.getAbsolutePath(), e);
- }
- }
-
- SyncFileUtil.writeEntriesFile(entryFile, (ResourceSyncInfo[]) syncInfos.toArray(new ResourceSyncInfo[syncInfos.size()]));
-
- // ensure that the external sync files are kept in sync with the workbench
- File[] entrySyncFiles = SyncFileUtil.getEntrySyncFiles(entryFile.getParentFile().getParentFile());
- broadcastSyncChange(entrySyncFiles, false);
- }
- }
-
- for (Iterator it = invalidatedFolderConfigs.iterator(); it.hasNext();) {
- File folder = (File) it.next();
- SyncFile info = (SyncFile)folderConfigCache.get(folder);
-
- // folder config may of been deleted from cache by a client calling
- // deleteFolderSync (e.g. pruning on update).
- if(info!=null) {
- SyncFileUtil.writeFolderConfig(folder, (FolderSyncInfo)info.config.get(folder.getName()));
- File rootFile = new File(SyncFileUtil.getCVSSubdirectory(folder), SyncFileUtil.ROOT);
- info.timestamp = rootFile.lastModified();
-
- // ensure that the external sync files are kept in sync with the workbench.
- File[] folderSyncFiles = SyncFileUtil.getFolderSyncFiles(folder);
- broadcastSyncChange(folderSyncFiles, false);
- }
- }
-
- // broadcast state changes for non-metadata files that have changed
- if(!filesToUpdate.isEmpty()) {
- broadcastSyncChange((File[]) filesToUpdate.toArray(new File[filesToUpdate.size()]), true);
- }
-
- // clear invalidated lists
- invalidatedEntryFiles.clear();
- invalidatedFolderConfigs.clear();
- }
-
- /**
- * Answers the sync information for child resources of this folder. Note that the
- * returned sync information may be for resources that no longer exist (e.g. in the
- * case of a pending deletion.)
- *
- * @param folder the folder for which to return the children resource sync infos.
- */
- public ResourceSyncInfo[] members(File folder) throws CVSException {
- File entriesFile = new File(SyncFileUtil.getCVSSubdirectory(folder), SyncFileUtil.ENTRIES);
- SyncFile entriesSync = (SyncFile)entriesCache.get(entriesFile);
-
- if(entriesSync==null) {
- return new ResourceSyncInfo[0];
- }
- Collection entries = entriesSync.config.values();
- return (ResourceSyncInfo[])entries.toArray(new ResourceSyncInfo[entries.size()]);
- }
-
- /**
- * Reload the sync information from disk for this folder and all its children depth first.
- *
- * @param folder the root folder at which to start reloading.
- * @param monitor the progress monitor, cannot be <code>null</code>.
- */
- public void reload(ICVSResource resource, IProgressMonitor monitor) throws CVSException {
- try {
- monitor = Policy.monitorFor(monitor);
- monitor.beginTask("", TOTAL_WORK);
- doReload(resource, monitor);
- } finally {
- monitor.done();
- }
- }
-
- /**
- * Clear the entire synchronizer cache. This will force a reload of sync information from
- * disk on subsequent get calls. There must not be any invalidated sync infos.
- */
- public void clear() {
- Assert.isTrue(invalidatedEntryFiles.isEmpty() && invalidatedFolderConfigs.isEmpty());
- entriesCache.clear();
- folderConfigCache.clear();
- }
-
- /**
- * Answers if the cache is empty and there are no pending saves.
- */
- public boolean isEmpty() {
- return entriesCache.isEmpty() && folderConfigCache.isEmpty();
- }
-
- /**
- * Internal helping for returning the folder sync info. If reload is <code>true</code>
- * then load entries from disk.
- *
- * @param folder the folder for which to retrieve folder sync info.
- * @param reload if <code>true</code> then reload config from disk, if <code>false</code>
- * config is taken from cache and reloaded only if it is not cached.
- */
- protected FolderSyncInfo getFolderSync(File folder, boolean reload) throws CVSException {
- SyncFile folderSync = (SyncFile)folderConfigCache.get(folder);
- if(folderSync==null || reload) {
-
- if(!folder.exists()) {
- return null;
- }
-
- folderSync = new SyncFile();
- FolderSyncInfo info = SyncFileUtil.readFolderConfig(folder);
-
- // no CVS sub-directory
- if(info==null) {
- return null;
- }
- folderSync.config.put(folder.getName(), info);
- folderConfigCache.put(folder, folderSync);
- }
- return (FolderSyncInfo)folderSync.config.get(folder.getName());
- }
-
- /**
- * Internal helping for returning the folder sync info. If reload is <code>true</code>
- * then load entries from disk.
- *
- * @param folder the folder for which to retrieve folder sync info.
- * @param reload if <code>true</code> then reload config from disk, if <code>false</code>
- * config is taken from cache and reloaded only if it is not cached.
- */
- protected ResourceSyncInfo getResourceSync(File file, boolean reload) throws CVSException {
- File entriesFile = new File(SyncFileUtil.getCVSSubdirectory(file.getParentFile()), SyncFileUtil.ENTRIES);
- SyncFile entriesSync = (SyncFile)entriesCache.get(entriesFile);
-
- // read entries file
- if(entriesSync==null || reload) {
- entriesSync = new SyncFile();
- ResourceSyncInfo infos[] = SyncFileUtil.readEntriesFile(file.getParentFile());
- // entries file does not exist
- if(infos==null) {
- entriesCache.remove(entriesFile);
- return null;
- }
- for (int i = 0; i < infos.length; i++) {
- entriesSync.config.put(infos[i].getName(), infos[i]);
- }
- entriesCache.put(entriesFile, entriesSync);
- }
- return (ResourceSyncInfo)entriesSync.config.get(file.getName());
- }
-
- /**
- * Notifies the worbench and the team plugin that changes to a resource have
- * occured. This allows components interested in the CVS state of a resource to
- * update when state changes, and also to keep resources in sync with the
- * workspace by refreshing the contents.
- *
- * @param file a file that has its CVS state changed. If the file does not exist
- * then the parent if notified instead.
- */
- protected void broadcastSyncChange(File[] files, boolean notifyOfStateChange) throws CVSException {
- List resourcesToUpdate = new ArrayList();
- int depth = IResource.DEPTH_ZERO;
-
- for(int i=0; i < files.length; i++) {
- File file = files[i];
- if(!file.exists()) {
- file = file.getParentFile();
- depth = IResource.DEPTH_ONE;
- }
-
- if(file.equals(ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile()) || !file.exists()) {
- return;
- }
-
- IResource resource;
- if(file.isDirectory()) {
- resource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(new Path(file.getAbsolutePath()));
- } else {
- resource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(file.getAbsolutePath()));
- }
-
- if(resource!=null) {
- try {
- resourcesToUpdate.add(resource);
- resource.refreshLocal(depth, null);
- } catch(CoreException e) {
- // throw new CVSException("Error refreshing file from local contents " + file.getAbsolutePath(), e);
- }
- }
- }
- if(!resourcesToUpdate.isEmpty() && notifyOfStateChange) {
- TeamPlugin.getManager().broadcastResourceStateChanges((IResource[]) resourcesToUpdate.toArray(new IResource[resourcesToUpdate.size()]));
- }
- }
-
- /**
- * Deletes a folder and all its children's sync information from the cache.
- * <p>
- * The workbench and team plugins are notified that the state of this resources has
- * changed.</p>
- *
- * @param folder the root folder at which to start deleting sync information.
- */
- protected void deleteFolderAndChildEntries(File folder, boolean deleteResourceSync) throws CVSException {
-
- // remove resource sync entries file from the cache
- File entriesFile = new File(SyncFileUtil.getCVSSubdirectory(folder), SyncFileUtil.ENTRIES);
- entriesCache.remove(entriesFile);
-
- // remove from parent
- if(deleteResourceSync) {
- deleteResourceSync(folder);
- }
-
- // remove folder sync
- folderConfigCache.remove(folder);
-
- // notify of state change to this folder
- broadcastSyncChange(new File[] {folder}, true);
- }
-
- /**
- * Perform the reload.
- */
- private void doReload(ICVSResource resource, IProgressMonitor monitor) throws CVSException {
- if (resource instanceof LocalFolder) {
- LocalFolder fsFolder = (LocalFolder) resource;
- File file = fsFolder.getLocalFile();
-
- String message = Policy.bind("Synchronizer.reload", fsFolder.getName());
- monitor.subTask(message);
-
- ICVSFolder[] folders = fsFolder.getFolders();
- for (int i = 0; i < folders.length; i++) {
- ICVSFolder iCVSFolder = folders[i];
- reload(iCVSFolder, monitor);
- }
-
- FolderSyncInfo info = getFolderSync(file, true);
-
- // info will be null if the CVS subdirectory or folder does not exist, then we can safely
- // clear this folder from the cache. Otherwise, reload the entries file for this folder as
- // well.
- if(info==null) {
- deleteFolderAndChildEntries(file, false);
- } else {
- getResourceSync(new File(file, "dummy"), true);
- }
-
- // Update monitor work amount
- if (--nextProgress <= 0) {
- monitor.worked(1);
- worked++;
- if (worked >= halfWay) {
- //we have passed the current halfway point, so double the
- //increment and reset the halfway point.
- currentIncrement *= 2;
- halfWay += (TOTAL_WORK - halfWay) / 2;
- }
- //reset the progress counter to another full increment
- nextProgress = currentIncrement;
- }
- }
- if(resource instanceof LocalFile) {
- // force a reload of entries file of parent
- getResourceSync(((LocalFile)resource).getLocalFile(), true);
- }
- }
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CacheData.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CacheData.java
new file mode 100644
index 000000000..368a94f45
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CacheData.java
@@ -0,0 +1,44 @@
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.eclipse.team.internal.ccvs.core.util.*;
+
+public class CacheData {
+ private Object data;
+ private Object id;
+ private Date expirationDate;
+
+ public CacheData(Object id, Object data, int minutesToLive) {
+ this.id = id;
+ this.data = data;
+ this.expirationDate = null; // if not set then default is to live forever
+ if(minutesToLive>0) {
+ expirationDate = new Date();
+ Calendar currentDate = Calendar.getInstance();
+ currentDate.add(Calendar.MINUTE, minutesToLive);
+ expirationDate = currentDate.getTime();
+ }
+ }
+
+ public CacheData(Object id, Object data) {
+ this(id, data, 0);
+ }
+
+ public boolean isExpired() {
+ if(expirationDate==null) {
+ return false;
+ } else {
+ return expirationDate.before(new Date());
+ }
+ }
+
+ public Object getId() {
+ return id;
+ }
+
+ public Object getData() {
+ return data;
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FileSystemSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FileSystemSynchronizer.java
new file mode 100644
index 000000000..51ab65ea3
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FileSystemSynchronizer.java
@@ -0,0 +1,402 @@
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.team.core.TeamPlugin;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.resources.*;
+import org.eclipse.team.internal.ccvs.core.util.Assert;
+import org.eclipse.team.internal.ccvs.core.util.FileUtil;
+import org.eclipse.team.internal.ccvs.core.util.ResourceDeltaVisitor;
+import org.eclipse.team.internal.ccvs.core.util.SyncFileUtil;
+
+/**
+ * The FileSystemSynchronizer stores sync information to be compatible with CVS command line
+ * clients. It is also responsible for synchronizing the workbench when changes are made to CVS
+ * metafiles (CVS/Entries, CVS/Root..) from outside of the workbench by 3rd party tools.
+ *
+ * @see ICVSSynchronizer
+ */
+public class FileSystemSynchronizer implements ICVSSynchronizer {
+
+ // caches for resource and folder sync. These are required to provide timely access to
+ // sync information that may be shown in the UI.
+ private ICache resourceSyncCache;
+ private ICache folderSyncCache;
+
+ // a specialized resource listener required to interpret metafile changes made to CVS managed
+ // resources.
+ private SyncResourceChangeListener resourceListener;
+
+ // time in minutes that a cached sync object should remain in the cache. A time of 0 indicates
+ // that the cache object will never expire.
+ private final static int CACHE_EXPIRATION_MINUTES = 0;
+
+ /**
+ * Initialize the caches and register as a resource listener.
+ */
+ public FileSystemSynchronizer() {
+ resourceSyncCache = new SimpleCache();
+ resourceSyncCache.registerLoader(new ResourceSyncCacheLoader());
+
+ folderSyncCache = new SimpleCache();
+ folderSyncCache.registerLoader(new FolderSyncCacheLoader());
+
+ resourceListener = new SyncResourceChangeListener();
+ resourceListener.register();
+ }
+
+ /**
+ * For every get request from the cache, load the entire entries and permissions file.
+ */
+ private class ResourceSyncCacheLoader implements ICacheLoader {
+ /*
+ * @see ICacheLoader#load(Object, ICache)
+ */
+ public CacheData load(Object id, ICache cache) {
+ CacheData idInfo = null;
+ try {
+ File file = (File)id;
+ File parent = file.getParentFile();
+ Assert.isTrue(parent.exists());
+
+ ResourceSyncInfo infos[] = SyncFileUtil.readEntriesFile(parent);
+ // if null then, entries file does not exist
+ if(infos!=null) {
+ for (int i = 0; i < infos.length; i++) {
+ ResourceSyncInfo info = infos[i];
+ CacheData cacheInfo = new CacheData(new File(parent, info.getName()), info, CACHE_EXPIRATION_MINUTES);
+ if(file.getName().equals(info.getName())) {
+ idInfo = cacheInfo;
+ } else {
+ cache.put(cacheInfo);
+ }
+ }
+ }
+ } catch(CVSException e) {
+ TeamPlugin.log(IStatus.ERROR, "Error loading from CVS/Entries file", e);
+ return null;
+ }
+ return idInfo;
+ }
+ }
+
+ /**
+ * For every get request from the cache that fails, load the files that contain the folder sync info.
+ */
+ private class FolderSyncCacheLoader implements ICacheLoader {
+ /*
+ * @see ICacheLoader#load(Object, ICache)
+ */
+ public CacheData load(Object id, ICache cache) {
+ try {
+ File folder = (File)id;
+ Assert.isTrue(folder.exists());
+ FolderSyncInfo info = SyncFileUtil.readFolderConfig(folder);
+
+ // no CVS sub-directory
+ if(info==null) {
+ return null;
+ } else {
+ return new CacheData(folder, info, CACHE_EXPIRATION_MINUTES);
+ }
+ } catch(CVSException e) {
+ TeamPlugin.log(IStatus.ERROR, "Error loading from CVS/Entries file", e);
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Handle changes made to meta files.
+ * 1.
+ */
+ private class SyncResourceChangeListener extends ResourceDeltaVisitor {
+ private Set delta = new HashSet();
+
+ protected void handleAdded(IResource[] resources) {
+ handleDefault(resources);
+ }
+
+ protected void handleRemoved(IResource[] resources) {
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ File file = resource.getLocation().toFile();
+ // if a resource is deleted, then clear the cache, there is not need for a delta.
+ if(!SyncFileUtil.isMetaFile(file)) {
+ clearCache(file, IResource.DEPTH_INFINITE);
+ } else {
+ if(resource.getName().equals("CVS")) {
+ handleMetaChange(file, resource);
+ }
+ }
+ }
+ }
+
+ protected void handleChanged(IResource[] resources) {
+ handleDefault(resources);
+ }
+
+ protected void finished() {
+ TeamPlugin.getManager().broadcastResourceStateChanges((IResource[]) delta.toArray(new IResource[delta.size()]));
+ delta.clear();
+ }
+
+ /**
+ * If a meta file has changed the cache will be out-of-date. It will be cleared and subsequent access
+ * will force a reload of the sync information when needed by a client.
+ */
+ private void handleMetaChange(File cvsdir, IResource resource) {
+ File parent = cvsdir.getParentFile();
+ clearCache(parent, IResource.DEPTH_ONE);
+
+ // generate deltas for children of the parent because their state may of changed.
+ // it is safe to get the parent two up from the metafile because we have already
+ // confirmed that this is a meta directory.
+ if(resource.exists()) {
+ IContainer resourceParent = resource.getParent();
+ delta.add(resourceParent);
+ try {
+ IResource[] children = resourceParent.members();
+ for (int i = 0; i < children.length; i++) {
+ delta.add(children[i]);
+ }
+ } catch(CoreException e) {
+ // XXX what can you do in a resource listener when an exception occurs???
+ }
+ }
+ }
+
+ /**
+ * Canonical handling of a resource change
+ */
+ private void handleDefault(IResource[] resources) {
+ for (int i = 0; i < resources.length; i++) {
+ File file = resources[i].getLocation().toFile();
+ if(SyncFileUtil.isMetaFile(file)) {
+ handleMetaChange(file.getParentFile(), resources[i].getParent());
+ // add all parents children to delta
+ } else {
+ if(!file.getName().equals("CVS")) {
+ delta.add(resources[i]);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * @see ICVSSynchronizer#getFolderSync(File)
+ */
+ public FolderSyncInfo getFolderSync(File file) throws CVSException {
+ if(file.exists() && file.isDirectory()) {
+ LocalFolder folder = new LocalFolder(file);
+ if(SyncFileUtil.getCVSSubdirectory(file).exists()) {
+ CacheData data = (CacheData)folderSyncCache.get(file, null);
+ if(data!=null) {
+ return (FolderSyncInfo)data.getData();
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * @see ICVSSynchronizer#getResourceSync(File)
+ */
+ public ResourceSyncInfo getResourceSync(File file) throws CVSException {
+ LocalFolder parent = new LocalFolder(file.getParentFile());
+ if(parent.exists() && parent.isCVSFolder()) {
+ CacheData data = (CacheData)resourceSyncCache.get(file, null);
+ if(data!=null) {
+ return (ResourceSyncInfo)data.getData();
+ }
+ }
+ return null;
+ }
+
+ /*
+ * @see ICVSSynchronizer#setFolderSync(File, FolderSyncInfo)
+ */
+ public void setFolderSync(File file, FolderSyncInfo info) throws CVSException {
+ Assert.isNotNull(info);
+ Assert.isTrue(file.exists());
+
+ SyncFileUtil.writeFolderConfig(file, info);
+ folderSyncCache.put(new CacheData(file, info, CACHE_EXPIRATION_MINUTES));
+
+ // the server won't add directories as sync info, therefore it must be done when
+ // a directory is shared with the repository.
+ setResourceSync(file, new ResourceSyncInfo(file.getName()));
+
+ }
+
+ /*
+ * @see ICVSSynchronizer#setResourceSync(File, ResourceSyncInfo)
+ */
+ public void setResourceSync(File file, ResourceSyncInfo info) throws CVSException {
+ Assert.isNotNull(info);
+ Assert.isTrue(file.getParentFile().exists());
+ Assert.isTrue(file.getName().equals(info.getName()));
+
+ try {
+ LocalFolder parent = new LocalFolder(file.getParentFile());
+ if(parent.exists() && parent.isCVSFolder()) {
+ SyncFileUtil.writeResourceSync(file, info);
+ }
+ } catch(CVSException e) {
+ // XXX Bad eating of exception
+ }
+ resourceSyncCache.put(new CacheData(file, info, CACHE_EXPIRATION_MINUTES));
+ }
+
+ /*
+ * @see ICVSSynchronizer#deleteFolderSync(File, IProgressMonitor)
+ */
+ public void deleteFolderSync(File file, IProgressMonitor monitor) throws CVSException {
+ destroySyncDeep(file, monitor);
+ }
+
+ /*
+ * @see ICVSSynchronizer#deleteResourceSync(File)
+ */
+ public void deleteResourceSync(File file) {
+ try {
+ SyncFileUtil.deleteSync(file);
+ } catch(CVSException e) {
+ // XXX Bad eating of exception
+ }
+ resourceSyncCache.remove(file);
+ }
+
+ /*
+ * If the file no longer exists, then clear the cache, or else, refresh from local and allow the
+ * resource change listener to adapt to changes.
+ *
+ * @see ICVSSynchronizer#reload(File, IProgressMonitor)
+ */
+ public void reload(File file, IProgressMonitor monitor) throws CVSException {
+
+ clearCache(file, IResource.DEPTH_INFINITE);
+
+ if(!file.exists()) {
+ // a non-existant file implies that there is no longer any meta information
+ // on disk, we can safely clear the cache.
+ // we can safely reload the parent if it exists.
+ file = file.getParentFile();
+ if(!file.exists()) {
+ return;
+ }
+ }
+
+ // the following is to refresh the workbench with the local file changes.
+ if(file.equals(ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile())) {
+ return;
+ }
+
+ IResource resource;
+ if(file.isDirectory()) {
+ resource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(new Path(file.getAbsolutePath()));
+ } else {
+ // reload a container always, or else sync info changes won't be loaded!
+ resource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(new Path(file.getParentFile().getAbsolutePath()));
+ }
+ try {
+ if(resource!=null) {
+ resource.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+ }
+ } catch(CoreException e) {
+ throw new CVSException(IStatus.ERROR, 0, "Error reloading sync information", e);
+ }
+ }
+
+ /*
+ * Simply reload to absorb changes made to the underlying file system.
+ *
+ * @see ICVSSynchronizer#save(File, IProgressMonitor)
+ */
+ public void save(File file, IProgressMonitor monitor) throws CVSException {
+ reload(file, monitor);
+ }
+
+ /*
+ * Answers if the caches are empty.
+ *
+ * @see ICVSSynchronizer#isEmpty()
+ */
+ public boolean isEmpty() {
+ return resourceSyncCache.isEmpty() && folderSyncCache.isEmpty();
+ }
+
+ /*
+ * @see ICVSSynchronizer#members(File)
+ */
+ public ResourceSyncInfo[] members(File folder) throws CVSException {
+ // read the entries file and cache if needed
+ Assert.isTrue(folder.exists());
+ ResourceSyncInfo[] infos = SyncFileUtil.readEntriesFile(folder);
+ if(infos==null) {
+ return new ResourceSyncInfo[0];
+ } else {
+ return infos;
+ }
+ }
+
+ protected void destroySyncDeep(File file, IProgressMonitor monitor) {
+ if (file.isDirectory()) {
+ File[] fileList = file.listFiles();
+ for (int i = 0; i < fileList.length; i++) {
+ destroySyncDeep(fileList[i], monitor);
+ }
+ folderSyncCache.remove(file);
+ File metaDir = SyncFileUtil.getCVSSubdirectory(file);
+ if(metaDir.exists()) {
+ FileUtil.deepDelete(metaDir);
+ }
+ }
+ deleteResourceSync(file);
+ }
+
+ protected void clearCache(File file, int depth) {
+ if(file.exists()) {
+ if (file.isDirectory()) {
+ if(depth!=IResource.DEPTH_ZERO) {
+ File[] fileList = file.listFiles();
+ for (int i = 0; i < fileList.length; i++) {
+ if(depth==IResource.DEPTH_ONE) {
+ depth = IResource.DEPTH_ZERO;
+ }
+ clearCache(fileList[i], depth);
+ }
+ }
+ folderSyncCache.remove(file);
+ }
+ resourceSyncCache.remove(file);
+ } else {
+ clearCacheForChildren(file);
+ }
+ }
+
+ protected void clearCacheForChildren(File file) {
+ // XXX not optimal, could instead have implement the cache as a tree
+ // and be able to traverse children. This is the safest for now.
+ resourceSyncCache.clear();
+ folderSyncCache.clear();
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FolderSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FolderSyncInfo.java
index 8e8effe03..bee61cd8c 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FolderSyncInfo.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/FolderSyncInfo.java
@@ -1,157 +1,158 @@
-package org.eclipse.team.internal.ccvs.core.resources;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-
-import org.eclipse.team.ccvs.core.CVSTag;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-
-/**
- * Value (immutable) object that represents workspace state information about the contents of a
- * folder that was retreived from a CVS repository. It is a specialized representation of the files from
- * the CVS sub-directory that contain folder specific connection information (e.g. Root, Repository, Tag).
- *
- * @see ICVSFolder#getFolderSyncInfo()
- */
-public class FolderSyncInfo {
-
- // relative path of this folder in the repository, project1/folder1/folder2
- private String repository;
-
- // :pserver:user@host:/home/user/repo
- private String root;
-
- // sticky tag (e.g. version, date, or branch tag applied to folder)
- private CVSEntryLineTag tag;
-
- // if true then it means only part of the folder was fetched from the repository, and CVS will not create
- // additional files in that folder.
- private boolean isStatic;
-
- /**
- * Construct a folder sync object.
- *
- * @param repo the relative path of this folder in the repository, cannot be <code>null</code>.
- * @param root the location of the repository, cannot be <code>null</code>.
- * @param tag the tag set for the folder or <code>null</code> if there is no tag applied.
- * @param isStatic to indicate is only part of the folder was fetched from the server.
- */
- public FolderSyncInfo(String repo, String root, CVSTag tag, boolean isStatic) {
- Assert.isNotNull(repo);
- Assert.isNotNull(root);
- this.repository = repo;
- this.root = root;
- this.isStatic = isStatic;
- if(tag != null) {
- this.tag = new CVSEntryLineTag(tag);
- }
- }
-
- public boolean equals(Object other) {
- if(other == this) return true;
- if (!(other instanceof FolderSyncInfo)) return false;
-
- FolderSyncInfo syncInfo = ((FolderSyncInfo)other);
- if (!getRoot().equals(syncInfo.getRoot())) return false;
- if (!getRepository().equals(syncInfo.getRepository())) return false;
- if (getIsStatic() != syncInfo.getIsStatic()) return false;
- if ((getTag() == null) || (syncInfo.getTag() == null)) {
- if ((getTag() == null) && (syncInfo.getTag() != null) && (syncInfo.getTag().getType() != CVSTag.HEAD)) {
- return false;
- } else if ((syncInfo.getTag() == null) && (getTag() != null) && (getTag().getType() != CVSTag.HEAD)) {
- return false;
- }
- } else if (!getTag().equals(syncInfo.getTag())) {
- return false;
- }
- return true;
- }
- /**
- * Gets the root, cannot be <code>null.
- *
- * @return Returns a String
- */
- public String getRoot() {
- return root;
- }
-
- /**
- * Gets the tag, may be <code>null</code>.
- *
- * @return Returns a String
- */
- public CVSEntryLineTag getTag() {
- return tag;
- }
-
- /**
- * Gets the repository, may be <code>null</code>.
- *
- * @return Returns a String
- */
- public String getRepository() {
- return repository;
- }
-
- /**
- * Gets the isStatic.
- *
- * @return Returns a boolean
- */
- public boolean getIsStatic() {
- return isStatic;
- }
-
- /**
- * Answers a full path to the folder on the remote server. This by appending the repository to the
- * repository location speficied in the root.
- *
- * Example:
- * root = :pserver:user@host:/home/user/repo
- * repository = folder1/folder2
- *
- * Returns:
- * /home/users/repo/folder1/folder2
- *
- * @return the full path of this folder on the server.
- * @throws a CVSException if the root or repository is malformed.
- */
- public String getRemoteLocation() throws CVSException {
-
- String result;
-
- try {
- result = getRoot().substring(getRoot().indexOf("@")+1);
- result = result.substring(result.indexOf(":")+1);
- result = result + "/" + getRepository();
- } catch (IndexOutOfBoundsException e) {
- throw new CVSException("Maleformed root");
- }
-
- return result;
- }
-
- /*
- * Provide a hashCode() method that gaurentees that equal object will have the
- * same hashCode
- */
- public int hashCode() {
- return getRoot().hashCode() | getRepository().hashCode();
- }
-
- /**
- * Sets the tag for the folder.
- *
- * @param tag The tag to set
- */
- private void setTag(CVSTag tag) {
- if (tag == null) {
- this.tag = null;
- } else {
- this.tag = new CVSEntryLineTag(tag);
- }
- }
-}
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.team.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.resources.*;
+import org.eclipse.team.internal.ccvs.core.util.Assert;
+
+/**
+ * Value (immutable) object that represents workspace state information about the contents of a
+ * folder that was retreived from a CVS repository. It is a specialized representation of the files from
+ * the CVS sub-directory that contain folder specific connection information (e.g. Root, Repository, Tag).
+ *
+ * @see ICVSFolder#getFolderSyncInfo()
+ */
+public class FolderSyncInfo {
+
+ // relative path of this folder in the repository, project1/folder1/folder2
+ private String repository;
+
+ // :pserver:user@host:/home/user/repo
+ private String root;
+
+ // sticky tag (e.g. version, date, or branch tag applied to folder)
+ private CVSEntryLineTag tag;
+
+ // if true then it means only part of the folder was fetched from the repository, and CVS will not create
+ // additional files in that folder.
+ private boolean isStatic;
+
+ /**
+ * Construct a folder sync object.
+ *
+ * @param repo the relative path of this folder in the repository, cannot be <code>null</code>.
+ * @param root the location of the repository, cannot be <code>null</code>.
+ * @param tag the tag set for the folder or <code>null</code> if there is no tag applied.
+ * @param isStatic to indicate is only part of the folder was fetched from the server.
+ */
+ public FolderSyncInfo(String repo, String root, CVSTag tag, boolean isStatic) {
+ Assert.isNotNull(repo);
+ Assert.isNotNull(root);
+ this.repository = repo;
+ this.root = root;
+ this.isStatic = isStatic;
+ if(tag != null) {
+ this.tag = new CVSEntryLineTag(tag);
+ }
+ }
+
+ public boolean equals(Object other) {
+ if(other == this) return true;
+ if (!(other instanceof FolderSyncInfo)) return false;
+
+ FolderSyncInfo syncInfo = ((FolderSyncInfo)other);
+ if (!getRoot().equals(syncInfo.getRoot())) return false;
+ if (!getRepository().equals(syncInfo.getRepository())) return false;
+ if (getIsStatic() != syncInfo.getIsStatic()) return false;
+ if ((getTag() == null) || (syncInfo.getTag() == null)) {
+ if ((getTag() == null) && (syncInfo.getTag() != null) && (syncInfo.getTag().getType() != CVSTag.HEAD)) {
+ return false;
+ } else if ((syncInfo.getTag() == null) && (getTag() != null) && (getTag().getType() != CVSTag.HEAD)) {
+ return false;
+ }
+ } else if (!getTag().equals(syncInfo.getTag())) {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Gets the root, cannot be <code>null.
+ *
+ * @return Returns a String
+ */
+ public String getRoot() {
+ return root;
+ }
+
+ /**
+ * Gets the tag, may be <code>null</code>.
+ *
+ * @return Returns a String
+ */
+ public CVSEntryLineTag getTag() {
+ return tag;
+ }
+
+ /**
+ * Gets the repository, may be <code>null</code>.
+ *
+ * @return Returns a String
+ */
+ public String getRepository() {
+ return repository;
+ }
+
+ /**
+ * Gets the isStatic.
+ *
+ * @return Returns a boolean
+ */
+ public boolean getIsStatic() {
+ return isStatic;
+ }
+
+ /**
+ * Answers a full path to the folder on the remote server. This by appending the repository to the
+ * repository location speficied in the root.
+ *
+ * Example:
+ * root = :pserver:user@host:/home/user/repo
+ * repository = folder1/folder2
+ *
+ * Returns:
+ * /home/users/repo/folder1/folder2
+ *
+ * @return the full path of this folder on the server.
+ * @throws a CVSException if the root or repository is malformed.
+ */
+ public String getRemoteLocation() throws CVSException {
+
+ String result;
+
+ try {
+ result = getRoot().substring(getRoot().indexOf("@")+1);
+ result = result.substring(result.indexOf(":")+1);
+ result = result + "/" + getRepository();
+ } catch (IndexOutOfBoundsException e) {
+ throw new CVSException("Maleformed root");
+ }
+
+ return result;
+ }
+
+ /*
+ * Provide a hashCode() method that gaurentees that equal object will have the
+ * same hashCode
+ */
+ public int hashCode() {
+ return getRoot().hashCode() | getRepository().hashCode();
+ }
+
+ /**
+ * Sets the tag for the folder.
+ *
+ * @param tag The tag to set
+ */
+ private void setTag(CVSTag tag) {
+ if (tag == null) {
+ this.tag = null;
+ } else {
+ this.tag = new CVSEntryLineTag(tag);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICache.java
new file mode 100644
index 000000000..a36ad9b06
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICache.java
@@ -0,0 +1,28 @@
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+
+/**
+ * Interface for a simple cache.
+ */
+public interface ICache {
+ /**
+ * Returns a reference to the object associated with name. If the object name is not
+ * found in the cache, it is loaded by the loader defined for this cache. If a loader is
+ * not registered then <code>null</code> will be returned.
+ */
+ public CacheData get(Object id, Object args);
+
+ public void put(CacheData data);
+
+ public void remove(Object id);
+
+ public boolean isEmpty();
+
+ public void registerLoader(ICacheLoader loader);
+
+ public void clear();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICacheLoader.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICacheLoader.java
new file mode 100644
index 000000000..d748e1738
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ICacheLoader.java
@@ -0,0 +1,20 @@
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.team.internal.ccvs.core.util.*;
+
+/**
+ * Interface for classes that can load an object from a store with the given id.
+ */
+public interface ICacheLoader {
+ /**
+ * Loads object associated with the given id from a store. The cache is passed so that if other objects
+ * are read as a side effect of fetching name, then they can automatically be added to the
+ * cache as well.
+ */
+ public CacheData load(Object id, ICache cache);
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ResourceSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
index ac663cf32..ce727133e 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/ResourceSyncInfo.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
@@ -1,370 +1,371 @@
-package org.eclipse.team.internal.ccvs.core.resources;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2002.
- * All Rights Reserved.
- */
-
-import org.eclipse.team.ccvs.core.CVSTag;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-import org.eclipse.team.internal.ccvs.core.util.EmptyTokenizer;
-
-/**
- * Value (immutable) object that represents workspace state information about a resource contained in
- * a CVS repository. It is a specialized representation of a line in the CVS/Entry file with the addition of
- * file permissions.
- *
- * Example entry line from the CVS/Entry file:
- *
- * /new.java/1.2/Fri Dec 07 00:17:52 2001/-kb/
- * D/src////
- *
- * @see ICVSResource#getSyncInfo()
- */
-public class ResourceSyncInfo {
-
- // a directory sync info will have nothing more than a name
- private boolean isDirectory = false;
-
- // utility constants
- private static final String DIRECTORY_PREFIX = "D/";
- public static final String BINARY_TAG = "-kb";
- private static final String SEPERATOR = "/";
-
- // Timestamp constants used to identify special cases
- public static final String DUMMY_TIMESTAMP = "dummy timestamp";
- public static final String RESULT_OF_MERGE = "Result of merge+";
-
- // safe default permissions. Permissions are saved separatly so that the correct permissions
- // can be sent back to the server on systems that don't save execute bits (e.g. windows).
- public static final String DEFAULT_PERMISSIONS = "u=rw,g=rw,o=r";
-
- // file sync information can be associated with a local resource that has been deleted. This is
- // noted by prefixing the revision with this character.
- // XXX Should this be private
- static final String DELETED_PREFIX = "-";
- private boolean isDeleted = false;
-
- // a sync element with a revision of '0' is considered a new file that has
- // not been comitted to the repo. Is visible so that clients can create sync infos
- // for new files.
- public static final String ADDED_REVISION = "0";
-
- // fields describing the synchronization of a resource in CVS parlance
- private String name;
- private String revision;
- private String timeStamp;
- private String keywordMode;
- private CVSEntryLineTag tag;
- private String permissions;
-
- /**
- * Constructor to create a sync object from entry line formats. The entry lines are parsed by this class.
- *
- * @param entryLine the entry line (e.g. /new.java/1.2/Fri Dec 07 00:17:52 2001/-kb/)
- * @param permissions the file permission (e.g. u=rw,g=rw,o=r). May be <code>null</code>.
- * @param timestamp if not included in the entry line. Will overide the value in the entry line. The
- * timestamp should be in the format specified in ICVSFile#getTimestamp(). May be <code>null</code>.
- *
- * @exception CVSException is thrown if the entry cannot be parsed.
- */
- public ResourceSyncInfo(String entryLine, String permissions, String timestamp) throws CVSException {
- Assert.isNotNull(entryLine);
-
- setEntryLine(entryLine);
-
- if (permissions != null) {
- this.permissions = permissions;
- }
- // override the timestamp that may of been in entryLine. In some cases the timestamp is not in the
- // entry line (e.g. receiving entry lines from the server versus reading them from the Entry file).
- if(timestamp!=null) {
- this.timeStamp = timestamp;
- }
- }
-
- /**
- * Constructor to create a sync object from predefined values.
- *
- * @param name of the resource for which this sync state is associated, cannot be <code>null</code>.
- * @param revision of the resource, cannot be <code>null</code>.
- * @param timestamp can be <code>null</code>.
- * @param keywordMode can be <code>null</code>
- * @param tag can be <code>null</code>
- * @param permissions can be <code>null</code>
- */
- public ResourceSyncInfo(String name, String revision, String timestamp, String keywordMode, CVSTag tag, String permissions) {
- Assert.isNotNull(name);
- Assert.isNotNull(revision);
- this.name = name;
- this.timeStamp = timestamp;
- this.keywordMode = keywordMode;
- this.permissions = permissions;
- setRevision(revision);
- setTag(tag);
- }
-
- /**
- * Constructor to create a folder sync object.
- *
- * @param name of the resource for which this sync state is associatied, cannot be <code>null</code>.
- */
- public ResourceSyncInfo(String name) {
- Assert.isNotNull(name);
- this.name = name;
- this.isDirectory = true;
- }
-
- /**
- * Answers if this sync information is for a folder in which case only a name is
- * available.
- *
- * @return <code>true</code> if the sync information is for a folder and <code>false</code>
- * if it is for a file.
- */
- public boolean isDirectory() {
- return isDirectory;
- }
-
- /**
- * Answers if this sync information is for a file that has been added but not comitted
- * to the CVS repository yet.
- *
- * @return <code>true</code> if the sync information is new or <code>false</code> if
- * the sync is for an file that exists remotely. For folder sync info this returns
- * <code>false</code>.
- */
- public boolean isAdded() {
- if(!isDirectory) {
- return getRevision().equals(ADDED_REVISION);
- } else {
- return false;
- }
- }
-
- /**
- * Answers if this sync information is for a file that is scheduled to be deleted
- * from the repository but the deletion has not yet been comitted.
- *
- * @return <code>true</code> if the sync information is deleted or <code>false</code> if
- * the sync is for an file that exists remotely.
- */
- public boolean isDeleted() {
- return isDeleted;
- }
-
- /**
- * Answers a CVS compatible entry line. The client can use this line to store in the CVS/Entry file or
- * sent it to the server.
- *
- * @param includeTimeStamp determines if the timestamp will be included in the returned entry line. In
- * some usages the timestamp should not be included in entry lines, for example when sending the entries
- * to the server.
- *
- * @return a file or folder entry line reflecting the state of this sync object.
- */
- public String getEntryLine(boolean includeTimeStamp) {
-
- StringBuffer result = new StringBuffer();
-
- if(isDirectory) {
- result.append(DIRECTORY_PREFIX);
- result.append(name + "////");
- } else {
- result.append(SEPERATOR);
- result.append(name);
- result.append(SEPERATOR);
-
- if(isDeleted){
- result.append(DELETED_PREFIX);
- }
-
- result.append(revision);
- result.append(SEPERATOR);
-
- if(includeTimeStamp) {
- result.append(timeStamp);
- }
- result.append(SEPERATOR);
- result.append(keywordMode == null ? "" : keywordMode);
- result.append(SEPERATOR);
- if (tag != null) {
- result.append(tag.toEntryLineFormat(true));
- }
- }
-
- return result.toString();
- }
-
- /**
- * Anwsers the a compatible permissions line for files.
- *
- * @return a permission line for files and <code>null</code> if this sync object is
- * a directory.
- */
- public String getPermissionLine() {
- if(isDirectory) {
- return null;
- } else {
- String permissions = this.permissions;
- if (permissions == null)
- permissions = DEFAULT_PERMISSIONS;
- return SEPERATOR + name + SEPERATOR + permissions;
- }
- }
-
- /**
- * Gets the permissions or <code>null</code> if permissions are not available.
- *
- * @return a string of the format "u=rw,g=rw,o=r"
- */
- public String getPermissions() {
- if(isDirectory) {
- return null;
- } else {
- if(permissions==null) {
- return DEFAULT_PERMISSIONS;
- } else {
- return permissions;
- }
- }
- }
-
- /**
- * Gets the tag or <code>null</code> if a tag is not available.
- *
- * @return Returns a String
- */
- public CVSTag getTag() {
- return tag;
- }
-
- /**
- * Gets the timeStamp or <code>null</code> if a timestamp is not available.
- *
- * @return a string of the format "Thu Oct 18 20:21:13 2001"
- */
- public String getTimeStamp() {
- return timeStamp;
- }
-
- /**
- * Gets the version or <code>null</code> if this is a folder sync info. The returned
- * revision will never include the DELETED_PREFIX. To found out if this sync info is
- * for a deleted resource call isDeleted().
- *
- * @return Returns a String
- */
- public String getRevision() {
- return revision;
- }
-
-
- /**
- * Gets the name.
- *
- * @return Returns a String
- */
- public String getName() {
- return name;
- }
-
- /**
- * Gets the keyword mode or <code>null</code> if a keyword mode is available.
- *
- * @return
- */
- public String getKeywordMode() {
- return keywordMode;
- }
-
- /**
- * Name equality between resource sync info objects.
- */
- public boolean equals(Object other) {
- if(other instanceof ResourceSyncInfo) {
- ResourceSyncInfo syncInfo = ((ResourceSyncInfo)other);
- if(other == this) return true;
- if(getName() == syncInfo.getName()) return true;
- return getName().equals(syncInfo.getName());
- } else {
- return false;
- }
- }
-
- public int hashCode() {
- return getName().hashCode();
- }
-
- /**
- * Sets the tag for the resource.
- */
- private void setTag(CVSTag tag) {
- if(tag!=null) {
- this.tag = new CVSEntryLineTag(tag);
- } else {
- this.tag = null;
- }
- }
-
- /**
- * Set the entry line
- *
- * @throws CVSException if the entryLine is malformed
- */
- private void setEntryLine(String entryLine) throws CVSException {
- if(entryLine.startsWith(DIRECTORY_PREFIX)) {
- isDirectory = true;
- entryLine = entryLine.substring(1);
- } else {
- isDirectory = false;
- }
-
- EmptyTokenizer tokenizer = new EmptyTokenizer(entryLine,SEPERATOR);
-
- if(tokenizer.countTokens() != 5) {
- throw new CVSException("Malformed entry line: " + entryLine);
- }
-
- name = tokenizer.nextToken();
-
- if(name.length()==0) {
- throw new CVSException("Malformed entry line, missing name: " + entryLine);
- }
-
- String rev = tokenizer.nextToken();
-
- if(rev.length()==0 && !isDirectory()) {
- throw new CVSException("Malformed entry line, missing revision: " + entryLine);
- } else {
- setRevision(rev);
- }
-
- timeStamp = tokenizer.nextToken();
- keywordMode = tokenizer.nextToken();
- String tagEntry = tokenizer.nextToken();
-
- if(tagEntry.length()>0) {
- tag = new CVSEntryLineTag(tagEntry);
- } else {
- tag = null;
- }
- }
-
- /**
- * Sets the version and decides if the revision is for a deleted resource the revision field
- * will not include the deleted prefix '-'.
- *
- * @param version the version to set
- */
- private void setRevision(String revision) {
- if(revision.startsWith(DELETED_PREFIX)) {
- this.revision = revision.substring(DELETED_PREFIX.length());
- isDeleted = true;
- } else {
- this.revision = revision;
- isDeleted = false;
- }
- }
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.team.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.resources.*;
+import org.eclipse.team.internal.ccvs.core.util.Assert;
+import org.eclipse.team.internal.ccvs.core.util.EmptyTokenizer;
+
+/**
+ * Value (immutable) object that represents workspace state information about a resource contained in
+ * a CVS repository. It is a specialized representation of a line in the CVS/Entry file with the addition of
+ * file permissions.
+ *
+ * Example entry line from the CVS/Entry file:
+ *
+ * /new.java/1.2/Fri Dec 07 00:17:52 2001/-kb/
+ * D/src////
+ *
+ * @see ICVSResource#getSyncInfo()
+ */
+public class ResourceSyncInfo {
+
+ // a directory sync info will have nothing more than a name
+ private boolean isDirectory = false;
+
+ // utility constants
+ private static final String DIRECTORY_PREFIX = "D/";
+ public static final String BINARY_TAG = "-kb";
+ private static final String SEPERATOR = "/";
+
+ // Timestamp constants used to identify special cases
+ public static final String DUMMY_TIMESTAMP = "dummy timestamp";
+ public static final String RESULT_OF_MERGE = "Result of merge+";
+
+ // safe default permissions. Permissions are saved separatly so that the correct permissions
+ // can be sent back to the server on systems that don't save execute bits (e.g. windows).
+ public static final String DEFAULT_PERMISSIONS = "u=rw,g=rw,o=r";
+
+ // file sync information can be associated with a local resource that has been deleted. This is
+ // noted by prefixing the revision with this character.
+ // XXX Should this be private
+ public static final String DELETED_PREFIX = "-";
+ private boolean isDeleted = false;
+
+ // a sync element with a revision of '0' is considered a new file that has
+ // not been comitted to the repo. Is visible so that clients can create sync infos
+ // for new files.
+ public static final String ADDED_REVISION = "0";
+
+ // fields describing the synchronization of a resource in CVS parlance
+ private String name;
+ private String revision;
+ private String timeStamp;
+ private String keywordMode;
+ private CVSEntryLineTag tag;
+ private String permissions;
+
+ /**
+ * Constructor to create a sync object from entry line formats. The entry lines are parsed by this class.
+ *
+ * @param entryLine the entry line (e.g. /new.java/1.2/Fri Dec 07 00:17:52 2001/-kb/)
+ * @param permissions the file permission (e.g. u=rw,g=rw,o=r). May be <code>null</code>.
+ * @param timestamp if not included in the entry line. Will overide the value in the entry line. The
+ * timestamp should be in the format specified in ICVSFile#getTimestamp(). May be <code>null</code>.
+ *
+ * @exception CVSException is thrown if the entry cannot be parsed.
+ */
+ public ResourceSyncInfo(String entryLine, String permissions, String timestamp) throws CVSException {
+ Assert.isNotNull(entryLine);
+
+ setEntryLine(entryLine);
+
+ if (permissions != null) {
+ this.permissions = permissions;
+ }
+ // override the timestamp that may of been in entryLine. In some cases the timestamp is not in the
+ // entry line (e.g. receiving entry lines from the server versus reading them from the Entry file).
+ if(timestamp!=null) {
+ this.timeStamp = timestamp;
+ }
+ }
+
+ /**
+ * Constructor to create a sync object from predefined values.
+ *
+ * @param name of the resource for which this sync state is associated, cannot be <code>null</code>.
+ * @param revision of the resource, cannot be <code>null</code>.
+ * @param timestamp can be <code>null</code>.
+ * @param keywordMode can be <code>null</code>
+ * @param tag can be <code>null</code>
+ * @param permissions can be <code>null</code>
+ */
+ public ResourceSyncInfo(String name, String revision, String timestamp, String keywordMode, CVSTag tag, String permissions) {
+ Assert.isNotNull(name);
+ Assert.isNotNull(revision);
+ this.name = name;
+ this.timeStamp = timestamp;
+ this.keywordMode = keywordMode;
+ this.permissions = permissions;
+ setRevision(revision);
+ setTag(tag);
+ }
+
+ /**
+ * Constructor to create a folder sync object.
+ *
+ * @param name of the resource for which this sync state is associatied, cannot be <code>null</code>.
+ */
+ public ResourceSyncInfo(String name) {
+ Assert.isNotNull(name);
+ this.name = name;
+ this.isDirectory = true;
+ }
+
+ /**
+ * Answers if this sync information is for a folder in which case only a name is
+ * available.
+ *
+ * @return <code>true</code> if the sync information is for a folder and <code>false</code>
+ * if it is for a file.
+ */
+ public boolean isDirectory() {
+ return isDirectory;
+ }
+
+ /**
+ * Answers if this sync information is for a file that has been added but not comitted
+ * to the CVS repository yet.
+ *
+ * @return <code>true</code> if the sync information is new or <code>false</code> if
+ * the sync is for an file that exists remotely. For folder sync info this returns
+ * <code>false</code>.
+ */
+ public boolean isAdded() {
+ if(!isDirectory) {
+ return getRevision().equals(ADDED_REVISION);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Answers if this sync information is for a file that is scheduled to be deleted
+ * from the repository but the deletion has not yet been comitted.
+ *
+ * @return <code>true</code> if the sync information is deleted or <code>false</code> if
+ * the sync is for an file that exists remotely.
+ */
+ public boolean isDeleted() {
+ return isDeleted;
+ }
+
+ /**
+ * Answers a CVS compatible entry line. The client can use this line to store in the CVS/Entry file or
+ * sent it to the server.
+ *
+ * @param includeTimeStamp determines if the timestamp will be included in the returned entry line. In
+ * some usages the timestamp should not be included in entry lines, for example when sending the entries
+ * to the server.
+ *
+ * @return a file or folder entry line reflecting the state of this sync object.
+ */
+ public String getEntryLine(boolean includeTimeStamp) {
+
+ StringBuffer result = new StringBuffer();
+
+ if(isDirectory) {
+ result.append(DIRECTORY_PREFIX);
+ result.append(name + "////");
+ } else {
+ result.append(SEPERATOR);
+ result.append(name);
+ result.append(SEPERATOR);
+
+ if(isDeleted){
+ result.append(DELETED_PREFIX);
+ }
+
+ result.append(revision);
+ result.append(SEPERATOR);
+
+ if(includeTimeStamp) {
+ result.append(timeStamp);
+ }
+ result.append(SEPERATOR);
+ result.append(keywordMode == null ? "" : keywordMode);
+ result.append(SEPERATOR);
+ if (tag != null) {
+ result.append(tag.toEntryLineFormat(true));
+ }
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Anwsers the a compatible permissions line for files.
+ *
+ * @return a permission line for files and <code>null</code> if this sync object is
+ * a directory.
+ */
+ public String getPermissionLine() {
+ if(isDirectory) {
+ return null;
+ } else {
+ String permissions = this.permissions;
+ if (permissions == null)
+ permissions = DEFAULT_PERMISSIONS;
+ return SEPERATOR + name + SEPERATOR + permissions;
+ }
+ }
+
+ /**
+ * Gets the permissions or <code>null</code> if permissions are not available.
+ *
+ * @return a string of the format "u=rw,g=rw,o=r"
+ */
+ public String getPermissions() {
+ if(isDirectory) {
+ return null;
+ } else {
+ if(permissions==null) {
+ return DEFAULT_PERMISSIONS;
+ } else {
+ return permissions;
+ }
+ }
+ }
+
+ /**
+ * Gets the tag or <code>null</code> if a tag is not available.
+ *
+ * @return Returns a String
+ */
+ public CVSTag getTag() {
+ return tag;
+ }
+
+ /**
+ * Gets the timeStamp or <code>null</code> if a timestamp is not available.
+ *
+ * @return a string of the format "Thu Oct 18 20:21:13 2001"
+ */
+ public String getTimeStamp() {
+ return timeStamp;
+ }
+
+ /**
+ * Gets the version or <code>null</code> if this is a folder sync info. The returned
+ * revision will never include the DELETED_PREFIX. To found out if this sync info is
+ * for a deleted resource call isDeleted().
+ *
+ * @return Returns a String
+ */
+ public String getRevision() {
+ return revision;
+ }
+
+
+ /**
+ * Gets the name.
+ *
+ * @return Returns a String
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the keyword mode or <code>null</code> if a keyword mode is available.
+ *
+ * @return
+ */
+ public String getKeywordMode() {
+ return keywordMode;
+ }
+
+ /**
+ * Name equality between resource sync info objects.
+ */
+ public boolean equals(Object other) {
+ if(other instanceof ResourceSyncInfo) {
+ ResourceSyncInfo syncInfo = ((ResourceSyncInfo)other);
+ if(other == this) return true;
+ if(getName() == syncInfo.getName()) return true;
+ return getName().equals(syncInfo.getName());
+ } else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ /**
+ * Sets the tag for the resource.
+ */
+ private void setTag(CVSTag tag) {
+ if(tag!=null) {
+ this.tag = new CVSEntryLineTag(tag);
+ } else {
+ this.tag = null;
+ }
+ }
+
+ /**
+ * Set the entry line
+ *
+ * @throws CVSException if the entryLine is malformed
+ */
+ private void setEntryLine(String entryLine) throws CVSException {
+ if(entryLine.startsWith(DIRECTORY_PREFIX)) {
+ isDirectory = true;
+ entryLine = entryLine.substring(1);
+ } else {
+ isDirectory = false;
+ }
+
+ EmptyTokenizer tokenizer = new EmptyTokenizer(entryLine,SEPERATOR);
+
+ if(tokenizer.countTokens() != 5) {
+ throw new CVSException("Malformed entry line: " + entryLine);
+ }
+
+ name = tokenizer.nextToken();
+
+ if(name.length()==0) {
+ throw new CVSException("Malformed entry line, missing name: " + entryLine);
+ }
+
+ String rev = tokenizer.nextToken();
+
+ if(rev.length()==0 && !isDirectory()) {
+ throw new CVSException("Malformed entry line, missing revision: " + entryLine);
+ } else {
+ setRevision(rev);
+ }
+
+ timeStamp = tokenizer.nextToken();
+ keywordMode = tokenizer.nextToken();
+ String tagEntry = tokenizer.nextToken();
+
+ if(tagEntry.length()>0) {
+ tag = new CVSEntryLineTag(tagEntry);
+ } else {
+ tag = null;
+ }
+ }
+
+ /**
+ * Sets the version and decides if the revision is for a deleted resource the revision field
+ * will not include the deleted prefix '-'.
+ *
+ * @param version the version to set
+ */
+ private void setRevision(String revision) {
+ if(revision.startsWith(DELETED_PREFIX)) {
+ this.revision = revision.substring(DELETED_PREFIX.length());
+ isDeleted = true;
+ } else {
+ this.revision = revision;
+ isDeleted = false;
+ }
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/SimpleCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/SimpleCache.java
new file mode 100644
index 000000000..6cb3c6863
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/SimpleCache.java
@@ -0,0 +1,76 @@
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A simple implementation of a cache. If a id is not in the cache it can be loaded via the loaded
+ * registered with the cache instance.
+ */
+public class SimpleCache implements ICache {
+
+ private Map cache = new HashMap();
+ private ICacheLoader loader;
+ private boolean cleanUpCache = false;
+
+ /*
+ * @see ICache#get(Object, Object)
+ */
+ public CacheData get(Object id, Object args) {
+ CacheData data = (CacheData)cache.get(id);
+ if(data==null && loader!=null) {
+ data = loader.load(id, this);
+ if(data!=null) {
+ put(data);
+ }
+ }
+ return data;
+ }
+
+ /*
+ * @see ICache#put(Object, Object)
+ */
+ public void put(CacheData data) {
+ cache.put(data.getId(), data);
+ }
+
+ /*
+ * @see ICache#remove(Object)
+ */
+ public void remove(Object id) {
+ cache.remove(id);
+ }
+
+ /*
+ * @see ICache#isEmpty()
+ */
+ public boolean isEmpty() {
+ return cache.isEmpty();
+ }
+
+ /*
+ * @see ICache#registerLoader(ICacheLoader)
+ */
+ public void registerLoader(ICacheLoader loader) {
+ this.loader = loader;
+ }
+
+ /*
+ * @see ICache#setAutoInvalidate(boolean)
+ */
+ public void setAutoInvalidate(boolean enable) {
+ cleanUpCache = true;
+ }
+
+ /*
+ * @see ICache#clear()
+ */
+ public void clear() {
+ cache.clear();
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ListFileFilter.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ListFileFilter.java
deleted file mode 100644
index e11a9487a..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ListFileFilter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.eclipse.team.internal.ccvs.core.util;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-
-import java.io.File;
-import java.io.FileFilter;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-import sun.audio.ContinuousAudioDataStream;
-
-/**
- * This class is a default FileFilter, that is used to
- * ex- or include certain files on a ioFile.listFiles.
- *
- * @see java.io.FileFilter
- */
-public class ListFileFilter implements FileFilter {
-
- private final String[] fileNameList;
- private final boolean exclude;
- private final boolean fileOnly;
- private final boolean folderOnly;
-
- /**
- * @param fileNameList the list of fileNames you want to include or exclude
- * @param exclude if true all files not in fileNameList are shown
- if false only files in fileNameList are shown
- */
- public ListFileFilter(String[] fileNameList, boolean exclude) {
- this(fileNameList,exclude,false, false);
- }
-
- /**
- * @param fileNameList the list of fileNames you want to include or exclude
- * @param exclude if true all files not in fileNameList are shown
- if false only files in fileNameList are shown
- * @param fileOnly if true only files are shown
- * @param folderOnly if true only folders are shown
- */
- public ListFileFilter(String[] fileNameList, boolean exclude, boolean fileOnly, boolean folderOnly) {
-
- Assert.isTrue(!fileOnly || !folderOnly);
-
- if (fileNameList == null) {
- fileNameList = new String[0];
- }
-
- this.fileNameList = fileNameList;
- this.exclude = exclude;
- this.fileOnly = fileOnly;
- this.folderOnly = folderOnly;
- }
-
- /**
- * @see FileFilter#accept(File)
- */
- public boolean accept(File file) {
-
- boolean result = exclude;
- String fileName = file.getName();
-
- // If the resource is of the wrong type reject it
- if (fileOnly && file.isDirectory()) {
- return false;
- }
- if (folderOnly && file.isFile()) {
- return false;
- }
-
- for (int i=0; i<fileNameList.length; i++) {
- // use starts-with because we do not want to be
- // messed up by an following seperator
- if (fileName.startsWith(fileNameList[i])) {
- result = !result;
- break;
- }
- }
-
- return result;
- }
-}
-
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/RemoteFolderTreeBuilder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/RemoteFolderTreeBuilder.java
index deed86950..ea4aa6ec2 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/RemoteFolderTreeBuilder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/RemoteFolderTreeBuilder.java
@@ -33,14 +33,15 @@ import org.eclipse.team.internal.ccvs.core.client.listeners.StatusListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.UpdateListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree;
import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.omg.CORBA.UNKNOWN;
/*
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ResourceDeltaVisitor.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ResourceDeltaVisitor.java
index 09623d412..ebc00b40e 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ResourceDeltaVisitor.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ResourceDeltaVisitor.java
@@ -1,7 +1,7 @@
package org.eclipse.team.internal.ccvs.core.util;
/*
- * (c) Copyright IBM Corp. 2000, 2002.
+ * (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
@@ -23,9 +23,7 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.team.ccvs.core.CVSTeamProvider;
import org.eclipse.team.core.ITeamProvider;
import org.eclipse.team.core.TeamPlugin;
-import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
@@ -43,40 +41,31 @@ public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
listener = new IResourceChangeListener() {
public void resourceChanged(IResourceChangeEvent event) {
try {
- if (event.getType() == IResourceChangeEvent.PRE_DELETE) {
- // We add the removal in the pre-delete.
- // It will be forwarded when we get the post change
- IResource resource = event.getResource();
+ IResourceDelta root = event.getDelta();
+ IResourceDelta[] projectDeltas = root.getAffectedChildren();
+ for (int i = 0; i < projectDeltas.length; i++) {
+ IResourceDelta delta = projectDeltas[i];
+ IResource resource = delta.getResource();
ITeamProvider provider = TeamPlugin.getManager().getProvider(resource);
- if (provider instanceof CVSTeamProvider)
- addRemoval(resource.getProject(), resource);
- } else {
- IResourceDelta root = event.getDelta();
- IResourceDelta[] projectDeltas = root.getAffectedChildren();
- for (int i = 0; i < projectDeltas.length; i++) {
- IResourceDelta delta = projectDeltas[i];
- IResource resource = delta.getResource();
- ITeamProvider provider = TeamPlugin.getManager().getProvider(resource);
-
- // if a project is moved the originating project will not be associated with the CVS provider
- // however listeners will probably still be interested in the move delta.
- if ((delta.getFlags() & IResourceDelta.MOVED_TO) > 0) {
- IResource destination = getResourceFor(resource.getProject(), resource, delta.getMovedToPath());
- provider = TeamPlugin.getManager().getProvider(destination);
- }
-
- if (provider instanceof CVSTeamProvider) {
- delta.accept(visitor);
- }
+
+ // if a project is moved the originating project will not be associated with the CVS provider
+ // however listeners will probably still be interested in the move delta.
+ if ((delta.getFlags() & IResourceDelta.MOVED_TO) > 0) {
+ IResource destination = getResourceFor(resource.getProject(), resource, delta.getMovedToPath());
+ provider = TeamPlugin.getManager().getProvider(destination);
+ }
+
+ if (provider instanceof CVSTeamProvider) {
+ delta.accept(visitor);
}
- visitor.handle();
}
+ visitor.handle();
} catch (CoreException e) {
Util.logError(Policy.bind("ResourceDeltaVisitor.visitError"), e);
}
}
};
- ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE);
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
return visitor;
}
@@ -161,6 +150,8 @@ public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
handleChanged(changes);
changes.clear();
+
+ finished();
}
/**
@@ -176,13 +167,8 @@ public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
Iterator i = additions.keySet().iterator();
while (i.hasNext()) {
IProject project = (IProject)i.next();
- ITeamProvider provider = TeamPlugin.getManager().getProvider(project);
- Iterator j = ((List)additions.get(project)).iterator();
- while (j.hasNext()) {
- IResource resource = (IResource)j.next();
- handleAdded(project,resource);
- //System.out.println(resource.toString());
- }
+ ArrayList resources = (ArrayList)additions.get(project);
+ handleAdded((IResource[])resources.toArray(new IResource[additions.size()]));
}
}
@@ -199,13 +185,8 @@ public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
Iterator i = changes.keySet().iterator();
while (i.hasNext()) {
IProject project = (IProject)i.next();
- ITeamProvider provider = TeamPlugin.getManager().getProvider(project);
- Iterator j = ((List)changes.get(project)).iterator();
- while (j.hasNext()) {
- IResource resource = (IResource)j.next();
- handleChanged(project,resource);
- //System.out.println(resource.toString());
- }
+ ArrayList resources = (ArrayList)changes.get(project);
+ handleChanged((IResource[])resources.toArray(new IResource[changes.size()]));
}
}
@@ -221,29 +202,26 @@ public abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
Iterator i = removals.keySet().iterator();
while (i.hasNext()) {
IProject project = (IProject)i.next();
- ITeamProvider provider = TeamPlugin.getManager().getProvider(project);
- Iterator j = ((List)removals.get(project)).iterator();
- while (j.hasNext()) {
- IResource resource = (IResource)j.next();
- handleRemoved(project,resource);
- //System.out.println(resource.toString());
- }
+ ArrayList resources = (ArrayList)removals.get(project);
+ handleRemoved((IResource[])resources.toArray(new IResource[removals.size()]));
}
}
/**
* React on every addition
*/
- protected abstract void handleAdded(IProject project,IResource resource);
+ protected abstract void handleAdded(IResource[] resources);
/**
* React on every removal
*/
- protected abstract void handleRemoved(IProject project,IResource resource);
+ protected abstract void handleRemoved(IResource[] resources);
/**
* React on every change
*/
- protected abstract void handleChanged(IProject project,IResource resource);
+ protected abstract void handleChanged(IResource[] resources);
+ protected abstract void finished();
}
+
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileUtil.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileUtil.java
index 7b00620fc..60f516a35 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileUtil.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileUtil.java
@@ -3,7 +3,7 @@ package org.eclipse.team.internal.ccvs.core.util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileFilter;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
@@ -13,17 +13,18 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.team.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
-import org.eclipse.team.internal.ccvs.core.resources.FolderSyncInfo;
-import org.eclipse.team.internal.ccvs.core.resources.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
public class SyncFileUtil {
- // CVS meta files located in CVS sub-directory of folders that are managed by CVS. These
- // files contain the workspace revision information for the resources that have been
- // checked out into a CVS workspace. See the CVS documentation for more details.
+ // All possible files available in the CVS subdir
+
public static final String REPOSITORY = "Repository";
public static final String ROOT = "Root";
public static final String STATIC = "Entries.Static";
@@ -35,6 +36,10 @@ public class SyncFileUtil {
// Some older CVS clients may of added a line to the entries file consisting
// of only a 'D'. It is safe to ingnore these entries.
private static final String FOLDER_TAG="D";
+
+ // Command characters found in the Entries.log file
+ private static final String ADD_TAG="A ";
+ private static final String REMOVE_TAG="R ";
/**
* Reads the CVS/Entry and CVS/Permissions files for the given folder. If the folder does not have a
@@ -88,6 +93,56 @@ public class SyncFileUtil {
return (ResourceSyncInfo[])infos.values().toArray(new ResourceSyncInfo[infos.size()]);
}
+ public static void writeResourceSync(File file, ResourceSyncInfo info) throws CVSException {
+ writeEntriesLog(file, info, ADD_TAG);
+ }
+
+ /**
+ * Append to Entries.log file
+ */
+ private static void writeEntriesLog(File file, ResourceSyncInfo info, String prefix) throws CVSException {
+ FileOutputStream out = null;
+ try {
+ File entriesLogFile = new File(getCVSSubdirectory(file.getParentFile()), ENTRIES_LOG);
+ if(!entriesLogFile.exists()) {
+ entriesLogFile.createNewFile();
+ }
+ String line = prefix + info.getEntryLine(true) +"\n";
+ out = new FileOutputStream(entriesLogFile.getAbsolutePath(), true);
+ out.write(line.getBytes());
+ } catch(IOException e) {
+ throw new CVSException(IStatus.ERROR, 0, "Error writing to Entries.log.", e);
+ } finally {
+ try {
+ if(out!=null) {
+ out.close();
+ }
+ } catch(IOException e) {
+ throw new CVSException(IStatus.ERROR, 0, "Cannot close Entries.log.", e);
+ }
+ }
+ }
+
+ /**
+ * Delete this file from Entries/Permissions file
+ */
+ public static void deleteSync(File file) throws CVSException {
+ if(file.isDirectory()) {
+ writeEntriesLog(file, new ResourceSyncInfo(file.getName()), REMOVE_TAG);
+ } else {
+ writeEntriesLog(file, new ResourceSyncInfo(file.getName(), "0", "", "", null, ""), REMOVE_TAG);
+ }
+ }
+
+ public static boolean isMetaFile(File file) {
+ File parent = file.getParentFile();
+ if(parent!=null&&parent.getName().equals("CVS")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
/**
* Writes the given resource sync infos into the CVS/Entry and CVS/Permissions files.
*/
@@ -139,6 +194,16 @@ public class SyncFileUtil {
return new FolderSyncInfo(repo, root, cvsTag, isStatic);
}
+ public static File[] getEntrySyncFiles(File folder) {
+ File cvsSubDir = getCVSSubdirectory(folder);
+ return new File[] { new File(cvsSubDir, ENTRIES), new File(cvsSubDir, PERMISSIONS) };
+ }
+
+ public static File[] getFolderSyncFiles(File folder) {
+ File cvsSubDir = getCVSSubdirectory(folder);
+ return new File[] { new File(cvsSubDir, ROOT), new File(cvsSubDir, REPOSITORY), new File(cvsSubDir, STATIC), new File(cvsSubDir, TAG) };
+ }
+
public static void writeFolderConfig(File parent, FolderSyncInfo info) throws CVSException {
if(!getCVSSubdirectory(parent).exists()) {
@@ -147,11 +212,7 @@ public class SyncFileUtil {
writeLine(parent, ROOT, info.getRoot());
if (info.getTag() != null) {
- String tagString = info.getTag().toEntryLineFormat(false);
- if (tagString.length() > 0)
- writeLine(parent, TAG, tagString);
- else
- writeLine(parent, TAG, null);
+ writeLine(parent, TAG, info.getTag().toEntryLineFormat(false));
} else {
writeLine(parent, TAG, null);
}
@@ -162,20 +223,6 @@ public class SyncFileUtil {
}
writeLine(parent, REPOSITORY, info.getRepository());
}
-
- public static File[] getEntrySyncFiles(File folder) {
- File cvsSubDir = getCVSSubdirectory(folder);
- return new File[] { new File(cvsSubDir, ENTRIES), new File(cvsSubDir, PERMISSIONS) };
- }
-
- public static File[] getFolderSyncFiles(File folder) {
- File cvsSubDir = getCVSSubdirectory(folder);
- return new File[] {new File(cvsSubDir, ROOT), new File(cvsSubDir, REPOSITORY), new File(cvsSubDir, STATIC), new File(cvsSubDir, TAG)};
- }
-
- public static File getCVSSubdirectory(File folder) {
- return new File(folder, "CVS");
- }
protected static void setContents(File parent, String filename, String[] contents) throws CVSException {
@@ -216,61 +263,14 @@ public class SyncFileUtil {
} else {
return null;
}
- }
+ }
- /**
- * To be compatible with other CVS clients meta files must be written with lines
- * terminating with a carriage return only.
- */
- private static void writeLines(File file, String[] content) throws CVSException {
-
- BufferedWriter fileWriter;
-
- try {
- fileWriter = new BufferedWriter(new FileWriter(file));
- for (int i = 0; i<content.length; i++) {
- fileWriter.write(content[i] + "\n");
- }
- fileWriter.close();
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
+ public static File getCVSSubdirectory(File folder) {
+ return new File(folder, "CVS");
}
- public static String[] readLines(File file) throws CVSException {
- BufferedReader fileReader;
- List fileContentStore = new ArrayList();
- String line;
-
- try {
- fileReader = new BufferedReader(new FileReader(file));
- while ((line = fileReader.readLine()) != null) {
- fileContentStore.add(line);
- }
- fileReader.close();
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
-
- return (String[]) fileContentStore.toArray(new String[fileContentStore.size()]);
- }
-
public static void mergeEntriesLogFiles(File root) throws CVSException {
- String FOLDER_TAG="D";
- String ADD_TAG="A ";
- String REMOVE_TAG="R ";
-
- File[] dirs = root.listFiles(new FileFilter() {
- public boolean accept(File file) {
- return file.isDirectory() && !file.getName().equals("CVS");
- }
- });
-
- //for (int i = 0; i < dirs.length; i++) {
- // mergeEntriesLogFiles(dirs[i]);
- //}
-
File logEntriesFile = new File(getCVSSubdirectory(root), ENTRIES_LOG);
File entriesFile = new File(getCVSSubdirectory(root), ENTRIES);
@@ -287,11 +287,13 @@ public class SyncFileUtil {
Map mergedEntries = new HashMap();
- String[] entries = readLines(entriesFile);
- for (int i = 0; i < entries.length; i++) {
- if (!FOLDER_TAG.equals(entries[i])) {
- mergedEntries.put((new ResourceSyncInfo(entries[i],null, null)).getName(),entries[i]);
- }
+ if(entriesFile.exists()) {
+ String[] entries = readLines(entriesFile);
+ for (int i = 0; i < entries.length; i++) {
+ if (!FOLDER_TAG.equals(entries[i])) {
+ mergedEntries.put((new ResourceSyncInfo(entries[i],null, null)).getName(),entries[i]);
+ }
+ }
}
String[] logEntries = readLines(logEntriesFile);
@@ -309,4 +311,41 @@ public class SyncFileUtil {
writeLines(entriesFile,(String[]) mergedEntries.values().toArray(new String[mergedEntries.size()]));
logEntriesFile.delete();
}
+
+ public static String[] readLines(File file) throws CVSException {
+ BufferedReader fileReader;
+ List fileContentStore = new ArrayList();
+ String line;
+
+ try {
+ fileReader = new BufferedReader(new FileReader(file));
+ while ((line = fileReader.readLine()) != null) {
+ fileContentStore.add(line);
+ }
+ fileReader.close();
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+
+ return (String[]) fileContentStore.toArray(new String[fileContentStore.size()]);
+ }
+
+ /**
+ * To be compatible with other CVS clients meta files must be written with lines
+ * terminating with a carriage return only.
+ */
+ private static void writeLines(File file, String[] content) throws CVSException {
+
+ BufferedWriter fileWriter;
+
+ try {
+ fileWriter = new BufferedWriter(new FileWriter(file));
+ for (int i = 0; i<content.length; i++) {
+ fileWriter.write(content[i] + "\n");
+ }
+ fileWriter.close();
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
} \ No newline at end of file

Back to the top