KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > mapping > ResourceModelContentProvider


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

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 /**
34  * This content provider displays the mappings as a flat list
35  * of elements.
36  * <p>
37  * There are three use-cases we need to consider. The first is when there
38  * are resource level mappings to be displayed. The second is when there
39  * are mappings from a model provider that does not have a content provider
40  * registered. The third is for the case where a resource mapping does not
41  * have a model provider registered (this may be considered an error case).
42  *
43  */

44 public class ResourceModelContentProvider extends SynchronizationContentProvider implements ITreePathContentProvider {
45
46     private WorkbenchContentProvider provider;
47
48     /* (non-Javadoc)
49      * @see org.eclipse.team.internal.ui.mapping.AbstractTeamAwareContentProvider#getDelegateContentProvider()
50      */

51     protected ITreeContentProvider getDelegateContentProvider() {
52         if (provider == null)
53             provider = new WorkbenchContentProvider();
54         return provider;
55     }
56
57     /* (non-Javadoc)
58      * @see org.eclipse.team.internal.ui.mapping.AbstractTeamAwareContentProvider#getModelProviderId()
59      */

60     protected String JavaDoc getModelProviderId() {
61         return ModelProvider.RESOURCE_MODEL_PROVIDER_ID;
62     }
63
64     /* (non-Javadoc)
65      * @see org.eclipse.team.internal.ui.mapping.AbstractTeamAwareContentProvider#getModelRoot()
66      */

67     protected Object JavaDoc getModelRoot() {
68         return ResourcesPlugin.getWorkspace().getRoot();
69     }
70
71     /* (non-Javadoc)
72      * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#isInScope(org.eclipse.team.core.mapping.IResourceMappingScope, java.lang.Object, java.lang.Object)
73      */

74     protected boolean isInScope(ISynchronizationScope scope, Object JavaDoc parent, Object JavaDoc elementOrPath) {
75         Object JavaDoc 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 JavaDoc 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     /* (non-Javadoc)
104      * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite)
105      */

106     public void init(ICommonContentExtensionSite site) {
107         super.init(site);
108         TeamUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(this);
109     }
110     
111     /* (non-Javadoc)
112      * @see org.eclipse.team.internal.ui.mapping.AbstractTeamAwareContentProvider#dispose()
113      */

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     /* (non-Javadoc)
128      * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getChildrenInContext(org.eclipse.team.core.mapping.ISynchronizationContext, java.lang.Object, java.lang.Object[])
129      */

130     protected Object JavaDoc[] getChildrenInContext(ISynchronizationContext context, Object JavaDoc parentOrPath, Object JavaDoc[] children) {
131         Object JavaDoc 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 JavaDoc[0];
136             IResourceDiffTree diffTree = context.getDiffTree();
137             // TODO: Could optimize this to a single pass over the children instead of 3
138
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 JavaDoc[] internalGetChildren(ISynchronizationContext context, Object JavaDoc parent, Object JavaDoc[] children) {
149         List result = new ArrayList(children.length);
150         for (int i = 0; i < children.length; i++) {
151             Object JavaDoc object = children[i];
152             // If the parent is a TreePath then the subclass is
153
// TreePath aware and we can send a TrePath to the
154
// isVisible method
155
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 JavaDoc[result.size()]);
163     }
164     
165     protected ResourceTraversal[] getTraversals(ISynchronizationContext context, Object JavaDoc elementOrPath) {
166         Object JavaDoc object = internalGetElement(elementOrPath);
167         ISynchronizationScope scope = context.getScope();
168         // First see if the object is a root of the scope
169
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         // Next, check if the object is within the scope
177
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                 // The resource is a parent of an in-scope resource
213
// TODO: fails due to use of roots
214
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 JavaDoc 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 JavaDoc element) {
237         if (element instanceof IResource) {
238             return (IResource) element;
239         }
240         return Utils.getResource(element);
241     }
242
243     /* (non-Javadoc)
244      * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#hasChildrenInContext(org.eclipse.team.core.mapping.ISynchronizationContext, java.lang.Object)
245      */

246     protected boolean hasChildrenInContext(ISynchronizationContext context, Object JavaDoc elementOrPath) {
247         return getTraversalCalculator().hasChildren(context, elementOrPath);
248     }
249     
250     /* (non-Javadoc)
251      * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#propertyChanged(int, org.eclipse.core.runtime.IPath[])
252      */

253     public void propertyChanged(IDiffTree tree, final int property, final IPath[] paths) {
254         Utils.syncExec(new Runnable JavaDoc() {
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         // Does the resource exist locally
277
IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
278         if (resource != null) {
279             return resource;
280         }
281         // Look in the diff tree for a phantom
282
if (context != null) {
283             IResourceDiffTree diffTree = context.getDiffTree();
284             // Is there a diff for the path
285
IDiff node = diffTree.getDiff(path);
286             if (node != null) {
287                 return diffTree.getResource(node);
288             }
289             // Is there any descendants of the path
290
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 JavaDoc[] getChildren(Object JavaDoc parent) {
306         if (parent instanceof ISynchronizationContext) {
307             // Put the resource projects directly under the context
308
parent = getModelRoot();
309         }
310         return super.getChildren(parent);
311     }
312     
313     public boolean hasChildren(Object JavaDoc element) {
314         if (element instanceof ISynchronizationContext) {
315             // Put the resource projects directly under the context
316
element = getModelRoot();
317         }
318         return super.hasChildren(element);
319     }
320     
321     public Object JavaDoc[] getElements(Object JavaDoc parent) {
322         if (parent instanceof ISynchronizationContext) {
323             // Put the resource projects directly under the context
324
parent = getModelRoot();
325         }
326         return super.getElements(parent);
327     }
328     
329     public Object JavaDoc getParent(Object JavaDoc elementOrPath) {
330         Object JavaDoc 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 JavaDoc() {
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 JavaDoc[] getChildren(TreePath parentPath) {
364         return getChildren((Object JavaDoc)parentPath);
365     }
366
367     public boolean hasChildren(TreePath path) {
368         return hasChildren((Object JavaDoc)path);
369     }
370
371     public TreePath[] getParents(Object JavaDoc 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 JavaDoc internalGetElement(Object JavaDoc 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 JavaDoc 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 JavaDoc() {
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 JavaDoc 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 JavaDoc p = (String JavaDoc)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 JavaDoc 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 JavaDoc 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                     // We need to check the list of displayed resources to see if one matches the given path
565
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