001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.model;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.Iterator;
015: import java.util.LinkedList;
016: import java.util.List;
017: import java.util.Set;
018:
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IAdaptable;
021: import org.eclipse.core.runtime.IPath;
022: import org.eclipse.core.runtime.IProgressMonitor;
023: import org.eclipse.core.runtime.NullProgressMonitor;
024:
025: import org.eclipse.core.resources.IFile;
026: import org.eclipse.core.resources.IFolder;
027: import org.eclipse.core.resources.IProject;
028: import org.eclipse.core.resources.IResource;
029: import org.eclipse.core.resources.ResourcesPlugin;
030: import org.eclipse.core.resources.mapping.ResourceMapping;
031: import org.eclipse.core.resources.mapping.ResourceMappingContext;
032: import org.eclipse.core.resources.mapping.ResourceTraversal;
033:
034: import org.eclipse.swt.custom.BusyIndicator;
035: import org.eclipse.swt.widgets.Control;
036: import org.eclipse.swt.widgets.Tree;
037: import org.eclipse.swt.widgets.TreeItem;
038:
039: import org.eclipse.jface.viewers.ITreeContentProvider;
040: import org.eclipse.jface.viewers.TreeViewer;
041:
042: import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
043: import org.eclipse.ui.navigator.PipelinedShapeModification;
044: import org.eclipse.ui.navigator.PipelinedViewerUpdate;
045:
046: import org.eclipse.team.core.diff.FastDiffFilter;
047: import org.eclipse.team.core.diff.IDiff;
048: import org.eclipse.team.core.diff.IDiffChangeEvent;
049: import org.eclipse.team.core.diff.IDiffTree;
050: import org.eclipse.team.core.diff.IDiffVisitor;
051: import org.eclipse.team.core.mapping.IResourceDiffTree;
052: import org.eclipse.team.core.mapping.ISynchronizationContext;
053: import org.eclipse.team.core.mapping.ISynchronizationScope;
054: import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
055:
056: import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
057: import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
058: import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
059: import org.eclipse.ltk.ui.refactoring.model.AbstractSynchronizationContentProvider;
060:
061: import org.eclipse.jdt.core.ICompilationUnit;
062: import org.eclipse.jdt.core.IJavaElement;
063: import org.eclipse.jdt.core.IJavaProject;
064: import org.eclipse.jdt.core.IPackageFragment;
065: import org.eclipse.jdt.core.IPackageFragmentRoot;
066: import org.eclipse.jdt.core.JavaCore;
067:
068: import org.eclipse.jdt.internal.corext.util.JavaElementResourceMapping;
069:
070: import org.eclipse.jdt.internal.ui.JavaPlugin;
071:
072: /**
073: * Java-aware synchronization content provider.
074: *
075: * @since 3.2
076: */
077: public final class JavaSynchronizationContentProvider extends
078: AbstractSynchronizationContentProvider implements
079: IPipelinedTreeContentProvider {
080:
081: /** The refactorings folder */
082: // private static final String NAME_REFACTORING_FOLDER= ".refactorings"; //$NON-NLS-1$
083: /**
084: * Returns the diffs associated with the element.
085: *
086: * @param context
087: * the synchronization context
088: * @param element
089: * the element
090: * @return an array of diffs
091: */
092: static IDiff[] getDiffs(final ISynchronizationContext context,
093: final Object element) {
094: return context.getDiffTree().getDiffs(
095: getResourceTraversals(element));
096: }
097:
098: /**
099: * Returns the resource mapping for the element.
100: *
101: * @param element
102: * the element to get the resource mapping
103: * @return the resource mapping
104: */
105: static ResourceMapping getResourceMapping(final Object element) {
106: if (element instanceof IJavaElement)
107: return JavaElementResourceMapping
108: .create((IJavaElement) element);
109: if (element instanceof IAdaptable) {
110: final IAdaptable adaptable = (IAdaptable) element;
111: final Object adapted = adaptable
112: .getAdapter(ResourceMapping.class);
113: if (adapted instanceof ResourceMapping)
114: return (ResourceMapping) adapted;
115: }
116: return null;
117: }
118:
119: /**
120: * Returns the resource traversals for the element.
121: *
122: * @param element
123: * the element to get the resource traversals
124: * @return the resource traversals
125: */
126: static ResourceTraversal[] getResourceTraversals(
127: final Object element) {
128: final ResourceMapping mapping = getResourceMapping(element);
129: if (mapping != null)
130: try {
131: return mapping.getTraversals(
132: ResourceMappingContext.LOCAL_CONTEXT,
133: new NullProgressMonitor());
134: } catch (final CoreException exception) {
135: JavaPlugin.log(exception);
136: }
137: return new ResourceTraversal[0];
138: }
139:
140: /** The content provider, or <code>null</code> */
141: private ITreeContentProvider fContentProvider = null;
142:
143: /** The model root, or <code>null</code> */
144: private Object fModelRoot = null;
145:
146: /**
147: * Returns the java element associated with the project.
148: *
149: * @param project
150: * the project
151: * @return the associated java element, or <code>null</code> if the
152: * project is not a java project
153: */
154: private IJavaProject asJavaProject(final IProject project) {
155: try {
156: if (project.getDescription().hasNature(JavaCore.NATURE_ID))
157: return JavaCore.create(project);
158: } catch (final CoreException exception) {
159: // Only log the error for projects that are accessible (i.e. exist and are open)
160: if (project.isAccessible())
161: JavaPlugin.log(exception);
162: }
163: return null;
164: }
165:
166: /**
167: * Converts the shape modification to use java elements.
168: *
169: * @param modification
170: * the shape modification to convert
171: */
172: private void convertToJavaElements(
173: final PipelinedShapeModification modification) {
174: final Object parent = modification.getParent();
175: if (parent instanceof IResource) {
176: final IJavaElement project = asJavaProject(((IResource) parent)
177: .getProject());
178: if (project != null) {
179: modification.getChildren().clear();
180: return;
181: }
182: }
183: if (parent instanceof ISynchronizationContext) {
184: final Set result = new HashSet();
185: for (final Iterator iterator = modification.getChildren()
186: .iterator(); iterator.hasNext();) {
187: final Object element = iterator.next();
188: if (element instanceof IProject) {
189: final IJavaElement project = asJavaProject((IProject) element);
190: if (project != null) {
191: iterator.remove();
192: result.add(project);
193: }
194: }
195: }
196: modification.getChildren().addAll(result);
197: }
198: }
199:
200: /**
201: * Converts the viewer update to use java elements.
202: *
203: * @param update
204: * the viewer update to convert
205: * @return <code>true</code> if any elements have been converted,
206: * <code>false</code> otherwise
207: */
208: private boolean convertToJavaElements(
209: final PipelinedViewerUpdate update) {
210: final Set result = new HashSet();
211: for (final Iterator iterator = update.getRefreshTargets()
212: .iterator(); iterator.hasNext();) {
213: final Object element = iterator.next();
214: if (element instanceof IProject) {
215: final IJavaElement project = asJavaProject((IProject) element);
216: if (project != null) {
217: iterator.remove();
218: result.add(project);
219: }
220: }
221: }
222: update.getRefreshTargets().addAll(result);
223: return !result.isEmpty();
224: }
225:
226: /**
227: * {@inheritDoc}
228: */
229: public void diffsChanged(final IDiffChangeEvent event,
230: final IProgressMonitor monitor) {
231: syncExec(new Runnable() {
232:
233: public void run() {
234: handleChange(event);
235: }
236: }, getViewer().getControl());
237: }
238:
239: /**
240: * Returns all the existing projects that contain additions,
241: * removals or deletions.
242: *
243: * @param event
244: * the event
245: * @return the projects that contain changes
246: */
247: private IJavaProject[] getChangedProjects(
248: final IDiffChangeEvent event) {
249: final Set result = new HashSet();
250: final IDiff[] changes = event.getChanges();
251: for (int index = 0; index < changes.length; index++) {
252: final IResource resource = ResourceDiffTree
253: .getResourceFor(changes[index]);
254: if (resource != null) {
255: final IJavaProject project = asJavaProject(resource
256: .getProject());
257: if (project != null)
258: result.add(project);
259: }
260: }
261: final IDiff[] additions = event.getAdditions();
262: for (int index = 0; index < additions.length; index++) {
263: final IResource resource = ResourceDiffTree
264: .getResourceFor(additions[index]);
265: if (resource != null) {
266: final IJavaProject project = asJavaProject(resource
267: .getProject());
268: if (project != null)
269: result.add(project);
270: }
271: }
272: final IPath[] removals = event.getRemovals();
273: for (int i = 0; i < removals.length; i++) {
274: IPath path = removals[i];
275: if (path.segmentCount() > 0) {
276: IProject project = ResourcesPlugin.getWorkspace()
277: .getRoot().getProject(path.segment(0));
278: // Only consider projects that still exist
279: if (project.exists()) {
280: final IJavaProject javaProject = asJavaProject(project
281: .getProject());
282: if (javaProject != null)
283: result.add(javaProject);
284: }
285: }
286: }
287: return (IJavaProject[]) result.toArray(new IJavaProject[result
288: .size()]);
289: }
290:
291: /**
292: * {@inheritDoc}
293: */
294: protected Object[] getChildrenInContext(
295: final ISynchronizationContext context, final Object parent,
296: final Object[] children) {
297: final Object[] elements = super .getChildrenInContext(context,
298: parent, children);
299: if (parent instanceof IPackageFragment)
300: return getPackageFragmentChildren(context, parent, elements);
301: else if (parent instanceof IPackageFragmentRoot)
302: return getPackageFragmentRootChildren(context, parent,
303: elements);
304: else if (parent instanceof IJavaProject)
305: return getJavaProjectChildren(context, parent, elements);
306: else if (parent instanceof RefactoringHistory)
307: return ((RefactoringHistory) parent).getDescriptors();
308: // It may be the case that the elements are folders that have a corresponding
309: // source folder in which case they should be filtered out
310: return getFilteredElements(parent, elements);
311: }
312:
313: /**
314: * Returns the filtered elements.
315: *
316: * @param parent
317: * the parent element
318: * @param children
319: * the child elements
320: * @return the filtered elements
321: */
322: private Object[] getFilteredElements(final Object parent,
323: final Object[] children) {
324: final List result = new ArrayList(children.length);
325: for (int index = 0; index < children.length; index++) {
326: if (children[index] instanceof IFolder) {
327: if (!(JavaCore.create((IFolder) children[index]) instanceof IPackageFragmentRoot))
328: result.add(children[index]);
329: } else
330: result.add(children[index]);
331: }
332: return result.toArray();
333: }
334:
335: /**
336: * {@inheritDoc}
337: */
338: protected ITreeContentProvider getDelegateContentProvider() {
339: if (fContentProvider == null)
340: fContentProvider = new JavaModelContentProvider();
341: return fContentProvider;
342: }
343:
344: /**
345: * Returns the projects that used to have changes in the diff tree
346: * but have been deleted from the workspace.
347: *
348: * @param event
349: * the event
350: * @return the deleted projects
351: */
352: private Set getDeletedProjects(final IDiffChangeEvent event) {
353: final Set result = new HashSet();
354: final IPath[] deletions = event.getRemovals();
355: for (int index = 0; index < deletions.length; index++) {
356: final IPath path = deletions[index];
357: if (path.segmentCount() > 0) {
358: IProject project = ResourcesPlugin.getWorkspace()
359: .getRoot().getProject(path.segment(0));
360: if (!project.isAccessible())
361: result.add(project);
362: }
363: }
364: return result;
365: }
366:
367: /**
368: * Since the this content provider overrides the resource content provider,
369: * this method is only invoked when the resource content provider is
370: * disabled. In this case, we still want the Java projects to appear at the
371: * root of the view.
372: *
373: * {@inheritDoc}
374: */
375: public Object[] getElements(Object parent) {
376: if (parent instanceof ISynchronizationContext)
377: // Put the resource projects directly under the context
378: parent = getModelRoot();
379: return super .getElements(parent);
380: }
381:
382: /**
383: * Returns the java project children in the current scope.
384: *
385: * @param context
386: * the synchronization context
387: * @param parent
388: * the parent element
389: * @param children
390: * the child elements
391: * @return the java project children
392: */
393: private Object[] getJavaProjectChildren(
394: final ISynchronizationContext context, final Object parent,
395: final Object[] children) {
396: final LinkedList list = new LinkedList();
397: for (int index = 0; index < children.length; index++) {
398: if (children[index] instanceof IPackageFragment) {
399: final IPackageFragment fragment = (IPackageFragment) children[index];
400: if (getChildren(fragment).length == 0)
401: continue;
402: }
403: // We need to check whether a folder has non-fragment children (bug 138767)
404: if (children[index] instanceof IFolder) {
405: IFolder folder = (IFolder) children[index];
406: if (getChildren(folder).length == 0)
407: continue;
408: }
409: list.add(children[index]);
410: }
411:
412: final IResource resource = JavaModelProvider
413: .getResource(parent);
414: if (resource != null) {
415: final IResourceDiffTree tree = context.getDiffTree();
416: final IResource[] members = tree.members(resource);
417: for (int index = 0; index < members.length; index++) {
418: IResource child = members[index];
419: if (isVisible(context, child)) {
420: if (hasPhantomFolder(tree, child)) {
421: // Add any phantom resources that are visible
422: list.add(child);
423: }
424:
425: // if (members[index] instanceof IFolder) {
426: // final IFolder folder= (IFolder) members[index];
427: // if (folder.getName().equals(NAME_REFACTORING_FOLDER)) {
428: // final RefactoringHistory history= getRefactorings(context, (IProject) resource, null);
429: // if (!history.isEmpty()) {
430: // list.remove(folder);
431: // list.addFirst(history);
432: // }
433: // }
434: // }
435: }
436: }
437:
438: }
439: return list.toArray(new Object[list.size()]);
440: }
441:
442: private boolean hasPhantomFolder(IResourceDiffTree tree,
443: IResource child) {
444: if (!child.exists())
445: return true;
446: final boolean[] found = new boolean[] { false };
447: tree.accept(child.getFullPath(), new IDiffVisitor() {
448: public boolean visit(IDiff delta) {
449: IResource treeResource = ResourceDiffTree
450: .getResourceFor(delta);
451: if (treeResource.getType() == IResource.FILE
452: && !treeResource.getParent().exists()) {
453: found[0] = true;
454: return false;
455: }
456:
457: return true;
458: }
459: }, IResource.DEPTH_INFINITE);
460: return found[0];
461: }
462:
463: /**
464: * {@inheritDoc}
465: */
466: protected String getModelProviderId() {
467: return JavaModelProvider.JAVA_MODEL_PROVIDER_ID;
468: }
469:
470: /**
471: * {@inheritDoc}
472: */
473: protected Object getModelRoot() {
474: if (fModelRoot == null)
475: fModelRoot = JavaCore.create(ResourcesPlugin.getWorkspace()
476: .getRoot());
477: return fModelRoot;
478: }
479:
480: /**
481: * Returns the package fragment children in the current scope.
482: *
483: * @param context
484: * the synchronization context
485: * @param parent
486: * the parent element
487: * @param children
488: * the child elements
489: * @return the package fragment children
490: */
491: private Object[] getPackageFragmentChildren(
492: final ISynchronizationContext context, final Object parent,
493: final Object[] children) {
494: final Set set = new HashSet();
495: for (int index = 0; index < children.length; index++)
496: set.add(children[index]);
497: final IResource resource = ((IPackageFragment) parent)
498: .getResource();
499: if (resource != null) {
500: final IResourceDiffTree tree = context.getDiffTree();
501: final IResource[] members = tree.members(resource);
502: for (int index = 0; index < members.length; index++) {
503: final int type = members[index].getType();
504: if (type == IResource.FILE) {
505: final IDiff diff = tree.getDiff(members[index]);
506: if (diff != null && isVisible(diff))
507: if (isInScope(context.getScope(), parent,
508: members[index])) {
509: final IJavaElement element = JavaCore
510: .create(members[index]);
511: if (element == null) {
512: set.add(members[index]);
513: } else {
514: set.add(element);
515: }
516: }
517: }
518: }
519: }
520: return set.toArray(new Object[set.size()]);
521: }
522:
523: /**
524: * Returns the package fragment root children in the current scope.
525: *
526: * @param context
527: * the synchronization context
528: * @param parent
529: * the parent element
530: * @param children
531: * the child elements
532: * @return the package fragment root children
533: */
534: private Object[] getPackageFragmentRootChildren(
535: final ISynchronizationContext context, final Object parent,
536: final Object[] children) {
537: final Set set = new HashSet();
538: for (int index = 0; index < children.length; index++) {
539: if (children[index] instanceof IPackageFragment) {
540: IPackageFragment fragment = (IPackageFragment) children[index];
541: if (fragment.isOpen()
542: && getChildren(fragment).length == 0)
543: // Don't add the default package unless it has children
544: continue;
545: }
546: set.add(children[index]);
547: }
548: final IResource resource = JavaModelProvider
549: .getResource(parent);
550: if (resource != null) {
551: final IResourceDiffTree tree = context.getDiffTree();
552: final IResource[] members = tree.members(resource);
553: for (int index = 0; index < members.length; index++) {
554: final int type = members[index].getType();
555: final boolean contained = isInScope(context.getScope(),
556: parent, members[index]);
557: final boolean visible = isVisible(context,
558: members[index]);
559: if (type == IResource.FILE && contained && visible) {
560: // If the file is not a compilation unit add it.
561: // (compilation units are always children of packages so they
562: // don't need to be added here)
563: final IJavaElement element = JavaCore
564: .create((IFile) members[index]);
565: if (element == null)
566: set.add(members[index]);
567: } else if (type == IResource.FOLDER && contained
568: && visible
569: && tree.getDiff(members[index]) != null) {
570: // If the folder is out-of-sync, add it
571: final IJavaElement element = JavaCore
572: .create(members[index]);
573: if (element != null)
574: set.add(element);
575: }
576: if (type == IResource.FOLDER) {
577: // If the folder contains java elements, add it
578: final IFolder folder = (IFolder) members[index];
579: tree.accept(folder.getFullPath(),
580: new IDiffVisitor() {
581:
582: public final boolean visit(
583: final IDiff diff) {
584: if (isVisible(diff)) {
585: final IResource current = tree
586: .getResource(diff);
587: if (current != null) {
588: final int kind = current
589: .getType();
590: if (kind == IResource.FILE) {
591: final IJavaElement element = JavaCore
592: .create(current
593: .getParent());
594: if (element != null)
595: set.add(element);
596: } else {
597: final IJavaElement element = JavaCore
598: .create(current);
599: if (element != null)
600: set.add(element);
601: }
602: }
603: }
604: return true;
605: }
606: }, IResource.DEPTH_INFINITE);
607: }
608: }
609: return set.toArray(new Object[set.size()]);
610: }
611: return children;
612: }
613:
614: /**
615: * {@inheritDoc}
616: */
617: public void getPipelinedChildren(final Object parent,
618: final Set children) {
619: if (parent instanceof ISynchronizationContext) {
620: // When a context is the root, the resource content provider returns
621: // projects as direct children. We should replace any projects that
622: // are Java projects with an IJavaProject
623: final Set result = new HashSet(children.size());
624: for (final Iterator iterator = children.iterator(); iterator
625: .hasNext();) {
626: final Object element = iterator.next();
627: if (element instanceof IProject) {
628: final IJavaElement java = asJavaProject((IProject) element);
629: if (java != null) {
630: iterator.remove();
631: result.add(java);
632: }
633: }
634: if (element instanceof IFolder) {
635: IFolder folder = (IFolder) element;
636: IJavaElement javaElement = JavaCore.create(folder);
637: // If the folder is also a package, don't show it
638: // as a folder since it will be shown as a package
639: if (javaElement instanceof IPackageFragmentRoot) {
640: iterator.remove();
641: }
642: }
643: }
644: children.addAll(result);
645: } else if (parent instanceof ISynchronizationScope) {
646: // When the root is a scope, we should return the
647: // Java model provider so all model providers appear
648: // at the root of the viewer.
649: children.add(getModelProvider());
650: } else if (parent instanceof IFolder) {
651: // Remove any children that are also source folders so they
652: // don't appear twice
653: for (final Iterator iterator = children.iterator(); iterator
654: .hasNext();) {
655: final Object element = iterator.next();
656: if (element instanceof IFolder) {
657: IFolder folder = (IFolder) element;
658: IJavaElement javaElement = JavaCore.create(folder);
659: if (javaElement instanceof IPackageFragmentRoot) {
660: iterator.remove();
661: }
662: }
663: }
664: }
665: }
666:
667: /**
668: * {@inheritDoc}
669: */
670: public void getPipelinedElements(final Object element,
671: final Set elements) {
672: getPipelinedChildren(element, elements);
673: }
674:
675: /**
676: * {@inheritDoc}
677: */
678: public Object getPipelinedParent(final Object element,
679: final Object parent) {
680: if (element instanceof IJavaElement)
681: return getParent(element);
682: return parent;
683: }
684:
685: /**
686: * {@inheritDoc}
687: */
688: protected ResourceTraversal[] getTraversals(
689: final ISynchronizationContext context, final Object object) {
690: return getResourceTraversals(object);
691: }
692:
693: /**
694: * Returns the visible projects.
695: *
696: * @return the visible projects
697: */
698: private Set getVisibleProjects() {
699: final TreeItem[] children = ((TreeViewer) getViewer())
700: .getTree().getItems();
701: final Set result = new HashSet();
702: for (int index = 0; index < children.length; index++) {
703: final Object data = children[index].getData();
704: if (data instanceof IJavaProject)
705: result.add(data);
706: }
707: return result;
708: }
709:
710: /**
711: * Handles a diff change event.
712: *
713: * @param event
714: * the event
715: */
716: private void handleChange(final IDiffChangeEvent event) {
717: final Set existing = getVisibleProjects();
718: // Get all existing and open projects that contain changes
719: // and determine what needs to be done to the project
720: // (i.e. add, remove or refresh)
721: final IJavaProject[] changed = getChangedProjects(event);
722: final List refreshes = new ArrayList(changed.length);
723: final List additions = new ArrayList(changed.length);
724: final List removals = new ArrayList(changed.length);
725: for (int index = 0; index < changed.length; index++) {
726: final IJavaProject project = changed[index];
727: if (hasVisibleChanges(event.getTree(), project)) {
728: if (existing.contains(project))
729: refreshes.add(project);
730: else
731: additions.add(project);
732: } else
733: removals.add(project);
734: }
735: // Remove any java projects that correspond to deleted or closed projects
736: final Set removed = getDeletedProjects(event);
737: for (final Iterator iterator = existing.iterator(); iterator
738: .hasNext();) {
739: final IJavaProject element = (IJavaProject) iterator.next();
740: if (removed.contains(element.getResource()))
741: removals.add(element);
742: }
743:
744: if (!removals.isEmpty() || !additions.isEmpty()
745: || !refreshes.isEmpty()) {
746: final TreeViewer viewer = (TreeViewer) getViewer();
747: final Tree tree = viewer.getTree();
748: try {
749: tree.setRedraw(false);
750: if (!additions.isEmpty())
751: viewer.add(viewer.getInput(), additions.toArray());
752: if (!removals.isEmpty())
753: viewer
754: .remove(viewer.getInput(), removals
755: .toArray());
756: if (!refreshes.isEmpty()) {
757: for (final Iterator iter = refreshes.iterator(); iter
758: .hasNext();)
759: viewer.refresh(iter.next());
760: }
761: } finally {
762: tree.setRedraw(true);
763: }
764: }
765: }
766:
767: /**
768: * {@inheritDoc}
769: */
770: public boolean hasChildren(final Object element) {
771: if (element instanceof ICompilationUnit
772: || element instanceof IFile
773: || element instanceof RefactoringDescriptorProxy
774: || element instanceof RefactoringDescriptor)
775: return false;
776: return super .hasChildren(element);
777: }
778:
779: /**
780: * Returns whether the element has some children in the current scope.
781: *
782: * @param scope
783: * the synchronization scope
784: * @param element
785: * the element
786: * @param resource
787: * the resource
788: * @return <code>true</code> if it has some children, <code>false</code>
789: * otherwise
790: */
791: private boolean hasChildrenInScope(
792: final ISynchronizationScope scope, final Object element,
793: final IResource resource) {
794: final IResource[] roots = scope.getRoots();
795: final IPath path = resource.getFullPath();
796: if (element instanceof IPackageFragment) {
797: for (int index = 0; index < roots.length; index++)
798: if (path.equals(roots[index].getFullPath()
799: .removeLastSegments(1)))
800: return true;
801: return false;
802: }
803: for (int index = 0; index < roots.length; index++)
804: if (path.isPrefixOf(roots[index].getFullPath()))
805: return true;
806: return false;
807: }
808:
809: /**
810: * Has the java project visible changes?
811: *
812: * @param tree
813: * the diff tree
814: * @param project
815: * the java project
816: * @return <code>true</code> if it has visible changes, <code>false</code>
817: * otherwise
818: */
819: private boolean hasVisibleChanges(final IDiffTree tree,
820: final IJavaProject project) {
821: return tree.hasMatchingDiffs(project.getResource()
822: .getFullPath(), new FastDiffFilter() {
823:
824: public boolean select(final IDiff diff) {
825: return isVisible(diff);
826: }
827: });
828: }
829:
830: /**
831: * {@inheritDoc}
832: */
833: public PipelinedShapeModification interceptAdd(
834: final PipelinedShapeModification modification) {
835: convertToJavaElements(modification);
836: return modification;
837: }
838:
839: /**
840: * {@inheritDoc}
841: */
842: public boolean interceptRefresh(final PipelinedViewerUpdate update) {
843: return convertToJavaElements(update);
844: }
845:
846: /**
847: * {@inheritDoc}
848: */
849: public PipelinedShapeModification interceptRemove(
850: final PipelinedShapeModification modification) {
851: convertToJavaElements(modification);
852: return modification;
853: }
854:
855: /**
856: * {@inheritDoc}
857: */
858: public boolean interceptUpdate(
859: final PipelinedViewerUpdate anUpdateSynchronization) {
860: return convertToJavaElements(anUpdateSynchronization);
861: }
862:
863: /**
864: * {@inheritDoc}
865: */
866: protected boolean isInScope(final ISynchronizationScope scope,
867: final Object parent, final Object element) {
868: final IResource resource = JavaModelProvider
869: .getResource(element);
870: if (resource == null)
871: return false;
872: if (scope.contains(resource))
873: return true;
874: if (hasChildrenInScope(scope, element, resource))
875: return true;
876: return false;
877: }
878:
879: /**
880: * Executes the given runnable.
881: *
882: * @param runnable
883: * the runnable
884: * @param control
885: * the control
886: */
887: private void syncExec(final Runnable runnable, final Control control) {
888: if (control != null && !control.isDisposed())
889: control.getDisplay().syncExec(new Runnable() {
890:
891: public void run() {
892: if (!control.isDisposed())
893: BusyIndicator.showWhile(control.getDisplay(),
894: runnable);
895: }
896: });
897: }
898: }
|