Java tutorial
/******************************************************************************* * Copyright (c) 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.ptp.launch; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.LaunchConfigurationDelegate; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.osgi.util.NLS; import org.eclipse.ptp.core.IPTPLaunchConfigurationConstants; import org.eclipse.ptp.core.PreferencesAdapter; import org.eclipse.ptp.core.jobs.IJobListener; import org.eclipse.ptp.core.jobs.IJobStatus; import org.eclipse.ptp.core.jobs.JobManager; import org.eclipse.ptp.core.util.LaunchUtils; import org.eclipse.ptp.debug.core.IPDebugConfiguration; import org.eclipse.ptp.debug.core.IPDebugger; import org.eclipse.ptp.debug.core.launch.IPLaunch; import org.eclipse.ptp.internal.debug.core.PTPDebugCorePlugin; import org.eclipse.ptp.internal.debug.core.launch.PLaunch; import org.eclipse.ptp.internal.debug.ui.PTPDebugUIPlugin; import org.eclipse.ptp.launch.internal.messages.Messages; import org.eclipse.ptp.launch.rulesengine.IRuleAction; import org.eclipse.ptp.launch.rulesengine.ISynchronizationRule; import org.eclipse.ptp.launch.rulesengine.RuleActionFactory; import org.eclipse.ptp.launch.rulesengine.RuleFactory; import org.eclipse.ptp.rm.jaxb.control.core.ILaunchController; import org.eclipse.ptp.rm.lml.monitor.core.IMonitorControl; import org.eclipse.ptp.rm.lml.monitor.core.MonitorControlManager; import org.eclipse.ptp.rm.lml.ui.ILMLUIConstants; import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnectionManager; import org.eclipse.remote.core.IRemoteFileManager; import org.eclipse.remote.core.IRemoteServices; import org.eclipse.remote.core.RemoteServices; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; /** * Abstract base class for launch configuration delegates that launch parallel jobs */ public abstract class AbstractParallelLaunchConfigurationDelegate extends LaunchConfigurationDelegate { private final class JobListener implements IJobListener { public void jobAdded(IJobStatus status) { // Nothing to do } public void jobChanged(IJobStatus status) { JobSubmission jobSub; synchronized (jobSubmissions) { jobSub = jobSubmissions.get(status.getJobId()); } if (jobSub != null) { jobSub.statusChanged(); } } } /** * Wait for job to begin running, then perform post launch operations. The job is guaranteed not to be in the UNDETERMINED * state. * * <pre> * Job state transition is: * * SUBMITTED ----> RUNNING ----> COMPLETED * ^ | * |- SUSPENDED <-| * </pre> * * We must call completion method when job state is RUNNING, however it is possible that the job may get to COMPLETED or * SUSPENDED before we are started. If either of these states is reached, assume that RUNNING has also been reached. */ private class JobSubmission extends Job { private final IPLaunch fLaunch; private final IPDebugger fDebugger; private final ILaunchController fLaunchControl; private final ReentrantLock fSubLock = new ReentrantLock(); private final Condition fSubCondition = fSubLock.newCondition(); public JobSubmission(IPLaunch launch, ILaunchController control, IPDebugger debugger) { super(launch.getJobId()); fLaunch = launch; fLaunchControl = control; fDebugger = debugger; setSystem(true); } @Override protected IStatus run(IProgressMonitor monitor) { SubMonitor subMon = SubMonitor.convert(monitor, 100); String jobId = fLaunch.getJobId(); try { IJobStatus status = waitForStatusChange(jobId, IJobStatus.SUBMITTED, subMon.newChild(50)); /* * Status could be RUNNING or COMPLETED at this point. If COMPLETED then we need to check it was not CANCELED before * calling doCompleteLaunch(). */ if (!subMon.isCanceled()) { if (!status.getStateDetail().equals(IJobStatus.CANCELED)) { doCompleteJobLaunch(fLaunch, fDebugger); } if (!status.getState().equals(IJobStatus.COMPLETED)) { status = waitForStatusChange(jobId, IJobStatus.RUNNING, subMon.newChild(50)); } if (!subMon.isCanceled() && !status.getStateDetail().equals(IJobStatus.CANCELED)) { /* * When the job terminates, do any post launch data synchronization. */ doPostLaunchSynchronization(fLaunch.getLaunchConfiguration()); } } } catch (CoreException e) { PTPLaunchPlugin.log(e); } /* * Clean up any launch activities. */ doCleanupLaunch(fLaunch); /* * Remove job submission */ synchronized (jobSubmissions) { jobSubmissions.remove(jobId); if (jobSubmissions.size() == 0) { JobManager.getInstance().removeListener(fJobListener); } } return Status.OK_STATUS; } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. IProgressMonitor) */ public void statusChanged() { fSubLock.lock(); try { fSubCondition.signalAll(); } finally { fSubLock.unlock(); } } private IJobStatus waitForStatusChange(String jobId, String jobStatus, IProgressMonitor monitor) throws CoreException { SubMonitor subMon = SubMonitor.convert(monitor, 100); IJobStatus status = fLaunchControl.getJobStatus(jobId, subMon.newChild(10)); while (status.getState().equals(jobStatus) && !subMon.isCanceled()) { fSubLock.lock(); try { fSubCondition.await(1000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // Expect to be interrupted if monitor is canceled } finally { fSubLock.unlock(); } status = fLaunchControl.getJobStatus(jobId, subMon.newChild(10)); subMon.setWorkRemaining(100); } subMon.worked(100); return status; } } /** * @since 5.0 */ public static IRemoteFileManager getLocalFileManager(ILaunchConfiguration configuration) throws CoreException { IRemoteServices localServices = RemoteServices.getLocalServices(); IRemoteConnectionManager lconnMgr = localServices.getConnectionManager(); IRemoteConnection lconn = lconnMgr.getConnection(IRemoteConnectionManager.LOCAL_CONNECTION_NAME); return lconn.getFileManager(); } /** * @param configuration * @param monitor * @return * @throws CoreException */ public static IRemoteFileManager getRemoteFileManager(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 10); IRemoteConnection conn = RMLaunchUtils.getRemoteConnection(configuration, progress.newChild(5)); if (conn != null) { if (!conn.isOpen()) { conn.open(progress.newChild(5)); if (!progress.isCanceled() && !conn.isOpen()) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Connection_is_not_open)); } } return conn.getFileManager(); } return null; } /* * Model listeners */ private final IJobListener fJobListener = new JobListener(); /* * HashMap used to keep track of job submissions */ protected Map<String, JobSubmission> jobSubmissions = Collections .synchronizedMap(new HashMap<String, JobSubmission>()); /** * Constructor */ public AbstractParallelLaunchConfigurationDelegate() { } /* * (non-Javadoc) * * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org .eclipse.debug.core.ILaunchConfiguration, * java.lang.String) */ /** * Check if the copy local file is enabled. If it is, copy the executable file from the local host to the remote host. * * @param configuration * launch configuration * @throws CoreException * if the copy fails or is cancelled */ protected void copyExecutable(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { boolean copyExecutable = LaunchUtils.getCopyExecutable(configuration); if (copyExecutable) { // Get remote and local paths String remotePath = LaunchUtils.getExecutablePath(configuration); String localPath = configuration .getAttribute(IPTPLaunchConfigurationConstants.ATTR_LOCAL_EXECUTABLE_PATH, (String) null); // Check if local path is valid if (localPath == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_1)); } // Copy data copyFileToRemoteHost(localPath, remotePath, configuration, monitor); } } /** * Copy a data from a path (can be a file or directory) from the remote host to the local host. * * @param remotePath * @param localPath * @param configuration * @throws CoreException */ protected void copyFileFromRemoteHost(String remotePath, String localPath, ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 15); IRemoteFileManager localFileManager = getLocalFileManager(configuration); IRemoteFileManager remoteFileManager = getRemoteFileManager(configuration, progress.newChild(5)); if (progress.isCanceled()) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Operation_cancelled_by_user, null)); } if (remoteFileManager == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_0)); } IFileStore rres = remoteFileManager.getResource(remotePath); if (!rres.fetchInfo(EFS.NONE, progress.newChild(5)).exists()) { // Local file not found! throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Remote_resource_does_not_exist)); } IFileStore lres = localFileManager.getResource(localPath); // Copy file rres.copy(lres, EFS.OVERWRITE, progress.newChild(5)); } /** * Copy a data from a path (can be a file or directory) from the local host to the remote host. * * @param localPath * @param remotePath * @param configuration * @throws CoreException */ protected void copyFileToRemoteHost(String localPath, String remotePath, ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 15); IRemoteFileManager localFileManager = getLocalFileManager(configuration); IRemoteFileManager remoteFileManager = getRemoteFileManager(configuration, progress.newChild(5)); if (progress.isCanceled()) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Operation_cancelled_by_user, null)); } if (remoteFileManager == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_0)); } IFileStore lres = localFileManager.getResource(localPath); if (!lres.fetchInfo(EFS.NONE, progress.newChild(5)).exists()) { // Local file not found! throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Local_resource_does_not_exist)); } IFileStore rres = remoteFileManager.getResource(remotePath); // Copy file lres.copy(rres, EFS.OVERWRITE, progress.newChild(5)); } /** * Called to cleanup once the job terminates * * @param config * @param mode * @param launch * @since 5.0 */ protected abstract void doCleanupLaunch(IPLaunch launch); /** * This method is called when the job state changes to RUNNING. This allows the launcher to complete the job launch. * * @param launch * @param debugger * @since 5.0 */ protected abstract void doCompleteJobLaunch(IPLaunch launch, IPDebugger debugger); /** * @param configuration * @throws CoreException */ protected void doPostLaunchSynchronization(ILaunchConfiguration configuration) throws CoreException { if (configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_AFTER, false)) { List<?> rulesList = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>()); // This faction generate action objects which execute according to // rules RuleActionFactory ruleActFactory = new RuleActionFactory(configuration, new NullProgressMonitor()); for (Object ruleObj : rulesList) { ISynchronizationRule syncRule = RuleFactory.createRuleFromString((String) ruleObj); if (syncRule.isDownloadRule()) { // Execute the action IRuleAction action = ruleActFactory.getAction(syncRule); action.run(); } } } } /** * This method does the synchronization step before the job submission * * @param configuration * @param monitor */ protected void doPreLaunchSynchronization(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { if (configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_BEFORE, false)) { SubMonitor progress = SubMonitor.convert(monitor, 10); // This faction generate action objects which execute according to // rules RuleActionFactory ruleActFactory = new RuleActionFactory(configuration, progress.newChild(10)); List<?> rulesList = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>()); // Iterate over rules executing them for (Object ruleObj : rulesList) { ISynchronizationRule syncRule = RuleFactory.createRuleFromString((String) ruleObj); if (syncRule.isUploadRule()) { // Execute the action IRuleAction action = ruleActFactory.getAction(syncRule); action.run(); } } } } /** * Get the debugger configuration * * @param configuration * launch configuration * @return debugger configuration * @throws CoreException * @since 6.0 */ protected IPDebugConfiguration getDebugConfig(ILaunchConfiguration config) throws CoreException { return PTPDebugCorePlugin.getDefault().getDebugConfiguration(LaunchUtils.getDebuggerID(config)); } @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { return new PLaunch(configuration, mode, null); } /** * Returns the (possible empty) list of synchronization rule objects according to the rules described in the configuration. * * @since 5.0 */ protected ISynchronizationRule[] getSynchronizeRules(ILaunchConfiguration configuration) throws CoreException { List<?> ruleStrings = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>()); List<ISynchronizationRule> result = new ArrayList<ISynchronizationRule>(); for (Object ruleObj : ruleStrings) { String element = (String) ruleObj; try { ISynchronizationRule rule = RuleFactory.createRuleFromString(element); result.add(rule); } catch (RuntimeException e) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Error_converting_rules)); } } return result.toArray(new ISynchronizationRule[result.size()]); } /** * Create a source locator from the ID specified in the configuration, or create a default one if it hasn't been specified. * * @param launch * @param configuration * @throws CoreException */ protected void setDefaultSourceLocator(ILaunch launch, ILaunchConfiguration configuration) throws CoreException { // set default source locator if none specified if (launch.getSourceLocator() == null) { IPersistableSourceLocator sourceLocator; String id = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String) null); if (id == null) { sourceLocator = PTPDebugUIPlugin.createDefaultSourceLocator(); sourceLocator.initializeDefaults(configuration); } else { sourceLocator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(id); String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String) null); if (memento == null) { sourceLocator.initializeDefaults(configuration); } else { sourceLocator.initializeFromMemento(memento); } } launch.setSourceLocator(sourceLocator); } } /** * Set the source locator for this application * * @param launch * @param config * @throws CoreException */ protected void setSourceLocator(ILaunch launch, ILaunchConfiguration config) throws CoreException { setDefaultSourceLocator(launch, config); } /** * Submit a job to the resource manager. Keeps track of the submission so we know when the job actually starts running. When * this happens, the abstract method doCompleteJobLaunch() is invoked. * * @param mode * @param launch * @param debugger * @param monitor * @throws CoreException * @since 5.0 */ protected void submitJob(String mode, IPLaunch launch, IPDebugger debugger, IProgressMonitor progress) throws CoreException { SubMonitor subMon = SubMonitor.convert(progress, 50); final ILaunchController control = RMLaunchUtils.getLaunchController(launch.getLaunchConfiguration()); if (control == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Specified_resource_manager_not_found)); } /* * Make sure controller is started before we submit the job */ control.start(subMon.newChild(10)); if (!mode.equals(ILaunchManager.DEBUG_MODE) && LaunchUtils.getSystemType(launch.getLaunchConfiguration()) != null) { IMonitorControl monitor = MonitorControlManager.getInstance().getMonitorControl(control.getControlId()); if (monitor == null) { if (switchPerspective(ILMLUIConstants.ID_SYSTEM_MONITORING_PERSPECTIVE, Messages.AbstractParallelLaunchConfigurationDelegate_launchType1, PreferenceConstants.PREF_SWITCH_TO_MONITORING_PERSPECTIVE, true)) { monitor = MonitorControlManager.getInstance().createMonitorControl(control); monitor.start(subMon.newChild(10)); } } else { if (!monitor.isActive()) { if (switchPerspective(ILMLUIConstants.ID_SYSTEM_MONITORING_PERSPECTIVE, Messages.AbstractParallelLaunchConfigurationDelegate_launchType2, PreferenceConstants.PREF_SWITCH_TO_MONITORING_PERSPECTIVE, true)) { monitor.start(subMon.newChild(10)); } } else { switchPerspective(ILMLUIConstants.ID_SYSTEM_MONITORING_PERSPECTIVE, Messages.AbstractParallelLaunchConfigurationDelegate_launchType3, PreferenceConstants.PREF_SWITCH_TO_MONITORING_PERSPECTIVE, false); } } } JobManager.getInstance().addListener(control.getControlId(), fJobListener); String jobId = control.submitJob(launch.getLaunchConfiguration(), mode, subMon.newChild(10)); if (subMon.isCanceled()) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Launch_was_cancelled)); } if (control.getJobStatus(jobId, subMon.newChild(10)).equals(IJobStatus.UNDETERMINED)) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_UnableToDetermineJobStatus)); } launch.setJobControl(control); launch.setJobId(jobId); JobSubmission jobSub = new JobSubmission(launch, control, debugger); synchronized (jobSubmissions) { jobSubmissions.put(jobId, jobSub); } jobSub.schedule(); } /** * Used to force switching to the supplied perspective * * @param perspectiveID */ protected boolean switchPerspective(final String perspectiveId, final String message, final String preferenceKey, final boolean alwaysDisplayMessage) { final boolean[] result = new boolean[1]; result[0] = false; if (perspectiveId != null) { final Display display = Display.getDefault(); if (display != null && !display.isDisposed()) { display.syncExec(new Runnable() { public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { if (!alwaysDisplayMessage && page.getPerspective().getId().equals(perspectiveId)) { result[0] = true; return; } IPreferenceStore store = new PreferencesAdapter( PTPLaunchPlugin.getUniqueIdentifier()); result[0] = !store .getString(PreferenceConstants.PREF_SWITCH_TO_MONITORING_PERSPECTIVE) .equals(MessageDialogWithToggle.NEVER); if (store.getString(PreferenceConstants.PREF_SWITCH_TO_MONITORING_PERSPECTIVE) .equals(MessageDialogWithToggle.PROMPT)) { MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion( display.getActiveShell(), Messages.AbstractParallelLaunchConfigurationDelegate_ConfirmActions, message, null, false, store, preferenceKey); result[0] = (dialog.getReturnCode() == IDialogConstants.YES_ID); } if (result[0]) { try { PlatformUI.getWorkbench().showPerspective(perspectiveId, window); } catch (WorkbenchException e) { // Ignore } } } } } }); } } return result[0]; } /** * Verify the validity of the debugger path. * * @param configuration * launch configuration * @param monitor * progress monitor * @throws CoreException * if the path is invalid or the monitor was canceled. * @since 5.0 */ protected IPath verifyDebuggerPath(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { String dbgPath = LaunchUtils.getDebuggerExePath(configuration); if (dbgPath == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_debuggerPathNotSpecified)); } try { return verifyResource(dbgPath, configuration, monitor); } catch (CoreException e) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Debugger_path_not_found, new FileNotFoundException(e.getLocalizedMessage()))); } } /** * Verify the validity of executable path. If the executable is to be copied, then no additional verification is required. * Otherwise, the path must point to an existing file. * * @param configuration * launch configuration * @param monitor * progress monitor * @return IPath representing path to the executable (either local or remote) * @throws CoreException * if the resource can't be found or the monitor was canceled. * @since 5.0 */ protected IPath verifyExecutablePath(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { if (LaunchUtils.getCopyExecutable(configuration)) { return new Path(LaunchUtils.getExecutablePath(configuration)); } else { String exePath = LaunchUtils.getExecutablePath(configuration); try { return verifyResource(exePath, configuration, monitor); } catch (CoreException e) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Application_file_does_not_exist, new FileNotFoundException(e.getLocalizedMessage()))); } } } /** * @since 5.0 */ protected boolean verifyLaunchAttributes(final ILaunchConfiguration configuration, String mode, final IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 30); /* * Verify executable path */ IPath path = verifyExecutablePath(configuration, progress.newChild(10)); if (progress.isCanceled() || path == null) { return false; } /* * Verify working directory. Use the executable path if no working directory has been set. */ String workPath = LaunchUtils.getWorkingDirectory(configuration); if (workPath != null) { path = verifyResource(workPath, configuration, progress.newChild(10)); if (progress.isCanceled() || path == null) { return false; } } return true; } /** * Verify that the project exists prior to the launch. * * @param configuration * @return * @throws CoreException */ protected IProject verifyProject(ILaunchConfiguration configuration) throws CoreException { String proName = LaunchUtils.getProjectName(configuration); if (proName == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Project_not_specified)); } IProject project = LaunchUtils.getProject(proName); if (project == null || !project.exists() || !project.isOpen()) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_Project_does_not_exist_or_is_not_a_project)); } return project; } /** * @param path * @param configuration * @return * @throws CoreException * @since 5.0 */ protected IPath verifyResource(String path, ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 10); IRemoteFileManager fileManager = getRemoteFileManager(configuration, progress.newChild(5)); if (!monitor.isCanceled()) { if (fileManager == null) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), Messages.AbstractParallelLaunchConfigurationDelegate_unableToObtainConnectionInfo)); } boolean exists = fileManager.getResource(path).fetchInfo(EFS.NONE, progress.newChild(5)).exists(); if (!progress.isCanceled()) { if (!exists) { throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), NLS.bind(Messages.AbstractParallelLaunchConfigurationDelegate_Path_not_found, new Object[] { path }))); } return new Path(path); } } return null; } /** * Verify the working directory. If no working directory is specified, the default is the location of the executable. * * @param configuration * launch configuration * @param monitor * progress monitor * @return path of working directory or null if the monitor was canceled * @throws CoreException * if the working directory is invalid. * @since 5.0 */ protected IPath verifyWorkDirectory(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException { String workPath = LaunchUtils.getWorkingDirectory(configuration); if (workPath == null) { return verifyExecutablePath(configuration, monitor).removeLastSegments(1); } return verifyResource(workPath, configuration, monitor); } }