| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.packageview; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IAdaptable; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.TreePath; |
| |
| import org.eclipse.ui.IWorkingSet; |
| import org.eclipse.ui.IWorkingSetManager; |
| |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaModel; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| |
| import org.eclipse.jdt.internal.ui.workingsets.WorkingSetModel; |
| |
| public class WorkingSetAwareContentProvider extends PackageExplorerContentProvider implements IMultiElementTreeContentProvider { |
| |
| private WorkingSetModel fWorkingSetModel; |
| private IPropertyChangeListener fListener; |
| |
| public WorkingSetAwareContentProvider(boolean provideMembers, WorkingSetModel model) { |
| super(provideMembers); |
| fWorkingSetModel= model; |
| fListener= new IPropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent event) { |
| workingSetModelChanged(event); |
| } |
| }; |
| fWorkingSetModel.addPropertyChangeListener(fListener); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void dispose() { |
| fWorkingSetModel.removePropertyChangeListener(fListener); |
| super.dispose(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean hasChildren(Object element) { |
| if (element instanceof IWorkingSet) |
| return true; |
| return super.hasChildren(element); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Object[] getChildren(Object element) { |
| Object[] children; |
| if (element instanceof WorkingSetModel) { |
| Assert.isTrue(fWorkingSetModel == element); |
| return fWorkingSetModel.getActiveWorkingSets(); |
| } else if (element instanceof IWorkingSet) { |
| children= getWorkingSetChildren((IWorkingSet)element); |
| } else { |
| children= super.getChildren(element); |
| } |
| return children; |
| } |
| |
| private Object[] getWorkingSetChildren(IWorkingSet set) { |
| IAdaptable[] elements= fWorkingSetModel.getChildren(set); |
| Set<IAdaptable> result= new HashSet<IAdaptable>(elements.length); |
| for (int i= 0; i < elements.length; i++) { |
| IAdaptable element= elements[i]; |
| if (element instanceof IProject) { |
| processResource((IProject) element, result); // also add closed projects |
| } else if (element instanceof IResource) { |
| IProject project= ((IResource) element).getProject(); |
| if (project.isOpen()) { |
| processResource((IResource) element, result); |
| } |
| } else if (element instanceof IJavaProject) { |
| result.add(element); // also add closed projects |
| } else if (element instanceof IJavaElement) { |
| IJavaElement elem= (IJavaElement) element; |
| IProject project= getProject(elem); |
| if (project != null && project.isOpen()) { |
| result.add(elem); |
| } |
| } else { |
| IProject project= element.getAdapter(IProject.class); |
| if (project != null) { |
| processResource(project, result); |
| } |
| } |
| } |
| return result.toArray(); |
| } |
| |
| private void processResource(IResource resource, Collection<IAdaptable> result) { |
| IJavaElement elem= JavaCore.create(resource); |
| if (elem != null && elem.exists()) { |
| result.add(elem); |
| } else { |
| result.add(resource); |
| } |
| } |
| |
| private IProject getProject(IJavaElement element) { |
| IJavaProject project= element.getJavaProject(); |
| if (project == null) |
| return null; |
| return project.getProject(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public TreePath[] getTreePaths(Object element) { |
| if (element instanceof IWorkingSet) { |
| TreePath path= new TreePath(new Object[] {element}); |
| return new TreePath[] {path}; |
| } |
| List<Object> modelParents= getModelPath(element); |
| List<TreePath> result= new ArrayList<TreePath>(); |
| for (int i= 0; i < modelParents.size(); i++) { |
| result.addAll(getTreePaths(modelParents, i)); |
| } |
| return result.toArray(new TreePath[result.size()]); |
| } |
| |
| private List<Object> getModelPath(Object element) { |
| List<Object> result= new ArrayList<Object>(); |
| result.add(element); |
| Object parent= super.getParent(element); |
| Object input= getViewerInput(); |
| // stop at input or on JavaModel. We never visualize it anyway. |
| while (parent != null && !parent.equals(input) && !(parent instanceof IJavaModel)) { |
| result.add(parent); |
| parent= super.getParent(parent); |
| } |
| Collections.reverse(result); |
| return result; |
| } |
| |
| private List<TreePath> getTreePaths(List<Object> modelParents, int index) { |
| List<TreePath> result= new ArrayList<TreePath>(); |
| Object input= getViewerInput(); |
| Object element= modelParents.get(index); |
| Object[] parents= fWorkingSetModel.getAllParents(element); |
| for (int i= 0; i < parents.length; i++) { |
| List<Object> chain= new ArrayList<Object>(); |
| if (!parents[i].equals(input)) |
| chain.add(parents[i]); |
| for (int m= index; m < modelParents.size(); m++) { |
| chain.add(modelParents.get(m)); |
| } |
| result.add(new TreePath(chain.toArray())); |
| } |
| return result; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Object getParent(Object child) { |
| Object[] parents= fWorkingSetModel.getAllParents(child); |
| if(parents.length == 0) |
| return super.getParent(child); |
| Object first= parents[0]; |
| return first; |
| } |
| |
| @Override |
| protected void augmentElementToRefresh(List<Object> toRefresh, int relation, Object affectedElement) { |
| // we are refreshing the JavaModel and are in working set mode. |
| if (JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).equals(affectedElement)) { |
| toRefresh.remove(affectedElement); |
| toRefresh.add(fWorkingSetModel); |
| } else if (relation == GRANT_PARENT) { |
| Object parent= internalGetParent(affectedElement); |
| if (parent != null) { |
| toRefresh.addAll(Arrays.asList(fWorkingSetModel.getAllParents(parent))); |
| } |
| } |
| List<IAdaptable> nonProjetTopLevelElemens= fWorkingSetModel.getNonProjectTopLevelElements(); |
| if (nonProjetTopLevelElemens.isEmpty()) |
| return; |
| List<Object> toAdd= new ArrayList<Object>(); |
| for (Iterator<IAdaptable> iter= nonProjetTopLevelElemens.iterator(); iter.hasNext();) { |
| Object element= iter.next(); |
| if (isChildOf(element, toRefresh)) |
| toAdd.add(element); |
| } |
| toRefresh.addAll(toAdd); |
| } |
| |
| private void workingSetModelChanged(PropertyChangeEvent event) { |
| String property= event.getProperty(); |
| Object newValue= event.getNewValue(); |
| List<Object> toRefresh= new ArrayList<Object>(1); |
| if (WorkingSetModel.CHANGE_WORKING_SET_MODEL_CONTENT.equals(property)) { |
| toRefresh.add(fWorkingSetModel); |
| } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) { |
| toRefresh.add(newValue); |
| } else if (IWorkingSetManager.CHANGE_WORKING_SET_LABEL_CHANGE.equals(property)) { |
| toRefresh.add(newValue); |
| } |
| ArrayList<Runnable> runnables= new ArrayList<Runnable>(); |
| postRefresh(toRefresh, true, runnables); |
| executeRunnables(runnables); |
| } |
| |
| private boolean isChildOf(Object element, List<Object> potentialParents) { |
| // Calling super get parent to bypass working set mapping |
| Object parent= super.getParent(element); |
| if (parent == null) |
| return false; |
| for (Iterator<Object> iter= potentialParents.iterator(); iter.hasNext();) { |
| Object potentialParent= iter.next(); |
| while(parent != null) { |
| if (parent.equals(potentialParent)) |
| return true; |
| parent= super.getParent(parent); |
| } |
| |
| } |
| return false; |
| } |
| } |