Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Valenta2002-12-13 10:50:14 -0500
committerMichael Valenta2002-12-13 10:50:14 -0500
commit8cb8bc26a955976914e10938b76ea258666d316d (patch)
tree4276a3cc0b050c7618c8ee2bca94eb19a7e717ec
parentf75e4e0544b97dca03cc16297d1999bad0d3f44e (diff)
downloadeclipse.platform.team-8cb8bc26a955976914e10938b76ea258666d316d.tar.gz
eclipse.platform.team-8cb8bc26a955976914e10938b76ea258666d316d.tar.xz
eclipse.platform.team-8cb8bc26a955976914e10938b76ea258666d316d.zip
Backed out of space optimizations due to time cost
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java4
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java46
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipsePhantomSynchronizer.java638
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java26
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java815
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java8
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LowLevelSyncInfoCache.java148
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java546
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java478
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java12
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/MoveDeleteHook.java2
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java73
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java12
13 files changed, 1230 insertions, 1578 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
index 24af7d793..458784654 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
@@ -473,7 +473,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
((EclipseFolder)getParent()).adjustModifiedCount(false);
}
// make sure the file is no longer marked
- EclipseSynchronizer.getInstance().flushDirtyCache(getIResource(), IResource.DEPTH_ZERO);
+ flushModificationCache();
return;
}
setModified(isModified(getSyncInfo()));
@@ -546,7 +546,7 @@ public class EclipseFile extends EclipseResource implements ICVSFile {
* Flush all cached info for the file and it's ancestors
*/
protected void flushModificationCache() throws CVSException {
- EclipseSynchronizer.getInstance().flushDirtyCache(getIFile(), IResource.DEPTH_ZERO);
+ EclipseSynchronizer.getInstance().flushModificationCache(getIFile());
}
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java
index ded8328df..16e8d54ea 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java
@@ -126,9 +126,8 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
* Method folderCreated.
*/
protected void folderCreated() throws CVSException {
- // flush the dirty cache for the ancestors
- String indicator = EclipseSynchronizer.getInstance().getDirtyIndicator(getIResource());
- if (indicator != null) {
+ Integer count = EclipseSynchronizer.getInstance().getDirtyCount((IContainer)getIResource());
+ if (count != null) {
flushWithAncestors();
}
EclipseSynchronizer.getInstance().folderCreated((IFolder)getIResource());
@@ -219,14 +218,14 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
setSyncInfo(new ResourceSyncInfo(getName()));
// if the sync info changed from null, we may need to adjust the ancestors
if (oldInfo == null) {
- int count = synchronizer.getDirtyCount((IContainer)getIResource());
- if (count == -1) {
+ Integer count = synchronizer.getDirtyCount((IContainer)getIResource());
+ if (count == null) {
// There was no cached count. Flush the ancestors so they are recalculated
flushWithAncestors();
} else {
// There is a count. Decrement the parent's count if the count is zero.
// Otherwise, the receiver and it's parents remain dirty.
- if (count == 0) {
+ if (count.intValue() == 0) {
synchronizer.setDirtyIndicator(getIResource(), EclipseSynchronizer.NOT_DIRTY_INDICATOR);
((EclipseFolder)getParent()).adjustModifiedCount(false);
}
@@ -266,13 +265,13 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
monitor.beginTask(null, 10);
monitor.subTask(container.getFullPath().toOSString());
EclipseSynchronizer.getInstance().deleteFolderSync(container);
- EclipseSynchronizer.getInstance().flushDirtyCache(container, IResource.DEPTH_ZERO);
+ EclipseSynchronizer.getInstance().flushModificationCache(container);
IResource[] members = container.members(true);
for (int i = 0; i < members.length; i++) {
monitor.worked(1);
IResource resource = members[i];
if (members[i].getType() == IResource.FILE) {
- EclipseSynchronizer.getInstance().flushDirtyCache(resource, IResource.DEPTH_ZERO);
+ EclipseSynchronizer.getInstance().flushModificationCache((IFile)resource);
} else {
recursiveUnmanage((IContainer) resource, monitor);
}
@@ -361,19 +360,17 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
public ICVSResource[] fetchChildren(IProgressMonitor monitor) throws CVSException {
return members(FILE_MEMBERS | FOLDER_MEMBERS);
}
-
/**
* @see org.eclipse.team.internal.ccvs.core.ICVSResource#delete()
*/
public void delete() throws CVSException {
if (!exists()) return;
if (isCVSFolder()) {
- //
EclipseSynchronizer.getInstance().prepareForDeletion((IContainer)getIResource());
}
super.delete();
}
-
+
/**
* Method adjustParentCount.
* @param file
@@ -390,7 +387,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
* Flush all cached info for the container and it's ancestors
*/
protected void flushModificationCache() throws CVSException {
- EclipseSynchronizer.getInstance().flushDirtyCache(getIResource(), IResource.DEPTH_ZERO);
+ EclipseSynchronizer.getInstance().flushModificationCache((IContainer)getIResource());
}
/*
@@ -399,11 +396,8 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
*/
protected void handleDeletion(IFile file, boolean modified) throws CVSException {
boolean adjustParent;
- int dirtyCount = EclipseSynchronizer.getInstance().getDirtyCount((IContainer)getIResource());
- if (dirtyCount == -1) {
- flushWithAncestors();
- return;
- }
+ Integer dirtyCount = EclipseSynchronizer.getInstance().getDirtyCount((IContainer)getIResource());
+ if (dirtyCount == null) return;
if (modified) {
adjustParent = EclipseSynchronizer.getInstance().addDeletedChild((IContainer)getIResource(), file);
} else {
@@ -419,8 +413,8 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
// if (isIgnored()) return false;
IContainer container = (IContainer)getIResource();
boolean shared = isCVSFolder();
- int count = EclipseSynchronizer.getInstance().getDirtyCount(container);
- if (count == -1) {
+ Integer count = EclipseSynchronizer.getInstance().getDirtyCount(container);
+ if (count == null) {
if (!exists()) return false;
String indicator = EclipseSynchronizer.getInstance().getDirtyIndicator(container);
if (indicator == null) {
@@ -439,7 +433,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
}
return EclipseSynchronizer.IS_DIRTY_INDICATOR.equals(indicator);
} else {
- return isModified(count, shared);
+ return isModified(count.intValue(), shared);
}
}
@@ -493,6 +487,16 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
return count > 0 || !shared;
}
+ /*
+ * @see org.eclipse.team.internal.ccvs.core.resources.EclipseResource#prepareToBeDeleted()
+ */
+ protected void prepareToBeDeleted() throws CVSException {
+ if (isCVSFolder()) {
+ EclipseSynchronizer.getInstance().prepareForDeletion((IContainer)getIResource());
+ }
+ super.prepareToBeDeleted();
+ }
+
public void syncInfoChanged() throws CVSException {
// It hard to deterime the effect of sync info for forlders so just flush the parent info
String indicator = EclipseSynchronizer.getInstance().getDirtyIndicator(getIResource());
@@ -501,7 +505,7 @@ class EclipseFolder extends EclipseResource implements ICVSFolder {
}
if (isIgnored()) {
// make sure the folder (or any of it's childen are no longer marked
- EclipseSynchronizer.getInstance().flushDirtyCache((IContainer)getIResource(), IResource.DEPTH_INFINITE);
+ EclipseSynchronizer.getInstance().flushModificationCache((IContainer)getIResource(), IResource.DEPTH_INFINITE);
}
}
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipsePhantomSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipsePhantomSynchronizer.java
new file mode 100644
index 000000000..0c2fd5ff8
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipsePhantomSynchronizer.java
@@ -0,0 +1,638 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.team.internal.ccvs.core.resources;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ISynchronizer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.ICVSResource;
+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.SyncFileWriter;
+
+/**
+ * Wraps the CVS EclipseSynchronizer with phantoms for folder deletions.
+ */
+public class EclipsePhantomSynchronizer extends EclipseSynchronizer {
+
+ private static final QualifiedName FOLDER_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-sync"); //$NON-NLS-1$
+ private static final QualifiedName RESOURCE_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync"); //$NON-NLS-1$
+
+ private Set changedResources = new HashSet();
+
+ EclipsePhantomSynchronizer() {
+ // Add the sync keys to the workspace synchronizer which is used to handle folder deletions
+ getWorkspaceSynchronizer().add(FOLDER_SYNC_KEY);
+ getWorkspaceSynchronizer().add(RESOURCE_SYNC_KEY);
+ getWorkspaceSynchronizer().add(DIRTY_COUNT);
+ }
+
+ /**
+ * Gets the folder sync info for the specified folder.
+ *
+ * @param folder the folder
+ * @return the folder sync info associated with the folder, or null if none.
+ * @see #setFolderSync, #deleteFolderSync
+ */
+ public FolderSyncInfo getFolderSync(IContainer container) throws CVSException{
+ if (container.isPhantom()) {
+ return getPhantomFolderSyncInfo(container);
+ }
+ return super.getFolderSync(container);
+ }
+
+ /**
+ * @see EclipseSynchronizer#setFolderSync(IContainer, FolderSyncInfo)
+ */
+ public void setFolderSync(IContainer container, FolderSyncInfo info) throws CVSException {
+ if (container.isPhantom()) {
+ try {
+ beginOperation(null);
+ changedResources.add(container);
+ try {
+ getWorkspaceSynchronizer().setSyncInfo(FOLDER_SYNC_KEY, container, getBytes(info));
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ } finally {
+ endOperation(null);
+ }
+ } else {
+ super.setFolderSync(container, info);
+ }
+ }
+
+ /**
+ * Deletes the folder sync for the specified folder and the resource sync
+ * for all of its children. Does not recurse.
+ *
+ * @param folder the folder
+ * @see #getFolderSync, #setFolderSync
+ */
+ public void deleteFolderSync(IContainer container) throws CVSException {
+ if (container.isPhantom()) {
+ try {
+ beginOperation(null);
+ changedResources.add(container);
+ flushPhantomInfo(container);
+ } finally {
+ endOperation(null);
+ }
+ } else {
+ super.deleteFolderSync(container);
+ }
+ }
+
+ /**
+ * Gets the resource sync info for the specified folder.
+ *
+ * @param resource the resource
+ * @return the resource sync info associated with the resource, or null if none.
+ * @see #setResourceSync, #deleteResourceSync
+ */
+ public ResourceSyncInfo getResourceSync(IResource resource) throws CVSException {
+ IContainer parent = resource.getParent();
+ if (parent != null && parent.isPhantom()) {
+ Map map = getPhantomResourceSyncInfoMap(parent);
+ return (ResourceSyncInfo)map.get(resource.getName());
+ }
+ return super.getResourceSync(resource);
+ }
+
+ /**
+ * @see EclipseSynchronizer#setResourceSync(IResource, ResourceSyncInfo)
+ */
+ public void setResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException {
+ IContainer parent = resource.getParent();
+ if (parent != null && parent.isPhantom()) {
+ // Look for the sync info in the workspace synchronizer
+ try {
+ beginOperation(null);
+ Map map = getPhantomResourceSyncInfoMap(parent);
+ map.put(resource.getName(), info);
+ getWorkspaceSynchronizer().setSyncInfo(RESOURCE_SYNC_KEY, parent, getBytes(map));
+ changedResources.add(resource);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ } finally {
+ endOperation(null);
+ }
+ } else {
+ super.setResourceSync(resource, info);
+ }
+ }
+
+ /**
+ * Deletes the resource sync info for the specified resource, if it exists.
+ *
+ * @param resource the resource
+ * @see #getResourceSync, #setResourceSync
+ */
+ public void deleteResourceSync(IResource resource) throws CVSException {
+ IContainer parent = resource.getParent();
+ if (parent != null && parent.isPhantom()) {
+ // Look for the sync info in the workspace synchronizer
+ try {
+ beginOperation(null);
+ Map map = getPhantomResourceSyncInfoMap(parent);
+ map.remove(resource.getName());
+ getWorkspaceSynchronizer().setSyncInfo(RESOURCE_SYNC_KEY, parent, getBytes(map));
+ changedResources.add(resource);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ } finally {
+ endOperation(null);
+ }
+ } else {
+ super.deleteResourceSync(resource);
+ }
+ }
+
+ /**
+ * Flush the folder sync and resource sync for a phantom folder that has no childen
+ * @param folder an empty phantom folder
+ */
+ private void flushEmptyFolder(IContainer folder) throws CVSException {
+ deleteFolderSync(folder);
+ deleteResourceSync(folder);
+ }
+
+ /**
+ * Returns the members of this folder which are either phantom folder
+ * or file deletions
+ *
+ * @param folder the container to list
+ * @return the array of members
+ */
+ public IResource[] members(IContainer container) throws CVSException {
+ if (container.isPhantom()) {
+ Map map = getPhantomResourceSyncInfoMap(container);
+ Set childResources = new HashSet();
+ for (Iterator it = map.values().iterator(); it.hasNext();) {
+ ResourceSyncInfo info = (ResourceSyncInfo) it.next();
+ IPath path = new Path(info.getName());
+ if(info.isDirectory()) {
+ childResources.add(container.getFolder(path));
+ } else {
+ childResources.add(container.getFile(path));
+ }
+ }
+ return (IResource[])childResources.toArray(new IResource[childResources.size()]);
+ } else {
+ return super.members(container);
+ }
+ }
+
+ /**
+ * Notify the receiver that a folder has been created.
+ * Any existing phantom sync info will be moved
+ *
+ * @param folder the folder that has been created
+ */
+ public void folderCreated(IFolder folder) throws CVSException {
+ try {
+ // set the dirty count using what was cached in the phantom it
+ beginOperation(null);
+ FolderSyncInfo folderInfo = getPhantomFolderSyncInfo(folder);
+ if (folderInfo != null) {
+ Map map = getPhantomResourceSyncInfoMap(folder);
+ if (folder.getFolder(SyncFileWriter.CVS_DIRNAME).exists()) {
+ // There is already a CVS subdirectory which indicates that
+ // either the folder was recreated by an external tool or that
+ // a folder with CVS information was copied from another location.
+ // To know the difference, we need to compare the folder sync info.
+ // If they are mapped to the same root and repository then just
+ // purge the phantom info. Otherwise, keep the original sync info.
+
+ // flush the phantom info so we can get what is on disk.
+ flushPhantomInfo(folder);
+
+ // Get the new folder sync info
+ FolderSyncInfo newFolderInfo = getFolderSync(folder);
+ if (newFolderInfo.getRoot().equals(folderInfo.getRoot())
+ && newFolderInfo.getRepository().equals(folderInfo.getRepository())) {
+ // The folder is the same so use what is on disk
+ return;
+ }
+
+ // The folder is mapped to a different location.
+ // Purge new resource sync before restoring from phantom
+ ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(folder);
+ ICVSResource[] children = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS);
+ for (int i = 0; i < children.length; i++) {
+ ICVSResource resource = children[i];
+ deleteResourceSync(resource.getIResource());
+ }
+ }
+
+ // set the sync info using what was cached in the phantom
+ setFolderSync(folder, folderInfo);
+ for (Iterator it = map.values().iterator(); it.hasNext();) {
+ ResourceSyncInfo info = (ResourceSyncInfo) it.next();
+ IPath path = new Path(info.getName());
+ IResource childResource;
+ if(info.isDirectory()) {
+ childResource = folder.getFolder(path);
+ } else {
+ childResource = folder.getFile(path);
+ }
+ setResourceSync(childResource, info);
+ }
+ }
+ } finally {
+ try {
+ endOperation(null);
+ } finally {
+ flushPhantomInfo(folder);
+ }
+ }
+ }
+
+ /**
+ * Return the cached folder sync info for the given container or null
+ * if there is none.
+ */
+ private FolderSyncInfo getPhantomFolderSyncInfo(IContainer container) throws CVSException {
+ try {
+ byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(FOLDER_SYNC_KEY, container);
+ if (bytes == null) return null;
+ return getFolderSyncInfo(bytes);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ private Map getPhantomResourceSyncInfoMap(IContainer container) throws CVSException {
+ try {
+ byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(RESOURCE_SYNC_KEY, container);
+ if (bytes == null) return new HashMap();
+ return getResourceSyncInfoMap(bytes);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * Flush any info cahced for the folder
+ */
+ private void flushPhantomInfo(IContainer container) throws CVSException {
+ try {
+ if (container.exists() || container.isPhantom()) {
+ getWorkspaceSynchronizer().flushSyncInfo(FOLDER_SYNC_KEY, container, IResource.DEPTH_ZERO);
+ }
+ if (container.exists() || container.isPhantom()) {
+ getWorkspaceSynchronizer().flushSyncInfo(RESOURCE_SYNC_KEY, container, IResource.DEPTH_ZERO);
+ }
+ internalFlushModificationCache(container);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * Return the Eclipse Workspace Synchronizer (from org.eclipse.core.resources)
+ */
+ private ISynchronizer getWorkspaceSynchronizer() {
+ return ResourcesPlugin.getWorkspace().getSynchronizer();
+ }
+
+ /**
+ * The folder is about to be deleted so move the folder's CVS information
+ * to the workspace synchronizer so it will survive the deletion
+ */
+ public void prepareForDeletion(IContainer container) throws CVSException {
+ try {
+ beginOperation(null);
+ if (container.getType() == IResource.PROJECT) {
+ getWorkspaceSynchronizer().flushSyncInfo(FOLDER_SYNC_KEY, container, IResource.DEPTH_INFINITE);
+ getWorkspaceSynchronizer().flushSyncInfo(RESOURCE_SYNC_KEY, container, IResource.DEPTH_INFINITE);
+ getWorkspaceSynchronizer().flushSyncInfo(DIRTY_COUNT, container, IResource.DEPTH_INFINITE);
+ } else {
+ // Move the folder sync info into phantom space
+ FolderSyncInfo info = getFolderSync(container);
+ if (info == null) return;
+ getWorkspaceSynchronizer().setSyncInfo(FOLDER_SYNC_KEY, container, getBytes(info));
+ getWorkspaceSynchronizer().setSyncInfo(RESOURCE_SYNC_KEY, container, getBytes(getResourceSyncInfosForChildren(container)));
+ changedResources.add(container);
+ // Move the dirty count into phantom space
+ Integer dirtyCount = getDirtyCount(container);
+ if (dirtyCount != null) {
+ internalSetDirtyCount(container, dirtyCount.intValue());
+ }
+ }
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ } finally {
+ endOperation(null);
+ }
+ }
+
+ /**
+ * Return a map of resource name to ResourceSyncInfo
+ *
+ * This should only be used on folders that exist in the workspace
+ */
+ private Map getResourceSyncInfosForChildren(IContainer parent) throws CVSException {
+ ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(parent);
+ ICVSResource[] files = folder.members(ICVSFolder.FILE_MEMBERS | ICVSFolder.FOLDER_MEMBERS | ICVSFolder.MANAGED_MEMBERS);
+ Map result = new HashMap();
+ for (int i = 0; i < files.length; i++) {
+ ICVSResource resource = files[i];
+ result.put(resource.getName(), resource.getSyncInfo());
+ }
+ return result;
+ }
+
+ /**
+ * Convert a byte array that was created using getBytes(FolderSyncInfo)
+ * into a FolderSyncInfo
+ */
+ private static FolderSyncInfo getFolderSyncInfo(byte[] bytes) throws CVSException {
+ ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+ DataInputStream dis = new DataInputStream(in);
+ String root;
+ String repository;
+ CVSEntryLineTag tag;
+ boolean isStatic;
+ try {
+ root = dis.readUTF();
+ repository = dis.readUTF();
+ String tagName = dis.readUTF();
+ if (tagName.length() == 0) {
+ tag = null;
+ } else {
+ tag = new CVSEntryLineTag(tagName);
+ }
+ isStatic = dis.readBoolean();
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+ return new FolderSyncInfo(repository, root, tag, isStatic);
+ }
+
+ /**
+ * Convert a FolderSyncInfo into a byte array that can be stored
+ * in the workspace synchronizer
+ */
+ private static byte[] getBytes(FolderSyncInfo info) throws CVSException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(out);
+ try {
+ dos.writeUTF(info.getRoot());
+ dos.writeUTF(info.getRepository());
+ CVSEntryLineTag tag = info.getTag();
+ if (tag == null) {
+ dos.writeUTF(""); //$NON-NLS-1$
+ } else {
+ dos.writeUTF(tag.toString());
+ }
+ dos.writeBoolean(info.getIsStatic());
+ dos.close();
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+ return out.toByteArray();
+ }
+
+ /**
+ * Convert a Map of ResourceSyncInfo into a byte array that can be stored
+ * in the workspace synchronizer
+ */
+ private static byte[] getBytes(Map infos) throws CVSException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(out);
+ try {
+ dos.writeInt(infos.size());
+ Iterator iter = infos.values().iterator();
+ while (iter.hasNext()) {
+ ResourceSyncInfo info = (ResourceSyncInfo)iter.next();
+ dos.writeUTF(info.getEntryLine());
+ }
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+ return out.toByteArray();
+ }
+
+ /**
+ * Convert a byte array that was created using getBytes(Map)
+ * into a Map of ResourceSyncInfo
+ */
+ private static Map getResourceSyncInfoMap(byte[] bytes) throws CVSException {
+ ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+ DataInputStream dis = new DataInputStream(in);
+ Map result = new HashMap();
+ try {
+ int size = dis.readInt();
+ for (int i = 0; i < size; i++) {
+ ResourceSyncInfo info = new ResourceSyncInfo(dis.readUTF(), null, null);
+ result.put(info.getName(), info);
+ }
+ } catch (IOException e) {
+ throw CVSException.wrapException(e);
+ }
+ return result;
+ }
+
+ /**
+ * @see EclipseSynchronizer#broadcastResourceStateChanges(IResource[])
+ */
+ void broadcastResourceStateChanges(IResource[] resources) {
+ // Add the changedResources to the list of broadcasted resources
+ if (changedResources.size() > 0) {
+ ArrayList allResources = new ArrayList();
+ allResources.addAll(Arrays.asList(resources));
+ allResources.addAll(changedResources);
+ resources = (IResource[]) allResources.toArray(new IResource[allResources.size()]);
+ changedResources.clear();
+ }
+ super.broadcastResourceStateChanges(resources);
+ }
+
+ /*
+ * Return the dirty count for the given folder. For existing folders, the
+ * dirty count may not have been calculated yet and this method will return
+ * null in that case. For phantom folders, the dirty count is calculated if
+ * it does not exist yet.
+ */
+ protected Integer getDirtyCount(IContainer parent) throws CVSException {
+ if (parent.isPhantom()) {
+ // get the count from the synchronizer
+ int count = internalGetDirtyCount(parent);
+ if (count == -1) {
+ count = calculateDirtyCountForPhantom(parent);
+ //setDirtyCount(parent, count);
+ }
+ return new Integer(count);
+ } else {
+ return super.getDirtyCount(parent);
+ }
+ }
+
+ protected int internalGetDirtyCount(IContainer parent) throws CVSException {
+ try {
+ byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(DIRTY_COUNT, parent);
+ if (bytes == null) return -1;
+ return intFromBytes(bytes);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ protected void setDirtyCount(IContainer container, int count) throws CVSException {
+ if (container.isPhantom()) {
+ internalSetDirtyCount(container, count);
+ } else {
+ super.setDirtyCount(container, count);
+ }
+ }
+
+ protected void internalSetDirtyCount(IContainer container, int count) throws CVSException {
+ try {
+ beginOperation(null);
+ getWorkspaceSynchronizer().setSyncInfo(DIRTY_COUNT, container, getBytes(count));
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ } finally {
+ endOperation(null);
+ }
+ }
+
+ /*
+ * Calculate the dirty count for the given phantom folder, performing any
+ * necessary calculations on the childen as well
+ */
+ private int calculateDirtyCountForPhantom(IContainer parent) throws CVSException {
+ ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(parent);
+ ICVSResource[] children = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS | ICVSFolder.PHANTOM_MEMBERS);
+ int count = 0;
+ for (int i = 0; i < children.length; i++) {
+ ICVSResource resource = children[i];
+ if (resource.isFolder()) {
+ Integer dc = getDirtyCount((IContainer)resource.getIResource());
+ if (dc.intValue() > 0) count++;
+ } else {
+ // Any non-existant managed files are dirty (outgoing deletion)
+ count++;
+ }
+ }
+ return count;
+ }
+ /*
+ * Convert an int to a byte array
+ */
+ private byte[] getBytes(int count) {
+ byte[] result = new byte[4];
+ result[0] = (byte)(count & 256);
+ result[1] = (byte)(count<<8 & 256);
+ result[1] = (byte)(count<<16 & 256);
+ result[1] = (byte)(count<<24 & 256);
+ return result;
+ }
+
+ /*
+ * Convert a byte array to an int
+ */
+ private int intFromBytes(byte[] bytes) {
+ return bytes[0] + (bytes[1]>>8) + (bytes[2]>>16) + (bytes[3]>>24);
+ }
+
+ /*
+ * Flush all cached info for the container and it's ancestors
+ */
+ protected void flushModificationCache(IContainer container) throws CVSException {
+ internalFlushModificationCache(container);
+ super.flushModificationCache(container);
+ }
+
+ private void internalFlushModificationCache(IContainer container) throws CVSException {
+// if (container.exists() || container.isPhantom()) {
+// try {
+// getWorkspaceSynchronizer().flushSyncInfo(DIRTY_COUNT, container, IResource.DEPTH_ZERO);
+// } catch (CoreException e) {
+// throw CVSException.wrapException(e);
+// }
+// }
+ }
+
+ /**
+ * @see org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer#addDeletedChild(org.eclipse.core.resources.IContainer, org.eclipse.core.resources.IFile)
+ */
+ protected boolean addDeletedChild(IContainer container, IFile file) throws CVSException {
+ if (container.isPhantom()) {
+// try {
+// beginOperation(null);
+// int oldCount = internalGetDirtyCount(container);
+// if (oldCount == -1) {
+// // there is no cached count so wait until the first query
+// // or there was no deleted file
+// return false;
+// }
+// int newCount = calculateDirtyCountForPhantom(container);
+// // adjust the parent folder count if the newCount is 1;
+// return oldCount == 0 && newCount == 1;
+// } finally {
+// endOperation(null);
+// }
+ return true;
+ } else {
+ return super.addDeletedChild(container, file);
+ }
+ }
+
+ /**
+ * @see org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer#removeDeletedChild(org.eclipse.core.resources.IContainer, org.eclipse.core.resources.IFile)
+ */
+ protected boolean removeDeletedChild(IContainer container, IFile file) throws CVSException {
+ if (container.isPhantom()) {
+// try {
+// beginOperation(null);
+// int oldCount = internalGetDirtyCount(container);
+// if (oldCount == -1 || oldCount == 0) {
+// // there is no cached count so wait until the first query
+// // or there was no deleted file
+// return false;
+// }
+// int newCount = calculateDirtyCountForPhantom(container);
+// // adjust the parent folder count if the newCount is 0;
+// return newCount == 0;
+// } finally {
+// endOperation(null);
+// }
+ return true;
+ } else {
+ return super.removeDeletedChild(container, file);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java
index 541163c25..84e58f931 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseResource.java
@@ -267,13 +267,23 @@ abstract class EclipseResource implements ICVSResource, Comparable {
return resource;
}
+ /*
+ * Flush all cached modification info for the resource and it's ancestors
+ */
+ protected abstract void flushModificationCache() throws CVSException;
+
public abstract boolean handleModification(boolean forAddition) throws CVSException;
/*
* Flush all cached info for the file and it's ancestors
*/
protected void flushWithAncestors() throws CVSException {
- EclipseSynchronizer.getInstance().flushDirtyCacheWithAncestors(getIResource());
+ if (resource.getType() == IResource.ROOT) return;
+ try {
+ flushModificationCache();
+ } finally {
+ ((EclipseResource)getParent()).flushWithAncestors();
+ }
}
protected String getDirtyIndicator() throws CVSException {
@@ -285,6 +295,20 @@ abstract class EclipseResource implements ICVSResource, Comparable {
}
/*
+ * Method prepareToBeDeleted is invoked by the move/delete hook to allow the
+ * resource to prepare to be deleted.
+ */
+ protected void prepareToBeDeleted() throws CVSException {
+ // Flush the dirty info for the resource and it's ancestors.
+ // Although we could be smarter, we need to do this because the
+ // deletion may fail.
+ String indicator = EclipseSynchronizer.getInstance().getDirtyIndicator(getIResource());
+ if (indicator != null) {
+ flushWithAncestors();
+ }
+ }
+
+ /*
* Method syncInfoChanged is invoked by the sync file change listener.
*/
protected abstract void syncInfoChanged() throws CVSException;
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
index c256171bb..e95f73bcd 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
@@ -7,6 +7,7 @@ package org.eclipse.team.internal.ccvs.core.resources;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -17,7 +18,6 @@ import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
@@ -26,11 +26,11 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSStatus;
-import org.eclipse.team.internal.ccvs.core.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.ICVSResource;
import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.syncinfo.BaserevInfo;
@@ -48,10 +48,26 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter;
* @see ResourceSyncInfo
* @see FolderSyncInfo
*/
-public class EclipseSynchronizer {
- protected static final String IS_DIRTY_INDICATOR = LowLevelSyncInfoCache.IS_DIRTY_INDICATOR;
- protected static final String NOT_DIRTY_INDICATOR = LowLevelSyncInfoCache.NOT_DIRTY_INDICATOR;
-
+public class EclipseSynchronizer {
+ // the resources plugin synchronizer is used to cache and possibly persist. These
+ // are keys for storing the sync info.
+ private static final QualifiedName FOLDER_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-sync"); //$NON-NLS-1$
+ private static final QualifiedName RESOURCE_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync"); //$NON-NLS-1$
+ private static final QualifiedName IGNORE_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-ignore"); //$NON-NLS-1$
+
+ protected static final QualifiedName IS_DIRTY = new QualifiedName(CVSProviderPlugin.ID, "is-dirty");
+ protected static final QualifiedName CLEAN_UPDATE = new QualifiedName(CVSProviderPlugin.ID, "clean-update");
+ protected static final QualifiedName DIRTY_COUNT = new QualifiedName(CVSProviderPlugin.ID, "dirty-count");
+ protected static final QualifiedName DELETED_CHILDREN = new QualifiedName(CVSProviderPlugin.ID, "deleted");
+ protected static final String IS_DIRTY_INDICATOR = "d";
+ protected static final String NOT_DIRTY_INDICATOR = "c";
+ protected static final String UPDATED_INDICATOR = "u";
+
+ private static final String[] NULL_IGNORES = new String[0];
+ private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("", "", null, false); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private static final IStatus STATUS_OK = new Status(IStatus.OK, CVSProviderPlugin.ID, 0, Policy.bind("ok"), null); //$NON-NLS-1$
+
// the cvs eclipse synchronizer is a singleton
private static EclipseSynchronizer instance;
@@ -61,13 +77,6 @@ public class EclipseSynchronizer {
private Set changedResources = new HashSet();
private Set changedFolders = new HashSet();
- private static IContainer cachedFolder;
- private static Map cachedResourceSyncInfos;
- private static boolean cacheDirty = false;
-
- private SessionPropertySyncInfoCache sessionPropertyCache = new SessionPropertySyncInfoCache();
- private SynchronizerSyncInfoCache synchronizerCache = new SynchronizerSyncInfoCache();
-
/*
* Package private contructor to allow specialized subclass for handling folder deletions
*/
@@ -79,23 +88,11 @@ public class EclipseSynchronizer {
*/
public static EclipseSynchronizer getInstance() {
if(instance==null) {
- instance = new EclipseSynchronizer();
+ instance = new EclipsePhantomSynchronizer();
}
return instance;
}
-
- public LowLevelSyncInfoCache getLowLevelCacheFor(IResource resource) {
- if (resource.isPhantom()) {
- return synchronizerCache;
- } else {
- return sessionPropertyCache;
- }
- }
- private boolean isValid(IResource resource) {
- return resource.exists() || resource.isPhantom();
- }
-
/**
* Sets the folder sync info for the specified folder.
* The folder must exist and must not be the workspace root.
@@ -106,14 +103,14 @@ public class EclipseSynchronizer {
*/
public void setFolderSync(IContainer folder, FolderSyncInfo info) throws CVSException {
Assert.isNotNull(info); // enforce the use of deleteFolderSync
- if (folder.getType() == IResource.ROOT || !isValid(folder)) {
+ if (folder.getType() == IResource.ROOT || ! folder.exists()) {
throw new CVSException(IStatus.ERROR, CVSException.UNABLE,
Policy.bind("EclipseSynchronizer.ErrorSettingFolderSync", folder.getFullPath().toString())); //$NON-NLS-1$
}
try {
beginOperation(null);
// set folder sync and notify
- getLowLevelCacheFor(folder).setCachedFolderSync(folder, info);
+ setCachedFolderSync(folder, info);
changedFolders.add(folder);
} finally {
endOperation(null);
@@ -128,11 +125,11 @@ public class EclipseSynchronizer {
* @see #setFolderSync, #deleteFolderSync
*/
public FolderSyncInfo getFolderSync(IContainer folder) throws CVSException {
- if (folder.getType() == IResource.ROOT || !isValid(folder)) return null;
+ if (folder.getType() == IResource.ROOT || ! folder.exists()) return null;
try {
beginOperation(null);
// cache folder sync and return it
- return getLowLevelCacheFor(folder).cacheFolderSync(folder);
+ return cacheFolderSync(folder);
} finally {
endOperation(null);
}
@@ -146,17 +143,17 @@ public class EclipseSynchronizer {
* @see #getFolderSync, #setFolderSync
*/
public void deleteFolderSync(IContainer folder) throws CVSException {
- if (folder.getType() == IResource.ROOT || !isValid(folder)) return;
+ if (folder.getType() == IResource.ROOT || ! folder.exists()) return;
try {
beginOperation(null);
// delete folder sync
- getLowLevelCacheFor(folder).setCachedFolderSync(folder, null);
+ setCachedFolderSync(folder, null);
changedFolders.add(folder);
// iterate over all children with sync info and prepare notifications
- getLowLevelCacheFor(folder).cacheResourceSyncForChildren(folder);
- fastCacheResourceSyncForChildren(folder);
- for (Iterator iter = cachedResourceSyncInfos.values().iterator(); iter.hasNext();) {
- ResourceSyncInfo info = (ResourceSyncInfo) iter.next();
+ cacheResourceSyncForChildren(folder);
+ Collection infos = getCachedResourceSyncForChildren(folder);
+ for (Iterator it = infos.iterator(); it.hasNext();) {
+ ResourceSyncInfo info = (ResourceSyncInfo) it.next();
IPath path = new Path(info.getName());
if(info.isDirectory()) {
changedResources.add(folder.getFolder(path));
@@ -165,7 +162,7 @@ public class EclipseSynchronizer {
}
}
// delete resource sync for all children
- getLowLevelCacheFor(folder).setCachedResourceSyncForChildren(folder, null);
+ deleteCachedResourceSyncForChildren(folder);
} finally {
endOperation(null);
}
@@ -182,14 +179,14 @@ public class EclipseSynchronizer {
public void setResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException {
Assert.isNotNull(info); // enforce the use of deleteResourceSync
IContainer parent = resource.getParent();
- if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) {
+ if (parent == null || ! parent.exists() || parent.getType() == IResource.ROOT) {
throw new CVSException(IStatus.ERROR, CVSException.UNABLE,
Policy.bind("EclipseSynchronizer.ErrorSettingResourceSync", resource.getFullPath().toString())); //$NON-NLS-1$
}
try {
beginOperation(null);
// cache resource sync for siblings, set for self, then notify
- getLowLevelCacheFor(parent).cacheResourceSyncForChildren(parent);
+ cacheResourceSyncForChildren(parent);
setCachedResourceSync(resource, info);
changedResources.add(resource);
} finally {
@@ -206,11 +203,11 @@ public class EclipseSynchronizer {
*/
public ResourceSyncInfo getResourceSync(IResource resource) throws CVSException {
IContainer parent = resource.getParent();
- if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) return null;
+ if (parent == null || ! parent.exists() || parent.getType() == IResource.ROOT) return null;
try {
beginOperation(null);
// cache resource sync for siblings, then return for self
- getLowLevelCacheFor(parent).cacheResourceSyncForChildren(parent);
+ cacheResourceSyncForChildren(parent);
return getCachedResourceSync(resource);
} finally {
endOperation(null);
@@ -225,11 +222,11 @@ public class EclipseSynchronizer {
*/
public void deleteResourceSync(IResource resource) throws CVSException {
IContainer parent = resource.getParent();
- if (parent == null || parent.getType() == IResource.ROOT || !isValid(parent)) return;
+ if (parent == null || ! parent.exists() || parent.getType() == IResource.ROOT) return;
try {
beginOperation(null);
// cache resource sync for siblings, delete for self, then notify
- getLowLevelCacheFor(parent).cacheResourceSyncForChildren(parent);
+ cacheResourceSyncForChildren(resource.getParent());
if (getCachedResourceSync(resource) != null) { // avoid redundant notifications
setCachedResourceSync(resource, null);
changedResources.add(resource);
@@ -247,7 +244,7 @@ public class EclipseSynchronizer {
* @see #addIgnored
*/
public String[] getIgnored(IContainer folder) throws CVSException {
- if (folder.getType() == IResource.ROOT || ! folder.exists()) return SessionPropertySyncInfoCache.NULL_IGNORES;
+ if (folder.getType() == IResource.ROOT || ! folder.exists()) return NULL_IGNORES;
try {
beginOperation(null);
return cacheFolderIgnores(folder);
@@ -302,16 +299,16 @@ public class EclipseSynchronizer {
* @return the array of members
*/
public IResource[] members(IContainer folder) throws CVSException {
- if (! isValid(folder)) return new IResource[0];
+ if (! folder.exists()) return new IResource[0];
try {
beginOperation(null);
if (folder.getType() == IResource.ROOT) return folder.members();
- getLowLevelCacheFor(folder).cacheResourceSyncForChildren(folder);
- fastCacheResourceSyncForChildren(folder);
+ cacheResourceSyncForChildren(folder);
+ Collection infos = getCachedResourceSyncForChildren(folder);
// add all children with or without sync info
Set childResources = new HashSet();
- for (Iterator iter = cachedResourceSyncInfos.values().iterator(); iter.hasNext();) {
- ResourceSyncInfo info = (ResourceSyncInfo) iter.next();
+ for (Iterator it = infos.iterator(); it.hasNext();) {
+ ResourceSyncInfo info = (ResourceSyncInfo) it.next();
IPath path = new Path(info.getName());
if(info.isDirectory()) {
childResources.add(folder.getFolder(path));
@@ -319,8 +316,7 @@ public class EclipseSynchronizer {
childResources.add(folder.getFile(path));
}
}
- if (folder.exists())
- childResources.addAll(Arrays.asList(folder.members()));
+ childResources.addAll(Arrays.asList(folder.members()));
return (IResource[])childResources.toArray(new IResource[childResources.size()]);
} catch (CoreException e) {
throw CVSException.wrapException(e);
@@ -356,11 +352,11 @@ public class EclipseSynchronizer {
*/
public void endOperation(IProgressMonitor monitor) throws CVSException {
try {
- IStatus status = LowLevelSyncInfoCache.STATUS_OK;
+ IStatus status = STATUS_OK;
if (lock.getNestingCount() == 1) {
status = commitCache(monitor);
}
- if (!status.isOK()) {
+ if (status != STATUS_OK) {
throw new CVSException(status);
}
} finally {
@@ -397,12 +393,12 @@ public class EclipseSynchronizer {
IStatus status = commitCache(Policy.subMonitorFor(monitor, 7));
// purge from memory too if we were asked to
- if (purgeCache) sessionPropertyCache.purgeCache(root, deep);
+ if (purgeCache) purgeCache(root, deep);
// prepare for the operation again if we cut the last one short
prepareCache(Policy.subMonitorFor(monitor, 1));
- if (!status.isOK()) {
+ if (status != STATUS_OK) {
throw new CVSException(status);
}
} finally {
@@ -438,94 +434,15 @@ public class EclipseSynchronizer {
* The folder is about to be deleted (including its CVS subfolder).
* Take any appropriate action to remember the CVS information.
*/
- public void prepareForDeletion(IResource resource) throws CVSException {
- try {
- beginOperation(null);
- // Flush the dirty info for the resource and it's ancestors.
- // Although we could be smarter, we need to do this because the
- // deletion may fail.
- String indicator = EclipseSynchronizer.getInstance().getDirtyIndicator(resource);
- if (indicator != null) {
- flushDirtyCacheWithAncestors(resource);
- }
- if (resource.getType() != IResource.FILE) {
- IContainer container = (IContainer)resource;
- purgeFastCache();
- if (container.getType() == IResource.PROJECT) {
- synchronizerCache.flush((IProject)container);
- } else {
- // Move the folder sync info into phantom space
- FolderSyncInfo info = getFolderSync(container);
- if (info == null) return;
- synchronizerCache.setCachedFolderSync(container, info);
- synchronizerCache.setCachedResourceSyncForChildren(container, sessionPropertyCache.getCachedResourceSyncForChildren(container));
- changedFolders.add(container);
- // todo
- // Move the dirty count into phantom space
- int dirtyCount = getDirtyCount(container);
- if (dirtyCount != -1) {
- synchronizerCache.setCachedDirtyCount(container, dirtyCount);
- }
- }
- }
- } finally {
- endOperation(null);
- }
+ public void prepareForDeletion(IContainer container) throws CVSException {
}
/**
- * Notify the receiver that a folder has been created.
- * Any existing phantom sync info will be moved
- *
- * @param folder the folder that has been created
+ * Signal to the synchronizer that a folder has been created
+ *
+ * @param folder the folder to be created
*/
public void folderCreated(IFolder folder) throws CVSException {
- try {
- // set the dirty count using what was cached in the phantom it
- beginOperation(null);
- FolderSyncInfo folderInfo = synchronizerCache.getCachedFolderSync(folder);
- if (folderInfo != null) {
- byte[][] infos = synchronizerCache.getCachedResourceSyncForChildren(folder);
- if (folder.getFolder(SyncFileWriter.CVS_DIRNAME).exists()) {
- // There is already a CVS subdirectory which indicates that
- // either the folder was recreated by an external tool or that
- // a folder with CVS information was copied from another location.
- // To know the difference, we need to compare the folder sync info.
- // If they are mapped to the same root and repository then just
- // purge the phantom info. Otherwise, keep the original sync info.
-
- // flush the phantom info so we can get what is on disk.
- synchronizerCache.flush(folder);
-
- // Get the new folder sync info
- FolderSyncInfo newFolderInfo = getFolderSync(folder);
- if (newFolderInfo.getRoot().equals(folderInfo.getRoot())
- && newFolderInfo.getRepository().equals(folderInfo.getRepository())) {
- // The folder is the same so use what is on disk
- return;
- }
-
- // The folder is mapped to a different location.
- // Purge new resource sync before restoring from phantom
- ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(folder);
- ICVSResource[] children = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS);
- for (int i = 0; i < children.length; i++) {
- ICVSResource resource = children[i];
- deleteResourceSync(resource.getIResource());
- }
- }
-
- // set the sync info using what was cached in the phantom
- setFolderSync(folder, folderInfo);
- sessionPropertyCache.setCachedResourceSyncForChildren(folder, infos);
- }
- } finally {
- try {
- endOperation(null);
- } finally {
- synchronizerCache.flush(folder);
- }
- }
}
/**
@@ -547,49 +464,103 @@ public class EclipseSynchronizer {
* @param monitor the progress monitor, may be null
*/
private IStatus commitCache(IProgressMonitor monitor) {
- // write the fast cache to the low level cache
- IStatus status = LowLevelSyncInfoCache.STATUS_OK;
- try {
- purgeFastCache();
- } catch (CVSException e) {
- status = e.getStatus();
+ if (changedFolders.isEmpty() && changedResources.isEmpty()) {
+ broadcastResourceStateChanges(new IResource[0]);
+ return STATUS_OK;
}
-
- // Commit the session property cache to disk.
- status = mergeStatus(sessionPropertyCache.commitCache(monitor), status);
+ List errors = new ArrayList();
+ try {
+ /*** prepare operation ***/
+ // find parents of changed resources
+ Set dirtyParents = new HashSet();
+ for(Iterator it = changedResources.iterator(); it.hasNext();) {
+ IResource resource = (IResource) it.next();
+ IContainer folder = resource.getParent();
+ dirtyParents.add(folder);
+ }
+
+ monitor = Policy.monitorFor(monitor);
+ int numDirty = dirtyParents.size();
+ int numResources = changedFolders.size() + numDirty;
+ monitor.beginTask(null, numResources);
+ if(monitor.isCanceled()) {
+ monitor.subTask(Policy.bind("EclipseSynchronizer.UpdatingSyncEndOperationCancelled")); //$NON-NLS-1$
+ } else {
+ monitor.subTask(Policy.bind("EclipseSynchronizer.UpdatingSyncEndOperation")); //$NON-NLS-1$
+ }
+
+ /*** write sync info to disk ***/
+ // folder sync info changes
+ for(Iterator it = changedFolders.iterator(); it.hasNext();) {
+ IContainer folder = (IContainer) it.next();
+ if (folder.exists() && folder.getType() != IResource.ROOT) {
+ try {
+ FolderSyncInfo info = getCachedFolderSync(folder);
+ if (info == null) {
+ // deleted folder sync info since we loaded it
+ SyncFileWriter.deleteFolderSync(folder);
+ dirtyParents.remove(folder);
+ } else {
+ // modified or created new folder sync info since we loaded it
+ SyncFileWriter.writeFolderSync(folder, info);
+ }
+ } catch(CVSException e) {
+ try {
+ purgeCache(folder, true /* deep */);
+ } catch(CVSException pe) {
+ errors.add(pe.getStatus());
+ }
+ errors.add(e.getStatus());
+ }
+ }
+ monitor.worked(1);
+ }
- /*** broadcast events ***/
- changedResources.addAll(changedFolders);
- IResource[] resources = (IResource[]) changedResources.toArray(
- new IResource[changedResources.size()]);
- broadcastResourceStateChanges(resources);
- changedResources.clear();
- changedFolders.clear();
- return status;
- }
-
- /**
- * Method mergeStatus.
- * @param iStatus
- * @param status
- * @return IStatus
- */
- private IStatus mergeStatus(IStatus status1, IStatus status2) {
- if (status1.isOK()) return status2;
- if (status2.isOK()) return status1;
- if (status1.isMultiStatus()) {
- ((MultiStatus)status1).merge(status2);
- return status1;
- }
- if (status2.isMultiStatus()) {
- ((MultiStatus)status2).merge(status1);
- return status2;
+ // update progress for parents we will skip because they were deleted
+ monitor.worked(numDirty - dirtyParents.size());
+
+ // resource sync info changes
+ for (Iterator it = dirtyParents.iterator(); it.hasNext();) {
+ IContainer folder = (IContainer) it.next();
+ if (folder.exists() && folder.getType() != IResource.ROOT) {
+ // write sync info for all children in one go
+ try {
+ Collection infos = getCachedResourceSyncForChildren(folder);
+ SyncFileWriter.writeAllResourceSync(folder,
+ (ResourceSyncInfo[]) infos.toArray(new ResourceSyncInfo[infos.size()]));
+ } catch(CVSException e) {
+ try {
+ purgeCache(folder, false /* depth 1 */);
+ } catch(CVSException pe) {
+ errors.add(pe.getStatus());
+ }
+ errors.add(e.getStatus());
+ }
+ }
+ monitor.worked(1);
+ }
+
+ /*** broadcast events ***/
+ changedResources.addAll(changedFolders);
+ IResource[] resources = (IResource[]) changedResources.toArray(
+ new IResource[changedResources.size()]);
+ broadcastResourceStateChanges(resources);
+ changedResources.clear();
+ changedFolders.clear();
+ if ( ! errors.isEmpty()) {
+ MultiStatus status = new MultiStatus(CVSProviderPlugin.ID,
+ CVSStatus.COMMITTING_SYNC_INFO_FAILED,
+ Policy.bind("EclipseSynchronizer.ErrorCommitting"), //$NON-NLS-1$
+ null);
+ for (int i = 0; i < errors.size(); i++) {
+ status.merge((IStatus)errors.get(i));
+ }
+ return status;
+ }
+ return STATUS_OK;
+ } finally {
+ monitor.done();
}
- return new MultiStatus(CVSProviderPlugin.ID,
- CVSStatus.COMMITTING_SYNC_INFO_FAILED,
- new IStatus[] { status1, status2 },
- Policy.bind("EclipseSynchronizer.ErrorCommitting"), //$NON-NLS-1$
- null);
}
/**
@@ -602,6 +573,61 @@ public class EclipseSynchronizer {
}
/**
+ * Purges the cache recursively for all resources beneath the container.
+ * There must not be any pending uncommitted changes.
+ */
+ private static void purgeCache(IContainer container, boolean deep) throws CVSException {
+ if (! container.exists()) return;
+ try {
+ if (container.getType() != IResource.ROOT) {
+ container.setSessionProperty(RESOURCE_SYNC_KEY, null);
+ container.setSessionProperty(IGNORE_SYNC_KEY, null);
+ container.setSessionProperty(FOLDER_SYNC_KEY, null);
+ }
+ if(deep) {
+ IResource[] members = container.members();
+ for (int i = 0; i < members.length; i++) {
+ IResource resource = members[i];
+ if (resource.getType() != IResource.FILE) {
+ purgeCache((IContainer) resource, deep);
+ }
+ }
+ }
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * If not already cached, loads and caches the resource sync for the children of the container.
+ * Folder must exist and must not be the workspace root.
+ *
+ * @param container the container
+ */
+ private static void cacheResourceSyncForChildren(IContainer container) throws CVSException {
+ try {
+ // don't try to load if the information is already cached
+ HashMap children = (HashMap)container.getSessionProperty(RESOURCE_SYNC_KEY);
+ if (children == null) {
+ // load the sync info from disk
+ ResourceSyncInfo[] infos = SyncFileWriter.readAllResourceSync(container);
+ if (infos != null) {
+ children = new HashMap(infos.length);
+ for (int i = 0; i < infos.length; i++) {
+ ResourceSyncInfo syncInfo = infos[i];
+ children.put(syncInfo.getName(), syncInfo);
+ }
+ } else {
+ children = new HashMap(0);
+ }
+ container.setSessionProperty(RESOURCE_SYNC_KEY, children);
+ }
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
* Returns the resource sync info for the resource; null if none.
* Parent must exist and must not be the workspace root.
* The resource sync info for the children of the parent container MUST ALREADY BE CACHED.
@@ -610,77 +636,153 @@ public class EclipseSynchronizer {
* @return the resource sync info for the resource, or null
* @see #cacheResourceSyncForChildren
*/
- private ResourceSyncInfo getCachedResourceSync(IResource resource) throws CVSException {
- fastCacheResourceSyncForChildren(resource.getParent());
- return (ResourceSyncInfo) cachedResourceSyncInfos.get(resource.getName());
- }
-
- private void fastCacheResourceSyncForChildren(IContainer parent) throws CVSException {
- if (!parent.equals(cachedFolder)) {
- purgeFastCache();
- byte[][] infos = getLowLevelCacheFor(parent).getCachedResourceSyncForChildren(parent);
- if (infos == null) {
+ private static ResourceSyncInfo getCachedResourceSync(IResource resource) throws CVSException {
+ try {
+ IContainer parent = resource.getParent();
+ HashMap children = (HashMap)resource.getParent().getSessionProperty(RESOURCE_SYNC_KEY);
+ if (children == null) {
// There should be sync info but it was missing. Report the error
throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", parent.getFullPath().toString())); //$NON-NLS-1$
}
- HashMap children = new HashMap();
- for (int i = 0; i < infos.length; i++) {
- ResourceSyncInfo info = new ResourceSyncInfo(infos[i]);
- children.put(info.getName(), info);
+ return (ResourceSyncInfo) children.get(resource.getName());
+ } catch(CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * Sets the resource sync info for the resource; if null, deletes it.
+ * Parent must exist and must not be the workspace root.
+ * The resource sync info for the children of the parent container MUST ALREADY BE CACHED.
+ *
+ * @param resource the resource
+ * @param info the new resource sync info
+ * @see #cacheResourceSyncForChildren
+ */
+ private static void setCachedResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException {
+ try {
+ IContainer parent = resource.getParent();
+ HashMap children = (HashMap)parent.getSessionProperty(RESOURCE_SYNC_KEY);
+ Assert.isNotNull(children);
+ if (info == null) {
+ children.remove(resource.getName());
+ } else {
+ children.put(resource.getName(), info);
}
- cachedResourceSyncInfos = children;
- cachedFolder = parent;
+ } catch(CoreException e) {
+ throw CVSException.wrapException(e);
}
}
/**
- * Method purgeCurrentFolderCache.
+ * Returns the resource sync info for all children of the container.
+ * Container must exist and must not be the workspace root.
+ * The resource sync info for the children of the container MUST ALREADY BE CACHED.
+ *
+ * @param container the container
+ * @return a collection of the resource sync info's for all children
+ * @see #cacheResourceSyncForChildren
*/
- private void purgeFastCache() throws CVSException {
+ private static Collection /* of ResourceSyncInfo */ getCachedResourceSyncForChildren(IContainer container) throws CVSException {
try {
- beginOperation(null);
- if (cacheDirty) {
- byte[][] newInfos;
- if (cachedResourceSyncInfos.isEmpty()) {
- newInfos = LowLevelSyncInfoCache.EMPTY_RESOURCE_SYNC_INFOS;
+ HashMap children = (HashMap)container.getSessionProperty(RESOURCE_SYNC_KEY);
+ if (children == null) {
+ // There should be sync info but it was missing. Report the error
+ throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$
+ }
+ return children.values();
+ } catch(CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * Deletes the resource sync info for all children of the container.
+ * Container must exist and must not be the workspace root.
+ * The resource sync info for the children of the container need not have previously been cached.
+ *
+ * @param container the container
+ */
+ private static void deleteCachedResourceSyncForChildren(IContainer container) throws CVSException {
+ try {
+ HashMap children = (HashMap)container.getSessionProperty(RESOURCE_SYNC_KEY);
+ if (children != null) {
+ children.clear();
+ } else {
+ children = new HashMap(0);
+ container.setSessionProperty(RESOURCE_SYNC_KEY, children);
+ }
+ } catch(CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * If not already cached, loads and caches the folder sync for the container.
+ * Folder must exist and must not be the workspace root.
+ *
+ * @param container the container
+ * @return the folder sync info for the folder, or null if none.
+ */
+ private static FolderSyncInfo cacheFolderSync(IContainer container) throws CVSException {
+ try {
+ // don't try to load if the information is already cached
+ FolderSyncInfo info = (FolderSyncInfo)container.getSessionProperty(FOLDER_SYNC_KEY);
+ if (info == null) {
+ // read folder sync info and remember it
+ info = SyncFileWriter.readFolderSync(container);
+ if (info == null) {
+ container.setSessionProperty(FOLDER_SYNC_KEY, NULL_FOLDER_SYNC_INFO);
} else {
- newInfos = new byte[cachedResourceSyncInfos.size()][];
- int i = 0;
- for (Iterator iter = cachedResourceSyncInfos.values().iterator(); iter.hasNext();) {
- ResourceSyncInfo info = (ResourceSyncInfo) iter.next();
- newInfos[i++] = info.getBytes();
- }
+ container.setSessionProperty(FOLDER_SYNC_KEY, info);
}
- getLowLevelCacheFor(cachedFolder).setCachedResourceSyncForChildren(cachedFolder, newInfos);
+ } else if (info == NULL_FOLDER_SYNC_INFO) {
+ info = null;
}
- cacheDirty = false;
- cachedFolder = null;
- cachedResourceSyncInfos = null;
- } finally {
- endOperation(null);
+ return info;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
}
}
/**
- * Sets the resource sync info for the resource; if null, deletes it. Parent
- * must exist and must not be the workspace root. The resource sync info for
- * the children of the parent container MUST ALREADY BE CACHED.
+ * Returns the folder sync info for the container; null if none.
+ * Folder must exist and must not be the workspace root.
+ * The folder sync info for the container MUST ALREADY BE CACHED.
*
- * @param resource the resource
- * @param info the new resource sync info
- * @see #cacheResourceSyncForChildren
+ * @param container the container
+ * @return the folder sync info for the folder, or null if none.
+ * @see #cacheFolderSync
*/
- private void setCachedResourceSync(IResource resource, ResourceSyncInfo info) throws CVSException {
- // Get the old info to trigger caching for the parent
- fastCacheResourceSyncForChildren(resource.getParent());
- Assert.isNotNull(cachedResourceSyncInfos);
- Assert.isTrue(resource.getParent().equals(cachedFolder));
- if (info == null) {
- cachedResourceSyncInfos.remove(resource.getName());
- } else {
- cachedResourceSyncInfos.put(resource.getName(), info);
+ private static FolderSyncInfo getCachedFolderSync(IContainer container) throws CVSException {
+ try {
+ FolderSyncInfo info = (FolderSyncInfo)container.getSessionProperty(FOLDER_SYNC_KEY);
+ if (info == null) {
+ // There should be sync info but it was missing. Report the error
+ throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$
+ }
+ if (info == NULL_FOLDER_SYNC_INFO) return null;
+ return info;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ /**
+ * Sets the folder sync info for the container; if null, deletes it.
+ * Folder must exist and must not be the workspace root.
+ * The folder sync info for the container need not have previously been cached.
+ *
+ * @param container the container
+ * @param info the new folder sync info
+ */
+ private static void setCachedFolderSync(IContainer container, FolderSyncInfo info) throws CVSException {
+ try {
+ if (info == null) info = NULL_FOLDER_SYNC_INFO;
+ container.setSessionProperty(FOLDER_SYNC_KEY, info);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
}
- cacheDirty = true;
}
/**
@@ -690,8 +792,20 @@ public class EclipseSynchronizer {
* @param container the container
* @return the folder ignore patterns, or an empty array if none
*/
- private String[] cacheFolderIgnores(IContainer container) throws CVSException {
- return sessionPropertyCache.cacheFolderIgnores(container);
+ private static String[] cacheFolderIgnores(IContainer container) throws CVSException {
+ try {
+ // don't try to load if the information is already cached
+ String[] ignores = (String[])container.getSessionProperty(IGNORE_SYNC_KEY);
+ if (ignores == null) {
+ // read folder ignores and remember it
+ ignores = SyncFileWriter.readCVSIgnoreEntries(container);
+ if (ignores == null) ignores = NULL_IGNORES;
+ container.setSessionProperty(IGNORE_SYNC_KEY, ignores);
+ }
+ return ignores;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
}
/**
@@ -701,8 +815,12 @@ public class EclipseSynchronizer {
* @param container the container
* @param ignores the array of ignore patterns
*/
- private void setCachedFolderIgnores(IContainer container, String[] ignores) throws CVSException {
- sessionPropertyCache.setCachedFolderIgnores(container, ignores);
+ private static void setCachedFolderIgnores(IContainer container, String[] ignores) throws CVSException {
+ try {
+ container.setSessionProperty(IGNORE_SYNC_KEY, ignores);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
}
/**
@@ -714,23 +832,17 @@ public class EclipseSynchronizer {
*/
private void accumulateNonManagedChildren(IContainer folder, List possibleIgnores) throws CVSException {
try {
- getLowLevelCacheFor(folder).cacheResourceSyncForChildren(folder);
+ cacheResourceSyncForChildren(folder);
IResource[] children = folder.members();
- List folders = new ArrayList();
- // deal with all files first and then folders to be otimized for caching scheme
for (int i = 0; i < children.length; i++) {
IResource child = children[i];
if(getCachedResourceSync(child)==null) {
possibleIgnores.add(child);
}
if(child.getType()!=IResource.FILE) {
- folders.add(child);
+ accumulateNonManagedChildren((IContainer)child, possibleIgnores);
}
}
- for (Iterator iter = folders.iterator(); iter.hasNext();) {
- IContainer child = (IContainer) iter.next();
- accumulateNonManagedChildren(child, possibleIgnores);
- }
} catch(CoreException e) {
throw CVSException.wrapException(e);
}
@@ -921,7 +1033,17 @@ public class EclipseSynchronizer {
// for all folders that have a CVS folder, ensure the sync info is cached
for (int i = 0; i < folders.length; i++) {
IContainer parent = folders[i];
- if (!getLowLevelCacheFor(parent).isSyncInfoLoaded(parent)) {
+ try {
+ if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) {
+ if (parent.getSessionProperty(RESOURCE_SYNC_KEY) == null)
+ return false;
+ if (parent.getSessionProperty(FOLDER_SYNC_KEY) == null)
+ return false;
+ if (parent.getSessionProperty(IGNORE_SYNC_KEY) == null)
+ return false;
+ }
+ } catch (CoreException e) {
+ // let future operations surface the error
return false;
}
}
@@ -942,8 +1064,8 @@ public class EclipseSynchronizer {
IContainer parent = folders[i];
try {
beginOperation(null);
- getLowLevelCacheFor(parent).cacheResourceSyncForChildren(parent);
- getLowLevelCacheFor(parent).cacheFolderSync(parent);
+ cacheResourceSyncForChildren(parent);
+ cacheFolderSync(parent);
cacheFolderIgnores(parent);
} finally {
endOperation(null);
@@ -1005,11 +1127,46 @@ public class EclipseSynchronizer {
}
protected void setDirtyIndicator(IResource resource, String indicator) throws CVSException {
- getLowLevelCacheFor(resource).setDirtyIndicator(resource, indicator);
+ if (resource.getType() == IResource.FILE) {
+ internalSetDirtyIndicator((IFile)resource, indicator);
+ } else {
+ internalSetDirtyIndicator((IContainer)resource, indicator);
+ }
}
-
protected String getDirtyIndicator(IResource resource) throws CVSException {
- return getLowLevelCacheFor(resource).getDirtyIndicator(resource);
+ if (resource.getType() == IResource.FILE) {
+ return internalGetDirtyIndicator((IFile)resource);
+ } else {
+ return internalGetDirtyIndicator((IContainer)resource);
+ }
+ }
+ private void internalSetDirtyIndicator(IFile file, String indicator) throws CVSException {
+ try {
+ file.setSessionProperty(IS_DIRTY, indicator);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+ private String internalGetDirtyIndicator(IFile file) throws CVSException {
+ try {
+ return (String)file.getSessionProperty(IS_DIRTY);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+ private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException {
+ try {
+ container.setPersistentProperty(IS_DIRTY, indicator);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+ private String internalGetDirtyIndicator(IContainer container) throws CVSException {
+ try {
+ return container.getPersistentProperty(IS_DIRTY);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
}
/*
@@ -1018,35 +1175,56 @@ public class EclipseSynchronizer {
* null in that case. For phantom folders, the dirty count is calculated if
* it does not exist yet.
*/
- protected int getDirtyCount(IContainer container) throws CVSException {
+ protected Integer getDirtyCount(IContainer parent) throws CVSException {
+ if (!parent.exists()) return null;
try {
beginOperation(null);
- return getLowLevelCacheFor(container).getCachedDirtyCount(container);
+ return (Integer)parent.getSessionProperty(DIRTY_COUNT);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
} finally {
endOperation(null);
}
}
protected void setDirtyCount(IContainer container, int count) throws CVSException {
+ if (!container.exists()) return;
try {
beginOperation(null);
- getLowLevelCacheFor(container).setCachedDirtyCount(container, count);
+ container.setSessionProperty(DIRTY_COUNT, new Integer(count));
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
} finally {
endOperation(null);
}
}
+
+ /*
+ * Mark the given existing file as either modified or clean using a session
+ * property. Also notify the parent to adjust it's modified count. Do
+ * nothing if the modified state is already what we want.
+ */
+ protected boolean setModified(IFile file, boolean modified) throws CVSException {
+ String indicator = modified ? IS_DIRTY_INDICATOR : NOT_DIRTY_INDICATOR;
+ if (getDirtyIndicator(file) == indicator) return false;
+ setDirtyIndicator(file, indicator);
+ return true;
+ }
/*
- * Mark the given resource as either modified or clean using a persistant
- * property. Do nothing if the modified state is already what we want.
- * Return true if the modification state was changed.
+ * Mark the given existing folder as either modified or clean using a
+ * persistant property. Do nothing if the modified state is already what we
+ * want.
*/
- protected boolean setModified(IResource container, boolean modified) throws CVSException {
+ protected void setModified(IContainer container, boolean modified) throws CVSException {
+ if (!container.exists()) return;
String indicator = modified ? IS_DIRTY_INDICATOR : NOT_DIRTY_INDICATOR;
+
// if it's already set, no need to set the property or adjust the parents count
- if (indicator.equals(getDirtyIndicator(container))) return false;
+ if (indicator.equals(getDirtyIndicator(container))) return;
+
// set the dirty indicator and adjust the parent accordingly
setDirtyIndicator(container, indicator);
- return true;
+ return;
}
/*
@@ -1054,10 +1232,10 @@ public class EclipseSynchronizer {
* parent should be adjusted
*/
protected boolean adjustModifiedCount(IContainer container, boolean dirty) throws CVSException {
- if (container.getType() == IResource.ROOT || !isValid(container)) return false;
- int count = getDirtyCount(container);
+ if (container.getType() == IResource.ROOT) return false;
+ Integer property = getDirtyCount(container);
boolean updateParent = false;
- if (count == -1) {
+ if (property == null) {
// The number of dirty children has not been tallied for this parent.
// (i.e. no one has queried this folder yet)
if (dirty) {
@@ -1077,6 +1255,7 @@ public class EclipseSynchronizer {
// property is still acurate.
}
} else {
+ int count = property.intValue();
if (dirty) {
count++;
if (count == 1) {
@@ -1102,8 +1281,17 @@ public class EclipseSynchronizer {
protected boolean addDeletedChild(IContainer container, IFile file) throws CVSException {
try {
beginOperation(null);
- getLowLevelCacheFor(container).addDeletedChild(container, file);
+ Set deletedFiles = getDeletedChildren(container);
+ if (deletedFiles == null)
+ deletedFiles = new HashSet();
+ String fileName = file.getName();
+ if (deletedFiles.contains(fileName))
+ return false;
+ deletedFiles.add(fileName);
+ setDeletedChildren(container, deletedFiles);
return true;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
} finally {
endOperation(null);
}
@@ -1112,8 +1300,18 @@ public class EclipseSynchronizer {
protected boolean removeDeletedChild(IContainer container, IFile file) throws CVSException {
try {
beginOperation(null);
- getLowLevelCacheFor(container).removeDeletedChild(container, file);
+ Set deletedFiles = getDeletedChildren(container);
+ if (deletedFiles == null || deletedFiles.isEmpty())
+ return false;
+ String fileName = file.getName();
+ if (!deletedFiles.contains(fileName))
+ return false;
+ deletedFiles.remove(fileName);
+ if (deletedFiles.isEmpty()) deletedFiles = null;
+ setDeletedChildren(container, deletedFiles);
return true;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
} finally {
endOperation(null);
}
@@ -1121,49 +1319,76 @@ public class EclipseSynchronizer {
protected void setDeletedChildren(IContainer parent, Set deletedFiles) throws CVSException {
if (!parent.exists()) return;
- sessionPropertyCache.setDeletedChildren(parent, deletedFiles);
+ try {
+ parent.setSessionProperty(DELETED_CHILDREN, deletedFiles);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
+ }
+
+ private Set getDeletedChildren(IContainer parent) throws CoreException {
+ return (Set)parent.getSessionProperty(DELETED_CHILDREN);
+ }
+ /*
+ * Flush all cached info for the container and it's ancestors
+ */
+ protected void flushModificationCache(IContainer container) throws CVSException {
+ if (container.getType() == IResource.ROOT) return;
+ if (container.exists()) {
+ try {
+ beginOperation(null);
+ container.setSessionProperty(DIRTY_COUNT, null);
+ container.setSessionProperty(DELETED_CHILDREN, null);
+ container.setPersistentProperty(IS_DIRTY, null);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ } finally {
+ endOperation(null);
+ }
+ }
}
- protected void flushDirtyCache(IResource resource, int depth) throws CVSException {
- if (resource.getType() == IResource.ROOT) return;
- if (!isValid(resource)) return;
+ protected void flushModificationCache(IContainer container, int depth) throws CVSException {
+ if (container.getType() == IResource.ROOT) return;
+ final CVSException[] exception = new CVSException[] { null };
try {
- final CVSException[] exception = new CVSException[] { null };
- beginOperation(null);
- resource.accept(new IResourceVisitor() {
+ container.accept(new IResourceVisitor() {
public boolean visit(IResource resource) throws CoreException {
try {
- getLowLevelCacheFor(resource).flushDirtyCache(resource);
+ if (resource.getType() == IResource.FILE) {
+ flushModificationCache((IFile)resource);
+ } else {
+ flushModificationCache((IContainer)resource);
+ }
} catch (CVSException e) {
exception[0] = e;
}
return true;
}
}, depth, true);
- if (exception[0] != null) {
- throw exception[0];
- }
} catch (CoreException e) {
throw CVSException.wrapException(e);
- } finally {
- endOperation(null);
+ }
+ if (exception[0] != null) {
+ throw exception[0];
}
}
-
+
/*
- * Flush all cached info for the file and it's ancestors
+ * Flush all cached info for
+ * the file and it's ancestors
*/
- protected void flushDirtyCacheWithAncestors(IResource resource) throws CVSException {
- if (resource.getType() == IResource.ROOT) return;
- try {
- beginOperation(null);
+ protected void flushModificationCache(IFile file) throws CVSException {
+ if (file.exists()) {
try {
- getLowLevelCacheFor(resource).flushDirtyCache(resource);
+ beginOperation(null);
+ file.setSessionProperty(IS_DIRTY, null);
+ file.setSessionProperty(CLEAN_UPDATE, null);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
} finally {
- flushDirtyCacheWithAncestors(resource.getParent());
+ endOperation(null);
}
- } finally {
- endOperation(null);
}
}
@@ -1175,10 +1400,26 @@ public class EclipseSynchronizer {
* @param mFile
*/
public void markFileAsUpdated(IFile file) throws CVSException {
- sessionPropertyCache.markFileAsUpdated(file);
+ try {
+ file.setSessionProperty(CLEAN_UPDATE, UPDATED_INDICATOR);
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
}
protected boolean contentsChangedByUpdate(IFile file) throws CVSException {
- return sessionPropertyCache.contentsChangedByUpdate(file);
+ try {
+ Object indicator = file.getSessionProperty(CLEAN_UPDATE);
+ boolean updated = false;
+ if (indicator == UPDATED_INDICATOR) {
+ // the file was changed due to a clean update (i.e. no local mods) so skip it
+ file.setSessionProperty(CLEAN_UPDATE, null);
+ file.setSessionProperty(IS_DIRTY, NOT_DIRTY_INDICATOR);
+ updated = true;
+ }
+ return updated;
+ } catch (CoreException e) {
+ throw CVSException.wrapException(e);
+ }
}
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
index 6299889c7..e1f6bfb4e 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
@@ -32,6 +32,7 @@ import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
+import org.eclipse.team.internal.ccvs.core.ICVSResource;
/**
* This class performs several functions related to determining the modified
@@ -185,5 +186,12 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa
throw e.toCoreException();
}
}
+ /**
+ * Method prepareToDelete.
+ * @param resource
+ */
+ public void prepareToDelete(ICVSResource resource) throws CVSException {
+ ((EclipseResource)resource).prepareToBeDeleted();
+ }
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LowLevelSyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LowLevelSyncInfoCache.java
deleted file mode 100644
index c3ef6b1bf..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/LowLevelSyncInfoCache.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2002 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM - Initial implementation
- ******************************************************************************/
-package org.eclipse.team.internal.ccvs.core.resources;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-
-/**
- * The low level cache provides the sync info as bytes
- */
-/*package*/ abstract class LowLevelSyncInfoCache {
-
- // the resources plugin synchronizer is used to cache and possibly persist. These
- // are keys for storing the sync info.
- /*package*/ static final QualifiedName FOLDER_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-sync"); //$NON-NLS-1$
- /*package*/ static final QualifiedName RESOURCE_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync"); //$NON-NLS-1$
- /*package*/ static final QualifiedName IGNORE_SYNC_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-ignore"); //$NON-NLS-1$
-
- /*package*/ static final byte[][] EMPTY_RESOURCE_SYNC_INFOS = new byte[0][0];
-
- /*package*/ static final QualifiedName IS_DIRTY = new QualifiedName(CVSProviderPlugin.ID, "is-dirty");
- /*package*/ static final QualifiedName CLEAN_UPDATE = new QualifiedName(CVSProviderPlugin.ID, "clean-update");
- /*package*/ static final QualifiedName DIRTY_COUNT = new QualifiedName(CVSProviderPlugin.ID, "dirty-count");
- /*package*/ static final QualifiedName DELETED_CHILDREN = new QualifiedName(CVSProviderPlugin.ID, "deleted");
- /*package*/ static final String IS_DIRTY_INDICATOR = "d";
- /*package*/ static final String NOT_DIRTY_INDICATOR = "c";
- /*package*/ static final String UPDATED_INDICATOR = "u";
-
- /*package*/ static final IStatus STATUS_OK = new Status(IStatus.OK, CVSProviderPlugin.ID, 0, Policy.bind("ok"), null); //$NON-NLS-1$
-
- /**
- * If not already cached, loads and caches the folder sync for the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- */
- /*package*/ abstract FolderSyncInfo cacheFolderSync(IContainer container) throws CVSException;
-
- /**
- * Returns the folder sync info for the container; null if none.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- * @see #cacheFolderSync
- */
- /*package*/ abstract FolderSyncInfo getCachedFolderSync(IContainer container) throws CVSException;
-
- /**
- * Sets the folder sync info for the container; if null, deletes it.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container need not have previously been
- * cached.
- *
- * @param container the container
- * @param info the new folder sync info
- */
- /*package*/ abstract void setCachedFolderSync(IContainer container, FolderSyncInfo info) throws CVSException;
-
- /**
- * If not already cached, loads and caches the resource sync for the children of the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- */
- /*package*/ abstract void cacheResourceSyncForChildren(IContainer container) throws CVSException;
-
- /**
- * Returns the resource sync info for all children of the container.
- * Container must exist and must not be the workspace root.
- * The resource sync info for the children of the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return a collection of the resource sync info's for all children
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ abstract byte[][] getCachedResourceSyncForChildren(IContainer container) throws CVSException;
-
- /**
- * Sets the resource sync info for the resource; if null, deletes it. Parent
- * must exist and must not be the workspace root. The resource sync info for
- * the children of the parent container MUST ALREADY BE CACHED.
- *
- * @param resource the resource
- * @param info the new resource sync info
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ abstract void setCachedResourceSyncForChildren(IContainer container, byte[][] infos) throws CVSException;
-
- /**
- * Commits the cache after a series of operations.
- *
- * Will return STATUS_OK unless there were problems writting sync
- * information to disk. If an error occurs a multistatus is returned
- * with the list of reasons for the failures. Failures are recovered,
- * and all changed resources are given a chance to be written to disk.
- *
- * @param monitor the progress monitor, may be null
- */
- /*package*/ abstract IStatus commitCache(IProgressMonitor monitor);
-
- /*package*/ abstract String getDirtyIndicator(IResource resource) throws CVSException;
-
- /*package*/ abstract void setDirtyIndicator(IResource resource, String indicator) throws CVSException;
-
- /**
- * Return the dirty count for the given folder. For existing folders, the
- * dirty count may not have been calculated yet and this method will return
- * -1 in that case.
- */
- /*package*/ abstract int getCachedDirtyCount(IContainer container) throws CVSException;
-
- /**
- * Set the dirty count for the given container to the given count.
- *
- * @param container
- * @param count
- * @throws CVSException
- */
- /*package*/ abstract void setCachedDirtyCount(IContainer container, int count) throws CVSException;
-
- /*package*/ abstract void flushDirtyCache(IResource resource) throws CVSException;
-
- /*package*/ abstract boolean addDeletedChild(IContainer container, IFile file) throws CVSException;
-
- /*package*/ abstract boolean removeDeletedChild(IContainer container, IFile file) throws CVSException;
-
- /*package*/ abstract boolean isSyncInfoLoaded(IContainer parent) throws CVSException;
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java
deleted file mode 100644
index 944fcb34b..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2002 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM - Initial implementation
- ******************************************************************************/
-package org.eclipse.team.internal.ccvs.core.resources;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.CVSStatus;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter;
-
-/**
- * This cache uses session properties to hold the bytes representing the sync
- * info
- */
-/*package*/ class SessionPropertySyncInfoCache extends LowLevelSyncInfoCache {
-
- /*package*/ static final String[] NULL_IGNORES = new String[0];
- private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("", "", null, false); //$NON-NLS-1$ //$NON-NLS-2$
-
- private Set changedResourceSync = new HashSet();
- private Set changedFolderSync = new HashSet();
-
- /**
- * If not already cached, loads and caches the folder ignores sync for the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- * @return the folder ignore patterns, or an empty array if none
- */
- /*package*/ String[] cacheFolderIgnores(IContainer container) throws CVSException {
- try {
- // don't try to load if the information is already cached
- String[] ignores = (String[])container.getSessionProperty(IGNORE_SYNC_KEY);
- if (ignores == null) {
- // read folder ignores and remember it
- ignores = SyncFileWriter.readCVSIgnoreEntries(container);
- if (ignores == null) ignores = NULL_IGNORES;
- container.setSessionProperty(IGNORE_SYNC_KEY, ignores);
- }
- return ignores;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
-
- /**
- * If not already cached, loads and caches the folder sync for the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- */
- /*package*/ FolderSyncInfo cacheFolderSync(IContainer container) throws CVSException {
- if (!container.exists()) return null;
- try {
- // don't try to load if the information is already cached
- FolderSyncInfo info = (FolderSyncInfo)container.getSessionProperty(FOLDER_SYNC_KEY);
- if (info == null) {
- // read folder sync info and remember it
- info = SyncFileWriter.readFolderSync(container);
- if (info == null) {
- container.setSessionProperty(FOLDER_SYNC_KEY, NULL_FOLDER_SYNC_INFO);
- } else {
- container.setSessionProperty(FOLDER_SYNC_KEY, info);
- }
- } else if (info == NULL_FOLDER_SYNC_INFO) {
- info = null;
- }
- return info;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
-
- /**
- * If not already cached, loads and caches the resource sync for the children of the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- */
- /*package*/ void cacheResourceSyncForChildren(IContainer container) throws CVSException {
- if (!container.exists()) return;
- try {
- // don't try to load if the information is already cached
- byte[][] infos = (byte[][])container.getSessionProperty(RESOURCE_SYNC_KEY);
- if (infos == null) {
- // load the sync info from disk
- infos = SyncFileWriter.readAllResourceSync(container);
- if (infos == null) {
- infos = EMPTY_RESOURCE_SYNC_INFOS;
- }
- container.setSessionProperty(RESOURCE_SYNC_KEY, infos);
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Returns the folder sync info for the container; null if none.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- * @see #cacheFolderSync
- */
- /*package*/ FolderSyncInfo getCachedFolderSync(IContainer container) throws CVSException {
- if (!container.exists()) return null;
- try {
- FolderSyncInfo info = (FolderSyncInfo)container.getSessionProperty(FOLDER_SYNC_KEY);
- if (info == null) {
- // There should be sync info but it was missing. Report the error
- throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$
- }
- if (info == NULL_FOLDER_SYNC_INFO) return null;
- return info;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Returns the resource sync info for all children of the container.
- * Container must exist and must not be the workspace root.
- * The resource sync info for the children of the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return a collection of the resource sync info's for all children
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ byte[][] getCachedResourceSyncForChildren(IContainer container) throws CVSException {
- if (!container.exists()) return EMPTY_RESOURCE_SYNC_INFOS;
- try {
- byte[][] infos = (byte[][])container.getSessionProperty(RESOURCE_SYNC_KEY);
- // todo: move check to caller
- if (infos == null) {
- // There should be sync info but it was missing. Report the error
- throw new CVSException(Policy.bind("EclipseSynchronizer.folderSyncInfoMissing", container.getFullPath().toString())); //$NON-NLS-1$
- }
- return infos;
- } catch(CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Purges the cache recursively for all resources beneath the container.
- * There must not be any pending uncommitted changes.
- */
- /*package*/ void purgeCache(IContainer container, boolean deep) throws CVSException {
- if (! container.exists()) return;
- try {
- if (container.getType() != IResource.ROOT) {
- container.setSessionProperty(RESOURCE_SYNC_KEY, null);
- container.setSessionProperty(IGNORE_SYNC_KEY, null);
- container.setSessionProperty(FOLDER_SYNC_KEY, null);
- }
- if(deep) {
- IResource[] members = container.members();
- for (int i = 0; i < members.length; i++) {
- IResource resource = members[i];
- if (resource.getType() != IResource.FILE) {
- purgeCache((IContainer) resource, deep);
- }
- }
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Sets the array of folder ignore patterns for the container, must not be null.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- * @param ignores the array of ignore patterns
- */
- /*package*/ void setCachedFolderIgnores(IContainer container, String[] ignores) throws CVSException {
- try {
- container.setSessionProperty(IGNORE_SYNC_KEY, ignores);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
-
- /**
- * Sets the folder sync info for the container; if null, deletes it.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container need not have previously been cached.
- *
- * @param container the container
- * @param info the new folder sync info
- */
- /*package*/ void setCachedFolderSync(IContainer container, FolderSyncInfo info) throws CVSException {
- if (!container.exists()) return;
- try {
- if (info == null) info = NULL_FOLDER_SYNC_INFO;
- container.setSessionProperty(FOLDER_SYNC_KEY, info);
- changedFolderSync.add(container);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Sets the resource sync info for the resource; if null, deletes it. Parent
- * must exist and must not be the workspace root. The resource sync info for
- * the children of the parent container MUST ALREADY BE CACHED.
- *
- * @param resource the resource
- * @param info the new resource sync info
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ void setCachedResourceSyncForChildren(IContainer container, byte[][] infos) throws CVSException {
- if (!container.exists()) return;
- try {
- if (infos == null)
- infos = EMPTY_RESOURCE_SYNC_INFOS;
- container.setSessionProperty(RESOURCE_SYNC_KEY, infos);
- changedResourceSync.add(container);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Commits the cache after a series of operations.
- *
- * Will return STATUS_OK unless there were problems writting sync
- * information to disk. If an error occurs a multistatus is returned
- * with the list of reasons for the failures. Failures are recovered,
- * and all changed resources are given a chance to be written to disk.
- *
- * @param monitor the progress monitor, may be null
- */
- /*package*/ IStatus commitCache(IProgressMonitor monitor) {
- List errors = new ArrayList();
- try {
- /*** prepare operation ***/
- // find parents of changed resources
-
- monitor = Policy.monitorFor(monitor);
- int numDirty = changedResourceSync.size();
- int numResources = changedFolderSync.size() + numDirty;
- monitor.beginTask(null, numResources);
- if(monitor.isCanceled()) {
- monitor.subTask(Policy.bind("EclipseSynchronizer.UpdatingSyncEndOperationCancelled")); //$NON-NLS-1$
- } else {
- monitor.subTask(Policy.bind("EclipseSynchronizer.UpdatingSyncEndOperation")); //$NON-NLS-1$
- }
-
- /*** write sync info to disk ***/
- // folder sync info changes
- for(Iterator it = changedFolderSync.iterator(); it.hasNext();) {
- IContainer folder = (IContainer) it.next();
- if (folder.exists() && folder.getType() != IResource.ROOT) {
- try {
- FolderSyncInfo info = getCachedFolderSync(folder);
- if (info == null) {
- // deleted folder sync info since we loaded it
- SyncFileWriter.deleteFolderSync(folder);
- changedResourceSync.remove(folder);
- } else {
- // modified or created new folder sync info since we loaded it
- SyncFileWriter.writeFolderSync(folder, info);
- }
- } catch(CVSException e) {
- try {
- purgeCache(folder, true /* deep */);
- } catch(CVSException pe) {
- errors.add(pe.getStatus());
- }
- errors.add(e.getStatus());
- }
- }
- monitor.worked(1);
- }
-
- // update progress for parents we will skip because they were deleted
- monitor.worked(numDirty - changedResourceSync.size());
-
- // resource sync info changes
- for (Iterator it = changedResourceSync.iterator(); it.hasNext();) {
- IContainer folder = (IContainer) it.next();
- if (folder.exists() && folder.getType() != IResource.ROOT) {
- // write sync info for all children in one go
- try {
- byte[][] infos = getCachedResourceSyncForChildren(folder);
- SyncFileWriter.writeAllResourceSync(folder, infos);
- } catch(CVSException e) {
- try {
- purgeCache(folder, false /* depth 1 */);
- } catch(CVSException pe) {
- errors.add(pe.getStatus());
- }
- errors.add(e.getStatus());
- }
- }
- monitor.worked(1);
- }
-
- /*** broadcast events ***/
- changedResourceSync.clear();
- changedFolderSync.clear();
- if ( ! errors.isEmpty()) {
- MultiStatus status = new MultiStatus(CVSProviderPlugin.ID,
- CVSStatus.COMMITTING_SYNC_INFO_FAILED,
- Policy.bind("EclipseSynchronizer.ErrorCommitting"), //$NON-NLS-1$
- null);
- for (int i = 0; i < errors.size(); i++) {
- status.merge((IStatus)errors.get(i));
- }
- return status;
- }
- return STATUS_OK;
- } finally {
- monitor.done();
- }
- }
-
- /*package*/ void setDirtyIndicator(IResource resource, String indicator) throws CVSException {
- if (resource.getType() == IResource.FILE) {
- internalSetDirtyIndicator((IFile)resource, indicator);
- } else {
- internalSetDirtyIndicator((IContainer)resource, indicator);
- }
- }
- /*package*/ String getDirtyIndicator(IResource resource) throws CVSException {
- if (resource.getType() == IResource.FILE) {
- return internalGetDirtyIndicator((IFile)resource);
- } else {
- return internalGetDirtyIndicator((IContainer)resource);
- }
- }
- private void internalSetDirtyIndicator(IFile file, String indicator) throws CVSException {
- try {
- file.setSessionProperty(IS_DIRTY, indicator);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
- private String internalGetDirtyIndicator(IFile file) throws CVSException {
- try {
- return (String)file.getSessionProperty(IS_DIRTY);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
- private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException {
- try {
- container.setPersistentProperty(IS_DIRTY, indicator);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
- private String internalGetDirtyIndicator(IContainer container) throws CVSException {
- try {
- return container.getPersistentProperty(IS_DIRTY);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Return the dirty count for the given folder. For existing folders, the
- * dirty count may not have been calculated yet and this method will return
- * null in that case. For phantom folders, the dirty count is calculated if
- * it does not exist yet.
- */
- /*package*/ int getCachedDirtyCount(IContainer container) throws CVSException {
- if (!container.exists()) return -1;
- try {
- Integer dirtyCount = (Integer)container.getSessionProperty(DIRTY_COUNT);
- if (dirtyCount == null) {
- return -1;
- } else {
- return dirtyCount.intValue();
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*package*/ void setCachedDirtyCount(IContainer container, int count) throws CVSException {
- if (!container.exists()) return;
- try {
- container.setSessionProperty(DIRTY_COUNT, new Integer(count));
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*
- * Flush all cached info for the container and it's ancestors
- */
- /*package*/ void flushDirtyCache(IResource resource) throws CVSException {
- if (resource.exists()) {
- try {
- if (resource.getType() == IResource.FILE) {
- resource.setSessionProperty(IS_DIRTY, null);
- resource.setSessionProperty(CLEAN_UPDATE, null);
- } else {
- resource.setSessionProperty(DIRTY_COUNT, null);
- resource.setSessionProperty(DELETED_CHILDREN, null);
- resource.setPersistentProperty(IS_DIRTY, null);
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
- }
-
- /*
- * Add the deleted child and return true if it didn't exist before
- */
- /*package*/ boolean addDeletedChild(IContainer container, IFile file) throws CVSException {
- try {
- Set deletedFiles = getDeletedChildren(container);
- if (deletedFiles == null)
- deletedFiles = new HashSet();
- String fileName = file.getName();
- if (deletedFiles.contains(fileName))
- return false;
- deletedFiles.add(fileName);
- setDeletedChildren(container, deletedFiles);
- return true;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*package*/ boolean removeDeletedChild(IContainer container, IFile file) throws CVSException {
- try {
- Set deletedFiles = getDeletedChildren(container);
- if (deletedFiles == null || deletedFiles.isEmpty())
- return false;
- String fileName = file.getName();
- if (!deletedFiles.contains(fileName))
- return false;
- deletedFiles.remove(fileName);
- if (deletedFiles.isEmpty()) deletedFiles = null;
- setDeletedChildren(container, deletedFiles);
- return true;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- protected void setDeletedChildren(IContainer parent, Set deletedFiles) throws CVSException {
- if (!parent.exists()) return;
- try {
- parent.setSessionProperty(DELETED_CHILDREN, deletedFiles);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- private Set getDeletedChildren(IContainer parent) throws CoreException {
- if (!parent.exists()) return null;
- return (Set)parent.getSessionProperty(DELETED_CHILDREN);
- }
-
- /**
- * Method updated flags the objetc as having been modfied by the updated
- * handler. This flag is read during the resource delta to determine whether
- * the modification made the file dirty or not.
- *
- * @param mFile
- */
- /*package*/ void markFileAsUpdated(IFile file) throws CVSException {
- try {
- file.setSessionProperty(CLEAN_UPDATE, UPDATED_INDICATOR);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*package*/ boolean contentsChangedByUpdate(IFile file) throws CVSException {
- try {
- Object indicator = file.getSessionProperty(CLEAN_UPDATE);
- boolean updated = false;
- if (indicator == UPDATED_INDICATOR) {
- // the file was changed due to a clean update (i.e. no local mods) so skip it
- file.setSessionProperty(CLEAN_UPDATE, null);
- file.setSessionProperty(IS_DIRTY, NOT_DIRTY_INDICATOR);
- updated = true;
- }
- return updated;
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Method isSyncInfoLoaded returns true if all the sync info for the
- * provided resources is loaded into the internal cache.
- *
- * @param resources
- * @param i
- * @return boolean
- */
- /*package*/ boolean isSyncInfoLoaded(IContainer parent) throws CVSException {
- try {
- if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) {
- if (parent.getSessionProperty(RESOURCE_SYNC_KEY) == null)
- return false;
- if (parent.getSessionProperty(FOLDER_SYNC_KEY) == null)
- return false;
- if (parent.getSessionProperty(IGNORE_SYNC_KEY) == null)
- return false;
- }
- } catch (CoreException e) {
- // let future operations surface the error
- return false;
- }
- return true;
- }
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java
deleted file mode 100644
index 21c3b66b1..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2002 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM - Initial implementation
- ******************************************************************************/
-package org.eclipse.team.internal.ccvs.core.resources;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ISynchronizer;
-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.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.ICVSResource;
-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.SyncFileWriter;
-
-/**
- * This cache uses session properties to hold the bytes representing the sync
- * info
- */
-/*package*/ class SynchronizerSyncInfoCache extends LowLevelSyncInfoCache {
-
- public SynchronizerSyncInfoCache() {
- getWorkspaceSynchronizer().add(FOLDER_SYNC_KEY);
- getWorkspaceSynchronizer().add(RESOURCE_SYNC_KEY);
- getWorkspaceSynchronizer().add(DIRTY_COUNT);
- }
- /**
- * Return the Eclipse Workspace Synchronizer (from org.eclipse.core.resources)
- */
- private ISynchronizer getWorkspaceSynchronizer() {
- return ResourcesPlugin.getWorkspace().getSynchronizer();
- }
-
- /**
- * Convert a FolderSyncInfo into a byte array that can be stored
- * in the workspace synchronizer
- */
- private byte[] getBytes(FolderSyncInfo info) throws CVSException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(out);
- try {
- dos.writeUTF(info.getRoot());
- dos.writeUTF(info.getRepository());
- CVSEntryLineTag tag = info.getTag();
- if (tag == null) {
- dos.writeUTF(""); //$NON-NLS-1$
- } else {
- dos.writeUTF(tag.toString());
- }
- dos.writeBoolean(info.getIsStatic());
- dos.close();
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
- return out.toByteArray();
- }
-
- /**
- * Convert a byte array that was created using getBytes(FolderSyncInfo)
- * into a FolderSyncInfo
- */
- private FolderSyncInfo getFolderSyncInfo(byte[] bytes) throws CVSException {
- ByteArrayInputStream in = new ByteArrayInputStream(bytes);
- DataInputStream dis = new DataInputStream(in);
- String root;
- String repository;
- CVSEntryLineTag tag;
- boolean isStatic;
- try {
- root = dis.readUTF();
- repository = dis.readUTF();
- String tagName = dis.readUTF();
- if (tagName.length() == 0) {
- tag = null;
- } else {
- tag = new CVSEntryLineTag(tagName);
- }
- isStatic = dis.readBoolean();
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
- return new FolderSyncInfo(repository, root, tag, isStatic);
- }
-
- /**
- * Method getBytes converts an array of bytes into a single byte array
- * @param infos
- * @return byte[]
- */
- private byte[] getBytes(byte[][] infos) throws CVSException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- SyncFileWriter.writeLines(out, infos);
- return out.toByteArray();
- }
-
- /**
- * Convert a byte array that was created using getBytes(Map)
- * into a Map of ResourceSyncInfo
- */
- private byte[][] getResourceSyncInfo(byte[] bytes) throws CVSException {
- byte[][] infos = SyncFileWriter.readLines(new ByteArrayInputStream(bytes));
- // check to make sure the info is not stored in the old format
- if (infos.length != 0) {
- byte[] firstLine = infos[0];
- if (firstLine.length != 0 && (firstLine[0] != (byte)'/' && firstLine[0] != (byte)'D')) {
- Map oldInfos = getResourceSyncInfoMap(bytes);
- infos = new byte[oldInfos.size()][];
- int i = 0;
- for (Iterator iter = oldInfos.values().iterator(); iter.hasNext();) {
- ResourceSyncInfo element = (ResourceSyncInfo) iter.next();
- infos[i++] = element.getBytes();
- }
- // We can't convert the info to the new format because the caller
- // may either not be in a workspace runnable or the resource tree
- // may be closed for modification
- }
- }
- return infos;
- }
-
- /**
- * ResourceSyncInfo used to be stored as a Map of ResourceSyncInfo.
- * We need to be able to retrieve that info the way it was and
- * convert it to the new way.
- *
- * Convert a byte array that was created using
- * getBytes(Map) into a Map of ResourceSyncInfo
- */
- private Map getResourceSyncInfoMap(byte[] bytes) throws CVSException {
- ByteArrayInputStream in = new ByteArrayInputStream(bytes);
- DataInputStream dis = new DataInputStream(in);
- Map result = new HashMap();
- try {
- int size = dis.readInt();
- for (int i = 0; i < size; i++) {
- ResourceSyncInfo info = new ResourceSyncInfo(dis.readUTF(), null, null);
- result.put(info.getName(), info);
- }
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
- return result;
- }
-
- /**
- * Flush any info cahced for the folder
- */
- private void flushPhantomInfo(IContainer container) throws CVSException {
- try {
- if (container.exists() || container.isPhantom()) {
- getWorkspaceSynchronizer().flushSyncInfo(FOLDER_SYNC_KEY, container, IResource.DEPTH_ZERO);
- }
- if (container.exists() || container.isPhantom()) {
- getWorkspaceSynchronizer().flushSyncInfo(RESOURCE_SYNC_KEY, container, IResource.DEPTH_ZERO);
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*package*/ void flush(IProject project) throws CVSException {
- try {
- getWorkspaceSynchronizer().flushSyncInfo(FOLDER_SYNC_KEY, project, IResource.DEPTH_INFINITE);
- getWorkspaceSynchronizer().flushSyncInfo(RESOURCE_SYNC_KEY, project, IResource.DEPTH_INFINITE);
- getWorkspaceSynchronizer().flushSyncInfo(DIRTY_COUNT, project, IResource.DEPTH_INFINITE);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Method flush.
- * @param folder
- */
- /*package*/ void flush(IFolder folder) throws CVSException {
- flushPhantomInfo(folder);
- }
-
- /**
- * If not already cached, loads and caches the folder sync for the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- */
- /*package*/ FolderSyncInfo cacheFolderSync(IContainer container) throws CVSException {
- // nothing needs to be done since the synchronizer is persisted
- return getCachedFolderSync(container);
- }
-
- /**
- * Returns the folder sync info for the container; null if none.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return the folder sync info for the folder, or null if none.
- * @see #cacheFolderSync
- */
- /*package*/ FolderSyncInfo getCachedFolderSync(IContainer container) throws CVSException {
- try {
- byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(FOLDER_SYNC_KEY, container);
- if (bytes == null) return null;
- return getFolderSyncInfo(bytes);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Sets the folder sync info for the container; if null, deletes it.
- * Folder must exist and must not be the workspace root.
- * The folder sync info for the container need not have previously been
- * cached.
- *
- * @param container the container
- * @param info the new folder sync info
- */
- /*package*/ void setCachedFolderSync(IContainer container, FolderSyncInfo info) throws CVSException {
- try {
- if (info == null) {
- if (container.exists() || container.isPhantom()) {
- getWorkspaceSynchronizer().flushSyncInfo(FOLDER_SYNC_KEY, container, IResource.DEPTH_ZERO);
- }
- } else {
- getWorkspaceSynchronizer().setSyncInfo(FOLDER_SYNC_KEY, container, getBytes(info));
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * If not already cached, loads and caches the resource sync for the children of the container.
- * Folder must exist and must not be the workspace root.
- *
- * @param container the container
- */
- /*package*/ void cacheResourceSyncForChildren(IContainer container) throws CVSException {
- // nothing needs to be done since the synchronizer is persisted
- }
-
- /**
- * Returns the resource sync info for all children of the container.
- * Container must exist and must not be the workspace root.
- * The resource sync info for the children of the container MUST ALREADY BE CACHED.
- *
- * @param container the container
- * @return a collection of the resource sync info's for all children
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ byte[][] getCachedResourceSyncForChildren(IContainer container) throws CVSException {
- try {
- byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(RESOURCE_SYNC_KEY, container);
- if (bytes == null) return null;
- return getResourceSyncInfo(bytes);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * Sets the resource sync info for the resource; if null, deletes it. Parent
- * must exist and must not be the workspace root. The resource sync info for
- * the children of the parent container MUST ALREADY BE CACHED.
- *
- * @param resource the resource
- * @param info the new resource sync info
- * @see #cacheResourceSyncForChildren
- */
- /*package*/ void setCachedResourceSyncForChildren(IContainer container, byte[][] infos) throws CVSException {
- try {
- if (infos == null) {
- if (container.exists() || container.isPhantom()) {
- getWorkspaceSynchronizer().flushSyncInfo(RESOURCE_SYNC_KEY, container, IResource.DEPTH_ZERO);
- }
- } else {
- getWorkspaceSynchronizer().setSyncInfo(RESOURCE_SYNC_KEY, container, getBytes(infos));
- }
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /**
- * @see org.eclipse.team.internal.ccvs.core.resources.LowLevelSyncInfoCache#commitCache(org.eclipse.core.runtime.IProgressMonitor)
- */
- IStatus commitCache(IProgressMonitor monitor) {
- // Nothing needs to be done since the synchronizer is persisted
- return STATUS_OK;
- }
-
- /**
- * @see org.eclipse.team.internal.ccvs.core.resources.LowLevelSyncInfoCache#getDirtyIndicator(org.eclipse.core.resources.IResource)
- */
- String getDirtyIndicator(IResource resource) throws CVSException {
- if (resource.getType() == IResource.FILE) {
- // if someone is asking about a non-existant file, it's probably dirty
- return IS_DIRTY_INDICATOR;
- } else {
- int dirtyCount = getCachedDirtyCount((IContainer)resource);
- switch (dirtyCount) {
- case -1 :
- return null;
- case 0 :
- return NOT_DIRTY_INDICATOR;
- default :
- return IS_DIRTY_INDICATOR;
- }
- }
- }
- /**
- * @see org.eclipse.team.internal.ccvs.core.resources.LowLevelSyncInfoCache#setDirtyIndicator(org.eclipse.core.resources.IResource, java.lang.String)
- */
- void setDirtyIndicator(IResource resource, String indicator) throws CVSException {
- // The count is used as the indicator
- }
-
- /**
- * Return the dirty count for the given folder. For existing folders, the
- * dirty count may not have been calculated yet and this method will return
- * null in that case. For phantom folders, the dirty count is calculated if
- * it does not exist yet.
- */
- /*package*/ int getCachedDirtyCount(IContainer container) throws CVSException {
- // get the count from the synchronizer
- int count = internalGetDirtyCount(container);
- if (count == -1) {
- count = calculateDirtyCountForPhantom(container);
- //setDirtyCount(parent, count);
- }
- return count;
- }
-
- /**
- * Set the dirty count for the given container to the given count.
- *
- * @param container
- * @param count
- * @throws CVSException
- */
- /*package*/ void setCachedDirtyCount(IContainer container, int count) throws CVSException {
- try {
- getWorkspaceSynchronizer().setSyncInfo(DIRTY_COUNT, container, getBytes(count));
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*
- * Convert an int to a byte array
- */
- private byte[] getBytes(int count) {
- byte[] result = new byte[4];
- result[0] = (byte)(count & 256);
- result[1] = (byte)(count<<8 & 256);
- result[1] = (byte)(count<<16 & 256);
- result[1] = (byte)(count<<24 & 256);
- return result;
- }
-
- /*
- * Convert a byte array to an int
- */
- private int intFromBytes(byte[] bytes) {
- return bytes[0] + (bytes[1]>>8) + (bytes[2]>>16) + (bytes[3]>>24);
- }
-
- private int internalGetDirtyCount(IContainer parent) throws CVSException {
- try {
- byte[] bytes = getWorkspaceSynchronizer().getSyncInfo(DIRTY_COUNT, parent);
- if (bytes == null) return -1;
- return intFromBytes(bytes);
- } catch (CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*
- * Calculate the dirty count for the given phantom folder, performing any
- * necessary calculations on the childen as well
- */
- private int calculateDirtyCountForPhantom(IContainer parent) throws CVSException {
- ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(parent);
- ICVSResource[] children = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS | ICVSFolder.PHANTOM_MEMBERS);
- int count = 0;
- for (int i = 0; i < children.length; i++) {
- ICVSResource resource = children[i];
- if (resource.isFolder()) {
- int dc = getCachedDirtyCount((IContainer)resource.getIResource());
- if (dc > 0) count++;
- } else {
- // Any non-existant managed files are dirty (outgoing deletion)
- count++;
- }
- }
- return count;
- }
-
- /*package*/ void flushDirtyCache(IResource container) throws CVSException {
-// if (container.exists() || container.isPhantom()) {
-// try {
-// getWorkspaceSynchronizer().flushSyncInfo(DIRTY_COUNT, container, IResource.DEPTH_ZERO);
-// } catch (CoreException e) {
-// throw CVSException.wrapException(e);
-// }
-// }
- }
-
- /**
- * @see org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer#addDeletedChild(org.eclipse.core.resources.IContainer, org.eclipse.core.resources.IFile)
- */
- protected boolean addDeletedChild(IContainer container, IFile file) throws CVSException {
-// try {
-// beginOperation(null);
-// int oldCount = internalGetDirtyCount(container);
-// if (oldCount == -1) {
-// // there is no cached count so wait until the first query
-// // or there was no deleted file
-// return false;
-// }
-// int newCount = calculateDirtyCountForPhantom(container);
-// // adjust the parent folder count if the newCount is 1;
-// return oldCount == 0 && newCount == 1;
-// } finally {
-// endOperation(null);
-// }
- return true;
- }
-
- /**
- * @see org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer#removeDeletedChild(org.eclipse.core.resources.IContainer, org.eclipse.core.resources.IFile)
- */
- protected boolean removeDeletedChild(IContainer container, IFile file) throws CVSException {
-// try {
-// beginOperation(null);
-// int oldCount = internalGetDirtyCount(container);
-// if (oldCount == -1 || oldCount == 0) {
-// // there is no cached count so wait until the first query
-// // or there was no deleted file
-// return false;
-// }
-// int newCount = calculateDirtyCountForPhantom(container);
-// // adjust the parent folder count if the newCount is 0;
-// return newCount == 0;
-// } finally {
-// endOperation(null);
-// }
- return true;
- }
-
- /*package*/ boolean isSyncInfoLoaded(IContainer parent) throws CVSException {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
index dc5a13352..1bfcbdbeb 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
@@ -86,10 +86,6 @@ public class ResourceSyncInfo {
protected ResourceSyncInfo() {
}
- public ResourceSyncInfo(byte[] entryLine) throws CVSException {
- this(new String(entryLine), null, null);
- }
-
/**
* Constructor to create a sync object from entry line formats. The entry lines are parsed by this class.
* The constructor can handle parsing entry lines from the server or from an entry file.
@@ -526,12 +522,4 @@ public class ResourceSyncInfo {
public void reported() {
// do nothing
}
-
- /**
- * Method getBytes.
- * @return byte[]
- */
- public byte[] getBytes() {
- return getEntryLine().getBytes();
- }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/MoveDeleteHook.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/MoveDeleteHook.java
index e9eb16031..865f3db0f 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/MoveDeleteHook.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/MoveDeleteHook.java
@@ -386,6 +386,6 @@ public class MoveDeleteHook implements IMoveDeleteHook {
* dirty count of it's parent can be reduced if appropriate.
*/
private void prepareToDelete(ICVSResource resource) throws CVSException {
- EclipseSynchronizer.getInstance().prepareForDeletion(resource.getIResource());
+ CVSProviderPlugin.getPlugin().getFileModificationManager().prepareToDelete(resource);
}
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java
index b834767e5..3fad8de16 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java
@@ -9,11 +9,9 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -92,7 +90,7 @@ public class SyncFileWriter {
* specified folder and returns ResourceSyncInfo instances for the data stored therein.
* If the folder does not have a CVS subdirectory then <code>null</code> is returned.
*/
- public static byte[][] readAllResourceSync(IContainer parent) throws CVSException {
+ public static ResourceSyncInfo[] readAllResourceSync(IContainer parent) throws CVSException {
IFolder cvsSubDir = getCVSSubdirectory(parent);
if (! cvsSubDir.exists()) return null;
@@ -125,14 +123,7 @@ public class SyncFileWriter {
}
}
- //return (ResourceSyncInfo[])infos.values().toArray(new ResourceSyncInfo[infos.size()]);
- byte[][] result = new byte[infos.size()][];
- int i = 0;
- for (Iterator iter = infos.values().iterator(); iter.hasNext();) {
- ResourceSyncInfo info = (ResourceSyncInfo) iter.next();
- result[i++] = info.getBytes();
- }
- return result;
+ return (ResourceSyncInfo[])infos.values().toArray(new ResourceSyncInfo[infos.size()]);
}
/**
@@ -160,27 +151,7 @@ public class SyncFileWriter {
throw CVSException.wrapException(e);
}
}
-
- public static void writeAllResourceSync(IContainer parent, byte[][] infos) throws CVSException {
- try {
- IFolder cvsSubDir = createCVSSubdirectory(parent);
-
- // format file contents
- String[] entries = new String[infos.length];
- for (int i = 0; i < infos.length; i++) {
- byte[] info = infos[i];
- entries[i] = new String(info);
- }
-
- // write Entries
- writeLines(cvsSubDir.getFile(ENTRIES), entries);
-
- // delete Entries.log
- cvsSubDir.getFile(ENTRIES_LOG).delete(IResource.NONE, null);
- } catch(CoreException e) {
- throw CVSException.wrapException(e);
- }
- }
+
/**
* Reads the CVS/Root, CVS/Repository, CVS/Tag, and CVS/Entries.static files from
* the specified folder and returns a FolderSyncInfo instance for the data stored therein.
@@ -470,28 +441,6 @@ public class SyncFileWriter {
}
/*
- * Reads all lines of the specified file.
- * Returns null if the file does not exist.
- */
- public static byte[][] readLines(InputStream stream) throws CVSException {
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- List fileContentStore = new ArrayList();
- try {
- String line;
- while ((line = reader.readLine()) != null) {
- fileContentStore.add(line.getBytes());
- }
- return (byte[][]) fileContentStore.toArray(new byte[fileContentStore.size()][]);
- } finally {
- reader.close();
- }
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
- }
-
- /*
* Writes all lines to the specified file, using linefeed terminators for
* compatibility with other CVS clients.
*/
@@ -536,22 +485,6 @@ public class SyncFileWriter {
throw CVSException.wrapException(e);
}
}
-
- public static void writeLines(OutputStream os, byte[][] contents) throws CVSException {
- try {
- try {
- for (int i = 0; i < contents.length; i++) {
- os.write(contents[i]);
- os.write(0x0A); // newline byte
- }
- } finally {
- os.close();
- }
- } catch (IOException e) {
- throw CVSException.wrapException(e);
- }
- }
-
/**
* Method writeFileToBaseDirectory.
*
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
index 360034080..f948ef0d0 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
@@ -240,16 +240,4 @@ public class Util {
result.add(next);
return (String[]) result.toArray(new String[result.size()]);
}
-
- public static String getSubstring(byte[] bytes, byte delimiter, int index, boolean includeRest) {
- String string = new String(bytes);
- int start = 0;
- for (int i = 0; i < index; i++) {
- start = string.indexOf(delimiter, start);
- if (start == -1) return null;
- }
- int end = string.indexOf(delimiter, start);
- if (end == -1 || includeRest) return string.substring(start + 1);
- return string.substring(start + 1, end);
- }
} \ No newline at end of file

Back to the top