/******************************************************************************* * Copyright (c) 2011 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.ui.views.workingsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.tm.te.runtime.events.EventManager; import org.eclipse.tm.te.runtime.interfaces.workingsets.IWorkingSetElement; import org.eclipse.tm.te.ui.views.events.ViewerContentChangeEvent; import org.eclipse.tm.te.ui.views.interfaces.IUIConstants; import org.eclipse.tm.te.ui.views.interfaces.workingsets.IWorkingSetIDs; import org.eclipse.tm.te.ui.views.internal.View; import org.eclipse.tm.te.ui.views.internal.ViewRoot; import org.eclipse.tm.te.ui.views.nls.Messages; import org.eclipse.ui.IAggregateWorkingSet; import org.eclipse.ui.ILocalWorkingSetManager; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.navigator.NavigatorContentService; import org.eclipse.ui.navigator.CommonNavigator; import org.eclipse.ui.navigator.CommonViewer; import org.eclipse.ui.navigator.ICommonContentExtensionSite; import org.eclipse.ui.navigator.ICommonContentProvider; import org.eclipse.ui.navigator.IExtensionStateModel; /** * Provides children and parents for IWorkingSets. * <p> * Copied and adapted from <code>org.eclipse.ui.internal.navigator.workingsets.WorkingSetContentProvider</code>. */ @SuppressWarnings("restriction") public class WorkingSetsContentProvider implements ICommonContentProvider { /** * The extension id for the WorkingSet extension. */ public static final String EXTENSION_ID = "org.eclipse.tm.te.ui.views.navigator.content.workingSets"; //$NON-NLS-1$ /** * A key used by the Extension State Model to keep track of whether top level Working Sets or * Projects should be shown in the viewer. */ public static final String SHOW_TOP_LEVEL_WORKING_SETS = EXTENSION_ID + ".showTopLevelWorkingSets"; //$NON-NLS-1$ private static final Object[] NO_CHILDREN = new Object[0]; private WorkingSetHelper helper; /* default */ IAggregateWorkingSet workingSetRoot; private IExtensionStateModel extensionStateModel; private CommonNavigator targetExplorer; private CommonViewer viewer; private ILocalWorkingSetManager localWorkingSetManager; private IPropertyChangeListener rootModeListener = new IPropertyChangeListener() { /* (non-Javadoc) * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ @SuppressWarnings("synthetic-access") @Override public void propertyChange(PropertyChangeEvent event) { if (SHOW_TOP_LEVEL_WORKING_SETS.equals(event.getProperty())) { updateRootMode(); } } }; /* (non-Javadoc) * @see org.eclipse.ui.navigator.ICommonContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite) */ @Override public void init(ICommonContentExtensionSite config) { NavigatorContentService cs = (NavigatorContentService) config.getService(); viewer = (CommonViewer) cs.getViewer(); targetExplorer = viewer.getCommonNavigator(); localWorkingSetManager = targetExplorer instanceof View ? ((View)targetExplorer).getLocalWorkingSetManager() : PlatformUI.getWorkbench().createLocalWorkingSetManager(); extensionStateModel = config.getExtensionStateModel(); extensionStateModel.addPropertyChangeListener(rootModeListener); updateRootMode(); } /* (non-Javadoc) * @see org.eclipse.ui.navigator.IMementoAware#restoreState(org.eclipse.ui.IMemento) */ @Override public void restoreState(IMemento memento) { // We can call the local working set manager restoreState(memento) method // only as long the working set manager is empty if (memento != null && localWorkingSetManager.getWorkingSets().length == 0) { localWorkingSetManager.restoreState(memento); IWorkingSet old = localWorkingSetManager.getWorkingSet("Others"); //$NON-NLS-1$ if (old != null) localWorkingSetManager.removeWorkingSet(old); // Create the "Others" working set if not restored from the memento IWorkingSet others = localWorkingSetManager.getWorkingSet(Messages.WorkingSetContentProvider_others_name); if (others == null) { others = localWorkingSetManager.createWorkingSet(Messages.WorkingSetContentProvider_others_name, new IAdaptable[0]); others.setId(IWorkingSetIDs.ID_WS_OTHERS); localWorkingSetManager.addWorkingSet(others); } else { others.setId(IWorkingSetIDs.ID_WS_OTHERS); } } // Trigger an update of the "Others" working set ViewerContentChangeEvent event = new ViewerContentChangeEvent(viewer, ViewerContentChangeEvent.REFRESH); EventManager.getInstance().fireEvent(event); } /* (non-Javadoc) * @see org.eclipse.ui.navigator.IMementoAware#saveState(org.eclipse.ui.IMemento) */ @Override public void saveState(IMemento memento) { if (memento != null) localWorkingSetManager.saveState(memento); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof IWorkingSet) { IWorkingSet workingSet = (IWorkingSet) parentElement; if (workingSet.isAggregateWorkingSet() && targetExplorer != null) { switch (targetExplorer.getRootMode()) { case IUIConstants.MODE_WORKING_SETS: List<IWorkingSet> allWorkingSets = new ArrayList<IWorkingSet>(); allWorkingSets.addAll(Arrays.asList(((IAggregateWorkingSet) workingSet).getComponents())); allWorkingSets.addAll(Arrays.asList(localWorkingSetManager.getWorkingSets())); return allWorkingSets.toArray(new IWorkingSet[allWorkingSets.size()]); case IUIConstants.MODE_NORMAL: return getWorkingSetElements(workingSet); } } return getWorkingSetElements(workingSet); } return NO_CHILDREN; } /* default */ IAdaptable[] getWorkingSetElements(IWorkingSet workingSet) { Assert.isNotNull(workingSet); List<IAdaptable> elements = new ArrayList<IAdaptable>(); for (IAdaptable candidate : workingSet.getElements()) { if (candidate instanceof WorkingSetElementHolder) { WorkingSetElementHolder holder = (WorkingSetElementHolder)candidate; IWorkingSetElement element = holder.getElement(); // If the element is null, try to look up the element through the content provider if (element == null) { ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider(); for (Object elementCandidate : contentProvider.getElements(ViewRoot.getInstance())) { if (elementCandidate instanceof IWorkingSetElement && ((IWorkingSetElement)elementCandidate).getElementId().equals(holder.getElementId())) { holder.setElement((IWorkingSetElement)elementCandidate); element = holder.getElement(); break; } } } if (element != null) elements.add(element); } else { elements.add(candidate); } } return elements.toArray(new IAdaptable[elements.size()]); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ @Override public Object getParent(Object element) { if (helper != null) return helper.getParent(element); return null; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ @Override public boolean hasChildren(Object element) { return true; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object) */ @Override public Object[] getElements(Object inputElement) { return getChildren(inputElement); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() { helper = null; extensionStateModel.removePropertyChangeListener(rootModeListener); // If we have create the local working set manager, we have to dispose it if (!(targetExplorer instanceof View)) localWorkingSetManager.dispose(); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (newInput instanceof IWorkingSet) { IWorkingSet rootSet = (IWorkingSet) newInput; helper = new WorkingSetHelper(rootSet); } } private void updateRootMode() { if (targetExplorer == null) { return; } if (extensionStateModel.getBooleanProperty(SHOW_TOP_LEVEL_WORKING_SETS)) { targetExplorer.setRootMode(IUIConstants.MODE_WORKING_SETS); } else { targetExplorer.setRootMode(IUIConstants.MODE_NORMAL); } } protected class WorkingSetHelper { private final IWorkingSet workingSet; private final Map<Object, Object> parents = new WeakHashMap<Object, Object>(); /** * Create a Helper class for the given working set * * @param set The set to use to build the item to parent map. */ public WorkingSetHelper(IWorkingSet set) { workingSet = set; if (workingSet.isAggregateWorkingSet()) { IAggregateWorkingSet aggregateSet = (IAggregateWorkingSet) workingSet; if (workingSetRoot == null) workingSetRoot = aggregateSet; IWorkingSet[] components = aggregateSet.getComponents(); for (int componentIndex = 0; componentIndex < components.length; componentIndex++) { IAdaptable[] elements = getWorkingSetElements(components[componentIndex]); for (int elementsIndex = 0; elementsIndex < elements.length; elementsIndex++) { parents.put(elements[elementsIndex], components[componentIndex]); } parents.put(components[componentIndex], aggregateSet); } } else { IAdaptable[] elements = getWorkingSetElements(workingSet); for (int elementsIndex = 0; elementsIndex < elements.length; elementsIndex++) { parents.put(elements[elementsIndex], workingSet); } } } /** * * @param element An element from the viewer * @return The parent associated with the element, if any. */ public Object getParent(Object element) { if (element instanceof IWorkingSet && element != workingSetRoot) return workingSetRoot; return parents.get(element); } } }