1 11 package org.eclipse.team.internal.ccvs.ui.operations; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashSet ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.compare.CompareUI; 20 import org.eclipse.core.runtime.*; 21 import org.eclipse.osgi.util.NLS; 22 import org.eclipse.swt.widgets.Display; 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.client.listeners.RDiffSummaryListener; 28 import org.eclipse.team.internal.ccvs.core.resources.*; 29 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 30 import org.eclipse.team.internal.ccvs.ui.*; 31 import org.eclipse.team.internal.ccvs.ui.Policy; 32 import org.eclipse.team.internal.ui.TeamUIPlugin; 33 import org.eclipse.ui.IWorkbenchPage; 34 import org.eclipse.ui.IWorkbenchPart; 35 36 39 public class RemoteCompareOperation extends RemoteOperation { 40 41 private CompareTreeBuilder builder; 42 private CVSTag left, right; 43 44 47 public static class CompareTreeBuilder implements RDiffSummaryListener.IFileDiffListener { 48 private ICVSRepositoryLocation location; 49 private RemoteFolderTree leftTree, rightTree; 50 private CVSTag left, right; 51 52 public CompareTreeBuilder(ICVSRepositoryLocation location, CVSTag left, CVSTag right) { 53 this.left = left; 54 this.right = right; 55 this.location = location; 56 reset(); 57 } 58 59 public RemoteFolderTree getLeftTree() { 60 return leftTree; 61 } 62 public RemoteFolderTree getRightTree() { 63 return rightTree; 64 } 65 66 69 public void reset() { 70 leftTree = new RemoteFolderTree(null, location, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, left); 71 leftTree.setChildren(new ICVSRemoteResource[0]); 72 rightTree = new RemoteFolderTree(null, location, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, right); 73 rightTree.setChildren(new ICVSRemoteResource[0]); 74 } 75 76 80 public void cacheContents(IProgressMonitor monitor) throws CVSException { 81 String [] overlappingFilePaths = getOverlappingFilePaths(); 82 if (overlappingFilePaths.length > 0) { 83 monitor.beginTask(null, 100); 84 fetchFileContents(leftTree, overlappingFilePaths, Policy.subMonitorFor(monitor, 50)); 85 fetchFileContents(rightTree, overlappingFilePaths, Policy.subMonitorFor(monitor, 50)); 86 monitor.done(); 87 } 88 } 89 90 93 public void openCompareEditor(final IWorkbenchPage page, final String title, final String toolTip) { 94 if (leftTree == null || rightTree == null) return; 95 Display.getDefault().asyncExec(new Runnable () { 96 public void run() { 97 CompareUI.openCompareEditorOnPage( 98 new CVSCompareEditorInput(title, toolTip, new ResourceEditionNode(leftTree), new ResourceEditionNode(rightTree)), page); 99 } 100 }); 101 } 102 103 108 public void addToTrees(ICVSRemoteFile predecessor, ICVSRemoteFile remote) { 109 if (remote != null) { 110 try { 111 Path filePath = new Path(null, remote.getRepositoryRelativePath()); 112 addFile(rightTree, right, filePath, remote.getRevision()); 113 getFolder(leftTree, left, filePath.removeLastSegments(1), Path.EMPTY); 114 } catch (TeamException e) { 115 CVSUIPlugin.log(e); 116 } 117 } 118 if (predecessor != null) { 119 try { 120 Path filePath = new Path(null, predecessor.getRepositoryRelativePath()); 121 addFile(leftTree, left, filePath, predecessor.getRevision()); 122 getFolder(rightTree, right, filePath.removeLastSegments(1), Path.EMPTY); 123 } catch (TeamException e) { 124 CVSUIPlugin.log(e); 125 } 126 } 127 } 128 129 private void addFile(RemoteFolderTree tree, CVSTag tag, Path filePath, String revision) throws CVSException { 130 RemoteFolderTree parent = (RemoteFolderTree)getFolder(tree, tag, filePath.removeLastSegments(1), Path.EMPTY); 131 String name = filePath.lastSegment(); 132 ICVSRemoteFile file = new RemoteFile(parent, 0, name, revision, null, getTag(revision, tag)); 133 addChild(parent, file); 134 } 135 136 private CVSTag getTag(String revision, CVSTag tag) { 137 if (tag == null) { 138 tag = new CVSTag(revision, CVSTag.VERSION); 139 } 140 return tag; 141 } 142 143 146 private ICVSRemoteFolder getFolder(RemoteFolderTree tree, CVSTag tag, IPath remoteFolderPath, IPath parentPath) throws CVSException { 147 if (remoteFolderPath.segmentCount() == 0) return tree; 148 String name = remoteFolderPath.segment(0); 149 ICVSResource child; 150 IPath childPath = parentPath.append(name); 151 if (tree.childExists(name)) { 152 child = tree.getChild(name); 153 } else { 154 child = new RemoteFolderTree(tree, tree.getRepository(), childPath.toString(), tag); 155 ((RemoteFolderTree)child).setChildren(new ICVSRemoteResource[0]); 156 addChild(tree, (ICVSRemoteResource)child); 157 } 158 return getFolder((RemoteFolderTree)child, tag, remoteFolderPath.removeFirstSegments(1), childPath); 159 } 160 161 private void addChild(RemoteFolderTree tree, ICVSRemoteResource resource) { 162 ICVSRemoteResource[] children = tree.getChildren(); 163 ICVSRemoteResource[] newChildren; 164 if (children == null) { 165 newChildren = new ICVSRemoteResource[] { resource }; 166 } else { 167 newChildren = new ICVSRemoteResource[children.length + 1]; 168 System.arraycopy(children, 0, newChildren, 0, children.length); 169 newChildren[children.length] = resource; 170 } 171 tree.setChildren(newChildren); 172 } 173 174 177 public void fileDiff(String remoteFilePath, String leftRevision, String rightRevision) { 178 try { 179 addFile(rightTree, right, new Path(null, remoteFilePath), rightRevision); 180 } catch (CVSException e) { 181 CVSUIPlugin.log(e); 182 } 183 try { 184 addFile(leftTree, left, new Path(null, remoteFilePath), leftRevision); 185 } catch (CVSException e) { 186 CVSUIPlugin.log(e); 187 } 188 } 189 190 193 public void newFile(String remoteFilePath, String rightRevision) { 194 try { 195 addFile(rightTree, right, new Path(null, remoteFilePath), rightRevision); 196 } catch (CVSException e) { 197 CVSUIPlugin.log(e); 198 } 199 } 200 201 204 public void deletedFile(String remoteFilePath, String leftRevision) { 205 try { 207 addFile(leftTree, left, new Path(null, remoteFilePath), leftRevision); 208 } catch (CVSException e) { 209 CVSUIPlugin.log(e); 210 } 211 } 212 213 216 public void directory(String remoteFolderPath) { 217 try { 218 getFolder(leftTree, left, new Path(null, remoteFolderPath), Path.EMPTY); 219 } catch (CVSException e) { 220 CVSUIPlugin.log(e); 221 } 222 try { 223 getFolder(rightTree, right, new Path(null, remoteFolderPath), Path.EMPTY); 224 } catch (CVSException e) { 225 CVSUIPlugin.log(e); 226 } 227 } 228 229 private String [] getOverlappingFilePaths() { 230 String [] leftFiles = getFilePaths(leftTree); 231 String [] rightFiles = getFilePaths(rightTree); 232 Set set = new HashSet (); 233 for (int i = 0; i < rightFiles.length; i++) { 234 String rightFile = rightFiles[i]; 235 for (int j = 0; j < leftFiles.length; j++) { 236 String leftFile = leftFiles[j]; 237 if (leftFile.equals(rightFile)) { 238 set.add(leftFile); 239 } 240 } 241 } 242 return (String []) set.toArray(new String [set.size()]); 243 } 244 245 private void fetchFileContents(RemoteFolderTree tree, String [] overlappingFilePaths, IProgressMonitor monitor) throws CVSException { 246 FileContentCachingService.fetchFileContents(tree, overlappingFilePaths, monitor); 247 } 248 249 private String [] getFilePaths(RemoteFolderTree tree) { 250 ICVSRemoteResource[] children = tree.getChildren(); 251 List result = new ArrayList (); 252 for (int i = 0; i < children.length; i++) { 253 ICVSRemoteResource resource = children[i]; 254 if (resource.isContainer()) { 255 result.addAll(Arrays.asList(getFilePaths((RemoteFolderTree)resource))); 256 } else { 257 result.add(resource.getRepositoryRelativePath()); 258 } 259 } 260 return (String []) result.toArray(new String [result.size()]); 261 } 262 } 263 264 public static CVSTag getTag(ICVSRemoteResource resource) throws CVSException { 265 CVSTag tag = null; 266 try { 267 if (resource.isContainer()) { 268 tag = ((ICVSRemoteFolder)resource).getTag(); 269 } else { 270 ICVSRemoteFile file = (ICVSRemoteFile)resource; 271 String revision = file.getRevision(); 272 if (revision.equals(ResourceSyncInfo.ADDED_REVISION)) { 273 ResourceSyncInfo info =file.getSyncInfo(); 274 if (info != null) tag = info.getTag(); 275 } else { 276 tag = new CVSTag(revision, CVSTag.VERSION); 277 } 278 } 279 } catch (TeamException e) { 280 throw CVSException.wrapException(e); 281 } 282 if (tag == null) tag = CVSTag.DEFAULT; 283 return tag; 284 } 285 286 public static RemoteCompareOperation create(IWorkbenchPart part, ICVSRemoteResource remoteResource, CVSTag tag) throws CVSException { 287 CVSTag tag0 = getTag(remoteResource); 288 CVSTag tag1 = tag; 289 if (tag0.getType() == CVSTag.DATE && tag1.getType() == CVSTag.DATE) { 290 if (tag0.asDate().after(tag1.asDate())) { 291 tag = tag0; 292 remoteResource = remoteResource.forTag(tag1); 293 } 294 } 295 return new RemoteCompareOperation(part, remoteResource, tag); 296 } 297 298 305 protected RemoteCompareOperation(IWorkbenchPart part, ICVSRemoteResource remoteResource, CVSTag tag) { 306 super(part, new ICVSRemoteResource[] {remoteResource}); 307 Assert.isNotNull(tag); 308 this.right = tag; 309 try { 310 this.left = getTag(remoteResource); 311 } catch (CVSException e) { 312 CVSProviderPlugin.log(e); 314 } 315 if (this.left == null) { 316 this.left = CVSTag.DEFAULT; 317 } 318 builder = new CompareTreeBuilder(remoteResource.getRepository(), left, right); 319 } 320 321 324 private ICVSRemoteResource getRemoteResource() { 325 return getRemoteResources()[0]; 326 } 327 328 331 protected void execute(IProgressMonitor monitor) throws CVSException { 332 boolean fetchContents = CVSUIPlugin.getPlugin().getPluginPreferences().getBoolean(ICVSUIConstants.PREF_CONSIDER_CONTENTS); 333 monitor.beginTask(getTaskName(), 50 + (fetchContents ? 100 : 0)); 334 try { 335 ICVSRemoteResource resource = getRemoteResource(); 336 IStatus status = buildTrees(resource, Policy.subMonitorFor(monitor, 50)); 337 if (status.isOK() && fetchContents) { 338 builder.cacheContents(Policy.subMonitorFor(monitor, 100)); 339 } 340 collectStatus(status); 341 openCompareEditor(builder); 342 } finally { 343 monitor.done(); 344 } 345 } 346 347 350 protected void openCompareEditor(CompareTreeBuilder builder) { 351 builder.openCompareEditor(getTargetPage(), null, null); 352 } 353 354 357 private IStatus buildTrees(ICVSRemoteResource resource, IProgressMonitor monitor) throws CVSException { 358 builder.reset(); 360 Command.QuietOption oldOption= CVSProviderPlugin.getPlugin().getQuietness(); 361 Session session = new Session(resource.getRepository(), builder.getLeftTree(), false); 362 try { 363 monitor.beginTask(getTaskName(), 100); 364 CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE); 365 session.open(Policy.subMonitorFor(monitor, 10)); 366 IStatus status = Command.RDIFF.execute(session, 367 Command.NO_GLOBAL_OPTIONS, 368 getLocalOptions(), 369 new ICVSResource[] { resource }, 370 new RDiffSummaryListener(builder), 371 Policy.subMonitorFor(monitor, 90)); 372 return status; 373 } finally { 374 try { 375 session.close(); 376 } finally { 377 CVSProviderPlugin.getPlugin().setQuietness(oldOption); 378 } 379 monitor.done(); 380 } 381 } 382 383 private LocalOption[] getLocalOptions() { 384 return new LocalOption[] {RDiff.SUMMARY, RDiff.makeTagOption(left), RDiff.makeTagOption(right)}; 385 } 386 387 390 protected String getTaskName() { 391 return NLS.bind(CVSUIMessages.RemoteCompareOperation_0, (new Object [] {left.getName(), right.getName(), getRemoteResource().getRepositoryRelativePath()})); 392 } 393 394 protected IWorkbenchPage getTargetPage() { 395 return TeamUIPlugin.getActivePage(); 396 } 397 } 398 | Popular Tags |