blob: b2e16ced79599876907c9f5ee7880a77b4da201b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2018 Red Hat Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui.commands;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.expressions.EvaluationContext;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerPortMapping;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.ui.DockerConnectionWatcher;
import org.eclipse.linuxtools.internal.docker.ui.consoles.RunConsole;
import org.eclipse.linuxtools.internal.docker.ui.preferences.PreferenceConstants;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerContainersView;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider.DockerContainerVolume;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerImageHierarchyView;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerService;
/**
* Utility class for all {@link IHandler} command handlers
*
*/
public class CommandUtils {
/**
* Refreshes (async) the {@link Viewer}.
*
* @param viewer
* - the {@link Viewer} to refresh
*/
public static void asyncRefresh(final Viewer viewer) {
Display.getDefault().asyncExec(() -> {
if (viewer != null && !viewer.getControl().isDisposed()) {
viewer.refresh();
}
});
}
/**
* @return the current {@link IDockerConnection} associated with the given
* {@link IWorkbenchPart} or {@code null} if none could be found.
* @param activePart
* - active Workbench part
*/
public static IDockerConnection getCurrentConnection(
final IWorkbenchPart activePart) {
if (DockerConnectionWatcher.getInstance().getConnection() != null)
return DockerConnectionWatcher.getInstance().getConnection();
else if (activePart instanceof DockerContainersView) {
return ((DockerContainersView) activePart).getConnection();
} else if (activePart instanceof DockerImagesView) {
return ((DockerImagesView) activePart).getConnection();
}
// fall back to first active connection in list if one exists
return Stream.of(DockerConnectionManager.getInstance().getConnections())
.filter(c -> c.isOpen()).findFirst().orElse(null);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the {@link List} of selected elements in the given active part or
* {@link Collections#emptyList()} if none was selected
*/
public static List<Object> getSelectedElements(
final IWorkbenchPart activePart) {
return getSelectedElements(activePart, Object.class);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the of selected element in the given active part or
* <code>null</code> if none was found
*/
public static Object getSelectedElement(final IWorkbenchPart activePart) {
final List<Object> selectedElements = getSelectedElements(activePart,
Object.class);
if (selectedElements != null && !selectedElements.isEmpty()) {
return selectedElements.get(0);
}
return null;
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @param targetClass
* @return the {@link List} of selected {@link IDockerContainer} in the
* given active part of {@link Collections#emptyList()} if none was
* selected
*/
private static <T> List<T> getSelectedElements(
final IWorkbenchPart activePart, final Class<T> targetClass) {
if (activePart instanceof DockerContainersView) {
final IStructuredSelection selection = ((DockerContainersView) activePart)
.getStructuredSelection();
return castSelectionTo(selection, targetClass);
} else if (activePart instanceof DockerImagesView) {
final IStructuredSelection selection = ((DockerImagesView) activePart)
.getStructuredSelection();
return castSelectionTo(selection, targetClass);
} else if (activePart instanceof DockerExplorerView) {
final IStructuredSelection selection = ((DockerExplorerView) activePart)
.getCommonViewer().getStructuredSelection();
return castSelectionTo(selection, targetClass);
} else if (activePart instanceof DockerImageHierarchyView) {
final IStructuredSelection selection = ((DockerImageHierarchyView) activePart)
.getCommonViewer().getStructuredSelection();
return adaptSelectionTo(selection, targetClass);
}
return Collections.emptyList();
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the {@link List} of selected {@link IDockerContainer} in the
* given active part of {@link Collections#emptyList()} if none was
* selected
*/
public static List<IDockerContainer> getSelectedContainers(
final IWorkbenchPart activePart) {
return getSelectedElements(activePart, IDockerContainer.class);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the {@link List} of selected {@link DockerContainerPortMapping}
* in the given active part of {@link Collections#emptyList()} if
* none was selected
*/
public static List<IDockerPortMapping> getSelectedPortMappings(
final IWorkbenchPart activePart) {
return getSelectedElements(activePart, IDockerPortMapping.class);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the {@link List} of selected {@link DockerContainerVolume} in the
* given active part of {@link Collections#emptyList()} if none was
* selected
*/
public static List<DockerContainerVolume> getSelectedVolumes(
final IWorkbenchPart activePart) {
return getSelectedElements(activePart, DockerContainerVolume.class);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the {@link List} of selected {@link IDockerImage} in the given
* active part of {@link Collections#emptyList()} if none was
* selected
*/
public static List<IDockerImage> getSelectedImages(
final IWorkbenchPart activePart) {
return getSelectedElements(activePart, IDockerImage.class);
}
/**
* @param activePart
* the active {@link IWorkbenchPart}
* @return the selected {@link IDockerImage} in the given active part of
* <code>null</code> if none was selected
*/
public static IDockerImage getSelectedImage(
final IWorkbenchPart activePart) {
final List<IDockerImage> selectedImages = getSelectedImages(activePart);
if (selectedImages == null || selectedImages.isEmpty()) {
return null;
}
return selectedImages.get(0);
}
/**
* Returns the given {@link List} <strong>typed</strong> with the given
* {@code targetClass}.
*
* @param selection
* the current selection
* @return Returns the given {@link List} typed with the
* {@code targetClass}.
*/
@SuppressWarnings("unchecked")
private static <T> List<T> castSelectionTo(
final IStructuredSelection selection, final Class<T> targetClass) {
return (List<T>) selection.toList().stream()
.filter(selectedElement -> targetClass
.isAssignableFrom(selectedElement.getClass()))
.map(selectedElement -> (T) selectedElement)
.collect(Collectors.toList());
}
/**
* Returns the given {@link List} <strong>adapted</strong> to the given
* {@code targetClass}.
*
* @param selection
* the current selection
* @param targetClass
* the target class in which the elements of the given
* {@code selection} should be adapted
* @return Returns the given {@link List} adapted to the
* {@code targetClass}.
*/
@SuppressWarnings("unchecked")
private static <T> List<T> adaptSelectionTo(
final IStructuredSelection selection, final Class<T> targetClass) {
return (List<T>) selection.toList().stream()
.filter(selectedElement -> selectedElement instanceof IAdaptable
&& ((IAdaptable) selectedElement)
.getAdapter(targetClass) != null)
.map(selectedElement -> ((IAdaptable) selectedElement)
.getAdapter(targetClass))
.collect(Collectors.toList());
}
/**
* Finds and returns a cleared {@link RunConsole} if the preference
* {@link PreferenceConstants#AUTOLOG_ON_START} is set to {@code true}.
*
* @param connection
* the current Docker connection
* @param container
* the container whose log should be sent in the
* {@link RunConsole}.
* @return the {@link RunConsole} or {@code null}
*/
public static RunConsole getRunConsole(final IDockerConnection connection, final IDockerContainer container) {
if (container != null
&& connection.getContainerInfo(container.id()) != null
&& connection.getContainerInfo(container.id()).config() != null
&& connection.getContainerInfo(container.id()).config().tty()) {
RunConsole.attachToTerminal(connection, container.id(), null);
return null;
}
final boolean autoLogOnStart = Activator.getDefault().getPreferenceStore()
.getBoolean(PreferenceConstants.AUTOLOG_ON_START);
// if we are auto-logging, grab the
// console for the container id and get
// its stream.
if (autoLogOnStart) {
final RunConsole console = RunConsole.findConsole(container);
if (console != null) {
console.attachToConsole(connection);
console.clearConsole();
return console;
}
}
return null;
}
/**
* Opens the given {@link IWizard} and returns <code>true</code> if the user
* finished the operation, <code>false</code> if he cancelled it.
*
* @param wizard
* the wizard to open
* @param shell
* the current {@link Shell}
* @return <code>true</code> if the wizard completed, <code>false</code>
* otherwise.
*/
public static boolean openWizard(final IWizard wizard, final Shell shell) {
final WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizardDialog.create();
return wizardDialog.open() == Window.OK;
}
/**
* Opens the given {@link IWizard} and returns <code>true</code> if the user
* finished the operation, <code>false</code> if he cancelled it.
*
* @param wizard
* the wizard to open
* @param shell
* the current {@link Shell}
* @param width
* width of the wizard
* @param height
* height of the wizard
* @return <code>true</code> if the wizard completed, <code>false</code>
* otherwise.
*/
public static boolean openWizard(final IWizard wizard, final Shell shell,
final int width, final int height) {
final WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizardDialog.setPageSize(width, height);
wizardDialog.create();
return wizardDialog.open() == Window.OK;
}
/**
* Executes the command identified by the given {@code id} on a context
* based on the given selection
*
* @param id
* the id of the command to execute
* @param selection
* the selection to use as a context to run the command
*/
public static void execute(final String id,
final IStructuredSelection selection) {
final ICommandService service = PlatformUI.getWorkbench()
.getService(ICommandService.class);
final Command command = service != null ? service.getCommand(id) : null;
if (command != null && command.isDefined()) {
try {
ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(command, null);
IHandlerService handlerSvc = PlatformUI.getWorkbench().getService(IHandlerService.class);
IEvaluationContext ctx = handlerSvc.getCurrentState();
ctx = new EvaluationContext(ctx, selection);
ctx.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
handlerSvc.executeCommandInContext(pCmd, null, ctx);
} catch (Exception e) {
Activator.log(e);
}
}
}
}