| /******************************************************************************* |
| * Copyright (c) 2006, 2009 Wind River Systems, Inc. and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Anton Leherbauer (Wind River Systems) - initial API and implementation |
| * Francis Upton IV (Oakland Software) - adapted for CNF tests |
| *******************************************************************************/ |
| package org.eclipse.ui.tests.navigator.cdt; |
| |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.navigator.CommonNavigator; |
| import org.eclipse.ui.navigator.ICommonContentExtensionSite; |
| import org.eclipse.ui.navigator.ICommonContentProvider; |
| import org.eclipse.ui.navigator.IPipelinedTreeContentProvider; |
| import org.eclipse.ui.navigator.PipelinedShapeModification; |
| import org.eclipse.ui.navigator.PipelinedViewerUpdate; |
| import org.eclipse.ui.navigator.resources.ProjectExplorer; |
| |
| /** |
| * A content provider populating a Common Navigator view with CDT model content. |
| */ |
| public class CNavigatorContentProvider implements |
| IPipelinedTreeContentProvider, ICommonContentProvider { |
| |
| /** |
| * Flag set in {@link #restoreState(IMemento) restoreState}, indicating |
| * whether link-with-editor should be enabled delayed as a (old) workaround |
| * for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186344">bug |
| * 186344</a> |
| */ |
| private boolean fLinkingEnabledDelayed; |
| |
| protected Map _resourceToModel = new HashMap(); |
| |
| protected CRoot _root; |
| protected Object _realInput; |
| |
| public void init(ICommonContentExtensionSite commonContentExtensionSite) { |
| IMemento memento = commonContentExtensionSite.getMemento(); |
| restoreState(memento); |
| |
| } |
| |
| public void restoreState(IMemento memento) { |
| } |
| |
| public void saveState(IMemento memento) { |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| _realInput = newInput; |
| if (newInput instanceof IWorkspaceRoot) { |
| _root = new CRoot(this, (IResource) newInput); |
| } |
| |
| workaroundForBug186344(); |
| } |
| |
| /** |
| * Old workaround for <a |
| * href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186344">bug |
| * 186344</a>. Kept for backword compatibility. |
| */ |
| private void workaroundForBug186344() { |
| if (fLinkingEnabledDelayed) { |
| // enable linking delayed |
| fLinkingEnabledDelayed = false; |
| final IWorkbenchWindow window = PlatformUI.getWorkbench() |
| .getActiveWorkbenchWindow(); |
| if (window != null) { |
| final IWorkbenchPage page = window.getActivePage(); |
| if (page != null) { |
| IViewPart viewPart = page.findView(ProjectExplorer.VIEW_ID); |
| if (viewPart instanceof CommonNavigator) { |
| final CommonNavigator cn = ((CommonNavigator) viewPart); |
| viewPart.getSite().getShell().getDisplay().asyncExec( |
| new Runnable() { |
| public void run() { |
| cn.setLinkingEnabled(true); |
| } |
| }); |
| } |
| } |
| } |
| } |
| } |
| |
| public Object getParent(Object element) { |
| Object parent; |
| if (element instanceof CElement) |
| parent = ((CElement) element).getParent(); |
| else |
| parent = ((IResource) element).getParent(); |
| if (parent instanceof CRoot) { |
| return ResourcesPlugin.getWorkspace().getRoot(); |
| } else if (parent instanceof CProject) |
| return ((CProject) parent).getResource(); |
| return parent; |
| } |
| |
| public Object[] getElements(Object parent) { |
| if (parent instanceof IWorkspaceRoot) { |
| IProject[] projects = ((IWorkspaceRoot) parent).getProjects(); |
| for (int i = 0; i < projects.length; i++) { |
| new CProject(this, projects[i], _root); |
| } |
| return projects; |
| } |
| CElement cElement = (CElement) _resourceToModel.get(parent); |
| if (cElement == null) |
| return new Object[]{}; |
| return cElement.getChildren().toArray(); |
| } |
| |
| public Object[] getChildren(Object element) { |
| return getElements(element); |
| } |
| |
| public boolean hasChildren(Object element) { |
| if (element instanceof IProject) { |
| IProject project = (IProject) element; |
| return project.isAccessible(); |
| } |
| return getChildren(element).length > 0; |
| } |
| |
| public void getPipelinedChildren(Object parent, Set currentChildren) { |
| customizeCElements(getChildren(parent), currentChildren); |
| } |
| |
| public void getPipelinedElements(Object input, Set currentElements) { |
| // only replace plain resource elements with custom elements |
| // and avoid duplicating elements already customized |
| // by upstream content providers |
| customizeCElements(getElements(input), currentElements); |
| } |
| |
| private void customizeCElements(Object[] cChildren, Set proposedChildren) { |
| List elementList = Arrays.asList(cChildren); |
| Iterator pcIt = proposedChildren.iterator(); |
| while (pcIt.hasNext()) { |
| Object element = pcIt.next(); |
| IResource resource = null; |
| if (element instanceof IResource) { |
| resource = (IResource) element; |
| } else if (element instanceof IAdaptable) { |
| resource = (IResource) ((IAdaptable) element) |
| .getAdapter(IResource.class); |
| } |
| if (resource != null) { |
| int i = elementList.indexOf(resource); |
| if (i >= 0) { |
| cChildren[i] = null; |
| } |
| } |
| } |
| for (int i = 0; i < cChildren.length; i++) { |
| if (cChildren[i] instanceof CElement) { |
| IResource resource = ((CElement) cChildren[i]).getResource(); |
| if (resource != null) { |
| proposedChildren.remove(resource); |
| } |
| proposedChildren.add(cChildren[i]); |
| } else if (cChildren[i] != null) { |
| proposedChildren.add(cChildren[i]); |
| } |
| } |
| } |
| |
| public Object getPipelinedParent(Object object, Object suggestedParent) { |
| return getParent(object); |
| } |
| |
| public PipelinedShapeModification interceptAdd( |
| PipelinedShapeModification addModification) { |
| Object parent = addModification.getParent(); |
| if (parent instanceof CProject) { |
| if (_realInput instanceof IWorkspaceRoot) { |
| addModification.setParent(((CProject) parent).getResource()); |
| } |
| } else if (parent instanceof IProject || parent instanceof IFolder) { |
| // ignore adds to C projects (we are issuing a refresh) |
| IProject project = ((IResource) parent).getProject(); |
| if (hasCNature(project)) { |
| addModification.getChildren().clear(); |
| return addModification; |
| } |
| } else if (parent instanceof IWorkspaceRoot) { |
| // ignore adds of C projects (we are issuing a refresh) |
| for (Iterator iterator = addModification.getChildren().iterator(); iterator |
| .hasNext();) { |
| Object child = iterator.next(); |
| if (child instanceof IProject) { |
| if (hasCNature((IProject) child)) { |
| iterator.remove(); |
| } |
| } |
| } |
| } |
| convertToCElements(addModification); |
| return addModification; |
| } |
| |
| public boolean interceptRefresh(PipelinedViewerUpdate refreshSynchronization) { |
| final Set refreshTargets = refreshSynchronization.getRefreshTargets(); |
| return convertToCElements(refreshTargets); |
| } |
| |
| public PipelinedShapeModification interceptRemove( |
| PipelinedShapeModification removeModification) { |
| final Set children = removeModification.getChildren(); |
| convertToCElements(children); |
| return removeModification; |
| } |
| |
| public boolean interceptUpdate(PipelinedViewerUpdate updateSynchronization) { |
| final Set refreshTargets = updateSynchronization.getRefreshTargets(); |
| return convertToCElements(refreshTargets); |
| } |
| |
| /** |
| * Converts the shape modification to use CElements. |
| * |
| * @param modification |
| * the shape modification to convert |
| * @return <code>true</code> if the shape modification set was modified |
| */ |
| private boolean convertToCElements(PipelinedShapeModification modification) { |
| Object parent = modification.getParent(); |
| // don't convert projects |
| if (parent instanceof IContainer) { |
| IContainer container = (IContainer) parent; |
| IProject project = container.getProject(); |
| if (project != null && hasCNature(project)) { |
| CElement element = new CContainer(this, container, |
| (CElement) _resourceToModel.get(container.getParent())); |
| if (element != null) { |
| // don't convert the root |
| if (!(element instanceof CElement) |
| && !(element instanceof CProject)) { |
| modification.setParent(element); |
| } |
| final Set children = modification.getChildren(); |
| return convertToCElements(children); |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Converts the given set to CElements. |
| * |
| * @param currentChildren |
| * The set of current children that would be contributed or |
| * refreshed in the viewer. |
| * @return <code>true</code> if the input set was modified |
| */ |
| private boolean convertToCElements(Set currentChildren) { |
| LinkedHashSet convertedChildren = new LinkedHashSet(); |
| CElement newChild; |
| for (Iterator iter = currentChildren.iterator(); iter.hasNext();) { |
| Object child = iter.next(); |
| // do not convert IProject |
| if (child instanceof IFile) { |
| IResource resource = (IResource) child; |
| if (resource.isAccessible() |
| && hasCNature(resource.getProject())) { |
| if ((newChild = new CElement(this, resource, |
| (CElement) _resourceToModel.get(resource |
| .getParent()))) != null) { |
| iter.remove(); |
| convertedChildren.add(newChild); |
| } |
| } |
| } |
| if (child instanceof IFolder) { |
| IResource resource = (IResource) child; |
| if (resource.isAccessible() |
| && hasCNature(resource.getProject())) { |
| if ((newChild = new CContainer(this, resource, |
| (CElement) _resourceToModel.get(resource |
| .getParent()))) != null) { |
| iter.remove(); |
| convertedChildren.add(newChild); |
| } |
| } |
| } |
| } |
| if (!convertedChildren.isEmpty()) { |
| currentChildren.addAll(convertedChildren); |
| return true; |
| } |
| return false; |
| } |
| |
| private boolean hasCNature(IProject project) { |
| return project.getName().startsWith("C"); |
| } |
| |
| public void dispose() { |
| } |
| |
| } |