1 11 package org.eclipse.team.internal.ccvs.ui.mappings; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.resources.mapping.*; 19 import org.eclipse.core.runtime.*; 20 import org.eclipse.osgi.util.NLS; 21 import org.eclipse.team.core.RepositoryProvider; 22 import org.eclipse.team.core.diff.IDiff; 23 import org.eclipse.team.core.diff.IThreeWayDiff; 24 import org.eclipse.team.core.diff.provider.DiffTree; 25 import org.eclipse.team.core.history.IFileRevision; 26 import org.eclipse.team.core.mapping.*; 27 import org.eclipse.team.core.mapping.provider.ResourceDiffTree; 28 import org.eclipse.team.core.subscribers.Subscriber; 29 import org.eclipse.team.core.subscribers.SubscriberScopeManager; 30 import org.eclipse.team.core.synchronize.SyncInfo; 31 import org.eclipse.team.core.synchronize.SyncInfoFilter; 32 import org.eclipse.team.core.synchronize.SyncInfoFilter.ContentComparisonSyncInfoFilter; 33 import org.eclipse.team.core.variants.IResourceVariant; 34 import org.eclipse.team.internal.ccvs.core.*; 35 import org.eclipse.team.internal.ccvs.core.client.PruneFolderVisitor; 36 import org.eclipse.team.internal.ccvs.core.mapping.CVSActiveChangeSetCollector; 37 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 38 import org.eclipse.team.internal.ccvs.core.resources.RemoteFile; 39 import org.eclipse.team.internal.ccvs.ui.*; 40 import org.eclipse.team.internal.ccvs.ui.Policy; 41 import org.eclipse.team.internal.ccvs.ui.operations.*; 42 import org.eclipse.team.internal.core.mapping.GroupProgressMonitor; 43 import org.eclipse.team.internal.core.subscribers.SubscriberDiffTreeEventHandler; 44 45 public class WorkspaceSubscriberContext extends CVSSubscriberMergeContext { 46 47 public static final class ChangeSetSubscriberScopeManager extends SubscriberScopeManager { 48 private final boolean consultSets; 49 50 private ChangeSetSubscriberScopeManager(String name, ResourceMapping[] mappings, Subscriber subscriber, boolean consultModels, boolean consultSets) { 51 super(name, mappings, subscriber, consultModels); 52 this.consultSets = consultSets; 53 } 54 55 protected ResourceTraversal[] adjustInputTraversals(ResourceTraversal[] traversals) { 56 if (isConsultSets()) 57 return ((CVSActiveChangeSetCollector)CVSUIPlugin.getPlugin().getChangeSetManager()).adjustInputTraversals(traversals); 58 return super.adjustInputTraversals(traversals); 59 } 60 61 public boolean isConsultSets() { 62 return consultSets; 63 } 64 } 65 66 private final int type; 67 68 public static SubscriberScopeManager createWorkspaceScopeManager(ResourceMapping[] mappings, boolean consultModels, final boolean consultChangeSets) { 69 return new ChangeSetSubscriberScopeManager(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().getName(), mappings, CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(), consultModels, consultChangeSets); 70 } 71 72 public static SubscriberScopeManager createUpdateScopeManager(ResourceMapping[] mappings, boolean consultModels) { 73 return new SubscriberScopeManager(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().getName(), mappings, CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(), consultModels); 74 } 75 76 public static WorkspaceSubscriberContext createContext(ISynchronizationScopeManager manager, int type) { 77 CVSWorkspaceSubscriber subscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); 78 WorkspaceSubscriberContext mergeContext = new WorkspaceSubscriberContext(subscriber, manager, type); 79 mergeContext.initialize(); 80 return mergeContext; 81 } 82 83 protected WorkspaceSubscriberContext(CVSWorkspaceSubscriber subscriber, ISynchronizationScopeManager manager, int type) { 84 super(subscriber, manager); 85 this.type = type; 86 } 87 88 public void markAsMerged(IDiff[] nodes, boolean inSyncHint, IProgressMonitor monitor) throws CoreException { 89 if (getType() == TWO_WAY) { 90 DiffTree tree = ((DiffTree)getDiffTree()); 94 try { 95 tree.beginInput(); 96 for (int i = 0; i < nodes.length; i++) { 97 IDiff diff = nodes[i]; 98 tree.remove(diff.getPath()); 99 } 100 } finally { 101 tree.endInput(monitor); 102 } 103 } else { 104 super.markAsMerged(nodes, inSyncHint, monitor); 105 } 106 } 107 108 public void markAsMerged(final IDiff diff, final boolean inSyncHint, IProgressMonitor monitor) throws CoreException { 109 run(new IWorkspaceRunnable() { 110 public void run(IProgressMonitor monitor) throws CoreException { 111 IResource resource = getDiffTree().getResource(diff); 115 if (resource.getType() != IResource.FILE) { 116 if (diff instanceof IThreeWayDiff) { 117 IThreeWayDiff twd = (IThreeWayDiff) diff; 118 if (resource.getType() == IResource.FOLDER 119 && twd.getKind() == IDiff.ADD 120 && twd.getDirection() == IThreeWayDiff.INCOMING 121 && resource.exists()) { 122 SyncInfo info = getSyncInfo(resource); 124 if (info instanceof CVSSyncInfo) { 125 CVSSyncInfo cvsInfo = (CVSSyncInfo) info; 126 cvsInfo.makeInSync(); 127 } 128 } 129 } 130 return; 131 } 132 if (getType() == TWO_WAY) { 133 ((DiffTree)getDiffTree()).remove(diff.getPath()); 137 } else { 138 SyncInfo info = getSyncInfo(resource); 139 ensureRemotesMatch(resource, diff, info); 140 if (info instanceof CVSSyncInfo) { 141 CVSSyncInfo cvsInfo = (CVSSyncInfo) info; 142 monitor.beginTask(null, 50 + (inSyncHint ? 100 : 0)); 143 cvsInfo.makeOutgoing(Policy.subMonitorFor(monitor, 50)); 144 if (inSyncHint) { 145 ContentComparisonSyncInfoFilter comparator = new SyncInfoFilter.ContentComparisonSyncInfoFilter(false); 148 if (resource.getType() == IResource.FILE && info.getRemote() != null) { 149 if (comparator.compareContents((IFile)resource, info.getRemote(), Policy.subMonitorFor(monitor, 100))) { 150 ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)resource); 151 cvsFile.checkedIn(null, false ); 152 } 153 } 154 } 155 monitor.done(); 156 } 157 } 158 } 159 }, getMergeRule(diff), IResource.NONE, monitor); 160 } 161 162 protected void makeInSync(final IDiff diff, IProgressMonitor monitor) throws CoreException { 163 run(new IWorkspaceRunnable() { 164 public void run(IProgressMonitor monitor) throws CoreException { 165 IResource resource = getDiffTree().getResource(diff); 169 if (resource.getType() != IResource.FILE) 170 return; 171 SyncInfo info = getSyncInfo(resource); 172 ensureRemotesMatch(resource, diff, info); 173 IResourceVariant remote = info.getRemote(); 174 RemoteFile file = (RemoteFile)remote; 175 if (file != null) 176 remote = file.getCachedHandle(); 177 178 if (info instanceof CVSSyncInfo) { 179 CVSSyncInfo cvsInfo = (CVSSyncInfo) info; 180 cvsInfo.makeOutgoing(monitor); 181 if (resource.getType() == IResource.FILE && info.getRemote() != null) { 182 ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)resource); 183 if (remote != null && remote instanceof RemoteFile){ 184 cvsFile.setExecutable(((RemoteFile)remote).isExecutable()); 185 cvsFile.setTimeStamp(((RemoteFile) remote).getTimeStamp()); 186 cvsFile.setReadOnly(getReadOnly(cvsFile)); 187 } 188 cvsFile.checkedIn(null , false ); 189 } 190 } 191 } 192 }, getMergeRule(diff), IResource.NONE, monitor); 193 } 194 195 protected boolean getReadOnly(ICVSFile cvsFile) { 196 IResource resource = cvsFile.getIResource(); 197 RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject()); 198 if (provider instanceof CVSTeamProvider) { 199 CVSTeamProvider ctp = (CVSTeamProvider) provider; 200 try { 201 return ctp.isWatchEditEnabled(); 202 } catch (CVSException e) { 203 CVSUIPlugin.log(e); 204 } 205 } 206 return false; 207 } 208 209 protected void ensureRemotesMatch(IResource resource, IDiff node, SyncInfo info) throws CVSException { 210 IResourceVariant variant = info.getRemote(); 211 IFileRevision remote = getRemote(node); 212 if (variant != null && remote != null && remote instanceof IFileRevision) { 213 String ci1 = variant.getContentIdentifier(); 214 String ci2 = ((IFileRevision)remote).getContentIdentifier(); 215 if (!ci1.equals(ci2)) { 216 throw new CVSException(NLS.bind(CVSUIMessages.WorkspaceSubscriberContext_0, resource.getFullPath().toString())); 217 } 218 } 219 } 220 221 private IFileRevision getRemote(IDiff node) { 222 if (node == null) return null; 223 if (node instanceof IThreeWayDiff) { 224 IThreeWayDiff twd = (IThreeWayDiff) node; 225 return getRemote(twd.getRemoteChange()); 226 } 227 if (node instanceof IResourceDiff) { 228 IResourceDiff rd = (IResourceDiff) node; 229 return rd.getAfterState(); 230 } 231 return null; 232 } 233 234 237 public IStatus merge(IDiff delta, boolean force, IProgressMonitor monitor) throws CoreException { 238 if (getMergeType() == ISynchronizationContext.TWO_WAY) { 239 force = true; 240 } 241 IThreeWayDiff currentDiff = (IThreeWayDiff)getSubscriber().getDiff(getDiffTree().getResource(delta)); 244 if (currentDiff == null 245 || currentDiff.getKind() == IDiff.NO_CHANGE 246 || (currentDiff.getDirection() == IThreeWayDiff.OUTGOING && !force)) { 247 return Status.OK_STATUS; 249 } 250 if (!equals(currentDiff, (IThreeWayDiff)delta)) { 251 throw new CVSException(NLS.bind(CVSUIMessages.CVSMergeContext_1, delta.getPath())); 252 } 253 try { 254 monitor.beginTask(null, 100); 255 IStatus status = super.merge(delta, force, Policy.subMonitorFor(monitor, 99)); 256 if (status.isOK()) { 257 IResource resource = getDiffTree().getResource(delta); 258 if (resource.getType() == IResource.FILE && !resource.exists()) { 259 ICVSResource localResource = CVSWorkspaceRoot.getCVSResourceFor(resource); 260 localResource.unmanage(Policy.subMonitorFor(monitor, 1)); 261 } 262 pruneEmptyParents(new IDiff[] { delta }); 263 } 264 return status; 265 } finally { 266 monitor.done(); 267 } 268 } 269 270 private boolean equals(IThreeWayDiff currentDiff, IThreeWayDiff otherDiff) { 271 return currentDiff.getKind() == otherDiff.getKind() 272 && currentDiff.getDirection() == otherDiff.getDirection(); 273 } 274 275 private void pruneEmptyParents(IDiff[] deltas) throws CVSException { 276 if (!CVSProviderPlugin.getPlugin().getPruneEmptyDirectories()) return; 279 ICVSResource[] cvsResources = new ICVSResource[deltas.length]; 280 for (int i = 0; i < cvsResources.length; i++) { 281 cvsResources[i] = CVSWorkspaceRoot.getCVSResourceFor(getDiffTree().getResource(deltas[i])); 282 } 283 new PruneFolderVisitor().visit( 284 CVSWorkspaceRoot.getCVSFolderFor(ResourcesPlugin.getWorkspace().getRoot()), 285 cvsResources); 286 } 287 288 291 public int getMergeType() { 292 return type; 293 } 294 295 298 public void refresh(final ResourceTraversal[] traversals, int flags, IProgressMonitor monitor) throws CoreException { 299 SubscriberDiffTreeEventHandler handler = getHandler(); 300 if (handler != null) { 301 GroupProgressMonitor group = getGroup(monitor); 302 if (group != null) 303 handler.setProgressGroupHint(group.getGroup(), group.getTicks()); 304 handler.initializeIfNeeded(); 305 ((CVSWorkspaceSubscriber)getSubscriber()).refreshWithContentFetch(traversals, monitor); 306 runInBackground(new IWorkspaceRunnable() { 307 public void run(IProgressMonitor monitor) throws CoreException { 308 cacheContents(traversals, getDiffTree(), true, monitor); 309 } 310 }); 311 } else { 312 super.refresh(traversals, flags, monitor); 313 runInBackground(new IWorkspaceRunnable() { 314 public void run(IProgressMonitor monitor) throws CoreException { 315 cacheContents(traversals, getDiffTree(), false, monitor); 316 } 317 }); 318 } 319 } 320 321 private SubscriberDiffTreeEventHandler getHandler() { 322 Object o = getAdapter(SubscriberDiffTreeEventHandler.class); 323 if (o instanceof SubscriberDiffTreeEventHandler) { 324 return (SubscriberDiffTreeEventHandler) o; 325 } 326 return null; 327 } 328 329 private GroupProgressMonitor getGroup(IProgressMonitor monitor) { 330 if (monitor instanceof GroupProgressMonitor) { 331 return (GroupProgressMonitor) monitor; 332 } 333 if (monitor instanceof ProgressMonitorWrapper) { 334 ProgressMonitorWrapper wrapper = (ProgressMonitorWrapper) monitor; 335 return getGroup(wrapper.getWrappedProgressMonitor()); 336 } 337 return null; 338 } 339 340 protected void cacheContents(final ResourceTraversal[] traversals, IResourceDiffTree tree, boolean baseOnly, IProgressMonitor monitor) throws CVSException { 341 ResourceMapping[] mappings = new ResourceMapping[] { new ResourceMapping() { 346 public Object getModelObject() { 347 return WorkspaceSubscriberContext.this; 348 } 349 public IProject[] getProjects() { 350 return ResourcesPlugin.getWorkspace().getRoot().getProjects(); 351 } 352 public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { 353 return traversals; 354 } 355 public boolean contains(ResourceMapping mapping) { 356 return false; 357 } 358 public String getModelProviderId() { 359 return ModelProvider.RESOURCE_MODEL_PROVIDER_ID; 360 } 361 }}; 362 try { 363 monitor.beginTask(null, 50); 364 new CacheBaseContentsOperation(null, mappings, tree, true).run(Policy.subMonitorFor(monitor, 25)); 365 if (!baseOnly) { 366 new CacheRemoteContentsOperation(null, mappings, tree).run(Policy.subMonitorFor(monitor, 25)); 367 } 368 } catch (InvocationTargetException e) { 369 throw CVSException.wrapException(e); 370 } catch (InterruptedException e) { 371 } finally { 373 monitor.done(); 374 } 375 } 376 377 public IStatus merge(IDiff[] deltas, boolean force, IProgressMonitor monitor) throws CoreException { 378 try { 379 if (deltas.length == 0) 380 return Status.OK_STATUS; 381 String taskName = getMergeTaskName(deltas, force); 382 monitor.beginTask(taskName, 100); 383 monitor.setTaskName(taskName); 384 cacheContents(getTraversals(deltas), getDiffTree(deltas), false, Policy.subMonitorFor(monitor, 30)); 385 return super.merge(deltas, force, Policy.subMonitorFor(monitor, 70)); 386 } finally { 387 monitor.done(); 388 } 389 } 390 391 private String getMergeTaskName(IDiff[] deltas, boolean force) { 392 if (force) { 393 if (deltas.length == 1) { 394 return NLS.bind(CVSUIMessages.WorkspaceSubscriberContext_1, getDiffTree().getResource(deltas[0]).getFullPath()); 395 } 396 return NLS.bind(CVSUIMessages.WorkspaceSubscriberContext_2, new Integer (deltas.length)); 397 } 398 if (deltas.length == 1) { 399 return NLS.bind(CVSUIMessages.WorkspaceSubscriberContext_3, getDiffTree().getResource(deltas[0]).getFullPath()); 400 } 401 return NLS.bind(CVSUIMessages.WorkspaceSubscriberContext_4, new Integer (deltas.length)); 402 } 403 404 private ResourceTraversal[] getTraversals(IDiff[] deltas) { 405 List result = new ArrayList (); 406 for (int i = 0; i < deltas.length; i++) { 407 IDiff diff = deltas[i]; 408 IResource resource = ResourceDiffTree.getResourceFor(diff); 409 if (resource != null) { 410 result.add(resource); 411 } 412 } 413 return new ResourceTraversal[] { 414 new ResourceTraversal((IResource[]) result.toArray(new IResource[result.size()]), IResource.DEPTH_ZERO, IResource.NONE) 415 }; 416 } 417 418 private IResourceDiffTree getDiffTree(IDiff[] deltas) { 419 ResourceDiffTree tree = new ResourceDiffTree(); 420 for (int i = 0; i < deltas.length; i++) { 421 IDiff diff = deltas[i]; 422 tree.add(diff); 423 } 424 return tree; 425 } 426 427 protected void performReplace(IDiff diff, IProgressMonitor monitor) throws CoreException { 428 IResource resource = ResourceDiffTree.getResourceFor(diff); 429 if (resource.getType() == IResource.FILE){ 430 IFile file = (IFile) resource; 431 ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor(file); 432 try { 433 if (mFile.isReadOnly()) mFile.setReadOnly(false); 435 } catch (CVSException e) { 436 CVSProviderPlugin.log(e); 438 } 439 } 440 super.performReplace(diff, monitor); 441 442 } 443 } | Popular Tags |