blob: 3eb7017d2a6359c67647958d8c472c91dc31459a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.debug.ui.launchConfigurations;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.debug.ui.messages.DLTKLaunchConfigurationsMessages;
import org.eclipse.dltk.internal.launching.LaunchConfigurationUtils;
import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants;
import org.eclipse.dltk.launching.process.ScriptRuntimeProcessFactory;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.preferences.FieldValidators;
import org.eclipse.dltk.ui.preferences.FieldValidators.FilePathValidator;
import org.eclipse.dltk.ui.util.SWTFactory;
import org.eclipse.dltk.utils.PlatformFileUtils;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;
public abstract class MainLaunchConfigurationTab extends
ScriptLaunchConfigurationTab implements IMainLaunchConfigurationTab {
private Text fScriptText;
private Button interactiveConsoleCheck;
private boolean useInteractiveConsoleGroup = false;
private final ListenerList<IMainLaunchConfigurationTabListener> listeners = new ListenerList<>();
public MainLaunchConfigurationTab(String mode) {
super(mode);
}
@Override
public void addListener(IMainLaunchConfigurationTabListener listener) {
this.listeners.add(listener);
}
@Override
public void removeListener(IMainLaunchConfigurationTabListener listener) {
this.listeners.remove(listener);
}
/*
* Increase visibility
*/
@Override
public IScriptProject getProject() {
return super.getProject();
}
private IProject lastProjectNotification = null;
private void notifyProjectChangedListeners(IProject project) {
if (project != null) {
if (project.equals(lastProjectNotification)) {
return;
}
} else {
if (lastProjectNotification == null) {
return;
}
}
lastProjectNotification = project;
for (IMainLaunchConfigurationTabListener listener : this.listeners) {
listener.projectChanged(project);
}
}
private void notifyInteractiveChangedListeners(boolean value) {
for (IMainLaunchConfigurationTabListener listener : listeners) {
listener.interactiveChanged(value);
}
}
/**
* Enable this to allow interactive group support.
*/
protected void enableInteractiveConsoleGroup() {
this.useInteractiveConsoleGroup = true;
}
@Override
protected void doInitializeForm(ILaunchConfiguration config) {
updateMainModuleFromConfig(config);
initializeDebugConsole(config);
initializeInteractiveConsoleFrom(config);
}
private void initializeDebugConsole(ILaunchConfiguration config) {
if (debugConsole != null) {
debugConsole.setSelection(LaunchConfigurationUtils.getBoolean(
config,
ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONSOLE,
true));
}
}
protected void initializeInteractiveConsoleFrom(
ILaunchConfiguration config) {
if (useInteractiveConsoleGroup) {
boolean console = LaunchConfigurationUtils.getBoolean(config,
ScriptLaunchConfigurationConstants.ATTR_USE_INTERACTIVE_CONSOLE,
false);
this.interactiveConsoleCheck.setSelection(console);
}
}
private Button fSearchButton;
protected static final String FIELD_SCRIPT = "mainScript"; //$NON-NLS-1$
/**
* Creates the widgets for specifying a main type.
*
* @param parent
* the parent composite
*/
protected void createMainModuleEditor(Composite parent, String text) {
final Composite editParent;
if (needGroupForField(FIELD_SCRIPT)) {
Group mainGroup = new Group(parent, SWT.NONE);
mainGroup.setText(text);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
mainGroup.setLayoutData(gd);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
mainGroup.setLayout(layout);
editParent = mainGroup;
} else {
createLabelForField(parent, FIELD_SCRIPT, text);
editParent = parent;
}
fScriptText = new Text(editParent, SWT.SINGLE | SWT.BORDER);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
WidgetListener listener = getWidgetListener();
fScriptText.setLayoutData(gd);
fScriptText.addModifyListener(listener);
fSearchButton = createPushButton(editParent,
DLTKLaunchConfigurationsMessages.mainTab_searchButton, null);
fSearchButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleSearchButtonSelected();
}
});
}
/**
* @param enabled
*/
protected void setEnableScriptField(boolean enabled) {
fScriptText.setEnabled(enabled);
fSearchButton.setEnabled(enabled && isValidProject());
}
/**
* The select button pressed handler
*/
protected void handleSearchButtonSelected() {
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
getShell(), new WorkbenchLabelProvider(),
new WorkbenchContentProvider());
dialog.setTitle(
DLTKLaunchConfigurationsMessages.mainTab_searchButton_title);
dialog.setMessage(
DLTKLaunchConfigurationsMessages.mainTab_searchButton_message);
IScriptProject proj = getProject();
if (proj == null)
return;
dialog.setInput(proj.getProject());
dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
if (dialog.open() == IDialogConstants.OK_ID) {
IResource resource = (IResource) dialog.getFirstResult();
String arg = resource.getProjectRelativePath().toPortableString();
// check extension
fScriptText.setText(arg);
}
}
/**
* Loads the main type from the launch configuration's preference store
*
* @param config
* the config to load the main type from
*/
protected void updateMainModuleFromConfig(ILaunchConfiguration config) {
fScriptText.setText(getMainModuleName(config));
}
@Override
protected void doCreateControl(Composite composite) {
createMainModuleEditor(composite,
DLTKLaunchConfigurationsMessages.mainTab_mainModule);
}
@Override
protected void createDebugOptions(Composite group) {
super.createDebugOptions(group);
if (canSelectDebugConsoleType()) {
debugConsole = SWTFactory.createCheckButton(group,
DLTKLaunchConfigurationsMessages.mainTab_debugConsoleRedirect);
debugConsole.addSelectionListener(getWidgetListener());
}
}
protected boolean canSelectDebugConsoleType() {
return false;
}
private Button debugConsole;
/*
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
*/
@Override
public String getName() {
return DLTKLaunchConfigurationsMessages.mainTab_title;
}
@Override
protected void setDefaults(ILaunchConfigurationWorkingCopy configuration,
IModelElement element) {
super.setDefaults(configuration, element);
if (element instanceof ISourceModule) {
configuration.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
element.getResource().getProjectRelativePath().toString());
}
setDefaultsDebugConsole(configuration, element);
}
private void setDefaultsDebugConsole(
ILaunchConfigurationWorkingCopy configuration,
IModelElement element) {
if (debugConsole != null) {
debugConsole.setSelection(true);
}
}
@Override
protected void doPerformApply(ILaunchConfigurationWorkingCopy config) {
config.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
getScriptName());
applyProcessFactory(config);
if (debugConsole != null) {
config.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONSOLE,
debugConsole.getSelection());
}
performApplyConnectionTimeout(config);
performApplyInteractiveConsole(config);
}
/**
* @since 2.0
*/
protected void applyProcessFactory(ILaunchConfigurationWorkingCopy config) {
config.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID,
ScriptRuntimeProcessFactory.PROCESS_FACTORY_ID);
}
protected void performApplyConnectionTimeout(
ILaunchConfigurationWorkingCopy config) {
config.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_DLTK_DBGP_WAITING_TIMEOUT,
(String) null);
}
@Override
protected IResource getResource(ILaunchConfiguration config)
throws CoreException {
final String projectName = LaunchConfigurationUtils
.getProjectName(config);
if (projectName == null || projectName.length() == 0
|| !Path.ROOT.isValidSegment(projectName)) {
return null;
}
final IProject project = getWorkspaceRoot().getProject(projectName);
if (project.exists() && project.isOpen()) {
final String scriptName = config.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
(String) null);
if (scriptName != null && scriptName.length() != 0
&& new Path(scriptName).segmentCount() > 0
&& Path.ROOT.isValidPath(scriptName)) {
final IFile scriptFile = project.getFile(scriptName);
if (scriptFile.exists()) {
return scriptFile;
}
}
}
return project;
}
protected void performApplyInteractiveConsole(
ILaunchConfigurationWorkingCopy config) {
if (useInteractiveConsoleGroup) {
final boolean useInteractiveConsole = this.interactiveConsoleCheck
.getSelection();
config.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_USE_INTERACTIVE_CONSOLE,
useInteractiveConsole);
String old = null;
try {
old = config.getAttribute(
ScriptLaunchConfigurationConstants.ATTR_DLTK_CONSOLE_ID,
(String) null);
} catch (CoreException e) {
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
if (old == null) {
config.setAttribute(
ScriptLaunchConfigurationConstants.ATTR_DLTK_CONSOLE_ID,
"dltk_" + System.currentTimeMillis()); //$NON-NLS-1$
}
}
}
protected String getScriptName() {
return fScriptText.getText().trim();
}
protected void setScriptName(String value) {
fScriptText.setText(value);
}
/**
* Validates the selected launch script.
*
* @return true if the selected script is valid, false otherwise
*/
protected boolean validateScript() {
URI script = validateAndGetScriptPath();
IScriptProject project = getProject();
IEnvironment environment = EnvironmentManager.getEnvironment(project);
if (script != null) {
FilePathValidator validator = new FieldValidators.FilePathValidator();
IStatus result = validator.validate(script, environment);
if (!result.isOK()) {
IFileHandle file = PlatformFileUtils
.findAbsoluteOrEclipseRelativeFile(environment,
Path.fromPortableString(script.getPath()));
if (file.exists() && file.isDirectory()) {
if (useInteractiveConsoleGroup) {
if (!interactiveConsoleCheck.getSelection()) {
setErrorMessage(
DLTKLaunchConfigurationsMessages.MainLaunchConfigurationTab_0);
return false;
}
return true;
} else {
setErrorMessage(
DLTKLaunchConfigurationsMessages.error_scriptNotFound);
return false;
}
}
setErrorMessage(
DLTKLaunchConfigurationsMessages.error_scriptNotFound);
return false;
}
}
return true;
}
/**
* typo in method name
*
* @return
*/
@Deprecated
protected final URI validatAndGetScriptPath() {
return validateAndGetScriptPath();
}
/**
* Gets the currently selected {@link ISourceModule}.
*
* @return the selected source module or <code>null</code>
*/
protected ISourceModule getSourceModule() {
final IScriptProject project = this.getProject();
if (project == null) {
return null;
}
final String scriptName = getScriptName();
if (scriptName.length() == 0) {
return null;
}
final IFile file = project.getProject().getFile(scriptName);
return (ISourceModule) DLTKCore.create(file);
}
protected URI validateAndGetScriptPath() {
String projectName = getProjectName();
IScriptProject proj = getScriptModel().getScriptProject(projectName);
if (proj != null) {
notifyProjectChangedListeners(proj.getProject());
} else {
return null;
}
URI location = proj.getProject().getLocationURI();
if (location == null) {
setErrorMessage(
DLTKLaunchConfigurationsMessages.error_notAValidProject);
return null;
}
URI script = null;
try {
script = new URI(location.getScheme(), location.getHost(),
location.getPath() + '/' + getScriptName(),
location.getFragment());
} catch (URISyntaxException e) {
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
if (script != null) {
IFile[] files = getWorkspaceRoot().findFilesForLocationURI(script);
if (files.length != 1) {
return script;
}
IFile file = files[0];
if (file.exists() && file.getLocationURI() != null) {
script = file.getLocationURI();
}
}
return script;
}
@Override
protected boolean validate() {
return super.validate() && validateScript();
}
@Override
public Image getImage() {
return DLTKPluginImages.get(DLTKPluginImages.IMG_OBJS_CLASS);
}
private String getMainModuleName(ILaunchConfiguration config) {
return LaunchConfigurationUtils.getString(config,
ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
EMPTY_STRING);
}
@Override
protected void createCustomSections(Composite parent) {
if (useInteractiveConsoleGroup) {
Group group = new Group(parent, SWT.NONE);
group.setText(
DLTKLaunchConfigurationsMessages.MainLaunchConfigurationTab_1);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
group.setLayoutData(gd);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
group.setLayout(layout);
interactiveConsoleCheck = createCheckButton(group,
DLTKLaunchConfigurationsMessages.MainLaunchConfigurationTab_2);
interactiveConsoleCheck.addSelectionListener(getWidgetListener());
interactiveConsoleCheck
.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
notifyInteractiveChangedListeners(
interactiveConsoleCheck.getSelection());
}
});
}
}
}