| /******************************************************************************* |
| * Copyright (c) 2005, 2018 QNX Software Systems 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: |
| * QNX Software Systems - initial API and implementation |
| * Ken Ryall (Nokia) - bug 178731 |
| * IBM Corporation |
| * Sergey Prigogin (Google) |
| *******************************************************************************/ |
| package org.eclipse.linuxtools.profiling.launch; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.model.IBinary; |
| import org.eclipse.cdt.core.model.ICElement; |
| import org.eclipse.cdt.core.model.ICProject; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescription; |
| import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; |
| import org.eclipse.cdt.launch.internal.ui.LaunchImages; |
| import org.eclipse.cdt.launch.internal.ui.LaunchMessages; |
| import org.eclipse.cdt.launch.ui.CAbstractMainTab; |
| import org.eclipse.cdt.launch.ui.ICDTLaunchHelpContextIds; |
| import org.eclipse.cdt.ui.CElementLabelProvider; |
| import org.eclipse.cdt.utils.pty.PTY; |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileInfo; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.linuxtools.internal.profiling.launch.ProfileLaunchPlugin; |
| import org.eclipse.linuxtools.profiling.launch.ui.ResourceSelectorWidget; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionListener; |
| 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.Label; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.dialogs.TwoPaneElementSelector; |
| |
| |
| /** |
| * A launch configuration tab that displays and edits project and main type name |
| * launch configuration attributes. |
| * <p> |
| * This class may be instantiated. This class is not intended to be subclassed. |
| * </p> |
| * |
| * @since 1.1 |
| */ |
| @SuppressWarnings("restriction") |
| public class RemoteProxyCMainTab extends CAbstractMainTab { |
| |
| /** |
| * Tab identifier used for ordering of tabs added using the |
| * <code>org.eclipse.debug.ui.launchConfigurationTabs</code> extension |
| * point. |
| * |
| * @since 6.0 |
| */ |
| public static final String TAB_ID = "org.eclipse.linuxtools.profiling.launch.RemoteProxyCMainTab"; //$NON-NLS-1$ |
| |
| private final boolean fWantsTerminalOption; |
| protected Button fTerminalButton; |
| |
| protected ResourceSelectorWidget exeSelector; |
| |
| protected Text copyFromExeText; |
| protected Button enableCopyFromExeButton; |
| protected ResourceSelectorWidget copyFromExeSelector; |
| protected Label toLabel; |
| protected String fPreviouslyCheckedCopyFromExe; |
| protected boolean fPreviouslyCheckedCopyFromExeIsValid; |
| protected String fPreviouslyCheckedCopyFromExeErrorMsg; |
| |
| protected Text workingDirText; |
| protected String fPreviouslyCheckedWorkingDir; |
| protected boolean fPreviouslyCheckedWorkingDirIsValid; |
| protected String fPreviouslyCheckedWorkingDirErrorMsg; |
| |
| private final boolean dontCheckProgram; |
| private final boolean fSpecifyCoreFile; |
| |
| public static final int WANTS_TERMINAL = 1; |
| public static final int DONT_CHECK_PROGRAM = 2; |
| /** @since 6.0 */ |
| public static final int SPECIFY_CORE_FILE = 4; |
| |
| public static final String ATTR_REMOTE_WORKING_DIRECTORY_NAME = "REMOTE_WORKING_DIRECTORY_NAME"; //$NON-NLS-1$ |
| public static final String ATTR_COPY_FROM_EXE_NAME = "COPY_FROM_EXE_NAME"; //$NON-NLS-1$ |
| public static final String ATTR_ENABLE_COPY_FROM_EXE = "ENABLE_COPY_FROM_EXE"; //$NON-NLS-1$ |
| |
| public RemoteProxyCMainTab() { |
| this(WANTS_TERMINAL); |
| } |
| |
| public RemoteProxyCMainTab(boolean terminalOption) { |
| this(terminalOption ? WANTS_TERMINAL : 0); |
| } |
| |
| public RemoteProxyCMainTab(int flags) { |
| fWantsTerminalOption = (flags & WANTS_TERMINAL) != 0; |
| dontCheckProgram = (flags & DONT_CHECK_PROGRAM) != 0; |
| fSpecifyCoreFile = (flags & SPECIFY_CORE_FILE) != 0; |
| } |
| |
| @Override |
| public void createControl(Composite parent) { |
| Composite comp = new Composite(parent, SWT.NONE); |
| setControl(comp); |
| |
| ProfileLaunchPlugin |
| .getDefault() |
| .getWorkbench() |
| .getHelpSystem() |
| .setHelp( |
| getControl(), |
| ICDTLaunchHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_MAIN_TAB); |
| |
| GridLayout topLayout = new GridLayout(); |
| comp.setLayout(topLayout); |
| |
| createVerticalSpacer(comp, 1); |
| createCopyFromExeGroup(comp, 1); |
| createExeFileGroup(comp, 1); |
| createWorkingDirGroup(comp, 1); |
| createProjectGroup(comp, 1); |
| createBuildOptionGroup(comp, 1); |
| createVerticalSpacer(comp, 1); |
| if (fSpecifyCoreFile) { |
| createCoreFileGroup(comp, 1); |
| } |
| if (wantsTerminalOption() /* && ProcessFactory.supportesTerminal() */) { |
| createTerminalOption(comp, 1); |
| } |
| } |
| |
| protected boolean wantsTerminalOption() { |
| return fWantsTerminalOption; |
| } |
| |
| protected void createTerminalOption(Composite parent, int colSpan) { |
| Composite mainComp = new Composite(parent, SWT.NONE); |
| GridLayout mainLayout = new GridLayout(); |
| mainLayout.numColumns = 1; |
| mainLayout.marginHeight = 0; |
| mainLayout.marginWidth = 0; |
| mainComp.setLayout(mainLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = colSpan; |
| mainComp.setLayoutData(gd); |
| |
| fTerminalButton = createCheckButton(mainComp, |
| LaunchMessages.CMainTab_UseTerminal); |
| fTerminalButton |
| .addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> updateLaunchConfigurationDialog())); |
| fTerminalButton.setEnabled(PTY.isSupported()); |
| } |
| |
| @Override |
| public void initializeFrom(ILaunchConfiguration config) { |
| filterPlatform = getPlatform(config); |
| updateProjectFromConfig(config); |
| updateCopyFromExeFromConfig(config); |
| updateProgramFromConfig(config); |
| updateWorkingDirFromConfig(config); |
| updateCoreFromConfig(config); |
| updateBuildOptionFromConfig(config); |
| updateTerminalFromConfig(config); |
| } |
| |
| protected void updateTerminalFromConfig(ILaunchConfiguration config) { |
| if (fTerminalButton != null) { |
| boolean useTerminal = true; |
| try { |
| useTerminal = config.getAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, |
| ICDTLaunchConfigurationConstants.USE_TERMINAL_DEFAULT); |
| } catch (CoreException e) { |
| ProfileLaunchPlugin.log(e); |
| } |
| fTerminalButton.setSelection(useTerminal); |
| } |
| } |
| |
| /** |
| * @param config The launch config to update from. |
| * @since 6.0 |
| * */ |
| protected void updateCoreFromConfig(ILaunchConfiguration config) { |
| if (fCoreText != null) { |
| String coreName = EMPTY_STRING; |
| try { |
| coreName = config.getAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, |
| EMPTY_STRING); |
| } catch (CoreException ce) { |
| ProfileLaunchPlugin.log(ce); |
| } |
| fCoreText.setText(coreName); |
| } |
| } |
| |
| @Override |
| public void performApply(ILaunchConfigurationWorkingCopy config) { |
| super.performApply(config); |
| ICProject cProject = this.getCProject(); |
| if (cProject != null && cProject.exists()) { |
| config.setMappedResources(new IResource[] { cProject.getProject() }); |
| } else { |
| // the user typed in a non-existent project name. Ensure that |
| // won't be suppressed from the dialog. This matches JDT behaviour |
| config.setMappedResources(null); |
| } |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| fProjText.getText()); |
| if (enableCopyFromExeButton != null) { |
| config.setAttribute( |
| ATTR_ENABLE_COPY_FROM_EXE, |
| enableCopyFromExeButton.getSelection()); |
| } |
| if (copyFromExeText != null) { |
| config.setAttribute( |
| ATTR_COPY_FROM_EXE_NAME, |
| copyFromExeText.getText()); |
| } |
| if (fProgText != null) { |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, |
| fProgText.getText()); |
| } |
| if (workingDirText != null) { |
| config.setAttribute( |
| ATTR_REMOTE_WORKING_DIRECTORY_NAME, |
| workingDirText.getText()); |
| } |
| if (fCoreText != null) { |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, |
| fCoreText.getText()); |
| } |
| if (fTerminalButton != null) { |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, |
| fTerminalButton.getSelection()); |
| } |
| } |
| |
| /** |
| * Show a dialog that lists all main types |
| */ |
| @Override |
| protected void handleSearchButtonSelected() { |
| if (getCProject() == null) { |
| MessageDialog |
| .openInformation( |
| getShell(), |
| LaunchMessages.CMainTab_Project_required, |
| LaunchMessages.CMainTab_Enter_project_before_searching_for_program); |
| return; |
| } |
| |
| ILabelProvider programLabelProvider = new CElementLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| if (element instanceof IBinary) { |
| IBinary bin = (IBinary) element; |
| StringBuilder name = new StringBuilder(); |
| name.append(bin.getPath().lastSegment()); |
| return name.toString(); |
| } |
| return super.getText(element); |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| if (!(element instanceof ICElement)) { |
| return super.getImage(element); |
| } |
| ICElement celement = (ICElement) element; |
| |
| if (celement.getElementType() == ICElement.C_BINARY) { |
| IBinary belement = (IBinary) celement; |
| if (belement.isExecutable()) { |
| return DebugUITools |
| .getImage(IDebugUIConstants.IMG_ACT_RUN); |
| } |
| } |
| |
| return super.getImage(element); |
| } |
| }; |
| |
| ILabelProvider qualifierLabelProvider = new CElementLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| if (element instanceof IBinary) { |
| IBinary bin = (IBinary) element; |
| StringBuilder name = new StringBuilder(); |
| name.append(bin.getCPU() |
| + (bin.isLittleEndian() ? "le" : "be")); //$NON-NLS-1$ //$NON-NLS-2$ |
| name.append(" - "); //$NON-NLS-1$ |
| name.append(bin.getPath().toString()); |
| return name.toString(); |
| } |
| return super.getText(element); |
| } |
| }; |
| |
| TwoPaneElementSelector dialog = new TwoPaneElementSelector(getShell(), |
| programLabelProvider, qualifierLabelProvider); |
| dialog.setElements(getBinaryFiles(getCProject())); |
| dialog.setMessage(LaunchMessages.CMainTab_Choose_program_to_run); |
| dialog.setTitle(LaunchMessages.CMainTab_Program_Selection); |
| dialog.setUpperListLabel(LaunchMessages.Launch_common_BinariesColon); |
| dialog.setLowerListLabel(LaunchMessages.Launch_common_QualifierColon); |
| dialog.setMultipleSelection(false); |
| // dialog.set |
| if (dialog.open() == Window.OK) { |
| IBinary binary = (IBinary) dialog.getFirstResult(); |
| fProgText.setText(binary.getResource().getProjectRelativePath() |
| .toString()); |
| } |
| } |
| |
| /** |
| * @since 6.0 |
| */ |
| @Override |
| protected void createProjectGroup(Composite parent, int colSpan) { |
| Composite projComp = new Composite(parent, SWT.NONE); |
| GridLayout projLayout = new GridLayout(); |
| projLayout.numColumns = 2; |
| projLayout.marginHeight = 0; |
| projLayout.marginWidth = 0; |
| projComp.setLayout(projLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = colSpan; |
| projComp.setLayoutData(gd); |
| |
| fProjLabel = new Label(projComp, SWT.NONE); |
| fProjLabel.setText(LaunchMessages.CMainTab_ProjectColon); |
| gd = new GridData(); |
| gd.horizontalSpan = 2; |
| fProjLabel.setLayoutData(gd); |
| |
| fProjText = new Text(projComp, SWT.SINGLE | SWT.BORDER); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| fProjText.setLayoutData(gd); |
| fProjText.addModifyListener(evt -> { |
| // if project changes, invalidate program name cache |
| fPreviouslyCheckedProgram = null; |
| |
| updateBuildConfigCombo(""); //$NON-NLS-1$ |
| updateLaunchConfigurationDialog(); |
| }); |
| |
| fProjButton = createPushButton(projComp, |
| LaunchMessages.Launch_common_Browse_1, null); |
| fProjButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { |
| handleProjectButtonSelected(); |
| updateLaunchConfigurationDialog(); |
| })); |
| } |
| |
| @Override |
| protected void updateProgramFromConfig(ILaunchConfiguration config) { |
| super.updateProgramFromConfig(config); |
| if(fProgText.getText().equals(EMPTY_STRING)){ |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| if(this.fProjText != null){ |
| IProject project = root.getProject(this.fProjText.getText()); |
| if(project != null){ |
| fProgText.setText(project.getLocationURI().toString()); |
| } |
| } |
| } |
| } |
| |
| protected void updateCopyFromExeFromConfig(ILaunchConfiguration config) { |
| if (copyFromExeText != null) { |
| String workingDir = EMPTY_STRING; |
| try { |
| workingDir = config.getAttribute(ATTR_COPY_FROM_EXE_NAME, EMPTY_STRING); |
| } catch (CoreException ce) { |
| ProfileLaunchPlugin.log(ce); |
| } |
| copyFromExeText.setText(workingDir); |
| } |
| if (enableCopyFromExeButton != null) { |
| boolean enableCopyFromExe = false; |
| try { |
| enableCopyFromExe = config.getAttribute(ATTR_ENABLE_COPY_FROM_EXE, false); |
| } catch (CoreException ce) { |
| ProfileLaunchPlugin.log(ce); |
| } |
| setEnableCopyFromSection(enableCopyFromExe); |
| } |
| } |
| |
| private void setEnableCopyFromSection(boolean enable) { |
| // setSelection will be redundant if called from a listener |
| enableCopyFromExeButton.setSelection(enable); |
| copyFromExeSelector.setEnabled(enable); |
| toLabel.setEnabled(enable); |
| } |
| |
| protected void createCopyFromExeGroup(Composite parent, int colSpan) { |
| Composite mainComp = new Composite(parent, SWT.NONE); |
| GridLayout mainLayout = new GridLayout(); |
| mainLayout.numColumns = 1; |
| mainLayout.marginHeight = 0; |
| mainLayout.marginWidth = 0; |
| mainComp.setLayout(mainLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = colSpan; |
| mainComp.setLayoutData(gd); |
| |
| enableCopyFromExeButton = createCheckButton(mainComp, ProxyLaunchMessages.copy_cpp_executable); |
| copyFromExeSelector = new ResourceSelectorWidget(mainComp, |
| ResourceSelectorWidget.ResourceType.FILE, |
| 2, ProxyLaunchMessages.executable_origin, null); |
| toLabel = new Label(mainComp, SWT.NONE); |
| toLabel.setText(ProxyLaunchMessages.to); |
| |
| // The "copy from" check box is initially off, the selector and "To:" label |
| // are disabled. |
| copyFromExeSelector.setEnabled(false); |
| enableCopyFromExeButton.setSelection(false); |
| |
| toLabel.setEnabled(false); |
| |
| enableCopyFromExeButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { |
| boolean copyEnabled = enableCopyFromExeButton.getSelection(); |
| setEnableCopyFromSection(copyEnabled); |
| updateLaunchConfigurationDialog(); |
| })); |
| |
| copyFromExeText = copyFromExeSelector.getURIText(); |
| copyFromExeText.addModifyListener(evt -> updateLaunchConfigurationDialog()); |
| } |
| |
| |
| protected void createExeFileGroup(Composite parent, int colSpan) { |
| Composite mainComp = new Composite(parent, SWT.NONE); |
| GridLayout mainLayout = new GridLayout(); |
| mainLayout.numColumns = 1; |
| mainLayout.marginHeight = 0; |
| mainLayout.marginWidth = 0; |
| mainComp.setLayout(mainLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = colSpan; |
| mainComp.setLayoutData(gd); |
| exeSelector = new ResourceSelectorWidget(mainComp, |
| ResourceSelectorWidget.ResourceType.FILE, |
| 2, "C/C++ executable", null); //$NON-NLS-1$ |
| fProgText = exeSelector.getURIText(); |
| fProgText.addModifyListener(evt -> updateLaunchConfigurationDialog()); |
| } |
| |
| protected void updateWorkingDirFromConfig(ILaunchConfiguration config) { |
| if (workingDirText != null) { |
| String projectDir = EMPTY_STRING; |
| try { |
| projectDir = config.getAttribute(ATTR_REMOTE_WORKING_DIRECTORY_NAME, EMPTY_STRING); |
| } catch (CoreException ce) { |
| ProfileLaunchPlugin.log(ce); |
| } |
| |
| if (projectDir.equals(EMPTY_STRING)){ |
| if(this.fProjText != null){ |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| IProject project = root.getProject(this.fProjText.getText()); |
| try { |
| projectDir = RemoteProxyManager.getInstance().getRemoteProjectLocation(project); |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.error_accessing_working_directory); |
| } |
| } |
| } |
| workingDirText.setText(projectDir); |
| } |
| } |
| |
| protected void createWorkingDirGroup(Composite parent, int colSpan) { |
| Composite mainComp = new Composite(parent, SWT.NONE); |
| GridLayout mainLayout = new GridLayout(); |
| mainLayout.numColumns = 1; |
| mainLayout.marginHeight = 0; |
| mainLayout.marginWidth = 0; |
| mainComp.setLayout(mainLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = colSpan; |
| mainComp.setLayoutData(gd); |
| ResourceSelectorWidget workingDirSelector = new ResourceSelectorWidget(mainComp, |
| ResourceSelectorWidget.ResourceType.DIRECTORY, |
| 2, "Working directory", null); //$NON-NLS-1$ |
| workingDirText = workingDirSelector.getURIText(); |
| workingDirText.addModifyListener(evt -> updateLaunchConfigurationDialog()); |
| } |
| |
| private boolean checkCopyFromExe(IProject project) { |
| if (!enableCopyFromExeButton.getSelection()) { |
| setErrorMessage(null); |
| return true; |
| } |
| |
| String name = copyFromExeText.getText().trim(); |
| if (name.length() == 0) { |
| setErrorMessage(ProxyLaunchMessages.copy_from_exe_is_not_specified); |
| return false; |
| } |
| // Avoid constantly checking the binary if nothing relevant has |
| // changed (binary or project name). See bug 277663. |
| if (name.equals(fPreviouslyCheckedCopyFromExe)) { |
| if (fPreviouslyCheckedCopyFromExeErrorMsg != null) { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg); |
| } |
| return fPreviouslyCheckedCopyFromExeIsValid; |
| } |
| fPreviouslyCheckedCopyFromExe = name; |
| fPreviouslyCheckedCopyFromExeIsValid = true; // we'll flip this below if |
| // not true |
| fPreviouslyCheckedCopyFromExeErrorMsg = null; // we'll set this below if |
| // there's an error |
| IPath exePath; |
| URI exeURI = null; |
| boolean passed = false; |
| |
| try { |
| exeURI = new URI(name); |
| String exePathStr = exeURI.getPath(); |
| if (exePathStr == null) { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.uri_of_copy_from_exe_is_invalid); |
| fPreviouslyCheckedCopyFromExeIsValid = false; |
| return false; |
| } |
| exePath = Path.fromOSString(exeURI.getPath()); |
| if (!exePath.isAbsolute() && exeURI != null && !exeURI.isAbsolute()) { |
| URI projectURI = project.getLocationURI(); |
| exeURI = new URI(projectURI.getScheme(), |
| projectURI.getAuthority(), projectURI.getRawPath() + '/' |
| + exePath.toString(), EMPTY_STRING); |
| } |
| if (exeURI != null) { |
| passed = true; |
| } |
| } catch (URISyntaxException e) { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.uri_of_copy_from_exe_is_invalid); |
| fPreviouslyCheckedCopyFromExeIsValid = false; |
| return false; |
| } |
| |
| if (!passed) { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.copy_from_exe_does_not_exist); |
| fPreviouslyCheckedCopyFromExeIsValid = false; |
| return false; |
| } |
| |
| passed = false; |
| try { |
| IRemoteFileProxy exeFileProxy; |
| exeFileProxy = RemoteProxyManager.getInstance().getFileProxy(exeURI); |
| if (exeFileProxy != null) { |
| String exeFilePath = exeURI.getPath(); |
| IFileStore exeFS = exeFileProxy |
| .getResource(exeFilePath); |
| if (exeFS != null) { |
| IFileInfo exeFI = exeFS.fetchInfo(); |
| if (exeFI != null) { |
| if (exeFI.exists()) { |
| if (exeFI.getAttribute(EFS.ATTRIBUTE_EXECUTABLE) && |
| !exeFI.isDirectory()) { |
| passed = true; |
| } else { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.copy_from_exe_does_not_have_execution_rights); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.copy_from_exe_does_not_exist); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.error_accessing_copy_from_exe); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.error_accessing_copy_from_exe); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.scheme_error_in_copy_from_exe); |
| } |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedCopyFromExeErrorMsg = ProxyLaunchMessages.connection_of_copy_from_exe_cannot_be_opened); |
| } |
| if (!passed) { |
| fPreviouslyCheckedCopyFromExeIsValid = false; |
| return false; |
| } |
| setErrorMessage(null); |
| return true; |
| } |
| |
| |
| private boolean checkProgram(IProject project) { |
| String name = fProgText.getText().trim(); |
| if (name.length() == 0) { |
| setErrorMessage(ProxyLaunchMessages.executable_is_not_specified); |
| return false; |
| } |
| // Avoid constantly checking the binary if nothing relevant has |
| // changed (binary or project name). See bug 277663. |
| if (name.equals(fPreviouslyCheckedProgram)) { |
| if (fPreviouslyCheckedProgramErrorMsg != null) { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg); |
| } |
| return fPreviouslyCheckedProgramIsValid; |
| } |
| fPreviouslyCheckedProgram = name; |
| fPreviouslyCheckedProgramIsValid = true; // we'll flip this below if |
| // not true |
| fPreviouslyCheckedProgramErrorMsg = null; // we'll set this below if |
| // there's an error |
| IPath exePath; |
| URI exeURI = null; |
| boolean passed = false; |
| |
| try { |
| exeURI = new URI(name); |
| String exePathStr = exeURI.getPath(); |
| if (exePathStr == null) { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.uri_of_executable_is_invalid); |
| fPreviouslyCheckedProgramIsValid = false; |
| return false; |
| } |
| |
| exePath = Path.fromOSString(exeURI.getPath()); |
| if (!exePath.isAbsolute() && exeURI != null && !exeURI.isAbsolute()) { |
| URI projectURI = project.getLocationURI(); |
| exeURI = new URI(projectURI.getScheme(), |
| projectURI.getAuthority(), projectURI.getRawPath() + '/' |
| + exePath.toString(), EMPTY_STRING); |
| } |
| if (exeURI != null) { |
| passed = true; |
| } |
| } catch (URISyntaxException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.uri_of_executable_is_invalid); |
| fPreviouslyCheckedProgramIsValid = false; |
| return false; |
| } |
| |
| if (!passed) { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = LaunchMessages.CMainTab_Program_does_not_exist); |
| fPreviouslyCheckedProgramIsValid = false; |
| return false; |
| } |
| |
| passed = false; |
| try { |
| IRemoteFileProxy exeFileProxy; |
| exeFileProxy = RemoteProxyManager.getInstance().getFileProxy(exeURI); |
| if (exeFileProxy != null) { |
| String exeFilePath = exeURI.getPath(); |
| IFileStore exeFS = exeFileProxy |
| .getResource(exeFilePath); |
| if (exeFS != null) { |
| IFileInfo exeFI = exeFS.fetchInfo(); |
| if (exeFI != null) { |
| if (dontCheckProgram || enableCopyFromExeButton.getSelection()) { |
| // The program may not exist yet if we are copying it. |
| passed = true; |
| } else { |
| if (exeFI.exists()) { |
| if (exeFI.getAttribute(EFS.ATTRIBUTE_EXECUTABLE) && |
| !exeFI.isDirectory()) { |
| passed = true; |
| } else { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.executable_does_not_have_execution_rights); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.executable_does_not_exist); |
| } |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.error_accessing_executable); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.error_accessing_executable); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.scheme_error_in_executable); |
| } |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedProgramErrorMsg = ProxyLaunchMessages.connection_of_executable_cannot_be_opened); |
| } |
| if (!passed) { |
| fPreviouslyCheckedProgramIsValid = false; |
| return false; |
| } |
| setErrorMessage(null); |
| return true; |
| } |
| |
| private boolean checkWorkingDir(IProject project) { |
| String name = workingDirText.getText().trim(); |
| if (name.length() == 0) { |
| return true; // an empty working directory means, "use the default" |
| } |
| // Avoid constantly checking the working dir if nothing relevant has |
| // changed (project). |
| if (name.equals(fPreviouslyCheckedWorkingDir)) { |
| if (fPreviouslyCheckedWorkingDirErrorMsg != null) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg); |
| } |
| return fPreviouslyCheckedWorkingDirIsValid; |
| } |
| fPreviouslyCheckedWorkingDir = name; |
| fPreviouslyCheckedWorkingDirIsValid = true; // we'll flip this below if |
| // not true |
| fPreviouslyCheckedWorkingDirErrorMsg = null; // we'll set this below if |
| // there's an error |
| IPath wdPath; |
| URI wdURI = null; |
| boolean passed = false; |
| |
| try { |
| wdURI = new URI(name); |
| String wdPathStr = wdURI.getPath(); |
| if (wdPathStr == null) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.uri_of_working_directory_is_invalid); |
| fPreviouslyCheckedWorkingDirIsValid = false; |
| return false; |
| } |
| |
| wdPath = Path.fromOSString(wdURI.getPath()); |
| if (!wdPath.isAbsolute() && wdURI != null && !wdURI.isAbsolute()) { |
| URI projectURI = project.getLocationURI(); |
| wdURI = new URI(projectURI.getScheme(), |
| projectURI.getAuthority(), projectURI.getRawPath() + '/' |
| + wdPath.toString(), EMPTY_STRING); |
| } |
| if (wdURI != null) { |
| passed = true; |
| } |
| } catch (URISyntaxException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.uri_of_working_directory_is_invalid); |
| fPreviouslyCheckedWorkingDirIsValid = false; |
| return false; |
| } |
| |
| if (!passed) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.working_directory_does_not_exist); |
| fPreviouslyCheckedWorkingDirIsValid = false; |
| return false; |
| } |
| |
| passed = false; |
| IRemoteFileProxy wdFileProxy; |
| try { |
| wdFileProxy = RemoteProxyManager.getInstance().getFileProxy(wdURI); |
| if (wdFileProxy != null) { |
| IFileStore wdFS = wdFileProxy |
| .getResource(wdURI.getPath()); |
| if (wdFS != null) { |
| IFileInfo wdFI = wdFS.fetchInfo(); |
| if (wdFI != null) { |
| if (wdFI.exists()) { |
| if (wdFI.isDirectory()) { |
| passed = true; |
| } else { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.working_directory_is_not_a_directory); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.working_directory_does_not_exist); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.error_accessing_working_directory); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.error_accessing_working_directory); |
| } |
| } else { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.scheme_error_in_working_directory); |
| } |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.connection_of_working_directory_cannot_be_opened); |
| } |
| |
| if (!passed) { |
| fPreviouslyCheckedWorkingDirIsValid = false; |
| return false; |
| } |
| setErrorMessage(null); |
| return true; |
| } |
| |
| /** |
| * Compare two strings as equal or not, but allow for one or both of |
| * the strings to be null. If both are null, they are treated as equal. |
| * If one is null and the other isn't, they are considered unequal. If |
| * they are both non-null, the result is the same as the |
| * String.equals() method. |
| * @param s1 First string to compare. |
| * @param s2 Second string to compare. |
| * @return Return true if equal, false otherwise. |
| */ |
| private static boolean equal(String s1, String s2) { |
| if (s1 == null && s2 == null) |
| return true; |
| if (s1 == null || s2 == null) |
| return false; |
| return s1.equals(s2); |
| } |
| |
| /** |
| * Check to see if the Executable's location has the same scheme and host name as |
| * the working directory. If not, this is an error. |
| * @return true if they are compatible, and false if not compatible. |
| */ |
| private boolean checkCompatibility() { |
| String wdName = workingDirText.getText().trim(); |
| String progName = fProgText.getText().trim(); |
| URI wdURI; |
| URI progURI; |
| |
| try { |
| wdURI = new URI(wdName); |
| progURI = new URI(progName); |
| } catch (URISyntaxException e) { |
| // this will have been dealt with by previous checks of the Program and Working |
| // directory |
| System.err.println(ProxyLaunchMessages.uri_syntax_error); |
| return false; |
| } |
| String wdScheme = wdURI.getScheme(); |
| String progScheme = progURI.getScheme(); |
| if (wdScheme == null && progScheme == null) { |
| // local filesystem. No further tests are needed. |
| setErrorMessage(null); |
| return true; |
| } |
| if (!equal(wdScheme, progScheme)) { |
| setErrorMessage(ProxyLaunchMessages.scheme_of_working_directory_and_program_do_not_match); |
| return false; |
| } |
| String wdAuth = wdURI.getAuthority(); |
| String progAuth = progURI.getAuthority(); |
| if (!equal(wdAuth, progAuth)) { |
| setErrorMessage(ProxyLaunchMessages.connection_of_working_directory_and_program_do_not_match); |
| return false; |
| } |
| String wdQuery = wdURI.getQuery(); |
| String progQuery = progURI.getQuery(); |
| if (!equal(wdQuery, progQuery)) { |
| setErrorMessage(ProxyLaunchMessages.connection_of_working_directory_and_program_do_not_match); |
| return false; |
| } |
| setErrorMessage(null); |
| return true; |
| } |
| |
| @Override |
| public boolean isValid(ILaunchConfiguration config) { |
| IProject project; |
| |
| this.setErrorMessage(null); |
| setMessage(null); |
| |
| String name = fProjText.getText().trim(); |
| if (name.length() == 0) { |
| setErrorMessage(LaunchMessages.CMainTab_Project_not_specified); |
| return false; |
| } |
| project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); |
| if (!project.exists()) { |
| setErrorMessage(LaunchMessages.Launch_common_Project_does_not_exist); |
| return false; |
| } |
| if (!project.isOpen()) { |
| setErrorMessage(LaunchMessages.CMainTab_Project_must_be_opened); |
| return false; |
| } |
| |
| if (!checkCopyFromExe(project)) |
| return false; |
| |
| if (!checkProgram(project)) |
| return false; |
| |
| if (!checkWorkingDir(project)) |
| return false; |
| |
| if (!checkCompatibility()) |
| return false; |
| |
| if (fCoreText != null) { |
| String coreName = fCoreText.getText().trim(); |
| // We accept an empty string. This should trigger a prompt to the |
| // user |
| // This allows to re-use the launch, with a different core file. |
| if (!coreName.equals(EMPTY_STRING)) { |
| if (coreName.equals(".") || coreName.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| setErrorMessage(LaunchMessages.CMainTab_Core_does_not_exist); |
| return false; |
| } |
| IPath corePath = new Path(coreName); |
| if (!corePath.toFile().exists()) { |
| setErrorMessage(LaunchMessages.CMainTab_Core_does_not_exist); |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| @Override |
| public void setDefaults(ILaunchConfigurationWorkingCopy config) { |
| // We set empty attributes for project & program so that when one config |
| // is |
| // compared to another, the existence of empty attributes doesn't cause |
| // an |
| // incorrect result (the performApply() method can result in empty |
| // values |
| // for these attributes being set on a config if there is nothing in the |
| // corresponding text boxes) |
| // plus getContext will use this to base context from if set. |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| EMPTY_STRING); |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, |
| EMPTY_STRING); |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, |
| EMPTY_STRING); |
| |
| // Set the auto choose build configuration to true for new |
| // configurations. |
| // Existing configurations created before this setting was introduced |
| // will have this disabled. |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, |
| true); |
| |
| ICElement cElement = null; |
| cElement = getContext(config, getPlatform(config)); |
| if (cElement != null) { |
| initializeCProject(cElement, config); |
| initializeProgramName(cElement, config); |
| } else { |
| // don't want to remember the interim value from before |
| config.setMappedResources(null); |
| } |
| if (wantsTerminalOption()) { |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, |
| ICDTLaunchConfigurationConstants.USE_TERMINAL_DEFAULT); |
| } |
| } |
| |
| /** |
| * Set the program name attributes on the working copy based on the |
| * ICElement. |
| * @param cElement The element to get data from. |
| * @param config The configuration to initialize |
| */ |
| protected void initializeProgramName(ICElement cElement, |
| ILaunchConfigurationWorkingCopy config) { |
| boolean renamed = false; |
| |
| if (!(cElement instanceof IBinary)) { |
| cElement = cElement.getCProject(); |
| } |
| |
| if (cElement instanceof ICProject) { |
| IProject project = cElement.getCProject().getProject(); |
| String name = project.getName(); |
| ICProjectDescription projDes = CCorePlugin.getDefault() |
| .getProjectDescription(project); |
| if (projDes != null) { |
| String buildConfigName = projDes.getActiveConfiguration() |
| .getName(); |
| // Bug 234951 |
| name = NLS.bind(LaunchMessages.CMainTab_Configuration_name, |
| name, buildConfigName); |
| } |
| name = getLaunchConfigurationDialog().generateName(name); |
| config.rename(name); |
| renamed = true; |
| } |
| |
| IBinary binary = null; |
| if (cElement instanceof ICProject) { |
| IBinary[] bins = getBinaryFiles((ICProject) cElement); |
| if (bins != null && bins.length == 1) { |
| binary = bins[0]; |
| } |
| } else if (cElement instanceof IBinary) { |
| binary = (IBinary) cElement; |
| } |
| |
| String projectDir = EMPTY_STRING; |
| IProject project = null; |
| try { |
| project = ConfigUtils.getProject(ConfigUtils.getProjectName(config)); |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.error_accessing_working_directory); |
| } |
| if(project != null){ |
| try { |
| projectDir = RemoteProxyManager.getInstance().getRemoteProjectLocation(project); |
| } catch (CoreException e) { |
| setErrorMessage(fPreviouslyCheckedWorkingDirErrorMsg = ProxyLaunchMessages.error_accessing_working_directory); |
| } |
| } |
| |
| String path = EMPTY_STRING; |
| if (binary != null) { |
| path = binary.getResource().getProjectRelativePath().toOSString(); |
| if (!renamed) { |
| String name = binary.getElementName(); |
| int index = name.lastIndexOf('.'); |
| if (index > 0) { |
| name = name.substring(0, index); |
| } |
| name = getLaunchConfigurationDialog().generateName(name); |
| config.rename(name); |
| renamed = true; |
| } |
| } |
| config.setAttribute( |
| ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, projectDir + IPath.SEPARATOR + path); |
| |
| if (!renamed) { |
| String name = getLaunchConfigurationDialog().generateName( |
| cElement.getCProject().getElementName()); |
| config.rename(name); |
| } |
| } |
| |
| @Override |
| public String getId() { |
| return TAB_ID; |
| } |
| |
| @Override |
| public String getName() { |
| return LaunchMessages.CMainTab_Main; |
| } |
| |
| @Override |
| public Image getImage() { |
| return LaunchImages.get(LaunchImages.IMG_VIEW_MAIN_TAB); |
| } |
| } |