diff options
author | Michael Valenta | 2002-07-17 13:15:39 +0000 |
---|---|---|
committer | Michael Valenta | 2002-07-17 13:15:39 +0000 |
commit | 97b0f07ec3295be83b1b6175b9047f0a39564034 (patch) | |
tree | 0f08b05c8cbf3e07d245d3bb5291b606947f71e0 | |
parent | 14c41ea875818c8ce5dc931e66eef89b66881717 (diff) | |
download | eclipse.platform.team-WatchEditBranch.tar.gz eclipse.platform.team-WatchEditBranch.tar.xz eclipse.platform.team-WatchEditBranch.zip |
Ongoing work on watch/edit supportWatchEditBranch
10 files changed, 225 insertions, 115 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java index 7532bdbe7..5826d55bb 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java @@ -333,43 +333,6 @@ public class CVSTeamProvider extends RepositoryProvider { throw new CVSServerException(status); } } - - /** - * Checkout the provided resources so they can be modified locally and committed. - */ - public void checkout(IResource[] resources, boolean recurse, IProgressMonitor progress) throws TeamException { - - final ICVSResource[] cvsResources = getCVSArguments(resources); - - // mark the files locally as being checked out - for (int i = 0; i < cvsResources.length; i++) { - ICVSResource resource = cvsResources[i]; - resource.accept(new ICVSResourceVisitor() { - public void visitFile(ICVSFile file) throws CVSException { - file.checkout(ICVSFile.NO_NOTIFICATION); - } - public void visitFolder(ICVSFolder folder) throws CVSException { - // nothing needs to be done here as the recurse will handle the traversal - } - }, recurse); - } - - // send the noop command to the server in order to deliver the notifications - final boolean[] connected = new boolean[] { false }; - try { - Session.run(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true, new ICVSRunnable() { - public void run(IProgressMonitor monitor) throws CVSException { - connected[0] = true; - Command.NOOP.execute(Command.NO_GLOBAL_OPTIONS, Command.NO_LOCAL_OPTIONS, - cvsResources, null, monitor); - } - }, progress); - } catch (CVSException e) { - // Only report the exception if we were able to connect. - // If we couldn't connect, the notification will be sent the next time we do. - if (connected[0]) throw e; - } - } /** * @see ITeamProvider#delete(IResource[], int, IProgressMonitor) @@ -482,7 +445,7 @@ public class CVSTeamProvider extends RepositoryProvider { progress.done(); } } - + /** * Replace the local version of the provided resources with the remote using "cvs update -C ..." * @@ -795,14 +758,6 @@ public class CVSTeamProvider extends RepositoryProvider { } /** - * Currently, we support only the optimistic model so uncheckout dores nothing. - * - * @see ITeamProvider#uncheckout(IResource[], int, IProgressMonitor) - */ - public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException { - } - - /** * Generally useful update. * * The tag parameter determines any stickyness after the update is run. If tag is null, any tagging on the @@ -1200,7 +1155,9 @@ public class CVSTeamProvider extends RepositoryProvider { if (readOnlys.isEmpty()) return OK; // XXX We should try to create a PM using the provided context - checkout((IFile[]) readOnlys.toArray(new IFile[readOnlys.size()]), false /* recurse */, null); + edit((IFile[]) readOnlys.toArray(new IFile[readOnlys.size()]), + false /* recurse */, true /* notify server */, + ICVSFile.NO_NOTIFICATION, null); } catch (TeamException e) { return e.getStatus(); } @@ -1210,7 +1167,9 @@ public class CVSTeamProvider extends RepositoryProvider { // Ignore files that are not read-only if (!file.isReadOnly()) return OK; try { - checkout(new IResource[] {file}, false /* recurse */, null); + edit(new IResource[] {file}, + false /* recurse */, true /* notify server */, + ICVSFile.NO_NOTIFICATION, null); } catch (TeamException e) { return e.getStatus(); } @@ -1224,8 +1183,114 @@ public class CVSTeamProvider extends RepositoryProvider { /** * Answer true if watch/edit support is enabled for this provider. + * @return boolean */ public boolean isWatchEditEnabled() { return CVSProviderPlugin.getPlugin().isWatchEditEnabled(); } + + /** + * Checkout (cvs edit) the provided resources so they can be modified locally and committed. + * This will make any read-only resources in the list writable and will notify the server + * that the file is being edited. This notification may be done immediately or at some + * later point depending on whether contact with the server is possble at the time of + * invocation or the value of the notify server parameter. + * + * The recurse parameter is equivalent to the cvs local options -l (<code>true</code>) and + * -R (<code>false</code>). The notifyServer parameter can be used to defer server contact + * until the next command. This may be approrpiate if no shell or progress monitor is available + * to the caller. The notification bit field indicates what temporary watches are to be used while + * the file is being edited. The possible values that can be ORed together are ICVSFile.EDIT, + * ICVSFile.UNEDIT and ICVSFile.COMMIT. There pre-ORed convenience values ICVSFile.NO_NOTIFICATION + * and ICVSFile.NOTIFY_ON_ALL are also available. + * + * @param resources the resources to be edited + * @param recurse indicates whether to recurse (-R) or not (-l) + * @param notifyServer indicates whether to notify the server now, if possible, + * or defer until the next command. + * @param notification the temporary watches. + * @param progress progress monitor to provide progress indication/cancellation or <code>null</code> + * @exception CVSException if this method fails. + * @since 2.1 + * + * @see CVSTeamProvider#unedit + */ + public void edit(IResource[] resources, boolean recurse, boolean notifyServer, final int notification, IProgressMonitor progress) throws CVSException { + notifyEditUnedit(resources, recurse, notifyServer, new ICVSResourceVisitor() { + public void visitFile(ICVSFile file) throws CVSException { + if (file.isReadOnly()) + file.edit(notification); + } + public void visitFolder(ICVSFolder folder) throws CVSException { + // nothing needs to be done here as the recurse will handle the traversal + } + }, progress); + } + + /** + * Unedit the given resources. Any writtable resources will be reverted to their base contents + * and made read-only and the server will be notified that the file is no longer being edited. + * This notification may be done immediately or at some + * later point depending on whether contact with the server is possble at the time of + * invocation or the value of the notify server parameter. + * + * The recurse parameter is equivalent to the cvs local options -l (<code>true</code>) and + * -R (<code>false</code>). The notifyServer parameter can be used to defer server contact + * until the next command. This may be approrpiate if no shell or progress monitor is available + * to the caller. + * + * @param resources the resources to be unedited + * @param recurse indicates whether to recurse (-R) or not (-l) + * @param notifyServer indicates whether to notify the server now, if possible, + * or defer until the next command. + * @param progress progress monitor to provide progress indication/cancellation or <code>null</code> + * @exception CVSException if this method fails. + * @since 2.1 + * + * @see CVSTeamProvider#edit + */ + public void unedit(IResource[] resources, boolean recurse, boolean notifyServer, IProgressMonitor progress) throws TeamException { + notifyEditUnedit(resources, recurse, notifyServer, new ICVSResourceVisitor() { + public void visitFile(ICVSFile file) throws CVSException { + if (!file.isReadOnly()) + file.unedit(); + } + public void visitFolder(ICVSFolder folder) throws CVSException { + // nothing needs to be done here as the recurse will handle the traversal + } + }, progress); + } + + /* + * This method captures the common behavior between the edit and unedit methods. + */ + private void notifyEditUnedit(IResource[] resources, boolean recurse, boolean notifyServer, ICVSResourceVisitor editUneditVisitor, IProgressMonitor progress) throws CVSException { + progress = Policy.monitorFor(progress); + final ICVSResource[] cvsResources = getCVSArguments(resources); + + // mark the files locally as being checked out + for (int i = 0; i < cvsResources.length; i++) { + cvsResources[i].accept(editUneditVisitor, recurse); + } + + // send the noop command to the server in order to deliver the notifications + if (notifyServer) { + final boolean[] connected = new boolean[] { false }; + try { + Session.run(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot(), true, new ICVSRunnable() { + public void run(IProgressMonitor monitor) throws CVSException { + connected[0] = true; + Command.NOOP.execute(Command.NO_GLOBAL_OPTIONS, Command.NO_LOCAL_OPTIONS, + cvsResources, null, monitor); + } + }, progress); + } catch (CVSException e) { + // Only report the exception if we were able to connect. + // If we couldn't connect, the notification will be sent the next time we do. + if (connected[0]) throw e; + } finally { + progress.done(); + } + } + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFile.java index 0ab33e457..6d9800ddb 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFile.java @@ -70,16 +70,14 @@ public interface ICVSFile extends ICVSResource { * Sets the file to read-only (<code>true</code>) or writable (<code>false</code>). * * This method is used by the command framework and should not be used by other clients. - * Other clients should use <code>checkout</code> and <code>uncheckout</code> instead as they + * Other clients should use <code>edit</code> and <code>unedit</code> instead as they * will report the change to the server if appropriate. */ void setReadOnly(boolean readOnly) throws CVSException; /** - * Answers whether the file is read-only or not. - * - * This method is used by the command framework and should not be used by other clients. - * Other clients should use <code>isCheckedOut</code> instead. + * Answers whether the file is read-only or not. If a file is read-only, <code>edit</code> + * should be invoked to make the file editable. */ boolean isReadOnly() throws CVSException; @@ -118,12 +116,6 @@ public interface ICVSFile extends ICVSResource { public ILogEntry[] getLogEntries(IProgressMonitor monitor) throws TeamException; /** - * Indicate whether a fiel has been checked out for local editing. A file is checked out - * for local editing if it's read-only bit is false. - */ - public boolean isCheckedOut() throws CVSException; - - /** * Mark the file as checked out to allow local editing (analogous to "cvs edit"). * If this method is invoked when <code>isCheckedOut()</code> returns <code>false</code>, * a notification message that will be sent to the server on the next connection @@ -132,7 +124,7 @@ public interface ICVSFile extends ICVSResource { * @param notifications the set of operations for which the local user would like notification * while the local file is being edited. */ - public void checkout(int notifications) throws CVSException; + public void edit(int notifications) throws CVSException; /** * Undo a checkout of the file (analogous to "cvs unedit"). @@ -140,7 +132,7 @@ public interface ICVSFile extends ICVSResource { * a notification message that will be sent to the server on the next connection * If <code>isCheckedOut()</code> returns <code>false</code> then nothing is done. */ - public void uncheckout() throws CVSException; + public void unedit() throws CVSException; /** * Answer any pending notification information associated with the receiver. diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFolder.java index c1a5d110e..7a1e585aa 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFolder.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSFolder.java @@ -152,12 +152,5 @@ public interface ICVSFolder extends ICVSResource { * @exception CVSException if the operation failed. */ public void run(ICVSRunnable job, IProgressMonitor monitor) throws CVSException; - - /** - * Answer the list of pending notifications for the folder. An empty list or <code>null</code> - * may be returned if there are no pending notifications. - * - * This method is used by the command framework and should not be used by other clients. - */ - public NotifyInfo[] getPendingNotifications() throws CVSException; + }
\ No newline at end of file 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 fe538bc0b..0c9104ff1 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 @@ -253,8 +253,8 @@ public class EclipseFile extends EclipseResource implements ICVSFile { /** * @see org.eclipse.team.internal.ccvs.core.ICVSFile#checkout(int) */ - public void checkout(int notifications) throws CVSException { - if (isCheckedOut()) return; + public void edit(int notifications) throws CVSException { + if (!isReadOnly()) return; // convert the notifications to internal form char[] internalFormat; @@ -287,17 +287,10 @@ public class EclipseFile extends EclipseResource implements ICVSFile { } /** - * @see org.eclipse.team.internal.ccvs.core.ICVSFile#isCheckedOut() - */ - public boolean isCheckedOut() throws CVSException { - return !isReadOnly(); - } - - /** * @see org.eclipse.team.internal.ccvs.core.ICVSFile#uncheckout() */ - public void uncheckout() throws CVSException { - if (!isCheckedOut()) return; + public void unedit() throws CVSException { + if (isReadOnly()) return; // record the notification NotifyInfo info = getNotifyInfo(); 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 941a12c21..73e35530f 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 @@ -315,14 +315,5 @@ 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.ICVSFolder#getPendingNotifications() - */ - public NotifyInfo[] getPendingNotifications() throws CVSException { - if (isCVSFolder()) { - return EclipseSynchronizer.getInstance().getAllNotifyInfo((IContainer)resource); - } - return null; - } + }
\ No newline at end of file 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 97b20960e..6c388fe0c 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 @@ -16,6 +16,7 @@ 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.runtime.CoreException; @@ -872,6 +873,7 @@ public class EclipseSynchronizer { */ public NotifyInfo getNotifyInfo(IResource resource) throws CVSException { NotifyInfo[] infos = SyncFileWriter.readAllNotifyInfo(resource.getParent()); + if (infos == null) return null; for (int i = 0; i < infos.length; i++) { NotifyInfo notifyInfo = infos[i]; if (notifyInfo.getName().equals(resource.getName())) { @@ -880,15 +882,6 @@ public class EclipseSynchronizer { } return null; } - - /** - * Anwser all the notification information associated with the given folder - * @param parent - * @return NotifyInfo[] - */ - public NotifyInfo[] getAllNotifyInfo(IContainer parent) throws CVSException { - return SyncFileWriter.readAllNotifyInfo(parent); - } /** * Method deleteNotifyInfo. @@ -911,4 +904,11 @@ public class EclipseSynchronizer { SyncFileWriter.writeAllNotifyInfo(resource.getParent(), newInfos); } + public void copyFileToBaseDirectory(IFile file) throws CVSException { + ResourceSyncInfo info = getResourceSync(file); + // The file must exist remotely and must exist + if (info == null || info.isAdded() || info.isDeleted()) + return; + SyncFileWriter.writeFileToBaseDirectory(file, info); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java index 44dd9c770..d05d7e132 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java @@ -548,21 +548,14 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { /** * @see org.eclipse.team.internal.ccvs.core.ICVSFile#checkout(int) */ - public void checkout(int notifications) throws CVSException { + public void edit(int notifications) throws CVSException { // do nothing } /** - * @see org.eclipse.team.internal.ccvs.core.ICVSFile#isCheckedOut() - */ - public boolean isCheckedOut() { - return false; - } - - /** * @see org.eclipse.team.internal.ccvs.core.ICVSFile#uncheckout() */ - public void uncheckout() throws CVSException { + public void unedit() throws CVSException { // do nothing } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java index 058d58efe..2f46f460c 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java @@ -760,12 +760,5 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC Assert.isTrue( ! path.isEmpty()); return getRelativePathFromRootRelativePath((ICVSFolder)root.getChild(path.segment(0)), path.removeFirstSegments(1)); } - - /** - * @see org.eclipse.team.internal.ccvs.core.ICVSFolder#getPendingNotifications() - */ - public NotifyInfo[] getPendingNotifications() throws CVSException { - return null; - } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseRevisionInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseRevisionInfo.java new file mode 100644 index 000000000..474b67a19 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseRevisionInfo.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2000, 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.syncinfo; + +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.Policy; +import org.eclipse.team.internal.ccvs.core.util.EmptyTokenizer; + +/** + * This class represents an entry in the CVS/Baserev file + */ +public class BaseRevisionInfo { + + protected static final String SEPERATOR = "/"; //$NON-NLS-1$ + protected static final char BASE_REVISION_PREFIX = 'B'; + + private String filename; + private String revision; + + public BaseRevisionInfo(String filename, String revision) { + this.filename = filename; + this.revision = revision; + } + + public BaseRevisionInfo(String line) throws CVSException { + if (line.charAt(0) != BASE_REVISION_PREFIX) { + throw new CVSException(Policy.bind("BaseRevisionInfo.MalformedLine", line)); //$NON-NLS-1$ + }; + EmptyTokenizer tokenizer = new EmptyTokenizer(line.substring(1), SEPERATOR); + if(tokenizer.countTokens() != 4) { + throw new CVSException(Policy.bind("BaseRevisionInfo.MalformedLine", line)); //$NON-NLS-1$ + } + filename = tokenizer.nextToken(); + revision = tokenizer.nextToken(); + } + + public String getBaserevLine() { + StringBuffer buffer = new StringBuffer(); + buffer.append(BASE_REVISION_PREFIX); + buffer.append(getName()); + buffer.append(SEPERATOR); + buffer.append(getRevision()); + buffer.append(SEPERATOR); + return buffer.toString(); + } + + private Object getRevision() { + return revision; + } + + private Object getName() { + return filename; + } + +} 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 d64d8cf8f..3c9730704 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 @@ -54,6 +54,8 @@ public class SyncFileWriter { //private static final String PERMISSIONS = "Permissions"; //$NON-NLS-1$ public static final String ENTRIES_LOG="Entries.Log"; //$NON-NLS-1$ public static final String NOTIFY = "Notify"; //$NON-NLS-1$ + public static final String BASE_DIRNAME = "Base"; //$NON-NLS-1$ + public static final String BASEREV = "Baserev"; //$NON-NLS-1$ // the local workspace file that contains pattern for ignored resources public static final String IGNORE_FILE = ".cvsignore"; //$NON-NLS-1$ @@ -425,4 +427,29 @@ public class SyncFileWriter { throw CVSException.wrapException(e); } } + /** + * Method writeFileToBaseDirectory. + * @param file + * @param info + */ + public static void writeFileToBaseDirectory(IFile file, ResourceSyncInfo info) throws CVSException { + try { + IContainer cvsFolder = getCVSSubdirectory(file.getParent()); + IFolder baseFolder = cvsFolder.getFolder(new Path(BASE_DIRNAME)); + if (!baseFolder.exists()) { + baseFolder.create(false /* force */, true /* local */, null); + } + IFile target = baseFolder.getFile(new Path(file.getName())); + if (target.exists()) { + // XXX Should ensure that we haven't already copied it + // XXX write the revision to the CVS/Baserev file + target.setContents(file.getContents(), false /* force */, false /* history */, null); + } else { + target.create(file.getContents(), false /* force */, null); + } + } catch (CoreException e) { + throw CVSException.wrapException(e); + } + } + }
\ No newline at end of file |