blob: fbe73b732966d9f43a355de139d7c0a18426edcc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2019 Chalmers | University of Gothenburg, rt-labs, IRT SystemX, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IRT SystemX - initial API and implementation
*******************************************************************************/
package org.eclipse.capra.ui.helpers;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.capra.core.helpers.ExtensionPointHelper;
import org.eclipse.capra.ui.selections.ISelectionSupport;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.part.WorkbenchPart;
import org.eclipse.ui.views.properties.PropertySheet;
/**
* A helper for extracting semantic elements from a selection of a workbench
* part. Handles the workbench part handler extensions.
*
* @author Dominique Blouin
*
*/
public class SelectionSupportHelper {
private static final List<ISelectionSupport> SELECTION_SUPPORTS = new ArrayList<>();
static {
for (Object extension : ExtensionPointHelper.getExtensions("org.eclipse.capra.ui.selectionSupport", "class")) {
SELECTION_SUPPORTS.add((ISelectionSupport) extension);
}
}
private SelectionSupportHelper() {
}
/**
* Extract selected elements from an {@link ExecutionEvent}.
*
* @param event This is the click event to create a trace
* @return A list of all the selected elements
*/
public static List<Object> extractSelectedElements(final ExecutionEvent event) {
final IWorkbenchPart workbenchPart = HandlerUtil.getActivePart(event);
final ISelection currentSelection;
// For some reason HandlerUtil.getCurrentSelection(event) returns the
// previous selection in some cases so we look for
// the selection from the selection provider first
if (workbenchPart.getSite().getSelectionProvider() != null) {
currentSelection = workbenchPart.getSite().getSelectionProvider().getSelection();
} else {
currentSelection = HandlerUtil.getCurrentSelection(event);
}
return extractSelectedElements(currentSelection, workbenchPart);
}
/**
* Extract selected elements from an {@link ISelection} by delegating the
* retrieval and unwrapping of the selection to the registered
* {@link ISelectionSupport} instances. If this fails, the selected elements of
* type {@link IAdaptable} are retrieved using
* {@link IAdaptable#getAdapter(Class)}. If this fails, too, the list is either
* empty or only contains those elements that are instances of type
* {@code IAdaptable}.
*
* @param selection the selection from the workbench part
* @param workbenchPart the workbench part from which the selection should be
* extracted
* @return a list of all selected elements retrieved using the first
* {@code IWorkbenchSelectionSupport} instance registered for the
* {@code WorkbenchPart} or all selected elements of type
* {@code IAdaptable}
*/
public static List<Object> extractSelectedElements(final ISelection selection, final IWorkbenchPart workbenchPart) {
List<Object> selectedElem = new ArrayList<>();
for (final ISelectionSupport handler : SELECTION_SUPPORTS) {
if (handler.supportsWorkbenchPart(workbenchPart)) {
List<Object> extractedElements = handler.extractSelectedElements(selection, workbenchPart);
if (extractedElements != null) {
selectedElem.addAll(extractedElements);
break;
}
}
}
if (selectedElem.isEmpty()) {
selectedElem = new ArrayList<>();
if (selection instanceof IStructuredSelection) {
for (final Object selElement : ((IStructuredSelection) selection).toList()) {
final Object element = AdapterFactoryEditingDomain.unwrap(selElement);
Object selectedElement = element;
if (element instanceof IAdaptable) {
final Object adaptedElement = ((IAdaptable) element).getAdapter(Object.class);
if (adaptedElement != null) {
selectedElement = adaptedElement;
}
}
selectedElem.add(selectedElement);
}
}
}
return selectedElem;
}
/**
* Attempts to retrieve the {@link ResourceSet} instance that is used by the
* {@link WorkbenchPart}. The {@code ResourceSet} is only available if the
* {@code WorkbenchPart} handles EMF models. If this is not the case, this
* method returns {@code null}.
*
* @param part the {@code WorkbenchPart} whose {@code ResourceSet} should be
* retrieved
* @return the {@code ResourceSet} used by {@code part} or {@code null} if no
* {@code ResourceSet} can be found
*/
public static ResourceSet getResourceSet(final IWorkbenchPart part) {
ResourceSet resourceSet = null;
if (!(part instanceof PropertySheet)) {
// Iterate over the WorkbenchPartHandlers and find one that can take
// care of the part
for (final ISelectionSupport handler : SELECTION_SUPPORTS) {
if (handler.supportsWorkbenchPart(part)) {
final ResourceSet resSet = handler.getResourceSet(part);
if (resSet != null) {
resourceSet = resSet;
}
}
}
// If that fails, see if we can get the resource set from the
// EditingDomain
if (resourceSet == null) {
final IEditingDomainProvider domainProvider = part.getAdapter(IEditingDomainProvider.class);
if (domainProvider != null) {
return domainProvider.getEditingDomain().getResourceSet();
}
}
}
return resourceSet;
}
}