blob: 34df685108506410351cec29dcb3fea3c1d20b5c [file] [log] [blame]
package org.eclipse.debug.internal.core;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.xerces.dom.DocumentImpl;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
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.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Launch configuration handle.
*
* @see ILaunchConfiguration
*/
public class LaunchConfiguration extends PlatformObject implements ILaunchConfiguration {
/**
* Location this configuration is stored in. This
* is the key for a launch configuration handle.
*/
private IPath fLocation;
/**
* Constructs a launch configuration in the given location.
*
* @param location path to where this launch configuration's
* underlying file is located
*/
protected LaunchConfiguration(IPath location) {
setLocation(location);
}
/**
* Constructs a launch configuration from the given
* memento.
*
* @param memento launch configuration memento
* @exception CoreException if the memento is invalid or
* an exception occurrs reading the memento
*/
protected LaunchConfiguration(String memento) throws CoreException {
Exception ex = null;
try {
Element root = null;
DocumentBuilder parser =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
StringReader reader = new StringReader(memento);
InputSource source = new InputSource(reader);
root = parser.parse(source).getDocumentElement();
String localString = root.getAttribute("local"); //$NON-NLS-1$
String path = root.getAttribute("path"); //$NON-NLS-1$
String message = null;
if (path == null) {
message = DebugCoreMessages.getString("LaunchConfiguration.Invalid_launch_configuration_memento__missing_path_attribute_3"); //$NON-NLS-1$
} else if (localString == null) {
message = DebugCoreMessages.getString("LaunchConfiguration.Invalid_launch_configuration_memento__missing_local_attribute_4"); //$NON-NLS-1$
}
if (message != null) {
IStatus s = newStatus(message, DebugException.INTERNAL_ERROR, null);
throw new CoreException(s);
}
IPath location = null;
boolean local = (Boolean.valueOf(localString)).booleanValue();
if (local) {
location = LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH.append(path);
} else {
location = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(path);
}
setLocation(location);
return;
} catch (ParserConfigurationException e) {
ex = e;
} catch (SAXException e) {
ex = e;
} catch (IOException e) {
ex = e;
}
IStatus s = newStatus(DebugCoreMessages.getString("LaunchConfiguration.Exception_occurred_parsing_memento_5"), DebugException.INTERNAL_ERROR, ex); //$NON-NLS-1$
throw new CoreException(s);
}
/**
* Creates and returns a new error status based on
* the given mesasge, code, and exception.
*
* @param message error message
* @param code error code
* @param e exception or <code>null</code>
* @return status
*/
protected IStatus newStatus(String message, int code, Throwable e) {
return new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), code, message, e);
}
/**
* @see ILaunchConfiguration#launch(String, IProgressMonitor)
*/
public ILaunch launch(String mode, IProgressMonitor monitor) throws CoreException {
ILaunch launch = new Launch(this, mode, null);
getLaunchManager().addLaunch(launch);
try {
getDelegate().launch(this, mode, launch, monitor);
} catch (CoreException e) {
// if there was an exception, and the launch is empty, remove it
if (!launch.hasChildren()) {
getLaunchManager().removeLaunch(launch);
}
throw e;
}
if (monitor != null && monitor.isCanceled()) {
getLaunchManager().removeLaunch(launch);
} else {
initializeSourceLocator(launch);
}
return launch;
}
/**
* Set the source locator to use with the launch, if specified
* by this configuration.
*
* @param launch the launch on which to set the source locator
*/
protected void initializeSourceLocator(ILaunch launch) throws CoreException {
if (launch.getSourceLocator() == null) {
String type = getAttribute(ATTR_SOURCE_LOCATOR_ID, (String)null);
if (type != null) {
IPersistableSourceLocator locator = getLaunchManager().newSourceLocator(type);
String memento = getAttribute(ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
if (memento == null) {
locator.initializeDefaults(this);
} else {
locator.initializeFromMemento(memento);
}
launch.setSourceLocator(locator);
}
}
}
/**
* @see ILaunchConfiguration#supportsMode(String)
*/
public boolean supportsMode(String mode) throws CoreException {
return getType().supportsMode(mode);
}
/**
* A configuration's name is that of the last segment
* in it's location (subtract the ".launch" extension).
*
* @see ILaunchConfiguration#getName()
*/
public String getName() {
return getLastLocationSegment();
}
private String getLastLocationSegment() {
String name = getLocation().lastSegment();
name = name.substring(0, name.length() - (LAUNCH_CONFIGURATION_FILE_EXTENSION.length() + 1));
return name;
}
/**
* @see ILaunchConfiguration#getLocation()
*/
public IPath getLocation() {
return fLocation;
}
/**
* Sets the location of this configuration's underlying
* file.
*
* @param location the location of this configuration's underlying
* file
*/
private void setLocation(IPath location) {
fLocation = location;
}
/**
* @see ILaunchConfiguration#exists()
*/
public boolean exists() {
IFile file = getFile();
if (file == null) {
return getLocation().toFile().exists();
} else {
return file.exists();
}
}
/**
* @see ILaunchConfiguration#getAttribute(String, int)
*/
public int getAttribute(String attributeName, int defaultValue) throws CoreException {
return getInfo().getIntAttribute(attributeName, defaultValue);
}
/**
* @see ILaunchConfiguration#getAttribute(String, String)
*/
public String getAttribute(String attributeName, String defaultValue) throws CoreException {
return getInfo().getStringAttribute(attributeName, defaultValue);
}
/**
* @see ILaunchConfiguration#getAttribute(String, boolean)
*/
public boolean getAttribute(String attributeName, boolean defaultValue) throws CoreException {
return getInfo().getBooleanAttribute(attributeName, defaultValue);
}
/**
* @see ILaunchConfiguration#getAttribute(String, List)
*/
public List getAttribute(String attributeName, List defaultValue) throws CoreException {
return getInfo().getListAttribute(attributeName, defaultValue);
}
/**
* @see ILaunchConfiguration#getAttribute(String, Map)
*/
public Map getAttribute(String attributeName, Map defaultValue) throws CoreException {
return getInfo().getMapAttribute(attributeName, defaultValue);
}
/**
* @see ILaunchConfiguration#getType()
*/
public ILaunchConfigurationType getType() throws CoreException {
return getInfo().getType();
}
/**
* @see ILaunchConfiguration#isLocal()
*/
public boolean isLocal() {
return getFile() == null;
}
/**
* @see ILaunchConfiguration#getWorkingCopy()
*/
public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException {
return new LaunchConfigurationWorkingCopy(this);
}
/**
* @see ILaunchConfiguration#copy(String name)
*/
public ILaunchConfigurationWorkingCopy copy(String name) throws CoreException {
ILaunchConfigurationWorkingCopy copy = new LaunchConfigurationWorkingCopy(this, name);
return copy;
}
/**
* @see ILaunchConfiguration#isWorkingCopy()
*/
public boolean isWorkingCopy() {
return false;
}
/**
* @see ILaunchConfiguration#delete()
*/
public void delete() throws CoreException {
if (exists()) {
if (isLocal()) {
if (!(getLocation().toFile().delete())) {
throw new DebugException(
new Status(Status.ERROR, DebugPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, DebugCoreMessages.getString("LaunchConfiguration.Failed_to_delete_launch_configuration._1"), null) //$NON-NLS-1$
);
}
// manually update the launch manager cache since there
// will be no resource delta
getLaunchManager().launchConfigurationDeleted(this);
} else {
// delete the resource using IFile API such that
// resource deltas are fired.
IResource file = getFile();
if (file != null) {
file.delete(true, null);
} else {
// Error - the exists test passed, but could not locate file
}
}
}
}
/**
* Returns the info object containing the attributes
* of this configuration
*
* @return info for this handle
* @exception CoreException if unable to retrieve the
* info object
*/
protected LaunchConfigurationInfo getInfo() throws CoreException {
return getLaunchManager().getInfo(this);
}
/**
* Returns the launch configuration delegate for this
* launch configuration.
*
* @return launch configuration delegate
* @exception CoreException if the delegate was unable
* to be created
*/
protected ILaunchConfigurationDelegate getDelegate() throws CoreException {
return ((LaunchConfigurationType)getType()).getDelegate();
}
/**
* Returns the launch manager
*
* @return launch manager
*/
protected LaunchManager getLaunchManager() {
return (LaunchManager)DebugPlugin.getDefault().getLaunchManager();
}
/**
* @see ILaunchConfiguration#getMemento()
*/
public String getMemento() throws CoreException {
IPath relativePath = null;
if (isLocal()) {
IPath rootPath = LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH;
IPath configPath = getLocation();
relativePath = configPath.removeFirstSegments(rootPath.segmentCount());
} else {
relativePath = getFile().getFullPath();
}
relativePath = relativePath.setDevice(null);
Document doc = new DocumentImpl();
Element node = doc.createElement("launchConfiguration"); //$NON-NLS-1$
doc.appendChild(node);
node.setAttribute("local", (new Boolean(isLocal())).toString()); //$NON-NLS-1$
node.setAttribute("path", relativePath.toString()); //$NON-NLS-1$
try {
return LaunchManager.serializeDocument(doc);
} catch (IOException e) {
IStatus status = newStatus(DebugCoreMessages.getString("LaunchConfiguration.Exception_occurred_creating_launch_configuration_memento_9"), DebugException.INTERNAL_ERROR, e); //$NON-NLS-1$
throw new CoreException(status);
}
}
/**
* @see ILaunchConfiguration#getFile()
*/
public IFile getFile() {
return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(getLocation());
}
/**
* @see ILaunchConfiguration#contentsEqual(ILaunchConfiguration)
*/
public boolean contentsEqual(ILaunchConfiguration object) {
try {
if (object instanceof LaunchConfiguration) {
LaunchConfiguration otherConfig = (LaunchConfiguration) object;
return getName().equals(otherConfig.getName())
&& getType().equals(otherConfig.getType())
&& getLocation().equals(otherConfig.getLocation())
&& getInfo().equals(otherConfig.getInfo());
}
return false;
} catch (CoreException ce) {
return false;
}
}
/**
* Returns whether this configuration is equal to the
* given configuration. Two configurations are equal if
* they are stored in the same location (and neither one
* is a working copy).
*
* @return whether this configuration is equal to the
* given configuration
* @see Object#equals(Object)
*/
public boolean equals(Object object) {
if (object instanceof ILaunchConfiguration) {
if (isWorkingCopy()) {
return this == object;
}
ILaunchConfiguration config = (ILaunchConfiguration) object;
if (!config.isWorkingCopy()) {
return config.getLocation().equals(getLocation());
}
}
return false;
}
/**
* @see Object#hashCode()
*/
public int hashCode() {
return getLocation().hashCode();
}
/**
* Returns the container this launch configuration is
* stored in, or <code>null</code> if this launch configuration
* is stored locally.
*
* @return the container this launch configuration is
* stored in, or <code>null</code> if this launch configuration
* is stored locally
*/
protected IContainer getContainer() {
IFile file = getFile();
if (file != null) {
return file.getParent();
}
return null;
}
}