From 0ed6496dfb8965c60f7acf21f00e1f00c29acb40 Mon Sep 17 00:00:00 2001 From: Michael Valenta Date: Mon, 24 Nov 2003 17:15:56 +0000 Subject: 46629: Cannot share project in a sub directory of a module --- .../ccvs/core/resources/CVSWorkspaceRoot.java | 71 -------- .../internal/ccvs/core/resources/RemoteFolder.java | 1 + .../ccvs/ui/operations/ShareProjectOperation.java | 178 +++++++++++++++++++++ .../internal/ccvs/ui/wizards/SharingWizard.java | 7 +- .../eclipse/team/tests/ccvs/core/EclipseTest.java | 20 ++- .../team/tests/ccvs/core/provider/ImportTest.java | 25 +++ 6 files changed, 227 insertions(+), 75 deletions(-) create mode 100644 bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShareProjectOperation.java diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java index ccdfe5297..478b08c3c 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java @@ -224,77 +224,6 @@ public class CVSWorkspaceRoot { } } - /** - * Create a remote module in the CVS repository and link the project directory to this remote module. - * The contents of the project are not imported. - */ - public static void createModule(final ICVSRepositoryLocation location, final IProject project, String moduleName, IProgressMonitor monitor) throws TeamException { - - // Determine if the repository is known - boolean alreadyExists = CVSProviderPlugin.getPlugin().isKnownRepository(location.getLocation()); - // Set the folder sync info of the project to point to the remote module - final ICVSFolder folder = (ICVSFolder)CVSWorkspaceRoot.getCVSResourceFor(project); - - try { - String projectName = project.getName(); - if (moduleName == null) - moduleName = projectName; - - // Perform the import using a dummy root so the local project is not traversed - RemoteFolderTree root = new RemoteFolderTree(null, location, Path.EMPTY.toString(), null); - root.setChildren(new ICVSRemoteResource[] { - new RemoteFolder(root, moduleName, null, null, null, false) - }); - Session s = new Session(location, root); - s.open(monitor, true /* open for modification */); - try { - IStatus status = Command.ADD.execute(s, - Command.NO_GLOBAL_OPTIONS, - Command.NO_LOCAL_OPTIONS, - new String[] { moduleName }, - null, - monitor); - // If we get a warning, the operation most likely failed so check that the status is OK - if (status.getCode() == CVSStatus.SERVER_ERROR || ! status.isOK()) { - throw new CVSServerException(status); - } - } finally { - s.close(); - } - - // perform the workspace modifications in a runnable - try { - final TeamException[] exception = new TeamException[] {null}; - final String modName = moduleName; - ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - try { - // Link the project to the newly created module - folder.setFolderSyncInfo(new FolderSyncInfo(modName, location.getLocation(), null, false)); - //Register it with Team. If it already is, no harm done. - RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); - } catch (TeamException e) { - exception[0] = e; - } - } - }, project, monitor); - if (exception[0] != null) - throw exception[0]; - } catch (CoreException e) { - throw CVSException.wrapException(e); - } - } catch (TeamException e) { - // The checkout may have triggered password caching - // Therefore, if this is a newly created location, we want to clear its cache - if ( ! alreadyExists) - CVSProviderPlugin.getPlugin().disposeRepository(location); - throw e; - } - // Add the repository if it didn't exist already - if ( ! alreadyExists) - CVSProviderPlugin.getPlugin().addRepository(location); - } - /** * Set the sharing for a project to enable it to be used with the CVSTeamProvider. * This method ensure that the repository in the FolderSyncInfo is known and that 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 8916a12e3..5841ae1c0 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 @@ -463,6 +463,7 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC * @see ICVSRemoteFolder#getTag() */ public CVSTag getTag() { + if (folderInfo == null) return null; return folderInfo.getTag(); } /* diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShareProjectOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShareProjectOperation.java new file mode 100644 index 000000000..66e733a7e --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShareProjectOperation.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.core.RepositoryProvider; +import org.eclipse.team.core.TeamException; +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.ICVSRemoteResource; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.client.Command; +import org.eclipse.team.internal.ccvs.core.client.Session; +import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree; +import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; +import org.eclipse.team.internal.ccvs.ui.Policy; + +/** + * Create a folder and any missing parents in the repository + */ +public class ShareProjectOperation extends CVSOperation { + + private ICVSRepositoryLocation location; + private IProject project; + private String moduleName; + + public ShareProjectOperation(Shell shell, ICVSRepositoryLocation location, IProject project, String moduleName) { + super(shell); + this.moduleName = moduleName; + this.project = project; + this.location = location; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { + + // Determine if the repository is known + boolean alreadyExists = CVSProviderPlugin.getPlugin().isKnownRepository(location.getLocation()); + + try { + createRemoteFolder(monitor); + mapProjectToRemoteFolder(monitor); + } catch (CVSException e) { + // The checkout may have triggered password caching + // Therefore, if this is a newly created location, we want to clear its cache + if ( ! alreadyExists) + CVSProviderPlugin.getPlugin().disposeRepository(location); + throw e; + } + // Add the repository if it didn't exist already + if ( ! alreadyExists) { + CVSProviderPlugin.getPlugin().addRepository(location); + } + } + + private void mapProjectToRemoteFolder(IProgressMonitor monitor) throws CVSException { + // perform the workspace modifications in a runnable + try { + // Set the folder sync info of the project to point to the remote module + final ICVSFolder folder = (ICVSFolder)CVSWorkspaceRoot.getCVSResourceFor(project); + final TeamException[] exception = new TeamException[] {null}; + final String modName = moduleName; + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + try { + // Link the project to the newly created module + folder.setFolderSyncInfo(new FolderSyncInfo(modName, location.getLocation(), null, false)); + //Register it with Team. If it already is, no harm done. + RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); + } catch (TeamException e) { + exception[0] = e; + } + } + }, project, 0, monitor); + if (exception[0] != null) + throw exception[0]; + } catch (CoreException e) { + throw CVSException.wrapException(e); + } + } + + /* + * Create the remote folder (and any ancestors). + */ + private void createRemoteFolder(IProgressMonitor monitor) throws CVSException { + String projectName = project.getName(); + if (moduleName == null) + moduleName = projectName; + + RemoteFolderTree root = new RemoteFolderTree(null, location, Path.EMPTY.toString(), null); + Path path = new Path(moduleName); + + try { + monitor.beginTask(getTaskName(), 100 * path.segmentCount()); + ensureTreeExists(root, path, monitor); + } catch (TeamException e) { + throw CVSException.wrapException(e); + } finally { + monitor.done(); + } + } + + /* + * Create handles for all the children in the moduleName path + */ + private RemoteFolderTree createChild(RemoteFolderTree parent, String name, IProgressMonitor monitor) throws CVSException, TeamException { + RemoteFolderTree child = new RemoteFolderTree(parent, name, location, new Path(parent.getRepositoryRelativePath()).append(name).toString(), null); + parent.setChildren(new ICVSRemoteResource[] { child }); + if (child.exists(Policy.subMonitorFor(monitor, 50))) { + // The child exists so get the handle that was received from the server + return (RemoteFolderTree)parent.getFolder(name); + } else { + // Create the folder remotely + createFolder(child, Policy.subMonitorFor(monitor, 50)); + return child; + } + } + + /* + * Ensure that all the folders in the tree exist + */ + private void ensureTreeExists(RemoteFolderTree folder, IPath path, IProgressMonitor monitor) throws TeamException { + if (path.isEmpty()) return; + String name = path.segment(0); + RemoteFolderTree child = createChild(folder, name, monitor); + ensureTreeExists(child, path.removeFirstSegments(1), monitor); + } + + private void createFolder(RemoteFolderTree folder, IProgressMonitor monitor) throws TeamException { + Session s = new Session(location, folder.getParent()); + s.open(monitor, true /* open for modification */); + try { + IStatus status = Command.ADD.execute(s, + Command.NO_GLOBAL_OPTIONS, + Command.NO_LOCAL_OPTIONS, + new String[] { folder.getName() }, + null, + monitor); + // If we get a warning, the operation most likely failed so check that the status is OK + if (status.getCode() == CVSStatus.SERVER_ERROR || ! status.isOK()) { + throw new CVSServerException(status); + } + } finally { + s.close(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() + */ + protected String getTaskName() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java index 4d10c0ff7..72699db59 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java @@ -29,6 +29,7 @@ import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.team.internal.ccvs.ui.operations.ShareProjectOperation; import org.eclipse.team.ui.IConfigurationWizard; import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; import org.eclipse.ui.IWorkbench; @@ -241,10 +242,14 @@ public class SharingWizard extends Wizard implements IConfigurationWizard { } // Create the remote module for the project - CVSWorkspaceRoot.createModule(location, project, getModuleName(), new SubProgressMonitor(monitor, 50)); + ShareProjectOperation op = new ShareProjectOperation(getShell(), location, project, getModuleName()); + op.run(new SubProgressMonitor(monitor, 50)); } } catch (TeamException e) { throw new InvocationTargetException(e); + } catch (InterruptedException e) { + // Must have been canceled + return; } finally { monitor.done(); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java index ae1860442..9aee85d69 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java @@ -22,7 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.*; +import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestSuite; @@ -32,7 +32,6 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -40,6 +39,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.tests.harness.EclipseWorkspaceTest; import org.eclipse.swt.widgets.Display; @@ -71,6 +71,7 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.core.util.SyncFileChangeListener; import org.eclipse.team.internal.ccvs.ui.operations.CVSOperation; import org.eclipse.team.internal.ccvs.ui.operations.CheckoutSingleProjectOperation; +import org.eclipse.team.internal.ccvs.ui.operations.ShareProjectOperation; import org.eclipse.team.internal.ccvs.ui.operations.ITagOperation; import org.eclipse.team.internal.ccvs.ui.operations.ReplaceOperation; import org.eclipse.team.internal.ccvs.ui.operations.TagInRepositoryOperation; @@ -718,7 +719,20 @@ public class EclipseTest extends EclipseWorkspaceTest { } protected void mapNewProject(IProject project) throws TeamException { - CVSWorkspaceRoot.createModule(getRepository(), project, null, DEFAULT_MONITOR); + shareProject(getRepository(), project, null, DEFAULT_MONITOR); + } + + /** + * Map the given local project to remote folder, creating the remote folder or any of + * its ancestors as necessary. + * @param location + * @param project + * @param moduleName + * @param default_monitor + */ + protected void shareProject(CVSRepositoryLocation location, IProject project, String moduleName, IProgressMonitor default_monitor) throws CVSException { + ShareProjectOperation op = new ShareProjectOperation(null, location, project, moduleName); + executeHeadless(op); } protected void commitNewProject(IProject project) throws CoreException, CVSException, TeamException { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ImportTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ImportTest.java index 99d22d990..c74dbd5d2 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ImportTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ImportTest.java @@ -157,4 +157,29 @@ public class ImportTest extends EclipseTest { } + + public void testRootShare() throws CoreException { + // Create a test project + IProject project = getUniqueTestProject(getName()); + IResource[] result = buildResources(project, new String[] { "file1.txt", "folder1/", "folder1/a.txt" }, true); + // Share the project + shareProject(getRepository(), project, null, DEFAULT_MONITOR); + addResources(project, new String[] { "file1.txt", "folder1/", "folder1/a.txt" }, true); + // Checkout a copy ans test + IProject copy = checkoutProject(getUniqueTestProject(getName() + "copy"), project.getName(), null); + assertEquals(project, copy); + } + + public void testNonRootShare() throws CoreException { + // Create a test project + IProject project = getUniqueTestProject(getName()); + IResource[] result = buildResources(project, new String[] { "file1.txt", "folder1/", "folder1/a.txt" }, true); + // Share it as a non-root folder in the repository + String moduleName = "root" + Long.toString(System.currentTimeMillis()) + "/" + project.getName(); + shareProject(getRepository(), project, moduleName, DEFAULT_MONITOR); + addResources(project, new String[] { "file1.txt", "folder1/", "folder1/a.txt" }, true); + // Checkout a copy and test + IProject copy = checkoutProject(getUniqueTestProject(getName() + "copy"), moduleName, null); + assertEquals(project, copy); + } } -- cgit v1.2.3