blob: ee0ee36ff2bb83e12d9510dc0c2aa440e5431e84 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, 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
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.launch.internal;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.core.resources.IContainer;
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.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.ptp.core.IPTPLaunchConfigurationConstants;
import org.eclipse.ptp.core.PTPCorePlugin;
import org.eclipse.ptp.core.attributes.AttributeManager;
import org.eclipse.ptp.core.attributes.EnumeratedAttribute;
import org.eclipse.ptp.core.attributes.IAttribute;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.elements.IPQueue;
import org.eclipse.ptp.core.elements.IPUniverse;
import org.eclipse.ptp.core.elements.IResourceManager;
import org.eclipse.ptp.core.elements.attributes.JobAttributes;
import org.eclipse.ptp.core.elements.attributes.ResourceManagerAttributes;
import org.eclipse.ptp.core.elements.attributes.JobAttributes.State;
import org.eclipse.ptp.core.elements.events.IJobChangeEvent;
import org.eclipse.ptp.core.elements.listeners.IJobListener;
import org.eclipse.ptp.debug.core.IAbstractDebugger;
import org.eclipse.ptp.debug.core.IPDebugConfiguration;
import org.eclipse.ptp.debug.core.PTPDebugCorePlugin;
import org.eclipse.ptp.debug.core.launch.IPLaunch;
import org.eclipse.ptp.debug.core.launch.PLaunch;
import org.eclipse.ptp.debug.ui.PTPDebugUIPlugin;
import org.eclipse.ptp.launch.PTPLaunchPlugin;
import org.eclipse.ptp.launch.internal.ui.LaunchMessages;
import org.eclipse.ptp.launch.ui.extensions.AbstractRMLaunchConfigurationFactory;
import org.eclipse.ptp.launch.ui.extensions.IRMLaunchConfigurationDynamicTab;
/**
*
*/
public abstract class AbstractParallelLaunchConfigurationDelegate
extends LaunchConfigurationDelegate implements IJobListener {
/**
* The JobSubmission class encapsulates all the information used in
* a job submission. Once the job is created *and starts running*,
* this information is used to complete the launch.
*/
private class JobSubmission {
private ILaunchConfiguration configuration;
private String mode;
private IPLaunch launch;
private AttributeManager attrMgr;
private IAbstractDebugger debugger;
public JobSubmission(ILaunchConfiguration configuration, String mode, IPLaunch launch,
AttributeManager attrMgr, IAbstractDebugger debugger) {
this.configuration = configuration;
this.mode = mode;
this.launch = launch;
this.attrMgr = attrMgr;
this.debugger = debugger;
}
/**
* @return the configuration
*/
public ILaunchConfiguration getConfiguration() {
return configuration;
}
/**
* @return the mode
*/
public String getMode() {
return mode;
}
/**
* @return the launch
*/
public IPLaunch getLaunch() {
return launch;
}
/**
* @return the attrMgr
*/
public AttributeManager getAttrMgr() {
return attrMgr;
}
/**
* @return the debugger
*/
public IAbstractDebugger getDebugger() {
return debugger;
}
}
protected Map<IPJob, JobSubmission> jobSubmissions = new HashMap<IPJob, JobSubmission>();
public AbstractParallelLaunchConfigurationDelegate() {
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getArgument(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_ARGUMENT, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getDebuggerExePath(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_EXECUTABLE_PATH, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getDebuggerID(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_ID, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getDebuggerWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_WORKING_DIR, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getProgramName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_APPLICATION_NAME, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getProjectName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getQueueName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.QUEUE_NAME, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getResourceManagerUniqueName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.RESOURCE_MANAGER_UNIQUENAME, (String)null);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected static String getWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_WORK_DIRECTORY, (String)null);
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
*/
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
return new PLaunch(configuration, mode, null);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.core.elements.listeners.IJobListener#handleEvent(org.eclipse.ptp.core.elements.events.IJobChangeEvent)
*/
public void handleEvent(IJobChangeEvent e) {
/*
* If the job state has changed to running, find the JobSubmission that
* corresponds to this job and perform remainder of job launch actions
*/
IAttribute<?,?,?> attr = e.getAttributes().get(JobAttributes.getStateAttributeDefinition());
if (attr != null) {
JobAttributes.State state = (State)((EnumeratedAttribute<?>)attr).getValue();
if (state == JobAttributes.State.RUNNING) {
synchronized (jobSubmissions) {
IPJob job = e.getSource();
JobSubmission jobSub = jobSubmissions.get(job);
if (jobSub != null) {
doCompleteJobLaunch(jobSub.getConfiguration(), jobSub.getMode(), jobSub.getLaunch(), jobSub.getAttrMgr(), jobSub.getDebugger(), job);
jobSubmissions.remove(job);
job.removeElementListener(this);
}
}
}
}
}
/**
* Get the attributes from the resource manager specific launch page.
*
* @param configuration
* @return IAttribute[]
* @throws CoreException
*/
private IAttribute<?,?,?>[] getLaunchAttributes(ILaunchConfiguration configuration)
throws CoreException {
String queueName = getQueueName(configuration);
IResourceManager rm = getResourceManager(configuration);
final AbstractRMLaunchConfigurationFactory rmFactory =
PTPLaunchPlugin.getDefault().getRMLaunchConfigurationFactory(rm);
if (rmFactory == null) {
return new IAttribute[0];
}
IRMLaunchConfigurationDynamicTab rmDynamicTab = rmFactory.create(rm);
IPQueue queue = rm.getQueueByName(queueName);
if (queue != null) {
return rmDynamicTab.getAttributes(rm, queue, configuration);
}
return new IAttribute[0];
}
/**
* @param message
* @param exception
* @param code
* @throws CoreException
*/
protected void abort(String message, Throwable exception, int code) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), code, message, exception));
}
/**
* @param job
*/
protected abstract void doCompleteJobLaunch(ILaunchConfiguration configuration, String mode, IPLaunch launch,
AttributeManager mgr, IAbstractDebugger debugger, IPJob job);
/**
* Get all the attributes specified in the launch configuration.
*
* @param configuration
* @return AttributeManager
* @throws CoreException
*/
protected AttributeManager getAttributeManager(ILaunchConfiguration configuration) throws CoreException {
AttributeManager attrMgr = new AttributeManager();
IResourceManager rm = getResourceManager(configuration);
if (rm != null) {
IPQueue queue = rm.getQueueByName(getQueueName(configuration));
if (queue != null) {
attrMgr.addAttribute(JobAttributes.getQueueIdAttributeDefinition().create(queue.getID()));
}
IPath programFile = getProgramFile(configuration);
attrMgr.addAttribute(JobAttributes.getExecutableNameAttributeDefinition().create(programFile.lastSegment()));
String path = programFile.removeLastSegments(1).toOSString();
if (path != null) {
attrMgr.addAttribute(JobAttributes.getExecutablePathAttributeDefinition().create(path));
}
String wd = verifyWorkDirectory(configuration);
if (wd != null) {
attrMgr.addAttribute(JobAttributes.getWorkingDirectoryAttributeDefinition().create(wd));
}
String[] argArr = getProgramParameters(configuration);
if (argArr != null) {
attrMgr.addAttribute(JobAttributes.getProgramArgumentsAttributeDefinition().create(argArr));
}
String[] envArr = DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
if (envArr != null) {
attrMgr.addAttribute(JobAttributes.getEnvironmentAttributeDefinition().create(envArr));
}
attrMgr.addAttributes(getLaunchAttributes(configuration));
}
return attrMgr;
}
/***
* Debug
*/
/**
* @param config
* @return
* @throws CoreException
*/
protected IPDebugConfiguration getDebugConfig(ILaunchConfiguration config) throws CoreException {
IPDebugConfiguration dbgCfg = null;
try {
dbgCfg = PTPDebugCorePlugin.getDefault().getDebugConfiguration(getDebuggerID(config));
} catch (CoreException e) {
System.out.println("ParallelLaunchConfigurationDelegate.getDebugConfig() Error");
throw e;
}
return dbgCfg;
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected IPath getProgramFile(ILaunchConfiguration configuration) throws CoreException {
IProject project = verifyProject(configuration);
String fileName = getProgramName(configuration);
if (fileName == null)
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Application_file_not_specified"), null, IStatus.INFO);
IPath programPath = new Path(fileName);
if (!programPath.isAbsolute()) {
programPath = project.getFile(programPath).getLocation();
}
if (!programPath.toFile().exists()) {
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Application_file_does_not_exist"), new FileNotFoundException(LaunchMessages.getResourceString("AbstractParallelLaunchDelegate.PROGRAM_PATH_not_found")), IPTPLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
}
/* --old
IFile programPath = project.getFile(fileName);
if (programPath == null || !programPath.exists() || !programPath.getLocation().toFile().exists())
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Application_file_does_not_exist"), new FileNotFoundException(LaunchMessages.getFormattedResourceString("AbstractParallelLaunchConfigurationDelegate.Application_path_not_found", programPath.getLocation().toString())), IStatus.INFO);
*/
return programPath;
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected String[] getProgramParameters(ILaunchConfiguration configuration) throws CoreException {
List<String> arguments = new ArrayList<String>();
String temp = getArgument(configuration);
if (temp != null && temp.length() > 0)
arguments.add(temp);
return (String[]) arguments.toArray(new String[arguments.size()]);
}
/**
* @param proName
* @return
*/
protected IProject getProject(String proName) {
return getWorkspaceRoot().getProject(proName);
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected IResourceManager getResourceManager(ILaunchConfiguration configuration) throws CoreException {
IPUniverse universe = PTPCorePlugin.getDefault().getUniverse();
IResourceManager[] rms = universe.getResourceManagers();
String rmUniqueName = getResourceManagerUniqueName(configuration);
for (int i = 0; i < rms.length; ++i) {
if (rms[i].getState() == ResourceManagerAttributes.State.STARTED &&
rms[i].getUniqueName().equals(rmUniqueName)) {
return rms[i];
}
}
return null;
}
/**
* @return
*/
protected IWorkspaceRoot getWorkspaceRoot() {
return ResourcesPlugin.getWorkspace().getRoot();
}
/**
* @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);
}
}
/****
* Source
****/
/**
* @param launch
* @param config
* @throws CoreException
*/
protected void setSourceLocator(ILaunch launch, ILaunchConfiguration config) throws CoreException {
setDefaultSourceLocator(launch, config);
}
protected void submitJob(ILaunchConfiguration configuration, String mode, IPLaunch launch,
AttributeManager attrMgr, IAbstractDebugger debugger, IProgressMonitor monitor) throws CoreException {
synchronized (jobSubmissions) {
final IResourceManager rm = getResourceManager(configuration);
if (rm == null) {
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.No_ResourceManager"), null, 0);
}
IPJob job = rm.submitJob(attrMgr, monitor);
if (job != null) {
JobSubmission jobSub = new JobSubmission(configuration, mode, launch, attrMgr, debugger);
jobSubmissions.put(job, jobSub);
job.addElementListener(this);
}
}
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected IBinaryObject verifyBinary(ILaunchConfiguration configuration) throws CoreException {
IProject project = verifyProject(configuration);
String fileName = getProgramName(configuration);
IPath programPath = new Path(fileName);
if (!programPath.isAbsolute()) {
programPath = project.getFile(programPath).getLocation();
}
return verifyBinary(project, programPath);
}
/**
* @param project
* @param exePath
* @return
* @throws CoreException
*/
protected IBinaryObject verifyBinary(IProject project, IPath exePath) throws CoreException {
ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(project);
for (int i = 0; i < parserRef.length; i++) {
try {
IBinaryParser parser = (IBinaryParser) parserRef[i].createExtension();
IBinaryObject exe = (IBinaryObject) parser.getBinary(exePath);
if (exe != null) {
return exe;
}
} catch (ClassCastException e) {
} catch (IOException e) {
}
}
IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser();
try {
return (IBinaryObject) parser.getBinary(exePath);
} catch (ClassCastException e) {
} catch (IOException e) {
}
Throwable exception = new FileNotFoundException(LaunchMessages.getResourceString("AbstractParallelLaunchDelegate.Program_is_not_a_recongnized_executable"));
int code = IPTPLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY;
MultiStatus status = new MultiStatus(PTPCorePlugin.getUniqueIdentifier(), code, LaunchMessages.getResourceString("AbstractParallelLaunchDelegate.Program_is_not_a_recongnized_executable"), exception);
status.add(new Status(IStatus.ERROR, PTPCorePlugin.getUniqueIdentifier(), code, exception == null ? "" : exception.getLocalizedMessage(), exception));
throw new CoreException(status);
}
/**
* @param path
* @throws CoreException
*/
protected void verifyDebuggerPath(String path) throws CoreException {
if (!verifyPath(path)) {
abort(LaunchMessages.getResourceString("AbstractParallelLaunchDelegate.Debugger_path_not_found"), new FileNotFoundException(LaunchMessages.getResourceString("AbstractParallelLaunchDelegate.Debugger_path_not_found")), IPTPLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
}
}
/**
* @param path
* @return
*/
protected boolean verifyPath(String path) {
IPath programPath = new Path(path);
if (programPath == null || programPath.isEmpty() || !programPath.toFile().exists()) {
return false;
}
return true;
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected IProject verifyProject(ILaunchConfiguration configuration) throws CoreException {
String proName = getProjectName(configuration);
if (proName == null)
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Project_not_specified"), null, IStatus.INFO);
IProject project = getProject(proName);
if (project == null || !project.exists() || !project.isOpen())
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Project_does_not_exist_or_is_not_a_project"), null, IStatus.INFO);
return project;
}
/**
* @param configuration
* @return
* @throws CoreException
*/
protected String verifyWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
String workPath = getWorkDirectory(configuration);
if (workPath == null) {
IProject project = verifyProject(configuration);
if (project != null)
return project.getLocation().toOSString();
} else {
IPath path = new Path(workPath);
if (path.isAbsolute()) {
File dir = new File(path.toOSString());
if (dir.isDirectory())
return path.toOSString();
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Working_directory_does_not_exist"), new FileNotFoundException(LaunchMessages.getFormattedResourceString("AbstractParallelLaunchConfigurationDelegate.Application_path_not_found", path.toOSString())), IStatus.INFO);
} else {
IResource res = getWorkspaceRoot().findMember(path);
if (res instanceof IContainer && res.exists())
return res.getLocation().toOSString();
abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Working_directory_does_not_exist"), new FileNotFoundException(LaunchMessages.getFormattedResourceString("AbstractParallelLaunchConfigurationDelegate.Application_path_not_found", path.toOSString())), IStatus.INFO);
}
}
return null;
}
}