1 11 package org.eclipse.team.internal.ccvs.ui.operations; 12 13 import java.util.ArrayList ; 14 import java.util.HashSet ; 15 import java.util.List ; 16 import java.util.Set ; 17 18 import org.eclipse.core.resources.*; 19 import org.eclipse.core.runtime.*; 20 import org.eclipse.core.runtime.jobs.ISchedulingRule; 21 import org.eclipse.osgi.util.NLS; 22 import org.eclipse.team.core.RepositoryProvider; 23 import org.eclipse.team.core.TeamException; 24 import org.eclipse.team.internal.ccvs.core.*; 25 import org.eclipse.team.internal.ccvs.core.client.*; 26 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; 27 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 28 import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; 29 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 30 import org.eclipse.team.internal.ccvs.ui.*; 31 import org.eclipse.team.internal.ccvs.ui.Policy; 32 import org.eclipse.ui.IWorkbenchPart; 33 34 40 public class CheckoutIntoOperation extends CheckoutOperation { 41 42 private boolean recursive; 43 private ICVSFolder localFolder; 44 private String localFolderName; 45 46 50 public CheckoutIntoOperation(IWorkbenchPart part, ICVSRemoteFolder[] remoteFolders, IContainer localFolder, boolean recursive) { 51 super(part, remoteFolders); 52 this.recursive = recursive; 53 this.localFolder = CVSWorkspaceRoot.getCVSFolderFor(localFolder); 54 } 55 56 59 public CheckoutIntoOperation(IWorkbenchPart part, ICVSRemoteFolder remoteFolder, IContainer localFolder, boolean recursive) { 60 this(part, new ICVSRemoteFolder[] { remoteFolder }, localFolder.getParent(), recursive); 61 this.localFolderName = localFolder.getName(); 62 } 63 64 67 protected String getTaskName() { 68 ICVSRemoteFolder[] remoteFolders = getRemoteFolders(); 69 String localFolderName = ""; localFolderName = getLocalFolder().getIResource().getFullPath().toString(); 71 return NLS.bind(CVSUIMessages.CheckoutIntoOperation_taskname, new String [] { new Integer (remoteFolders.length).toString(), localFolderName }); 72 } 73 74 77 public ICVSFolder getLocalFolder() { 78 return localFolder; 79 } 80 81 84 public boolean isRecursive() { 85 return recursive; 86 } 87 88 91 protected IStatus checkout(final ICVSRemoteFolder folder, IProgressMonitor monitor) throws CVSException { 92 final IStatus[] result = new IStatus[] { null }; 93 try { 94 ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { 101 public void run(IProgressMonitor monitor) throws CoreException { 102 result[0] = checkout(folder, getLocalFolder(), isRecursive(), monitor); 103 } 104 }, getSchedulingRule(), 0, monitor); 105 } catch (CoreException e) { 106 result[0] = CVSException.wrapException(e).getStatus(); 107 } 108 return result[0]; 109 } 110 111 114 protected void checkout(final ICVSRemoteFolder[] folders, IProgressMonitor monitor) throws CVSException { 115 EclipseSynchronizer.getInstance().run(getSchedulingRule(), new ICVSRunnable() { 117 public void run(IProgressMonitor monitor) throws CVSException { 118 monitor.beginTask(null, 100); 119 try { 120 CheckoutIntoOperation.super.checkout(folders, Policy.subMonitorFor(monitor, 90)); 122 refreshRoot(getLocalRoot(getLocalFolder()), Policy.subMonitorFor(monitor, 10)); 123 } finally { 124 monitor.done(); 125 } 126 } 127 }, Policy.monitorFor(monitor)); 128 } 129 130 135 private ICVSFolder[] prepareLocalFolders(Session session, ICVSRemoteFolder remoteFolder, ICVSFolder parentFolder, String localFolderName, IProgressMonitor monitor) throws CVSException { 136 Set targetFolderSet = new HashSet (); 137 monitor.beginTask(null, 30); 138 if (localFolderName == null) { 139 140 IStatus status = Request.EXPAND_MODULES.execute(session, new String [] { remoteFolder.getRepositoryRelativePath()}, Policy.subMonitorFor(monitor, 10)); 142 if (status.getCode() == CVSStatus.SERVER_ERROR) { 143 addError(status); 144 return null; 145 } 146 147 String [] expansions = session.getModuleExpansions(); 149 for (int j = 0; j < expansions.length; j++) { 150 String childPath = new Path(null, expansions[j]).segment(0); 151 ICVSResource resource = parentFolder.getChild(childPath); 152 if (resource != null && !resource.isFolder()) { 153 addError(new CVSStatus(IStatus.ERROR, NLS.bind(CVSUIMessages.CheckoutIntoOperation_targetIsFile, new String [] { remoteFolder.getName(), resource.getIResource().getFullPath().toString() }))); 155 return null; 156 } 157 targetFolderSet.add(parentFolder.getFolder(childPath)); 158 } 159 160 } else { 161 targetFolderSet.add(parentFolder.getFolder(localFolderName)); 162 } 163 164 final ICVSFolder[] targetFolders = (ICVSFolder[]) targetFolderSet.toArray(new ICVSFolder[targetFolderSet.size()]); 165 166 IStatus status = validateTargetFolders(remoteFolder, targetFolders, Policy.subMonitorFor(monitor, 10)); 168 if (!status.isOK()) { 169 addError(status); 170 return null; 171 } 172 173 status = scrubFolders(remoteFolder, targetFolders, Policy.subMonitorFor(monitor, 10)); 175 if (status.isOK()) { 177 return targetFolders; 178 } else { 179 addError(status); 180 return null; 181 } 182 } 183 184 187 private IStatus validateTargetFolders(ICVSRemoteFolder remoteFolder, ICVSFolder[] targetFolders, IProgressMonitor monitor) throws CVSException { 188 for (int i = 0; i < targetFolders.length; i++) { 189 ICVSFolder targetFolder = targetFolders[i]; 190 FolderSyncInfo localInfo = targetFolder.getFolderSyncInfo(); 191 FolderSyncInfo remoteInfo = remoteFolder.getFolderSyncInfo(); 192 193 if (!remoteInfo.isSameMapping(localInfo)) { 194 if (localInfo != null ) { 195 if (isRemoteChildOfParent(targetFolder)) { 196 String message; 199 if (targetFolder.exists()) { 200 message = NLS.bind(CVSUIMessages.CheckoutIntoOperation_targetIsFolder, new String [] { remoteFolder.getName(), targetFolder.getIResource().getFullPath().toString() }); 201 } else { 202 message = NLS.bind(CVSUIMessages.CheckoutIntoOperation_targetIsPrunedFolder, new String [] { remoteFolder.getName(), targetFolder.getFolderSyncInfo().getRepository() }); 203 } 204 return new CVSStatus(IStatus.ERROR, message); 205 } 206 } 207 IStatus status = validateUniqueMapping(remoteFolder, targetFolder, Policy.subMonitorFor(monitor, 10)); 209 if (!status.isOK()) return status; 210 } 211 } 212 return OK; 213 } 214 215 219 private boolean isRemoteChildOfParent(ICVSFolder targetFolder) throws CVSException { 220 FolderSyncInfo localInfo = targetFolder.getFolderSyncInfo(); 221 if (localInfo == null) return false; 222 FolderSyncInfo parentInfo = targetFolder.getParent().getFolderSyncInfo(); 223 if (parentInfo == null) return false; 224 IPath childPath = new Path(null, localInfo.getRepository()); 225 IPath parentPath = new Path(null, parentInfo.getRepository()); 226 return parentPath.isPrefixOf(childPath); 227 } 228 229 233 private IContainer getLocalRoot(ICVSFolder targetFolder) throws CVSException { 234 return targetFolder.getIResource().getProject(); 235 } 236 237 240 private IStatus validateUniqueMapping(final ICVSRemoteFolder remoteFolder, final ICVSFolder targetFolder, IProgressMonitor iProgressMonitor) throws CVSException { 241 242 final IContainer root = getLocalRoot(targetFolder); 243 final FolderSyncInfo remoteInfo = remoteFolder.getFolderSyncInfo(); 244 if (remoteInfo.equals(FolderSyncInfo.VIRTUAL_DIRECTORY)) { 245 return OK; 248 } 249 ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(root); 250 try { 251 cvsFolder.accept(new ICVSResourceVisitor() { 252 public void visitFile(ICVSFile file) throws CVSException { 253 } 255 public void visitFolder(ICVSFolder folder) throws CVSException { 256 if (!folder.isCVSFolder()) return; 257 IResource resource = folder.getIResource(); 258 if (resource == null) return; 259 FolderSyncInfo info = folder.getFolderSyncInfo(); 260 if (info.isSameMapping(remoteInfo)) { 261 throw new CVSException(NLS.bind(CVSUIMessages.CheckoutIntoOperation_mappingAlreadyExists, (new Object [] { 262 remoteFolder.getName(), 263 targetFolder.getIResource().getFullPath().toString(), 264 resource.getFullPath().toString() 265 }))); 266 } 267 folder.acceptChildren(this); 268 } 269 }); 270 } catch (CVSException e) { 271 return e.getStatus(); 272 } 273 return OK; 274 } 275 276 279 private IStatus scrubFolders(ICVSRemoteFolder remoteFolder, ICVSFolder[] targetFolders, IProgressMonitor monitor) throws CVSException { 280 monitor.beginTask(null, 100 * targetFolders.length); 281 282 if (targetFolders.length > 1) { 284 setInvolvesMultipleResources(true); 285 } 286 for (int i=0;i<targetFolders.length;i++) { 287 ICVSFolder targetFolder = targetFolders[i]; 288 if (needsPromptForOverwrite(targetFolder, Policy.subMonitorFor(monitor, 50)) && !promptToOverwrite(targetFolder)) { 289 return new CVSStatus(IStatus.INFO, NLS.bind(CVSUIMessages.CheckoutIntoOperation_cancelled, new String [] { remoteFolder.getName() })); 290 } 291 } 292 293 for (int i = 0; i < targetFolders.length; i++) { 294 IStatus status = scrubFolder(targetFolders[i], Policy.subMonitorFor(monitor, 50)); 295 if (!status.isOK()) return status; 296 } 297 monitor.done(); 298 return OK; 299 } 300 301 private boolean needsPromptForOverwrite(ICVSFolder targetFolder, IProgressMonitor monitor) throws CVSException { 302 return targetFolder.isModified(monitor); 303 } 304 305 private boolean promptToOverwrite(ICVSFolder folder) { 306 return promptToOverwrite( 307 CVSUIMessages.CheckoutOperation_confirmOverwrite, 308 NLS.bind(CVSUIMessages.CheckoutIntoOperation_overwriteMessage, new String [] { folder.getName() }), 309 folder.getIResource()); 310 } 311 312 private IStatus scrubFolder(ICVSFolder folder, IProgressMonitor monitor) throws CVSException { 313 if (folder.exists() || folder.isCVSFolder()) { 314 folder.unmanage(Policy.subMonitorFor(monitor, 50)); 316 if (folder.exists()) folder.delete(); 317 } 318 return OK; 319 } 320 321 IStatus checkout(final ICVSRemoteFolder remoteFolder, ICVSFolder parentFolder, boolean recurse, IProgressMonitor monitor) throws CVSException { 322 monitor.beginTask(null, 100); 324 ICVSRepositoryLocation repository = remoteFolder.getRepository(); 325 Session session = new Session(repository, parentFolder); 326 try { 327 session.open(Policy.subMonitorFor(monitor, 5), false ); 328 329 String localName = localFolderName; 331 if (localName == null) { 332 IPath path = new Path(null, remoteFolder.getRepositoryRelativePath()); 333 if (path.segmentCount() > 1) { 334 localName = path.lastSegment(); 335 } 336 } 337 ICVSFolder[] targetFolders = prepareLocalFolders(session, remoteFolder, parentFolder, localName, Policy.subMonitorFor(monitor, 5)); 338 if (targetFolders == null) { 339 return getLastError(); 341 } 342 343 List localOptions = new ArrayList (); 345 if (!recurse) 346 localOptions.add(Command.DO_NOT_RECURSE); 347 if (localName != null) { 348 localOptions.add(Checkout.makeDirectoryNameOption(localName)); 349 } 350 351 if (CVSProviderPlugin.getPlugin().getPruneEmptyDirectories()) 353 localOptions.add(Command.PRUNE_EMPTY_DIRECTORIES); 354 CVSTag tag = remoteFolder.getTag(); 356 if (tag == null) { 357 tag = CVSTag.DEFAULT; 359 } 360 localOptions.add(Update.makeTagOption(tag)); 361 362 IStatus status = Command.CHECKOUT.execute(session, 364 Command.NO_GLOBAL_OPTIONS, 365 (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]), 366 new String [] { remoteFolder.getRepositoryRelativePath() }, 367 null, 368 Policy.subMonitorFor(monitor, 80)); 369 if (!status.isOK()) { 370 return status; 371 } 372 373 manageFolders(targetFolders, repository.getLocation(false)); 374 375 return OK; 376 377 } finally { 378 session.close(); 379 } 380 } 381 382 private void manageFolders(ICVSFolder[] targetFolders, String root) throws CVSException { 383 for (int i = 0; i < targetFolders.length; i++) { 384 manageFolder(targetFolders[i], root); 385 } 386 } 387 388 private static void manageFolder(ICVSFolder folder, String root) throws CVSException { 389 ICVSFolder parent = folder.getParent(); 391 if (!parent.isCVSFolder()) { 392 parent.setFolderSyncInfo(new FolderSyncInfo(FolderSyncInfo.VIRTUAL_DIRECTORY, root, CVSTag.DEFAULT, true)); 393 IResource resource = parent.getIResource(); 394 if (resource.getType() != IResource.PROJECT) { 395 manageFolder(parent, root); 396 } 397 } 398 folder.setFolderSyncInfo(folder.getFolderSyncInfo()); 400 } 401 402 405 private static void refreshRoot(IContainer root, IProgressMonitor monitor) throws CVSException { 406 try { 407 IProject project = root.getProject(); 408 CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()); 409 if (provider == null) { 410 ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(project); 411 if (folder.isCVSFolder()) { 412 RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); 414 415 provider = (CVSTeamProvider)RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()); 417 provider.setWatchEditEnabled(CVSProviderPlugin.getPlugin().isWatchEditEnabled()); 418 } 419 } 420 } catch (TeamException e) { 421 throw CVSException.wrapException(e); 422 } 423 } 424 425 428 protected ISchedulingRule getSchedulingRule() { 429 IProject tempProject = getLocalFolder().getIResource().getProject(); 433 IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory(); 434 return ruleFactory.modifyRule(tempProject); 435 } 436 437 } 438 | Popular Tags |