blob: 8fa2c27ea045bc722aeac0a408001e7d65c19784 [file] [log] [blame]
package org.eclipse.linuxtools.internal.docker.ui.launch;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
/**
* Base class for {@link ILaunchShortcut} that rely on an
* {@link IDockerConnection} and an {@link IResource}. A matching
* {@link ILaunchConfiguration} may be retrieved from the selected
* {@link IResource} or a new one may be created if needed.
*/
public abstract class BaseResourceAwareLaunchShortcut implements ILaunchShortcut {
@Override
public void launch(final ISelection selection, final String mode) {
if (selection instanceof IStructuredSelection) {
final IResource resource = getResourceFromSelection(selection);
if (resource != null) {
launch(resource, mode);
} else {
MessageDialog.openError(Display.getDefault().getActiveShell(),
LaunchMessages.getString("LaunchShortcut.error.msg"), //$NON-NLS-1$
LaunchMessages.getString("LaunchShortcut.error.msg")); //$NON-NLS-1$
}
}
}
/**
* Retrieves the {@link IResource} associated with the first element in the
* given {@code selection}.
*
* @param selection
* the {@link ISelection} to process
* @return the corresponding {@link IResource} or <code>null</code> if none
* was found
*/
private static IResource getResourceFromSelection(
final ISelection selection) {
final Object selectedElement = ((IStructuredSelection) selection)
.toArray()[0];
if (selectedElement instanceof IResource) {
return (IResource) selectedElement;
} else if (selectedElement instanceof IAdaptable) {
// may return null, which will be dealt with in the caller method
return ((IAdaptable) selection).getAdapter(IResource.class);
}
// if the selected element is neither a resource nor an 'adaptable'
return null;
}
@Override
public void launch(IEditorPart editor, String mode) {
launch(editor.getEditorInput().getAdapter(IResource.class), mode);
}
/**
* Locate a configuration to launch for the given type. If one cannot be
* found, create one.
*
* @param resource
* The {@code docker-compose.yml} to look up launch for.
*
* @return A re-useable config or <code>null</code> if none was found.
*/
protected ILaunchConfiguration findLaunchConfiguration(
final String configTypeId, final IResource resource,
final Predicate<ILaunchConfiguration> predicate) {
final ILaunchConfigurationType configType = LaunchConfigurationUtils
.getLaunchConfigType(
configTypeId);
final List<ILaunchConfiguration> candidateConfigs = new ArrayList<>();
try {
final ILaunchConfiguration[] configs = DebugPlugin.getDefault()
.getLaunchManager().getLaunchConfigurations(configType);
Stream.of(configs).filter(predicate)
.forEach(config -> candidateConfigs.add(config));
} catch (CoreException e) {
Activator.log(e);
}
// If there are no existing configurations associated with the
// given resource,
// create one. If there is exactly one configuration associated with the
// given resource, return it. Otherwise, if there is more than one
// configuration associated with the given resource, prompt the user to
// choose
// one.
int candidateCount = candidateConfigs.size();
if (candidateCount < 1) {
return createConfiguration(resource);
} else if (candidateCount == 1) {
return candidateConfigs.get(0);
} else {
// Prompt the user to choose a configuration. A null result means
// the user
// cancelled the dialog, in which case this method returns null,
// since canceling the dialog should also cancel launching
// anything.
return chooseConfiguration(candidateConfigs);
}
}
/**
* Get the path of the {@code Dockerfile}.
*
* @param sourcePathLocation
* - location path of the {@code Dockerfile}
* @param sourcePathWorkspaceRelativeLocation
* - true, if path above is relative to workspace
* @return the absolute file path of the {@code Dockerfile}
*/
public static IPath getPath(final String sourcePathLocation,
final boolean sourcePathWorkspaceRelativeLocation) {
if (sourcePathWorkspaceRelativeLocation) {
final IResource resource = ResourcesPlugin.getWorkspace().getRoot()
.findMember(new Path(sourcePathLocation));
if (resource != null)
return resource.getLocation();
else // return an empty path that won't match an existing resource
return new Path(""); //$NON-NLS-1$
}
return new Path(sourcePathLocation);
}
protected abstract ILaunchConfiguration createConfiguration(
final IResource resource);
/**
* Show a selection dialog that allows the user to choose one of the
* specified launch configurations.
*
* @param configList
* The list of launch configurations to choose from.
* @return The chosen config, or <code>null</code> if the user cancelled the
* dialog.
*/
protected ILaunchConfiguration chooseConfiguration(List<ILaunchConfiguration> configList) {
IDebugModelPresentation labelProvider = DebugUITools
.newDebugModelPresentation();
ElementListSelectionDialog dialog = new ElementListSelectionDialog(
getActiveWorkbenchShell(), labelProvider);
dialog.setElements(configList.toArray());
dialog.setTitle(
LaunchMessages.getString(
"DockerComposeUpShortcutConfigSelection.title")); //$NON-NLS-1$
dialog.setMessage(
LaunchMessages
.getString("DockerComposeUpShortcutChooseLaunch.msg")); //$NON-NLS-1$
dialog.setMultipleSelection(false);
int result = dialog.open();
labelProvider.dispose();
if (result == IStatus.OK) {
return (ILaunchConfiguration) dialog.getFirstResult();
}
return null;
}
/**
* Get the active Workbench shell.
*
* @return active shell as returned by the plug-in
*/
protected Shell getActiveWorkbenchShell() {
return Activator.getActiveWorkbenchShell();
}
protected abstract void launch(IResource resource, String mode);
}