1 11 package org.eclipse.team.internal.ui.mapping; 12 13 import java.util.*; 14 15 import org.eclipse.core.resources.*; 16 import org.eclipse.core.resources.mapping.*; 17 import org.eclipse.core.runtime.IPath; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.jface.util.PropertyChangeEvent; 20 import org.eclipse.jface.viewers.*; 21 import org.eclipse.swt.widgets.Tree; 22 import org.eclipse.swt.widgets.TreeItem; 23 import org.eclipse.team.core.diff.*; 24 import org.eclipse.team.core.mapping.*; 25 import org.eclipse.team.core.mapping.provider.ResourceDiffTree; 26 import org.eclipse.team.internal.ui.*; 27 import org.eclipse.team.ui.mapping.ITeamContentProviderManager; 28 import org.eclipse.team.ui.mapping.SynchronizationContentProvider; 29 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; 30 import org.eclipse.ui.model.WorkbenchContentProvider; 31 import org.eclipse.ui.navigator.ICommonContentExtensionSite; 32 33 44 public class ResourceModelContentProvider extends SynchronizationContentProvider implements ITreePathContentProvider { 45 46 private WorkbenchContentProvider provider; 47 48 51 protected ITreeContentProvider getDelegateContentProvider() { 52 if (provider == null) 53 provider = new WorkbenchContentProvider(); 54 return provider; 55 } 56 57 60 protected String getModelProviderId() { 61 return ModelProvider.RESOURCE_MODEL_PROVIDER_ID; 62 } 63 64 67 protected Object getModelRoot() { 68 return ResourcesPlugin.getWorkspace().getRoot(); 69 } 70 71 74 protected boolean isInScope(ISynchronizationScope scope, Object parent, Object elementOrPath) { 75 Object object = internalGetElement(elementOrPath); 76 if (object instanceof IResource) { 77 IResource resource = (IResource) object; 78 if (resource == null) 79 return false; 80 if (!resource.getProject().isAccessible()) 81 return false; 82 if (scope.contains(resource)) 83 return true; 84 if (hasChildrenInScope(scope, object, resource)) { 85 return true; 86 } 87 } 88 return false; 89 } 90 91 private boolean hasChildrenInScope(ISynchronizationScope scope, Object object, IResource resource) { 92 if (!resource.isAccessible()) 93 return false; 94 IResource[] roots = scope.getRoots(); 95 for (int i = 0; i < roots.length; i++) { 96 IResource root = roots[i]; 97 if (resource.getFullPath().isPrefixOf(root.getFullPath())) 98 return true; 99 } 100 return false; 101 } 102 103 106 public void init(ICommonContentExtensionSite site) { 107 super.init(site); 108 TeamUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(this); 109 } 110 111 114 public void dispose() { 115 provider.dispose(); 116 super.dispose(); 117 TeamUIPlugin.getPlugin().getPreferenceStore().removePropertyChangeListener(this); 118 } 119 120 public void propertyChange(PropertyChangeEvent event) { 121 if (event.getProperty().equals(IPreferenceIds.SYNCVIEW_DEFAULT_LAYOUT)) { 122 refresh(); 123 } 124 super.propertyChange(event); 125 } 126 127 130 protected Object [] getChildrenInContext(ISynchronizationContext context, Object parentOrPath, Object [] children) { 131 Object parent = internalGetElement(parentOrPath); 132 if (parent instanceof IResource) { 133 IResource resource = (IResource) parent; 134 if (resource.getType() == IResource.PROJECT && !resource.getProject().isAccessible()) 135 return new Object [0]; 136 IResourceDiffTree diffTree = context.getDiffTree(); 137 children = getTraversalCalculator().filterChildren(diffTree, resource, parentOrPath, children); 139 if (children.length != 0) 140 children = getChildrenInScope(context.getScope(), parentOrPath, children); 141 if (children.length != 0) 142 children = internalGetChildren(context, parentOrPath, children); 143 return children; 144 } 145 return super.getChildrenInContext(context, parentOrPath, children); 146 } 147 148 private Object [] internalGetChildren(ISynchronizationContext context, Object parent, Object [] children) { 149 List result = new ArrayList(children.length); 150 for (int i = 0; i < children.length; i++) { 151 Object object = children[i]; 152 if (parent instanceof TreePath) { 156 TreePath tp = (TreePath) parent; 157 object = tp.createChildPath(object); 158 } 159 if (isVisible(context, object)) 160 result.add(internalGetElement(object)); 161 } 162 return result.toArray(new Object [result.size()]); 163 } 164 165 protected ResourceTraversal[] getTraversals(ISynchronizationContext context, Object elementOrPath) { 166 Object object = internalGetElement(elementOrPath); 167 ISynchronizationScope scope = context.getScope(); 168 ResourceMapping mapping = scope.getMapping(object); 170 if (mapping != null) { 171 ResourceTraversal[] traversals = scope.getTraversals(mapping); 172 if (traversals == null) 173 return new ResourceTraversal[0]; 174 return traversals; 175 } 176 if (object instanceof IResource) { 178 IResource resource = (IResource) object; 179 if (scope.contains(resource)) { 180 List result = new ArrayList(); 181 ResourceTraversal[] traversals = scope.getTraversals(); 182 for (int i = 0; i < traversals.length; i++) { 183 ResourceTraversal traversal = traversals[i]; 184 if (traversal.contains(resource)) { 185 boolean include = false; 186 int depth = traversal.getDepth(); 187 if (depth == IResource.DEPTH_INFINITE) { 188 include = true; 189 } else { 190 IResource[] roots = traversal.getResources(); 191 for (int j = 0; j < roots.length; j++) { 192 IResource root = roots[j]; 193 if (root.equals(resource)) { 194 include = true; 195 break; 196 } 197 if (root.getFullPath().equals(resource.getFullPath().removeLastSegments(1)) && depth == IResource.DEPTH_ONE) { 198 include = true; 199 depth = IResource.DEPTH_ZERO; 200 break; 201 } 202 } 203 } 204 if (include) { 205 int layoutDepth = getTraversalCalculator().getLayoutDepth(resource, internalGetPath(elementOrPath)); 206 result.add(new ResourceTraversal(new IResource[] { resource}, Math.min(depth, layoutDepth), IResource.NONE)); 207 } 208 } 209 } 210 return (ResourceTraversal[]) result.toArray(new ResourceTraversal[result.size()]); 211 } else { 212 ResourceMapping[] mappings = scope.getMappings(ModelProvider.RESOURCE_MODEL_PROVIDER_ID); 215 List result = new ArrayList(); 216 for (int i = 0; i < mappings.length; i++) { 217 ResourceMapping resourceMapping = mappings[i]; 218 Object element = resourceMapping.getModelObject(); 219 IResource root = getResource(element); 220 if (root != null) { 221 if (resource.getFullPath().isPrefixOf(root.getFullPath())) { 222 mapping = scope.getMapping(element); 223 if (mapping != null) { 224 ResourceTraversal[] traversals = scope.getTraversals(mapping); 225 result.addAll(Arrays.asList(traversals)); 226 } 227 } 228 } 229 } 230 return (ResourceTraversal[]) result.toArray(new ResourceTraversal[result.size()]); 231 } 232 } 233 return new ResourceTraversal[0]; 234 } 235 236 private IResource getResource(Object element) { 237 if (element instanceof IResource) { 238 return (IResource) element; 239 } 240 return Utils.getResource(element); 241 } 242 243 246 protected boolean hasChildrenInContext(ISynchronizationContext context, Object elementOrPath) { 247 return getTraversalCalculator().hasChildren(context, elementOrPath); 248 } 249 250 253 public void propertyChanged(IDiffTree tree, final int property, final IPath[] paths) { 254 Utils.syncExec(new Runnable () { 255 public void run() { 256 ISynchronizationContext context = getContext(); 257 if (context != null) { 258 updateLabels(context, paths); 259 } 260 } 261 }, (StructuredViewer)getViewer()); 262 } 263 264 private IResource[] getResources(ISynchronizationContext context, IPath[] paths) { 265 List resources = new ArrayList(); 266 for (int i = 0; i < paths.length; i++) { 267 IPath path = paths[i]; 268 IResource resource = getResource(context, path); 269 if (resource != null) 270 resources.add(resource); 271 } 272 return (IResource[]) resources.toArray(new IResource[resources.size()]); 273 } 274 275 private IResource getResource(ISynchronizationContext context, IPath path) { 276 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path); 278 if (resource != null) { 279 return resource; 280 } 281 if (context != null) { 283 IResourceDiffTree diffTree = context.getDiffTree(); 284 IDiff node = diffTree.getDiff(path); 286 if (node != null) { 287 return diffTree.getResource(node); 288 } 289 if (diffTree.getChildren(path).length > 0) { 291 if (path.segmentCount() == 1) { 292 return ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); 293 } else if (path.segmentCount() > 1) { 294 return ResourcesPlugin.getWorkspace().getRoot().getFolder(path); 295 } 296 } 297 } 298 return null; 299 } 300 301 protected StructuredViewer getStructuredViewer() { 302 return (StructuredViewer)getViewer(); 303 } 304 305 public Object [] getChildren(Object parent) { 306 if (parent instanceof ISynchronizationContext) { 307 parent = getModelRoot(); 309 } 310 return super.getChildren(parent); 311 } 312 313 public boolean hasChildren(Object element) { 314 if (element instanceof ISynchronizationContext) { 315 element = getModelRoot(); 317 } 318 return super.hasChildren(element); 319 } 320 321 public Object [] getElements(Object parent) { 322 if (parent instanceof ISynchronizationContext) { 323 parent = getModelRoot(); 325 } 326 return super.getElements(parent); 327 } 328 329 public Object getParent(Object elementOrPath) { 330 Object element = internalGetElement(elementOrPath); 331 if (element instanceof IProject) { 332 ISynchronizationContext context = getContext(); 333 if (context != null) 334 return context; 335 } 336 return super.getParent(elementOrPath); 337 } 338 339 protected void refresh() { 340 Utils.syncExec(new Runnable () { 341 public void run() { 342 TreeViewer treeViewer = ((TreeViewer)getViewer()); 343 treeViewer.refresh(); 344 } 345 346 }, getViewer().getControl()); 347 } 348 349 protected void updateLabels(ISynchronizationContext context, final IPath[] paths) { 350 IResource[] resources = getResources(context, paths); 351 if (resources.length > 0) 352 ((AbstractTreeViewer)getViewer()).update(resources, null); 353 } 354 355 protected ResourceModelTraversalCalculator getTraversalCalculator() { 356 return ResourceModelTraversalCalculator.getTraversalCalculator(getConfiguration()); 357 } 358 359 protected boolean isVisible(IDiff diff) { 360 return super.isVisible(diff); 361 } 362 363 public Object [] getChildren(TreePath parentPath) { 364 return getChildren((Object )parentPath); 365 } 366 367 public boolean hasChildren(TreePath path) { 368 return hasChildren((Object )path); 369 } 370 371 public TreePath[] getParents(Object element) { 372 TreePath path = getTraversalCalculator().getParentPath(getContext(), getModelProvider(), element); 373 if (path != null) { 374 return new TreePath[] { path }; 375 } 376 return new TreePath[0]; 377 } 378 379 private Object internalGetElement(Object elementOrPath) { 380 if (elementOrPath instanceof TreePath) { 381 TreePath tp = (TreePath) elementOrPath; 382 return tp.getLastSegment(); 383 } 384 return elementOrPath; 385 } 386 387 private TreePath internalGetPath(Object elementOrPath) { 388 if (elementOrPath instanceof TreePath) { 389 return (TreePath) elementOrPath; 390 } 391 return null; 392 } 393 394 public void diffsChanged(final IDiffChangeEvent event, IProgressMonitor monitor) { 395 Utils.syncExec(new Runnable () { 396 public void run() { 397 handleChange(event); 398 } 399 }, (StructuredViewer)getViewer()); 400 } 401 402 private void handleChange(IDiffChangeEvent event) { 403 List refreshes = new ArrayList(); 404 List additions = new ArrayList(); 405 List removals = new ArrayList(); 406 if (isFlatPresentation()) { 407 Set existingResources = getVisibleResources(); 408 IResource[] changedResources = getChangedResources(event, existingResources); 409 for (int i = 0; i < changedResources.length; i++) { 410 IResource resource = changedResources[i]; 411 if (event.getTree().getDiff(resource.getFullPath()) != null) { 412 if (existingResources.contains(resource)) { 413 refreshes.add(resource); 414 } else { 415 additions.add(resource); 416 } 417 } else if (existingResources.contains(resource)) { 418 removals.add(resource); 419 420 } 421 } 422 } else { 423 IProject[] changedProjects = getChangedProjects(event); 424 Set existingProjects = getVisibleProjects(); 425 for (int i = 0; i < changedProjects.length; i++) { 426 IProject project = changedProjects[i]; 427 if (hasVisibleChanges(event.getTree(), project)) { 428 if (existingProjects.contains(project)) { 429 refreshes.add(project); 430 } else { 431 additions.add(project); 432 } 433 } else if (existingProjects.contains(project)) { 434 removals.add(project); 435 436 } 437 } 438 } 439 if (!removals.isEmpty() || !additions.isEmpty() || !refreshes.isEmpty()) { 440 TreeViewer viewer = (TreeViewer)getViewer(); 441 Tree tree = viewer.getTree(); 442 try { 443 tree.setRedraw(false); 444 if (!additions.isEmpty()) 445 viewer.add(viewer.getInput(), additions.toArray()); 446 if (!removals.isEmpty()) 447 viewer.remove(viewer.getInput(), removals.toArray()); 448 if (!refreshes.isEmpty()) { 449 for (Iterator iter = refreshes.iterator(); iter.hasNext();) { 450 Object element = iter.next(); 451 viewer.refresh(element); 452 } 453 } 454 } finally { 455 tree.setRedraw(true); 456 } 457 } 458 } 459 460 private boolean isFlatPresentation() { 461 ISynchronizePageConfiguration configuration = getConfiguration(); 462 if (configuration != null) { 463 String p = (String )configuration.getProperty(ITeamContentProviderManager.PROP_PAGE_LAYOUT); 464 return p != null && p.equals(ITeamContentProviderManager.FLAT_LAYOUT); 465 } 466 return false; 467 } 468 469 private boolean hasVisibleChanges(IDiffTree tree, IResource resource) { 470 return tree.hasMatchingDiffs(resource.getFullPath(), new FastDiffFilter() { 471 public boolean select(IDiff diff) { 472 return isVisible(diff); 473 } 474 }); 475 } 476 477 private IProject[] getChangedProjects(IDiffChangeEvent event) { 478 Set result = new HashSet(); 479 IDiff[] changes = event.getChanges(); 480 for (int i = 0; i < changes.length; i++) { 481 IDiff diff = changes[i]; 482 IResource resource = ResourceDiffTree.getResourceFor(diff); 483 if (resource != null) { 484 result.add(resource.getProject()); 485 } 486 } 487 IDiff[] additions = event.getAdditions(); 488 for (int i = 0; i < additions.length; i++) { 489 IDiff diff = additions[i]; 490 IResource resource = ResourceDiffTree.getResourceFor(diff); 491 if (resource != null) { 492 result.add(resource.getProject()); 493 } 494 } 495 IPath[] removals = event.getRemovals(); 496 for (int i = 0; i < removals.length; i++) { 497 IPath path = removals[i]; 498 if (path.segmentCount() > 0) { 499 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); 500 result.add(project); 501 } 502 } 503 return (IProject[]) result.toArray(new IProject[result.size()]); 504 } 505 506 private Set getVisibleProjects() { 507 TreeViewer viewer = (TreeViewer)getViewer(); 508 Tree tree = viewer.getTree(); 509 TreeItem[] children = tree.getItems(); 510 Set result = new HashSet(); 511 for (int i = 0; i < children.length; i++) { 512 TreeItem control = children[i]; 513 Object data = control.getData(); 514 IResource resource = Utils.getResource(data); 515 if (resource != null && resource.getType() == IResource.PROJECT) { 516 result.add(resource); 517 } 518 } 519 return result; 520 } 521 522 private Set getVisibleResources() { 523 TreeViewer viewer = (TreeViewer)getViewer(); 524 Tree tree = viewer.getTree(); 525 TreeItem[] children = tree.getItems(); 526 Set result = new HashSet(); 527 for (int i = 0; i < children.length; i++) { 528 TreeItem control = children[i]; 529 Object data = control.getData(); 530 IResource resource = Utils.getResource(data); 531 if (resource != null) { 532 result.add(resource); 533 } 534 } 535 return result; 536 } 537 538 private IResource[] getChangedResources(IDiffChangeEvent event, Set existingResources) { 539 Set result = new HashSet(); 540 IDiff[] changes = event.getChanges(); 541 for (int i = 0; i < changes.length; i++) { 542 IDiff diff = changes[i]; 543 IResource resource = ResourceDiffTree.getResourceFor(diff); 544 if (resource != null) { 545 result.add(resource); 546 } 547 } 548 IDiff[] additions = event.getAdditions(); 549 for (int i = 0; i < additions.length; i++) { 550 IDiff diff = additions[i]; 551 IResource resource = ResourceDiffTree.getResourceFor(diff); 552 if (resource != null) { 553 result.add(resource); 554 } 555 } 556 IPath[] removals = event.getRemovals(); 557 for (int i = 0; i < removals.length; i++) { 558 IPath path = removals[i]; 559 if (path.segmentCount() > 0) { 560 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path); 561 if (resource != null) { 562 result.add(resource); 563 } else { 564 for (Iterator iterator = existingResources.iterator(); iterator 566 .hasNext();) { 567 resource = (IResource) iterator.next(); 568 if (resource.getFullPath().equals(path)) { 569 result.add(resource); 570 break; 571 } 572 } 573 } 574 } 575 } 576 return (IResource[]) result.toArray(new IResource[result.size()]); 577 } 578 } 579 | Popular Tags |