| /******************************************************************************* |
| * 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()); |
| } |
| }); |
| } |
| } |
| } |