| /******************************************************************************* |
| * Copyright (c) 2011, 2012 University of Illinois 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: |
| * Albert L. Rossi - design and implementation |
| * Jeff Overbey - Environment Manager support |
| * Greg Watson - adapted to new framework |
| ******************************************************************************/ |
| package org.eclipse.ptp.internal.rm.jaxb.control.core; |
| |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| import java.util.UUID; |
| |
| 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.Path; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.ILaunchMode; |
| import org.eclipse.ptp.core.IPTPLaunchConfigurationConstants; |
| import org.eclipse.ptp.core.Preferences; |
| import org.eclipse.ptp.core.jobs.IJobStatus; |
| import org.eclipse.ptp.core.util.CoreExceptionUtils; |
| import org.eclipse.ptp.ems.core.EnvManagerConfigString; |
| import org.eclipse.ptp.ems.core.EnvManagerRegistry; |
| import org.eclipse.ptp.ems.core.IEnvManager; |
| import org.eclipse.ptp.ems.core.IEnvManagerConfig; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.messages.Messages; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.JobStatusMap; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.ManagedFilesJob; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.ManagedFilesJob.Operation; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.ScriptHandler; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.command.CommandJob; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.command.CommandJob.JobMode; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.runnable.command.CommandJobStatus; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.utils.JobIdPinTable; |
| import org.eclipse.ptp.internal.rm.jaxb.control.core.variables.RMVariableMap; |
| import org.eclipse.ptp.internal.rm.jaxb.core.JAXBInitializationUtils; |
| import org.eclipse.ptp.remote.server.core.RemoteServerManager; |
| import org.eclipse.ptp.rm.jaxb.control.core.ILaunchController; |
| import org.eclipse.ptp.rm.jaxb.control.core.LaunchControllerManager; |
| import org.eclipse.ptp.rm.jaxb.core.IVariableMap; |
| import org.eclipse.ptp.rm.jaxb.core.data.AttributeType; |
| import org.eclipse.ptp.rm.jaxb.core.data.CommandType; |
| import org.eclipse.ptp.rm.jaxb.core.data.ManagedFileType; |
| import org.eclipse.ptp.rm.jaxb.core.data.ManagedFilesType; |
| import org.eclipse.ptp.rm.jaxb.core.data.ResourceManagerData; |
| import org.eclipse.ptp.rm.jaxb.core.data.ScriptType; |
| import org.eclipse.ptp.rm.jaxb.core.data.SiteType; |
| import org.eclipse.ptp.rm.lml.da.server.core.LMLDAServer; |
| import org.eclipse.remote.core.IRemoteConnection; |
| import org.eclipse.remote.core.IRemoteConnectionChangeListener; |
| import org.eclipse.remote.core.IRemoteConnectionHostService; |
| import org.eclipse.remote.core.RemoteConnectionChangeEvent; |
| import org.eclipse.remote.core.exception.RemoteConnectionException; |
| import org.eclipse.ui.progress.IProgressConstants; |
| |
| /** |
| * The part of the JAXB framework responsible for handling job submission, termination, suspension and resumption. Also provides |
| * on-demand job status checking. <br> |
| * <br> |
| * The state maintained by the control is volatile (in-memory only). The control is responsible for handing off to the caller status |
| * objects containing job state, as well as means of accessing the process (if interactive) and the standard out and error streams. |
| * When the job completes, these are eliminated from its internal map.<br> |
| * <br> |
| * The logic of this manager is generic; the specific commands used, files staged, and script constructed (if any) are all |
| * configured via the resource manager XML. <br> |
| * <br> |
| * Currently, it is the control which handles updating the monitor component. |
| * |
| * @author arossi |
| * @author Jeff Overbey - Environment Manager support |
| */ |
| public class LaunchController implements ILaunchController { |
| |
| /* |
| * copied from AbstractToolRuntimeSystem; the RM should shut down when the remote connection is closed |
| */ |
| private class ConnectionChangeListener implements IRemoteConnectionChangeListener { |
| public ConnectionChangeListener() { |
| // Nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.remote.core.IRemoteConnectionChangeListener# connectionChanged |
| * (org.eclipse.remote.core.IRemoteConnectionChangeEvent) |
| */ |
| @Override |
| public void connectionChanged(RemoteConnectionChangeEvent event) { |
| if (event.getType() == RemoteConnectionChangeEvent.CONNECTION_ABORTED |
| || event.getType() == RemoteConnectionChangeEvent.CONNECTION_CLOSED) { |
| try { |
| stop(); |
| } catch (CoreException e) { |
| JAXBControlCorePlugin.log(e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * tries to open connection if closed |
| * |
| * @param connection |
| * @param progress |
| * @throws RemoteConnectionException |
| */ |
| public static void checkConnection(IRemoteConnection connection, SubMonitor progress) throws CoreException { |
| try { |
| if (connection != null) { |
| if (!progress.isCanceled() && !connection.isOpen()) { |
| connection.open(progress); |
| if (!progress.isCanceled() && !connection.isOpen()) { |
| throw CoreExceptionUtils.newException(Messages.RemoteConnectionError + connection.getName()); |
| } |
| } |
| } |
| } catch (RemoteConnectionException e) { |
| throw CoreExceptionUtils.newException(Messages.RemoteConnectionError + connection.getName(), e); |
| } |
| } |
| |
| private final ConnectionChangeListener connectionListener = new ConnectionChangeListener(); |
| private final Map<String, String> launchEnv = new TreeMap<String, String>(); |
| |
| private final JobIdPinTable pinTable = new JobIdPinTable(); |
| |
| private String fControlId; |
| private ICommandJobStatusMap jobStatusMap; |
| private RMVariableMap rmVarMap; |
| private String servicesId; |
| private String connectionName; |
| private boolean appendLaunchEnv; |
| private boolean isActive = false; |
| private boolean isInitialized = false; |
| private String configURL; |
| private RemoteServicesDelegate fRemoteServicesDelegate; |
| |
| private ResourceManagerData configData; |
| |
| public LaunchController() { |
| } |
| |
| /** |
| * Helper to add a read-only attribute |
| * |
| * @param name |
| * @param value |
| */ |
| private void addAttribute(String name, String value) { |
| AttributeType attr = getEnvironment().get(name); |
| if (attr == null) { |
| attr = new AttributeType(); |
| attr.setName(name); |
| attr.setVisible(true); |
| attr.setReadOnly(true); |
| getEnvironment().put(name, attr); |
| } |
| attr.setValue(value); |
| } |
| |
| /** |
| * Checks to see if there was an exception thrown by the run method. |
| * |
| * @param job |
| * @throws CoreException |
| * if the job execution raised and exception |
| */ |
| private void checkJobForError(ICommandJob job) throws CoreException { |
| IStatus status = job.getRunStatus(); |
| if (status != null && status.getSeverity() == IStatus.ERROR) { |
| throw CoreExceptionUtils.newException(status.getMessage(), status.getException()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#control(java.lang.String, java.lang.String, |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void control(String jobId, String operation, IProgressMonitor monitor) throws CoreException { |
| if (!isActive()) { |
| throw CoreExceptionUtils.newException(Messages.LaunchController_notStarted, null); |
| } |
| |
| ICommandJobStatus status = jobStatusMap.getStatus(jobId); |
| |
| if (RERUN_OPERATION.equals(operation) && status != null) { |
| status.rerun(); |
| } else if (status == null || !status.getState().equals(IJobStatus.COMPLETED)) { |
| SubMonitor progress = SubMonitor.convert(monitor, 100); |
| worked(progress, 30); |
| try { |
| pinTable.pin(jobId); |
| AttributeType a = getRMVariableMap().get(jobId); |
| AttributeType tmp = null; |
| if (a == null) { |
| tmp = new AttributeType(); |
| tmp.setVisible(false); |
| tmp.setName(jobId); |
| getRMVariableMap().put(jobId, tmp); |
| } |
| doControlCommand(jobId, operation); |
| if (tmp != null) { |
| getRMVariableMap().remove(jobId); |
| } |
| } finally { |
| pinTable.release(jobId); |
| } |
| worked(progress, 40); |
| if (TERMINATE_OPERATION.equals(operation)) { |
| jobStatusMap.cancel(jobId); |
| } |
| worked(progress, 30); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#dispose() |
| */ |
| @Override |
| public void dispose() { |
| // NOP for the moment |
| } |
| |
| /** |
| * @param jobId |
| * resource-specific id |
| * @param operation |
| * terminate, hold, suspend, release, resume. |
| * @throws CoreException |
| * If the command is not supported |
| */ |
| private void doControlCommand(String jobId, String operation) throws CoreException { |
| CoreException ce = CoreExceptionUtils.newException(Messages.RMNoSuchCommandError + operation, null); |
| |
| CommandType cmd = null; |
| if (TERMINATE_OPERATION.equals(operation)) { |
| maybeKillInteractive(jobId); |
| cmd = getConfiguration().getControlData().getTerminateJob(); |
| if (cmd == null) { // there may not be an external cancel |
| return; |
| } |
| } else if (SUSPEND_OPERATION.equals(operation)) { |
| cmd = getConfiguration().getControlData().getSuspendJob(); |
| } else if (RESUME_OPERATION.equals(operation)) { |
| cmd = getConfiguration().getControlData().getResumeJob(); |
| } else if (RELEASE_OPERATION.equals(operation)) { |
| cmd = getConfiguration().getControlData().getReleaseJob(); |
| } else if (HOLD_OPERATION.equals(operation)) { |
| cmd = getConfiguration().getControlData().getHoldJob(); |
| } |
| |
| if (cmd == null) { |
| throw ce; |
| } |
| |
| runCommand(jobId, cmd, CommandJob.JobMode.INTERACTIVE, getEnvironment(), null, ILaunchManager.RUN_MODE); |
| } |
| |
| /** |
| * Run either interactive or batch job for run or debug modes. ILaunchManager.RUN_MODE and ILaunchManager.DEBUG_MODE are the |
| * corresponding LaunchConfiguration modes; batch/interactive are currently determined by the configuration (the configuration |
| * cannot implement both). This may need to be modified. |
| * |
| * @param uuid |
| * temporary internal id for as yet unsubmitted job |
| * @param launch |
| * launch information for the job |
| * @return job wrapper object |
| * @throws CoreException |
| */ |
| private ICommandJob doJobSubmitCommand(String uuid, ILaunchConfiguration launchConfig, String launchMode) throws CoreException { |
| CommandType command = null; |
| CommandJob.JobMode jobMode = CommandJob.JobMode.INTERACTIVE; |
| |
| if (ILaunchManager.RUN_MODE.equals(launchMode)) { |
| command = getConfiguration().getControlData().getSubmitBatch(); |
| if (command != null) { |
| jobMode = CommandJob.JobMode.BATCH; |
| } else { |
| command = getConfiguration().getControlData().getSubmitInteractive(); |
| } |
| } else if (ILaunchManager.DEBUG_MODE.equals(launchMode)) { |
| command = getConfiguration().getControlData().getSubmitBatchDebug(); |
| if (command != null) { |
| jobMode = CommandJob.JobMode.BATCH; |
| } else { |
| command = getConfiguration().getControlData().getSubmitInteractiveDebug(); |
| } |
| } |
| |
| if (command == null) { |
| throw CoreExceptionUtils.newException( |
| Messages.MissingRunCommandsError + JAXBControlConstants.SP + uuid + JAXBControlConstants.SP + launchMode, null); |
| } |
| |
| /* |
| * NOTE: changed this to join, because the waitForId is now part of the run() method of the command itself (05.01.2011) |
| */ |
| return runCommand(uuid, command, jobMode, getEnvironment(), launchConfig, launchMode); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) |
| */ |
| @SuppressWarnings("rawtypes") |
| public Object getAdapter(Class adapter) { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#getAppendEnv() |
| */ |
| public boolean getAppendEnv() { |
| return appendLaunchEnv; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBJobControl#getConfiguration() |
| */ |
| @Override |
| public ResourceManagerData getConfiguration() { |
| return configData; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#getConnectionName() |
| */ |
| @Override |
| public String getConnectionName() { |
| return connectionName; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBJobControl#getControlId() |
| */ |
| @Override |
| public String getControlId() { |
| return fControlId; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBJobControl#getEnvironment() |
| */ |
| @Override |
| public IVariableMap getEnvironment() { |
| return getRMVariableMap(); |
| } |
| |
| /** |
| * Get the environment manager configuration that was specified in the launch configuration. If no |
| * launchConfiguration was specified then this CommandJob does not need to use environment management so we can safely return |
| * null. |
| * |
| * @return environment manager configuration or null if no configuration can be found |
| */ |
| private IEnvManagerConfig getEnvManagerConfig(ILaunchConfiguration configuration) { |
| try { |
| String emsConfigAttr = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_EMS_CONFIG, (String) null); |
| if (emsConfigAttr != null) { |
| final EnvManagerConfigString config = new EnvManagerConfigString(emsConfigAttr); |
| if (config.isEnvMgmtEnabled()) { |
| return config; |
| } |
| } |
| } catch (CoreException e) { |
| // Ignore |
| } |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#getJobStatus(java.lang.String, boolean, |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public IJobStatus getJobStatus(String jobId, boolean force, IProgressMonitor monitor) throws CoreException { |
| if (!isActive()) { |
| throw CoreExceptionUtils.newException(Messages.LaunchController_notStarted, null); |
| } |
| |
| SubMonitor progress = SubMonitor.convert(monitor, 100); |
| ICommandJobStatus status = jobStatusMap.getStatus(jobId); |
| |
| /* |
| * First check to see when the last call was made; throttle requests coming in intervals less than |
| * ICommandJobStatus.UPDATE_REQUEST_INTERVAL |
| */ |
| |
| if (status != null) { |
| if (IJobStatus.COMPLETED.equals(status.getState())) { |
| |
| /* |
| * leave the status in the map in case there are further calls (regarding remote file state); it will be pruned |
| * by the daemon; note that a COMPLETED state can correspond to a COMPLETED, CANCELED, FAILED or |
| * JOB_OUTERR_READY detail |
| */ |
| return jobStatusMap.terminated(jobId, progress.newChild(50)); |
| } |
| |
| if (!force) { |
| long now = System.currentTimeMillis(); |
| long lapse = now - status.getLastUpdateRequest(); |
| if (lapse < ICommandJobStatus.UPDATE_REQUEST_INTERVAL) { |
| return status; |
| } |
| status.setUpdateRequestTime(now); |
| } |
| } |
| |
| AttributeType jobIdAttr = getRMVariableMap().get(jobId); |
| |
| ICommandJob job = null; |
| CommandType cmd = getConfiguration().getControlData().getGetJobStatus(); |
| if (cmd != null && isActive() && !progress.isCanceled()) { |
| /* |
| * Create a temporary jobId attribute with the same name as this job. This attribute is used to obtain the status from |
| * the get-job-status command rather than the actual jobId attribute to avoid incorrectly setting the status when |
| * running the command as an interactive job. |
| */ |
| String tmpJobId = UUID.randomUUID().toString(); |
| AttributeType a = new AttributeType(); |
| a.setVisible(false); |
| a.setName(jobId); |
| getRMVariableMap().put(tmpJobId, a); |
| |
| /* |
| * Run the get-job-status command using the temporary jobId attribute. |
| */ |
| job = runCommand(tmpJobId, cmd, CommandJob.JobMode.STATUS, getEnvironment(), null, ILaunchManager.RUN_MODE); |
| |
| /* |
| * If there is already a jobId attribute, replace its value with the result of the get-job-status command so the new |
| * status is correctly updated. |
| */ |
| a = getRMVariableMap().remove(tmpJobId); |
| if (jobIdAttr != null) { |
| try { |
| pinTable.pin(jobId); |
| jobIdAttr.setValue(a.getValue()); |
| } finally { |
| pinTable.release(jobId); |
| } |
| } else { |
| jobIdAttr = a; |
| } |
| } |
| |
| String state = IJobStatus.UNDETERMINED; |
| |
| if (jobIdAttr != null) { |
| state = String.valueOf(jobIdAttr.getValue()); |
| } else if (status != null) { |
| state = status.getStateDetail(); |
| } |
| |
| if (status == null) { |
| status = new CommandJobStatus(jobId, state, null, this, getEnvironment(), ILaunchManager.RUN_MODE); |
| status.setOwner(getRMVariableMap().getString(JAXBControlConstants.CONTROL_USER_NAME)); |
| jobStatusMap.addJobStatus(jobId, status); |
| } else { |
| status.setState(state); |
| } |
| |
| /* |
| * as specified by the contract |
| */ |
| if ((job != null && isCanceled(job)) || progress.isCanceled()) { |
| status.setState(IJobStatus.UNDETERMINED); |
| return status; |
| } |
| |
| if (IJobStatus.COMPLETED.equals(state)) { |
| /* |
| * leave the status in the map in case there are further calls (regarding remote file state); it will be pruned by |
| * the daemon |
| */ |
| jobStatusMap.terminated(jobId, progress.newChild(50)); |
| } |
| |
| return status; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#getJobStatus(java.lang.String, |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public IJobStatus getJobStatus(String jobId, IProgressMonitor monitor) throws CoreException { |
| return getJobStatus(jobId, false, monitor); |
| } |
| |
| /** |
| * @return any environment variables passed in through the LaunchConfiguration |
| */ |
| public Map<String, String> getLaunchEnv() { |
| return launchEnv; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#getRemoteServicesId() |
| */ |
| @Override |
| public String getRemoteServicesId() { |
| return servicesId; |
| } |
| |
| /** |
| * Get the variable map. Returns an initialized map if one doesn't already exist. |
| * |
| * @return initialized variable map |
| */ |
| private RMVariableMap getRMVariableMap() { |
| if (rmVarMap == null) { |
| rmVarMap = new RMVariableMap(); |
| } |
| if (!rmVarMap.isInitialized()) { |
| JAXBInitializationUtils.initializeMap(getConfiguration(), rmVarMap); |
| } |
| return rmVarMap; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#getStatusMap() |
| */ |
| public ICommandJobStatusMap getStatusMap() { |
| return jobStatusMap; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#hasRunningJobs() |
| */ |
| @Override |
| public boolean hasRunningJobs() { |
| return jobStatusMap != null && !jobStatusMap.isEmpty(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#initialize() |
| */ |
| @Override |
| public void initialize() throws CoreException { |
| realizeRMDataFromXML(); |
| if (servicesId == null && connectionName == null) { |
| /* |
| * Set connection information from the site configuration. This may get overidden by the launch configuration |
| * later |
| */ |
| SiteType site = getConfiguration().getSiteData(); |
| if (site != null) { |
| servicesId = site.getRemoteServices(); |
| if (servicesId == null) { |
| servicesId = "org.eclipse.remote.JSch"; //$NON-NLS-1$ |
| } |
| connectionName = site.getConnectionName(); |
| } |
| } |
| if (servicesId == null || connectionName == null) { |
| throw CoreExceptionUtils.newException(Messages.LaunchController_missingServicesOrConnectionName); |
| } |
| fControlId = LaunchControllerManager.generateControlId(servicesId, connectionName, getConfiguration().getName()); |
| isInitialized = true; |
| } |
| |
| /** |
| * @return whether the state of the resource manager is stopped or not. |
| */ |
| private boolean isActive() { |
| return isActive; |
| } |
| |
| private boolean isCanceled(ICommandJob job) { |
| IStatus status = job.getRunStatus(); |
| return (status != null && status.getSeverity() == IStatus.CANCEL); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#isInitialized() |
| */ |
| @Override |
| public boolean isInitialized() { |
| return isInitialized; |
| } |
| |
| /** |
| * Checks for existence of either internally generated script or custom script path. In either case, either replaces contents of |
| * the corresponding managed file object or creates one. |
| * |
| * @param lists |
| * the lists of managed files for this submission |
| * @param stagingLocation |
| * for the script (may be <code>null</null> |
| * @param delete |
| * whether the script target should be deleted after submission |
| */ |
| private void maybeAddManagedFileForScript(List<ManagedFilesType> lists, String stagingLocation, boolean delete) { |
| ManagedFilesType files = null; |
| if (stagingLocation == null) { |
| IPath path = new Path(fRemoteServicesDelegate.getRemoteHome().getPath()).append(JAXBControlConstants.ECLIPSESETTINGS); |
| stagingLocation = path.toString(); |
| } |
| for (ManagedFilesType f : lists) { |
| if (stagingLocation.equals(f.getFileStagingLocation())) { |
| files = f; |
| break; |
| } |
| } |
| |
| AttributeType scriptVar = getRMVariableMap().get(JAXBControlConstants.SCRIPT); |
| AttributeType scriptPathVar = getRMVariableMap().get(JAXBControlConstants.SCRIPT_PATH); |
| if (scriptVar != null || scriptPathVar != null) { |
| if (files == null) { |
| files = new ManagedFilesType(); |
| files.setFileStagingLocation(stagingLocation); |
| lists.add(files); |
| } |
| List<ManagedFileType> fileList = files.getFile(); |
| ManagedFileType scriptFile = null; |
| if (!fileList.isEmpty()) { |
| for (ManagedFileType f : fileList) { |
| if (f.getName().equals(JAXBControlConstants.SCRIPT_FILE)) { |
| scriptFile = f; |
| break; |
| } |
| } |
| } |
| if (scriptFile == null) { |
| scriptFile = new ManagedFileType(); |
| scriptFile.setName(JAXBControlConstants.SCRIPT_FILE); |
| fileList.add(scriptFile); |
| } |
| scriptFile.setResolveContents(false); |
| scriptFile.setUniqueIdPrefix(true); |
| if (scriptPathVar != null) { |
| scriptFile.setPath(String.valueOf(scriptPathVar.getValue())); |
| scriptFile.setDeleteSourceAfterUse(false); |
| } else { |
| scriptFile.setContents(JAXBControlConstants.OPENVRM + JAXBControlConstants.SCRIPT + JAXBControlConstants.PD |
| + JAXBControlConstants.VALUE + JAXBControlConstants.CLOSV); |
| scriptFile.setDeleteSourceAfterUse(true); |
| } |
| scriptFile.setDeleteTargetAfterUse(delete); |
| } |
| } |
| |
| /** |
| * Looks for cleanup flag and removes the remote file if indicated. |
| * |
| * @param uuid |
| * @param lists |
| * @throws CoreException |
| */ |
| private void maybeCleanupManagedFiles(String uuid, List<ManagedFilesType> lists) throws CoreException { |
| if (lists == null || lists.isEmpty() || Preferences.getBoolean(JAXBControlCorePlugin.getUniqueIdentifier(), |
| JAXBRMPreferenceConstants.KEEP_MANAGED_FILES)) { |
| return; |
| } |
| for (ManagedFilesType files : lists) { |
| if (files.getFile().isEmpty()) { |
| continue; |
| } |
| ManagedFilesJob job = new ManagedFilesJob(uuid, files, this); |
| job.setOperation(Operation.DELETE); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (InterruptedException ignored) { |
| // Ignore |
| } |
| } |
| } |
| |
| /** |
| * Serialize script content if necessary. We first check to see if there is a custom script (path). |
| * |
| * @param uuid |
| * temporary internal id for as yet unsubmitted job |
| * @param script |
| * configuration object describing how to construct the script from the environment |
| * @param monitor |
| * progress monitor |
| * @return whether the script target should be deleted |
| */ |
| private boolean maybeHandleScript(String uuid, ScriptType script, IProgressMonitor monitor) { |
| AttributeType a = getRMVariableMap().get(JAXBControlConstants.SCRIPT_PATH); |
| if (a != null && a.getValue() != null) { |
| return false; |
| } |
| if (script == null) { |
| return false; |
| } |
| ScriptHandler job = new ScriptHandler(uuid, script, getRMVariableMap(), launchEnv, false); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (InterruptedException ignored) { |
| // Ignore |
| } |
| return script.isDeleteAfterSubmit(); |
| } |
| |
| /** |
| * If job is interactive, kill the process directly rather than issuing a remote command. |
| * |
| * @param jobId |
| * either process id or internal identifier. |
| * @return whether job has been canceled |
| */ |
| private boolean maybeKillInteractive(String jobId) { |
| ICommandJobStatus status = jobStatusMap.getStatus(jobId); |
| boolean killed = false; |
| if (status != null) { |
| killed = status.cancel(); |
| } |
| return killed; |
| } |
| |
| /** |
| * Write content to file if indicated, and stage to host. |
| * |
| * @param uuid |
| * temporary internal id for as yet unsubmitted job |
| * @param lists |
| * the set of managed files for this submission |
| * @return whether the necessary staging completed without error |
| * @throws CoreException |
| */ |
| private boolean maybeTransferManagedFiles(String uuid, List<ManagedFilesType> lists) throws CoreException { |
| if (lists == null || lists.isEmpty()) { |
| return true; |
| } |
| /* |
| * one job to a staging location |
| */ |
| for (ManagedFilesType files : lists) { |
| if (files.getFile().isEmpty()) { |
| continue; |
| } |
| ManagedFilesJob job = new ManagedFilesJob(uuid, files, this); |
| job.setOperation(Operation.COPY); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (InterruptedException ignored) { |
| // Ignore |
| } |
| if (!job.getSuccess()) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Some target configurations require helper scripts for launching, debugging, etc. Make sure these helper scripts are available |
| * on the target system if no monitoring is enabled. |
| * |
| * @param monitor |
| * progress monitor |
| * @throws CoreException |
| */ |
| private void maybeUpdateServer(IProgressMonitor monitor) throws CoreException { |
| SubMonitor progress = SubMonitor.convert(monitor, 100); |
| IRemoteConnection conn = fRemoteServicesDelegate.getRemoteConnection(); |
| LMLDAServer server = (LMLDAServer) RemoteServerManager.getServer(LMLDAServer.SERVER_ID, conn); |
| server.setWorkDir(new Path(fRemoteServicesDelegate.getRemoteFileService().getBaseDirectory()) |
| .append(JAXBControlConstants.ECLIPSESETTINGS).toString()); |
| try { |
| server.updateServer(progress.newChild(100)); |
| } catch (IOException e) { |
| throw CoreExceptionUtils.newException(e.getMessage(), e); |
| } |
| } |
| |
| /** |
| * Unmarshals the XML into the JAXB data tree. |
| * |
| * @throws unmarshaling |
| * or URL exceptions |
| */ |
| private void realizeRMDataFromXML() throws CoreException { |
| if (configURL != null) { |
| try { |
| String configXML = JAXBInitializationUtils.getRMConfigurationXML(new URL(configURL)); |
| configData = JAXBInitializationUtils.initializeRMData(configXML); |
| } catch (Exception e) { |
| throw CoreExceptionUtils.newException(e.getLocalizedMessage(), e.getCause()); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#runCommand(org.eclipse.ptp.rm.jaxb.core.data.CommandType, |
| * org.eclipse.ptp.rm.jaxb.core.IVariableMap) |
| */ |
| @Override |
| public void runCommand(CommandType command, IVariableMap attributes) throws CoreException { |
| runCommand(null, command, CommandJob.JobMode.INTERACTIVE, attributes, null, ILaunchManager.RUN_MODE); |
| } |
| |
| /** |
| * Create command job, and schedule. Used for job-specific commands directly. |
| * |
| * @param uuid |
| * Temporary internal id for as yet unsubmitted job. If null, the command will be assumed to be interactive. |
| * @param command |
| * Configuration object containing the command arguments and tokenizers. |
| * @param jobMode |
| * Whether batch, interactive, or a status job. |
| * @param map |
| * Attribute map to use when running the command. Allows an alternate map to be used if required. |
| * @param launchConfig |
| * Launch configuration. This is only required if the launch environment needs to be passed to the remote command, |
| * otherwise null can be used. |
| * @param launchMode |
| * Launch mode (see {@link ILaunchMode}). Will be returned in the job status {@link IJobStatus#getLaunchMode()}. |
| * @return the runnable job object |
| * @throws CoreException |
| */ |
| private ICommandJob runCommand(String uuid, CommandType command, CommandJob.JobMode jobMode, IVariableMap map, |
| ILaunchConfiguration launchConfig, String launchMode) throws CoreException { |
| if (command == null) { |
| throw CoreExceptionUtils.newException(Messages.RMNoSuchCommandError, null); |
| } |
| |
| ICommandJob job = new CommandJob(uuid, command, jobMode, this, map, launchConfig, launchMode); |
| ((Job) job).setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE); |
| job.schedule(); |
| try { |
| job.join(); |
| } catch (InterruptedException ignored) { |
| // Ignore |
| } |
| if (!command.isIgnoreExitStatus()) { |
| checkJobForError(job); |
| } |
| return job; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#runCommand(java.lang.String, java.lang.String, |
| * org.eclipse.debug.core.ILaunchConfiguration) |
| */ |
| @Override |
| public void runCommand(String name, String resetValue, ILaunchConfiguration configuration) throws CoreException { |
| if (!isActive()) { |
| throw CoreExceptionUtils.newException(Messages.LaunchController_notStarted, null); |
| } |
| |
| if (configuration != null) { |
| updateAttributeValues(configuration, ILaunchManager.RUN_MODE, null); |
| } |
| |
| AttributeType changedValue = null; |
| |
| if (resetValue != null) { |
| changedValue = getRMVariableMap().get(resetValue); |
| changedValue.setValue(null); |
| } |
| |
| CommandType command = null; |
| |
| for (CommandType cmd : getConfiguration().getControlData().getButtonAction()) { |
| if (cmd.getName().equals(name)) { |
| command = cmd; |
| break; |
| } |
| } |
| |
| if (command == null) { |
| for (CommandType cmd : getConfiguration().getControlData().getStartUpCommand()) { |
| if (cmd.getName().equals(name)) { |
| command = cmd; |
| break; |
| } |
| } |
| } |
| |
| if (command == null) { |
| for (CommandType cmd : getConfiguration().getControlData().getShutDownCommand()) { |
| if (cmd.getName().equals(name)) { |
| command = cmd; |
| break; |
| } |
| } |
| } |
| |
| if (command != null) { |
| runCommand(null, command, CommandJob.JobMode.INTERACTIVE, getEnvironment(), configuration, ILaunchManager.RUN_MODE); |
| } |
| } |
| |
| /** |
| * Run command sequence. Invoked by startup or shutdown commands. Delegates to |
| * {@link #runCommand(String, CommandType, JobMode, ILaunchConfiguration, String, boolean)}. If a job in the sequence fails, the |
| * subsequent commands will not run. |
| * |
| * @param cmds |
| * configuration objects containing the command arguments and tokenizers |
| * @throws CoreException |
| */ |
| private void runCommands(List<CommandType> cmds) throws CoreException { |
| for (CommandType cmd : cmds) { |
| runCommand(null, cmd, CommandJob.JobMode.INTERACTIVE, getEnvironment(), null, ILaunchManager.RUN_MODE); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#setConnectionName(java.lang.String) |
| */ |
| @Override |
| public void setConnectionName(String connName) { |
| connectionName = connName; |
| } |
| |
| /** |
| * Add connection properties to the attribute map. |
| * |
| * @param conn |
| */ |
| private void setConnectionPropertyAttributes(IRemoteConnection conn) { |
| String property = conn.getProperty(IRemoteConnection.OS_ARCH_PROPERTY); |
| if (property != null) { |
| addAttribute(IRemoteConnection.OS_ARCH_PROPERTY, property); |
| } |
| property = conn.getProperty(IRemoteConnection.OS_NAME_PROPERTY); |
| if (property != null) { |
| addAttribute(IRemoteConnection.OS_NAME_PROPERTY, property); |
| } |
| property = conn.getProperty(IRemoteConnection.OS_VERSION_PROPERTY); |
| if (property != null) { |
| addAttribute(IRemoteConnection.OS_VERSION_PROPERTY, property); |
| } |
| } |
| |
| /** |
| * Create attributes from constants that are fixed while the controller is initialized. |
| * |
| * @throws CoreException |
| */ |
| private void setFixedConfigurationProperties(RemoteServicesDelegate delegate) throws CoreException { |
| IRemoteConnectionHostService hostSvc = delegate.getRemoteConnection().getService(IRemoteConnectionHostService.class); |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.CONTROL_USER_VAR, hostSvc.getUsername(), false); |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.CONTROL_ADDRESS_VAR, hostSvc.getHostname(), false); |
| String workingDir = delegate.getRemoteFileService().getBaseDirectory(); |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.CONTROL_WORKING_DIR_VAR, workingDir, false); |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.WORKING_DIRECTORY, workingDir, false); |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.PTP_DIRECTORY, |
| new Path(workingDir).append(JAXBControlConstants.ECLIPSESETTINGS).toString(), false); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.ILaunchController#setRemoteServicesId(java.lang.String) |
| */ |
| @Override |
| public void setRemoteServicesId(String id) { |
| servicesId = id; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#setRMConfigurationURL(java.net.URL) |
| */ |
| @Override |
| public void setRMConfigurationURL(URL url) { |
| if (url != null) { |
| configURL = url.toExternalForm(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#start(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void start(IProgressMonitor monitor) throws CoreException { |
| SubMonitor progress = SubMonitor.convert(monitor, 10); |
| if (!isActive) { |
| /* |
| * Support legacy RM API |
| */ |
| if (!isInitialized) { |
| initialize(); |
| } |
| |
| fRemoteServicesDelegate = RemoteServicesDelegate.getDelegate(servicesId, connectionName, progress.newChild(50)); |
| IRemoteConnection conn = fRemoteServicesDelegate.getRemoteConnection(); |
| if (conn != null) { |
| checkConnection(conn, progress.newChild(10)); |
| conn.addConnectionChangeListener(connectionListener); |
| } |
| |
| getRMVariableMap().setEnvManagerFromConnection(conn); |
| setFixedConfigurationProperties(fRemoteServicesDelegate); |
| setConnectionPropertyAttributes(conn); |
| |
| appendLaunchEnv = true; |
| |
| /* |
| * start daemon |
| */ |
| jobStatusMap = JobStatusMap.getInstance(this); |
| jobStatusMap.initialize(); |
| |
| /* |
| * Run the start up commands, if any |
| */ |
| List<CommandType> onStartUp = getConfiguration().getControlData().getStartUpCommand(); |
| runCommands(onStartUp); |
| |
| isActive = true; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.control.core.IJAXBLaunchControl#stop() |
| */ |
| @Override |
| public void stop() throws CoreException { |
| if (isActive) { |
| List<CommandType> onShutDown = getConfiguration().getControlData().getShutDownCommand(); |
| runCommands(onShutDown); |
| |
| jobStatusMap.dispose(); |
| |
| if (rmVarMap != null) { |
| rmVarMap.clear(); |
| } |
| |
| IRemoteConnection conn = fRemoteServicesDelegate.getRemoteConnection(); |
| if (conn != null) { |
| conn.removeConnectionChangeListener(connectionListener); |
| } |
| |
| isActive = false; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.core.jobs.IJobControl#submitJob(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public String submitJob(ILaunchConfiguration launchConfig, String launchMode, IProgressMonitor monitor) throws CoreException { |
| /* |
| * give submission a unique id which will in most cases be replaced by the resource-generated id for the job/process |
| */ |
| String uuid = UUID.randomUUID().toString(); |
| |
| if (!isActive()) { |
| throw CoreExceptionUtils.newException(Messages.LaunchController_notStarted, null); |
| } |
| |
| SubMonitor progress = SubMonitor.convert(monitor, 100); |
| |
| /* |
| * Create attribute representing job ID. This will be updated with a name (the job ID returned from the scheduler) and a |
| * value (the job status) by the tokenizer for the job submission command. |
| */ |
| AttributeType a = new AttributeType(); |
| a.setVisible(false); |
| getRMVariableMap().put(uuid, a); |
| |
| /* |
| * Overwrite attribute values based on user choices. Note that the launch can also modify attributes. |
| */ |
| updateAttributeValues(launchConfig, launchMode, progress.newChild(5)); |
| |
| /* |
| * process script |
| */ |
| ScriptType script = getConfiguration().getControlData().getScript(); |
| boolean delScript = maybeHandleScript(uuid, script, progress.newChild(5)); |
| worked(progress, 20); |
| |
| List<ManagedFilesType> files = getConfiguration().getControlData().getManagedFiles(); |
| |
| /* |
| * if the script is to be staged, a managed file pointing to either its content (${ptp_rm:script#value}), or to its path |
| * (SCRIPT_PATH) must exist. |
| */ |
| if (script != null) { |
| maybeAddManagedFileForScript(files, script.getFileStagingLocation(), delScript); |
| } |
| worked(progress, 5); |
| |
| if (!maybeTransferManagedFiles(uuid, files)) { |
| throw CoreExceptionUtils.newException(Messages.CannotCompleteSubmitFailedStaging, null); |
| } |
| worked(progress, 20); |
| |
| maybeUpdateServer(progress.newChild(10)); |
| |
| ICommandJob job = null; |
| |
| try { |
| job = doJobSubmitCommand(uuid, launchConfig, launchMode); |
| |
| if (isCanceled(job)) { |
| throw CoreExceptionUtils.newException(Messages.OperationWasCancelled, null); |
| } |
| worked(progress, 40); |
| } finally { |
| /* |
| * if the staged files can be removed, delete them |
| */ |
| maybeCleanupManagedFiles(uuid, files); |
| worked(progress, 5); |
| } |
| |
| ICommandJobStatus status = job.getJobStatus(); |
| |
| /* |
| * property containing actual jobId as name was set in the wait call; we may need the new jobId mapping momentarily to |
| * resolve proxy-specific info |
| */ |
| getRMVariableMap().remove(uuid); |
| |
| /* |
| * initialize the job status while the id property is live |
| */ |
| jobStatusMap.addJobStatus(status.getJobId(), status); |
| worked(progress, 5); |
| |
| /* |
| * to ensure the most recent script is used at the next call |
| */ |
| getRMVariableMap().remove(JAXBControlConstants.SCRIPT_PATH); |
| getRMVariableMap().remove(JAXBControlConstants.SCRIPT); |
| return status.getJobId(); |
| } |
| |
| /** |
| * Transfers the values from the configuration to the attribute map. This needs to be called whenever a new launch configuration |
| * is being used in order to switch the attributes to use the new values. |
| * |
| * @param configuration |
| * passed in from Launch Tab when the "run" command is chosen. |
| * @throws CoreException |
| */ |
| private void updateAttributeValues(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) |
| throws CoreException { |
| /* |
| * Update attributes from launch configuration |
| */ |
| Map<String, Object> lcattr = RMVariableMap.getValidAttributes(configuration); |
| for (String key : lcattr.keySet()) { |
| Object value = lcattr.get(key); |
| AttributeType target = getRMVariableMap().get(key.toString()); |
| if (target != null) { |
| target.setValue(value); |
| } |
| } |
| |
| /* |
| * The non-selected variables have been excluded from the valid attributes of the configuration; but we need to null out the |
| * superset values here that are undefined. |
| */ |
| for (String key : getRMVariableMap().getAttributes().keySet()) { |
| if (!lcattr.containsKey(key)) { |
| AttributeType target = getRMVariableMap().get(key.toString()); |
| if (target.isVisible()) { |
| target.setValue(null); |
| } |
| } |
| } |
| |
| /* |
| * Add launch mode attribute or update it if present |
| */ |
| getRMVariableMap().maybeAddAttribute(JAXBControlConstants.LAUNCH_MODE, mode, false); |
| |
| /* |
| * make sure these fixed properties are included |
| */ |
| getRMVariableMap().overwrite(JAXBControlConstants.SCRIPT_PATH, JAXBControlConstants.SCRIPT_PATH, lcattr); |
| getRMVariableMap().overwrite(JAXBControlConstants.EXEC_PATH, JAXBControlConstants.EXEC_PATH, lcattr); |
| getRMVariableMap().overwrite(JAXBControlConstants.EXEC_DIR, JAXBControlConstants.EXEC_DIR, lcattr); |
| getRMVariableMap().overwrite(JAXBControlConstants.PROG_ARGS, JAXBControlConstants.PROG_ARGS, lcattr); |
| getRMVariableMap().overwrite(JAXBControlConstants.DEBUGGER_ID, JAXBControlConstants.DEBUGGER_ID, lcattr); |
| getRMVariableMap().overwrite(JAXBControlConstants.DEBUGGER_LAUNCHER, JAXBControlConstants.DEBUGGER_LAUNCHER, lcattr); |
| |
| /* |
| * update the dynamic attributes |
| */ |
| String attr = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_EXECUTABLE_PATH, (String) null); |
| if (attr != null) { |
| AttributeType a = getEnvironment().get(JAXBControlConstants.DEBUGGER_EXEC_PATH); |
| if (a == null) { |
| a = new AttributeType(); |
| a.setName(JAXBControlConstants.DEBUGGER_EXEC_PATH); |
| getEnvironment().put(JAXBControlConstants.DEBUGGER_EXEC_PATH, a); |
| } |
| a.setValue(attr); |
| } |
| |
| attr = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_ARGS, (String) null); |
| if (attr != null) { |
| AttributeType a = getEnvironment().get(JAXBControlConstants.DEBUGGER_ARGS); |
| if (a == null) { |
| a = new AttributeType(); |
| a.setName(JAXBControlConstants.DEBUGGER_ARGS); |
| getEnvironment().put(JAXBControlConstants.DEBUGGER_ARGS, a); |
| } |
| a.setValue(attr); |
| } |
| |
| /* |
| * Set the following attributes: |
| * |
| * WORKING_DIRECTORY - Set to the ATTR_WORKING_DIR attribute from the Arguments tab. Default value is the connection |
| * working directory. |
| * DIRECTORY - Set to the ATTR_WORKING_DIR attribute from the Arguments tab. Default value is the executable working |
| * directory, or if no executable has been set, the connection working directory. |
| */ |
| attr = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_WORKING_DIR, (String) null); |
| if (attr == null) { |
| AttributeType a = getEnvironment().get(JAXBControlConstants.EXEC_DIR); |
| if (a != null) { |
| attr = (String) a.getValue(); |
| } |
| } else { |
| AttributeType a = getEnvironment().get(JAXBControlConstants.WORKING_DIRECTORY); |
| a.setValue(attr); |
| } |
| if (attr != null) { |
| AttributeType a = getEnvironment().get(JAXBControlConstants.DIRECTORY); |
| if (a == null) { |
| a = new AttributeType(); |
| a.setName(JAXBControlConstants.DIRECTORY); |
| getEnvironment().put(JAXBControlConstants.DIRECTORY, a); |
| } |
| a.setValue(attr); |
| } |
| |
| IEnvManagerConfig envMgrConfig = getEnvManagerConfig(configuration); |
| if (envMgrConfig != null) { |
| IEnvManager envManager = EnvManagerRegistry.getEnvManager(monitor, fRemoteServicesDelegate.getRemoteConnection()); |
| if (envManager != null) { |
| String emsStr = envManager.getBashConcatenation("\n", false, envMgrConfig, null); //$NON-NLS-1$ |
| AttributeType a = getEnvironment().get(JAXBControlConstants.EMS_ATTR); |
| if (a == null) { |
| a = new AttributeType(); |
| a.setName(JAXBControlConstants.EMS_ATTR); |
| getEnvironment().put(JAXBControlConstants.EMS_ATTR, a); |
| } |
| a.setValue(emsStr); |
| } |
| } |
| |
| launchEnv.clear(); |
| launchEnv.putAll(configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, launchEnv)); |
| appendLaunchEnv = configuration.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, appendLaunchEnv); |
| } |
| |
| /** |
| * Encapsulates null check. |
| * |
| * @param monitor |
| * @param units |
| */ |
| private void worked(IProgressMonitor monitor, int units) { |
| if (monitor != null) { |
| if (units == 0) { |
| monitor.done(); |
| } else { |
| monitor.worked(units); |
| } |
| } |
| } |
| } |