Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: ae84b5690b1a4813d53dc58ff75ce90c19014986 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*******************************************************************************
 * Copyright (c) 2016, 2018 Red Hat.
 * 
 * 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.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);

}

Back to the top