| package org.eclipse.debug.internal.core; |
| |
| /********************************************************************** |
| Copyright (c) 2000, 2002 IBM Corp. All rights reserved. |
| This file is made available under the terms of the Common Public License v1.0 |
| which accompanies this distribution, and is available at |
| http://www.eclipse.org/legal/cpl-v10.html |
| **********************************************************************/ |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.text.MessageFormat; |
| 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.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.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| 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().getFile(new Path(path)).getLocation(); |
| } |
| setLocation(location); |
| if (location == null) { |
| IStatus s = newStatus(MessageFormat.format(DebugCoreMessages.getString("LaunchConfiguration.Unable_to_restore_location_for_launch_configuration_from_memento__{0}_1"), new String[]{path}), DebugPlugin.INTERNAL_ERROR, null); //$NON-NLS-1$ |
| throw new CoreException(s); |
| } |
| 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 message, 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 { |
| // bug 28245 - force the delegate to load in case it is interested in launch notifications |
| ILaunchConfigurationDelegate delegate= getDelegate(); |
| |
| ILaunch launch = new Launch(this, mode, null); |
| getLaunchManager().addLaunch(launch); |
| if (monitor == null) { |
| monitor= new NullProgressMonitor(); |
| } |
| try { |
| delegate.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.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() { |
| return getLocation().toFile().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() { |
| IPath localPath = LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH; |
| return localPath.isPrefixOf(getLocation()); |
| } |
| |
| /** |
| * @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. |
| IFile file = getFile(); |
| if (file != null) { |
| // validate edit |
| if (file.isReadOnly()) { |
| IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, null); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| 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()); |
| relativePath = relativePath.setDevice(null); |
| } else { |
| relativePath = getFile().getFullPath(); |
| } |
| |
| 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() { |
| if (isLocal()) { |
| return null; |
| } |
| 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; |
| } |
| |
| /** |
| * @see org.eclipse.debug.core.ILaunchConfiguration#getCategory() |
| */ |
| public String getCategory() throws CoreException { |
| return getType().getCategory(); |
| } |
| |
| /** |
| * @see org.eclipse.debug.core.ILaunchConfiguration#getAttributes() |
| */ |
| public Map getAttributes() throws CoreException { |
| LaunchConfigurationInfo info = getInfo(); |
| return info.getAttributes(); |
| } |
| |
| } |
| |