1 11 package org.eclipse.team.internal.ccvs.core.resources; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.core.resources.IContainer; 21 import org.eclipse.core.resources.IResource; 22 import org.eclipse.core.runtime.*; 23 import org.eclipse.osgi.util.NLS; 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.*; 27 import org.eclipse.team.internal.ccvs.core.client.listeners.*; 28 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; 29 import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; 30 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 31 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 32 import org.eclipse.team.internal.ccvs.core.util.Util; 33 34 45 public class RemoteFolderTreeBuilder { 46 47 private static final int MAX_REVISION_FETCHES_PER_CONNECTION = 1024; 48 49 private Map fileDeltas; 50 private List changedFiles; 51 private Map remoteFolderTable; 52 53 private ICVSFolder root; 54 private RemoteFolderTree remoteRoot; 55 private CVSRepositoryLocation repository; 56 57 private CVSTag tag; 58 59 private LocalOption[] updateLocalOptions; 60 61 private boolean rootDoesNotExist = false; 62 63 private static String UNKNOWN = ""; private static String DELETED = "DELETED"; private static String ADDED = "ADDED"; private static String FOLDER = "FOLDER"; 68 private static Map EMPTY_MAP = new HashMap (); 69 70 private boolean newFolderExist = false; 71 72 static class DeltaNode { 73 int syncState = Update.STATE_NONE; 74 String name; 75 String revision; 76 77 DeltaNode(String name, String revision, int syncState) { 78 this.name = name; 79 this.revision = revision; 80 this.syncState = syncState; 81 } 82 83 String getName() { 84 return name; 85 } 86 87 String getRevision() { 88 return revision; 89 } 90 91 int getSyncState() { 92 return syncState; 93 } 94 } 95 96 97 RemoteFolderTreeBuilder(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag) { 98 this.repository = repository; 99 this.root = root; 100 this.tag = tag; 101 this.fileDeltas = new HashMap (); 102 this.changedFiles = new ArrayList (); 103 this.remoteFolderTable = new HashMap (); 104 105 List localOptions = new ArrayList (); 107 if (tag != null) { 108 if (tag.getType() == CVSTag.HEAD) { 109 localOptions.add(Update.CLEAR_STICKY); 110 } else { 111 localOptions.add(Update.makeTagOption(tag)); 112 } 113 } 114 updateLocalOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]); 115 } 116 117 private LocalOption[] getOptionsWithoutTag() { 118 List localOptions = new ArrayList (); 120 localOptions.add(Update.RETRIEVE_ABSENT_DIRECTORIES); 121 return (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]); 122 } 123 124 public static RemoteFolder buildBaseTree(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor progress) throws CVSException { 125 try { 126 RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag); 127 progress.beginTask(null, 100); 128 IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(progress, 100); 129 subProgress.beginTask(null, 512); 130 subProgress.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_buildingBase, new String [] { root.getName() })); 131 return builder.buildBaseTree(null, root, subProgress); 132 } finally { 133 progress.done(); 134 } 135 } 136 137 public static RemoteFolderTree buildRemoteTree(CVSRepositoryLocation repository, IContainer root, CVSTag tag, IProgressMonitor monitor) throws CVSException { 138 return buildRemoteTree(repository, CVSWorkspaceRoot.getCVSFolderFor(root), tag, monitor); 139 } 140 141 public static RemoteFolderTree buildRemoteTree(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor monitor) throws CVSException { 142 RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag); 143 return builder.buildTree(new ICVSResource[] { root }, monitor); 144 } 145 public static RemoteFile buildRemoteTree(CVSRepositoryLocation repository, ICVSFile file, CVSTag tag, IProgressMonitor monitor) throws CVSException { 146 RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, file.getParent(), tag); 147 return builder.buildTree(file, monitor); 148 } 149 150 RemoteFolderTree buildTree(ICVSResource[] resources, IProgressMonitor monitor) throws CVSException { 151 152 QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness(); 154 try { 155 CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE); 156 157 monitor.beginTask(null, 100); 158 159 if (!fetchDelta(resources, Policy.subMonitorFor(monitor, 75))) { 161 return null; 162 } 163 164 fetchNewDirectories(Policy.subMonitorFor(monitor, 10)); 167 168 fetchFileRevisions(Policy.subMonitorFor(monitor, 15)); 170 171 return remoteRoot; 172 173 } finally { 174 CVSProviderPlugin.getPlugin().setQuietness(quietness); 175 monitor.done(); 176 } 177 } 178 179 private boolean fetchDelta(ICVSResource[] resources, IProgressMonitor monitor) throws CVSException { 180 181 ArrayList arguments = new ArrayList (); 183 for (int i = 0; i < resources.length; i++) { 184 ICVSResource resource = resources[i]; 185 arguments.add(resource.getRelativePath(root)); 186 } 187 188 monitor.beginTask(null, 100); 190 Policy.checkCanceled(monitor); 191 Session session = new Session(repository, root, false); 192 session.open(Policy.subMonitorFor(monitor, 10), false ); 193 try { 194 Policy.checkCanceled(monitor); 195 fetchDelta(session, (String []) arguments.toArray(new String [arguments.size()]), Policy.subMonitorFor(monitor, 90)); 196 if (rootDoesNotExist) { 197 if (root.isCVSFolder() && ! root.isManaged()) { 200 IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSMessages.RemoteFolderTreeBuild_folderDeletedFromServer, new String [] { root.getFolderSyncInfo().getRepository() }),root); 201 throw new CVSException(status); 202 } else { 203 return false; 204 } 205 } 206 } finally { 207 session.close(); 208 monitor.done(); 209 } 210 return true; 211 } 212 213 private void fetchNewDirectories(IProgressMonitor monitor) throws CVSException { 214 monitor.beginTask(null, 100); 217 Session session; 218 FolderSyncInfo folderSyncInfo = root.getFolderSyncInfo(); 219 if (folderSyncInfo == null) { 220 if (root.exists()) { 223 IResource resource = root.getIResource(); 224 String path; 225 if (resource == null) { 226 path = root.getName(); 227 } else { 228 path = resource.getFullPath().toString(); 229 } 230 IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSMessages.RemoteFolderTreeBuilder_0, new String [] { path }), root); 231 throw new CVSException(status); 232 } else { 233 return; 235 } 236 } 237 remoteRoot = 238 new RemoteFolderTree(null, root.getName(), repository, 239 folderSyncInfo.getRepository(), 240 tagForRemoteFolder(root, tag)); 241 if (newFolderExist) { 242 session = new Session(repository, remoteRoot, false); 244 session.open(Policy.subMonitorFor(monitor, 10), false ); 245 } else { 246 session = null; 247 } 248 try { 249 IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(monitor, 90); 251 subProgress.beginTask(null, 512); 252 buildRemoteTree(session, root, remoteRoot, "", subProgress); } finally { 255 if (session != null) { 256 session.close(); 257 } 258 monitor.done(); 259 } 260 } 261 262 private void fetchFileRevisions(IProgressMonitor monitor) throws CVSException { 263 if (remoteRoot != null && !changedFiles.isEmpty()) { 265 String [] allChangedFiles = (String [])changedFiles.toArray(new String [changedFiles.size()]); 266 int iterations = (allChangedFiles.length / MAX_REVISION_FETCHES_PER_CONNECTION) 267 + (allChangedFiles.length % MAX_REVISION_FETCHES_PER_CONNECTION == 0 ? 0 : 1); 268 for (int i = 0; i < iterations ; i++) { 269 int length = Math.min(MAX_REVISION_FETCHES_PER_CONNECTION, 270 allChangedFiles.length - (MAX_REVISION_FETCHES_PER_CONNECTION * i)); 271 String buffer[] = new String [length]; 272 System.arraycopy(allChangedFiles, i * MAX_REVISION_FETCHES_PER_CONNECTION, buffer, 0, length); 273 Session session = new Session(repository, remoteRoot, false); 274 session.open(Policy.subMonitorFor(monitor, 1), false ); 275 try { 276 fetchFileRevisions(session, buffer, Policy.subMonitorFor(monitor, 2)); 277 } finally { 278 session.close(); 279 } 280 } 281 } 282 } 283 284 RemoteFile buildTree(ICVSFile file, IProgressMonitor monitor) throws CVSException { 285 QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness(); 286 try { 287 CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE); 288 289 monitor.beginTask(null, 100); 290 291 Policy.checkCanceled(monitor); 293 Session session = new Session(repository, root, false); 294 session.open(Policy.subMonitorFor(monitor, 10), false ); 295 try { 296 Policy.checkCanceled(monitor); 297 fetchDelta(session, new String [] { file.getName() }, Policy.subMonitorFor(monitor, 50)); 298 if (rootDoesNotExist) { 299 return null; 300 } 301 } finally { 302 session.close(); 303 } 304 remoteRoot = 306 new RemoteFolderTree(null, root.getName(), repository, 307 root.getFolderSyncInfo().getRepository(), 308 tagForRemoteFolder(root, tag)); 309 RemoteFile remoteFile; 311 Map deltas = (Map )fileDeltas.get(""); if (deltas == null || deltas.isEmpty()) { 313 byte[] syncBytes = file.getSyncBytes(); 316 if ( syncBytes == null || ResourceSyncInfo.isAddition(syncBytes)) { 317 return null; 318 } 319 remoteFile = new RemoteFile(remoteRoot, syncBytes); 320 } else { 321 DeltaNode d = (DeltaNode)deltas.get(file.getName()); 322 if (d.getRevision() == DELETED) { 323 return null; 324 } 325 remoteFile = new RemoteFile(remoteRoot, 326 d.getSyncState(), 327 file.getName(), 328 null, 329 getKeywordMode(file), 330 tagForRemoteFolder(remoteRoot, tag)); 331 } 332 remoteRoot.setChildren(new ICVSRemoteResource[] {remoteFile}); 334 if (!changedFiles.isEmpty()) { 336 recordRemoteFolder(remoteRoot); 338 session = new Session(repository, remoteRoot, false); 339 session.open(Policy.subMonitorFor(monitor, 10), false ); 340 try { 341 fetchFileRevisions(session, (String [])changedFiles.toArray(new String [changedFiles.size()]), Policy.subMonitorFor(monitor, 20)); 342 } finally { 343 session.close(); 344 } 345 } 346 return remoteFile; 347 348 } finally { 349 CVSProviderPlugin.getPlugin().setQuietness(quietness); 350 monitor.done(); 351 } 352 } 353 354 private Command.KSubstOption getKeywordMode(ICVSFile file) throws CVSException { 355 if (file == null) return null; 356 byte[] syncBytes = file.getSyncBytes(); 357 if (syncBytes == null) return null; 358 return ResourceSyncInfo.getKeywordMode(syncBytes); 359 } 360 361 368 RemoteFolder buildBaseTree(RemoteFolder parent, ICVSFolder local, IProgressMonitor monitor) throws CVSException { 369 370 Policy.checkCanceled(monitor); 371 372 FolderSyncInfo folderSyncInfo = local.getFolderSyncInfo(); 374 if (folderSyncInfo == null) return null; 375 RemoteFolder remote = createRemoteFolder(local, parent, folderSyncInfo); 376 377 List children = new ArrayList (); 379 380 ICVSResource[] folders = local.members(ICVSFolder.FOLDER_MEMBERS); 382 for (int i=0;i<folders.length;i++) { 383 ICVSFolder folder = (ICVSFolder)folders[i]; 384 if (folder.isManaged() && folder.isCVSFolder()) { 385 monitor.worked(1); 386 RemoteFolder tree = buildBaseTree(remote, folder, monitor); 387 if (tree != null) 388 children.add(tree); 389 } 390 } 391 392 ICVSResource[] files = local.members(ICVSFolder.FILE_MEMBERS); 394 for (int i=0;i<files.length;i++) { 395 ICVSFile file = (ICVSFile)files[i]; 396 byte[] syncBytes = file.getSyncBytes(); 397 if (syncBytes==null) 399 continue; 400 if (ResourceSyncInfo.isAddition(syncBytes)) 402 continue; 403 if (ResourceSyncInfo.isDeletion(syncBytes)) { 405 syncBytes = ResourceSyncInfo.convertFromDeletion(syncBytes); 406 } 407 children.add(createRemoteFile(remote, syncBytes)); 408 monitor.worked(1); 409 } 410 411 if (children.isEmpty() && isPruneEmptyDirectories() && !local.exists()) 413 return null; 414 415 remote.setChildren((ICVSRemoteResource[])children.toArray(new ICVSRemoteResource[children.size()])); 417 418 return remote; 419 } 420 421 protected RemoteFile createRemoteFile(RemoteFolder remote, byte[] syncBytes) throws CVSException { 422 return new RemoteFile(remote, syncBytes); 423 } 424 425 protected RemoteFolder createRemoteFolder(ICVSFolder local, RemoteFolder parent, FolderSyncInfo folderSyncInfo) { 426 return new RemoteFolderTree(parent, local.getName(), repository, folderSyncInfo.getRepository(), folderSyncInfo.getTag()); 427 } 428 429 436 private void buildRemoteTree(Session session, ICVSFolder local, RemoteFolderTree remote, String localPath, IProgressMonitor monitor) throws CVSException { 437 438 Policy.checkCanceled(monitor); 439 440 recordRemoteFolder(remote); 442 443 Map children = new HashMap (); 445 446 if (local == null) { 448 fetchNewDirectory(session, remote, localPath, monitor); 449 } 450 451 Map deltas = (Map )fileDeltas.get(localPath); 453 if (deltas == null) 454 deltas = EMPTY_MAP; 455 456 if (local != null) { 458 ICVSResource[] folders = local.members(ICVSFolder.FOLDER_MEMBERS); 460 for (int i=0;i<folders.length;i++) { 461 ICVSFolder folder = (ICVSFolder)folders[i]; 462 DeltaNode d = (DeltaNode)deltas.get(folder.getName()); 463 if (folder.isCVSFolder() && ! isOrphanedSubtree(folder) && (d==null || d.getRevision() != DELETED)) { 464 children.put(folders[i].getName(), 465 new RemoteFolderTree(remote, folders[i].getName(), repository, 466 folder.getFolderSyncInfo().getRepository(), 467 tagForRemoteFolder(folder,tag))); 468 } 469 } 470 ICVSResource[] files = local.members(ICVSFolder.FILE_MEMBERS); 472 for (int i=0;i<files.length;i++) { 473 ICVSFile file = (ICVSFile)files[i]; 474 475 DeltaNode d = (DeltaNode)deltas.get(file.getName()); 476 byte[] syncBytes = file.getSyncBytes(); 477 if (syncBytes==null) 480 continue; 481 if (ResourceSyncInfo.isAddition(syncBytes) && d==null) 483 continue; 484 if (ResourceSyncInfo.isDeletion(syncBytes) && d==null) 486 continue; 487 488 int type = d==null ? Update.STATE_NONE : d.getSyncState(); 489 children.put(file.getName(), new RemoteFile(remote, type, syncBytes)); 490 } 491 } 492 493 Iterator i = deltas.keySet().iterator(); 495 while (i.hasNext()) { 496 String name = (String )i.next(); 497 DeltaNode d = (DeltaNode)deltas.get(name); 498 String revision = d.getRevision(); 499 if (revision == FOLDER) { 500 children.put(name, new RemoteFolderTree(remote, repository, 501 Util.appendPath(remote.getRepositoryRelativePath(), name), 502 tagForRemoteFolder(remote, tag))); 503 } else if (revision == ADDED) { 504 children.put(name, new RemoteFile(remote, 505 d.getSyncState(), 506 name, 507 null, 508 null, 509 tagForRemoteFolder(remote, tag))); 510 } else if (revision == UNKNOWN) { 511 children.put(name, new RemoteFile(remote, 515 d.getSyncState(), 516 name, 517 null, 518 getKeywordMode((ICVSFile)children.get(name)), 519 tagForRemoteFolder(remote, tag))); 520 } else if (revision == DELETED) { 521 if (children.containsKey(name)) 524 children.remove(name); 525 } else { 526 } 528 monitor.worked(1); 529 } 530 531 remote.setChildren((ICVSRemoteResource[])children.values().toArray(new ICVSRemoteResource[children.size()])); 533 534 Iterator childIterator = children.entrySet().iterator(); 538 List emptyChildren = new ArrayList (); 539 while (childIterator.hasNext()) { 540 Map.Entry entry = (Map.Entry )childIterator.next(); 541 if (((RemoteResource)entry.getValue()).isFolder()) { 542 RemoteFolderTree remoteFolder = (RemoteFolderTree)entry.getValue(); 543 String name = (String )entry.getKey(); 544 ICVSFolder localFolder; 545 DeltaNode d = (DeltaNode)deltas.get(name); 546 if (d!=null && d.getRevision() == FOLDER) 548 localFolder = null; 549 else 550 localFolder = local.getFolder(name); 551 buildRemoteTree(session, localFolder, remoteFolder, Util.appendPath(localPath, name), monitor); 552 if (isPruneEmptyDirectories() && remoteFolder.getChildren().length == 0) { 554 if (localFolder == null || (localFolder.members(ICVSFolder.ALL_EXISTING_MEMBERS).length == 0)) 556 emptyChildren.add(remoteFolder); 557 else { 558 FolderSyncInfo info = localFolder.getFolderSyncInfo(); 560 if (tag != null && info != null && ! tag.equals(CVSTag.DEFAULT) && ! tag.equals(info.getTag())) 561 emptyChildren.add(remoteFolder); 562 } 563 } 564 } 565 } 566 567 if (isPruneEmptyDirectories() && !emptyChildren.isEmpty()) { 569 List newChildren = new ArrayList (); 570 newChildren.addAll(Arrays.asList(remote.getChildren())); 571 newChildren.removeAll(emptyChildren); 572 remote.setChildren((ICVSRemoteResource[])newChildren.toArray(new ICVSRemoteResource[newChildren.size()])); 573 574 } 575 } 576 577 583 private List fetchDelta(Session session, String [] arguments, final IProgressMonitor monitor) throws CVSException { 584 585 IUpdateMessageListener listener = new IUpdateMessageListener() { 587 public void directoryInformation(ICVSFolder root, String path, boolean newDirectory) { 588 if (newDirectory) { 589 recordDelta(path, FOLDER, Update.STATE_NONE); 591 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(path, 3) })); 592 } 593 } 594 public void directoryDoesNotExist(ICVSFolder root, String path) { 595 if (path.length() == 0) { 597 rootDoesNotExist = true; 598 } else { 599 recordDelta(path, DELETED, Update.STATE_NONE); 600 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(path, 3) })); 601 } 602 } 603 public void fileInformation(int type, ICVSFolder root, String filename) { 604 switch(type) { 609 case Update.STATE_MERGEABLE_CONFLICT : 610 case Update.STATE_CONFLICT : 611 Map deltas = (Map )fileDeltas.get(Util.removeLastSegment(filename)); 616 DeltaNode d = deltas != null ? (DeltaNode)deltas.get(Util.getLastSegment(filename)) : null; 617 if ((d!=null) && (d.getRevision() == DELETED)) 618 break; 619 case Update.STATE_DELETED : case Update.STATE_REMOTE_CHANGES : changedFiles.add(filename); 622 recordDelta(filename, UNKNOWN, type); 623 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(filename, 3) })); 624 break; 625 } 626 } 627 public void fileDoesNotExist(ICVSFolder root, String filename) { 628 recordDelta(filename, DELETED, Update.STATE_NONE); 629 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(filename, 3) })); 630 } 631 }; 632 633 IStatus status = Command.SYNCUPDATE.execute(session, 637 new GlobalOption[] { Command.DO_NOT_CHANGE }, 638 updateLocalOptions, 639 arguments, 640 new UpdateListener(listener), 641 monitor); 642 if (status.getCode() == CVSStatus.SERVER_ERROR) { 643 CVSServerException e = new CVSServerException(status); 644 if (e.isNoTagException()) { 645 rootDoesNotExist = true; 648 } else if (e.containsErrors()) { 649 CVSProviderPlugin.log(e); 651 } 652 } 653 return changedFiles; 654 } 655 660 private void fetchNewDirectory(Session session, RemoteFolderTree newFolder, String localPath, final IProgressMonitor monitor) throws CVSException { 661 662 IUpdateMessageListener listener = new IUpdateMessageListener() { 664 public void directoryInformation(ICVSFolder root, String path, boolean newDirectory) { 665 if (newDirectory) { 666 recordDelta(path, FOLDER, Update.STATE_NONE); 669 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(path, 3) })); 670 } 671 } 672 public void directoryDoesNotExist(ICVSFolder root, String path) { 673 } 674 public void fileInformation(int type, ICVSFolder root, String filename) { 675 changedFiles.add(filename); 677 recordDelta(filename, ADDED, type); 678 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingDelta, new String [] { Util.toTruncatedPath(filename, 3) })); 679 } 680 public void fileDoesNotExist(ICVSFolder root, String filename) { 681 } 682 }; 683 684 IStatus status = Command.UPDATE.execute(session, 686 new GlobalOption[] { Command.DO_NOT_CHANGE }, 687 updateLocalOptions, 688 new String [] { localPath }, 689 new UpdateListener(listener), 690 Policy.subMonitorFor(monitor, 1)); 691 if (status.getCode() == CVSStatus.SERVER_ERROR) { 692 CVSServerException e = new CVSServerException(status); 693 if ( ! e.isNoTagException() && e.containsErrors()) 694 throw e; 695 Policy.checkCanceled(monitor); 699 status = Command.UPDATE.execute(session, 700 new GlobalOption[] { Command.DO_NOT_CHANGE }, 701 getOptionsWithoutTag(), 702 new String [] { localPath }, 703 new UpdateListener(listener), 704 Policy.subMonitorFor(monitor, 1)); 705 if (status.getCode() == CVSStatus.SERVER_ERROR) { 706 throw new CVSServerException(status); 707 } 708 } 709 } 710 711 private void fetchFileRevisions(Session session, String [] fileNames, final IProgressMonitor monitor) throws CVSException { 713 714 final List exceptions = new ArrayList (); 716 IStatusListener listener = new IStatusListener() { 717 public void fileStatus(ICVSFolder root, String path, String remoteRevision) { 718 try { 719 updateRevision(path, remoteRevision); 720 monitor.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_receivingRevision, new String [] { Util.toTruncatedPath(path, 3) })); 721 } catch (CVSException e) { 722 exceptions.add(e); 723 } 724 } 725 }; 726 727 IStatus status = Command.STATUS.execute(session, 729 Command.NO_GLOBAL_OPTIONS, 730 Command.NO_LOCAL_OPTIONS, 731 fileNames, 732 new StatusListener(listener), 733 monitor); 734 if (status.getCode() == CVSStatus.SERVER_ERROR) { 735 throw new CVSServerException(status); 736 } 737 738 if ( ! exceptions.isEmpty()) { 740 if (exceptions.size() == 1) { 741 throw (CVSException)exceptions.get(0); 742 } else { 743 MultiStatus multi = new MultiStatus(CVSProviderPlugin.ID, 0, CVSMessages.RemoteFolder_errorFetchingRevisions, null); 744 for (int i = 0; i < exceptions.size(); i++) { 745 multi.merge(((CVSException)exceptions.get(i)).getStatus()); 746 } 747 throw new CVSException(multi); 748 } 749 } 750 } 751 752 protected boolean isPruneEmptyDirectories() { 753 return false; 754 } 755 763 private void recordDelta(String path, String revision, int syncState) { 764 if (revision == FOLDER) { 765 newFolderExist = true; 766 } 767 String parent = Util.removeLastSegment(path); 768 Map deltas = (Map )fileDeltas.get(parent); 769 if (deltas == null) { 770 deltas = new HashMap (); 771 fileDeltas.put(parent, deltas); 772 } 773 String name = Util.getLastSegment(path); 774 deltas.put(name, new DeltaNode(name, revision, syncState)); 775 } 776 777 private void updateRevision(String path, String revision) throws CVSException { 778 RemoteFolderTree folder = getRecoredRemoteFolder(Util.removeLastSegment(path)); 779 if (folder == null) { 780 IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSMessages.RemoteFolderTreeBuilder_missingParent, new String [] { path.toString(), revision }), root); 781 throw new CVSException(status); 782 } 783 ((RemoteFile)folder.getFile(Util.getLastSegment(path))).setRevision(revision); 784 } 785 786 797 private CVSTag tagForRemoteFolder(ICVSFolder folder, CVSTag tag) throws CVSException { 798 return tag == null ? folder.getFolderSyncInfo().getTag() : tag; 799 } 800 801 private boolean isOrphanedSubtree(ICVSFolder mFolder) throws CVSException { 802 return mFolder.isCVSFolder() && ! mFolder.isManaged() && ! mFolder.equals(root) && mFolder.getParent().isCVSFolder(); 803 } 804 805 private void recordRemoteFolder(RemoteFolderTree remote) throws CVSException { 806 String path = remote.getFolderSyncInfo().getRemoteLocation(); 807 remoteFolderTable.put(Util.asPath(path), remote); 808 } 809 810 private RemoteFolderTree getRecoredRemoteFolder(String path) { 811 return (RemoteFolderTree)remoteFolderTable.get(Util.asPath(path)); 812 } 813 814 819 public String [] getFileDiffs() { 820 return (String []) changedFiles.toArray(new String [changedFiles.size()]); 821 } 822 } 823 | Popular Tags |