diff options
author | Darin Wright | 2007-01-03 17:52:52 +0000 |
---|---|---|
committer | Darin Wright | 2007-01-03 17:52:52 +0000 |
commit | dfa0ea6b6208ef8bc84ff4ec2ec1036ed68b791b (patch) | |
tree | f40a4be4b6cfa03175992cff974502399b9df1da | |
parent | 942e940f399ffca44c585ef195cc63ec5914b485 (diff) | |
download | eclipse.platform.debug-dfa0ea6b6208ef8bc84ff4ec2ec1036ed68b791b.tar.gz eclipse.platform.debug-dfa0ea6b6208ef8bc84ff4ec2ec1036ed68b791b.tar.xz eclipse.platform.debug-dfa0ea6b6208ef8bc84ff4ec2ec1036ed68b791b.zip |
Bug 74480 [launching] Simplify the launch experience for less technical users of Eclipse
6 files changed, 273 insertions, 26 deletions
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationWorkingCopy.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationWorkingCopy.java index 254febf8d..9a75b496c 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationWorkingCopy.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationWorkingCopy.java @@ -50,7 +50,12 @@ public interface ILaunchConfigurationWorkingCopy extends ILaunchConfiguration, I * a handle to the resulting launch configuration. * Has no effect if this configuration does not need saving. * Creates the underlying file if not yet created. - * + * <p> + * <strong>EXPERIMENTAL</strong> - Since 3.3, if this is a nested + * working copy, the contents of this working copy are saved to the + * parent working copy and the parent working copy is returned without + * effecting the original launch configuration. + * </p> * @exception CoreException if an exception occurs while * writing this configuration to its underlying file. */ @@ -247,4 +252,43 @@ public interface ILaunchConfigurationWorkingCopy extends ILaunchConfiguration, I * @since 3.3 */ public void removeModes(Set modes); + + /** + * Returns a working copy of this working copy. Changes to the working copy will + * be applied to this working copy when saved. The working copy will + * refer to this launch configuration as its parent. Changes are only + * saved to the underlying original configuration when the root working + * copy is saved. + * + * @return a working copy of this working copy + * @exception CoreException if this method fails. Reasons include: + * <ul> + * <li>An exception occurs while initializing the contents of the + * working copy from this configuration's underlying storage.</li> + * </ul> + * @see ILaunchConfigurationWorkingCopy#getOriginal() + * @see ILaunchConfigurationWorkingCopy#getParent() + * @since 3.3 + * <p> + * <strong>EXPERIMENTAL</strong>. This method has been added as + * part of a work in progress. There is no guarantee that this API will + * remain unchanged during the 3.3 release cycle. Please do not use this API + * without consulting with the Platform/Debug team. + * </p> + */ + public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException; + + /** + * Returns the parent of this working copy or <code>null</code> if this working + * copy is not a nested copy of another working copy. + * + * @return parent or <code>null</code> + * <p> + * <strong>EXPERIMENTAL</strong>. This method has been added as + * part of a work in progress. There is no guarantee that this API will + * remain unchanged during the 3.3 release cycle. Please do not use this API + * without consulting with the Platform/Debug team. + * </p> + */ + public ILaunchConfigurationWorkingCopy getParent(); } diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java index 7cbf24ba6..696204c41 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java @@ -14,6 +14,7 @@ package org.eclipse.debug.core; import java.util.Map; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IPersistableSourceLocator; @@ -459,6 +460,42 @@ public interface ILaunchManager { */ public void removeLaunchListener(ILaunchListener listener); + /** + * Sets the given launch configuration as the default configuration for the specified + * resource. There is only one default configuration per resource and this replaces + * any previously existing launch configuration for the resource, if any. Specifying + * a configuration of <code>null</code> clears the default configuration for the + * given resource. + * + * @param resource resource + * @param configuration launch configuration or <code>null</code> + * @exception CoreException if unable to set as default + * @since 3.3 + * <p> + * <strong>EXPERIMENTAL</strong>. This method has been added as + * part of a work in progress. There is no guarantee that this API will + * remain unchanged during the 3.3 release cycle. Please do not use this API + * without consulting with the Platform/Debug team. + * </p> + */ + public void setDefaultConfiguration(IResource resource, ILaunchConfiguration configuration) throws CoreException; + + /** + * Returns the default launch configuration for the specified resource, or <code>null</code> + * if none. + * + * @param configuration launch configuration + * @return launch configuration or <code>null</code> + * @exception CoreException if an error occurs retrieving the configuration + * @since 3.3 + * <p> + * <strong>EXPERIMENTAL</strong>. This method has been added as + * part of a work in progress. There is no guarantee that this API will + * remain unchanged during the 3.3 release cycle. Please do not use this API + * without consulting with the Platform/Debug team. + * </p> + */ + public ILaunchConfiguration getDefaultConfiguration(IResource resource) throws CoreException; } diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java index 74021284e..aa286b8f7 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java @@ -35,6 +35,8 @@ public class DebugCoreMessages extends NLS { public static String LaunchDelegate_0; + public static String LaunchManager_29; + public static String LaunchOption_0; public static String SystemPropertyResolver_0; public static String InputStreamMonitor_label; diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties index 68865e9c4..b6055b42e 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties @@ -51,6 +51,7 @@ LaunchManager_Invalid_launch_configuration_index__18=Invalid launch configuratio LaunchManager_does_not_exist=Launch configuration {0} at {1} does not exist. LaunchManager_Source_locator_does_not_exist___0__13=Source locator does not exist: {0} LaunchManager_30=Unable to retrieve shared launch configuration file for {0} +LaunchManager_29=A shared launch configuration must be shared in same project that it is a default configuration for. LaunchDelegate_0=No description provided. LaunchMode_1=Required attribute {0} missing for launchMode extension. LaunchMode_0={0} As diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java index 2f4b00434..b7b869013 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationWorkingCopy.java @@ -87,6 +87,12 @@ public class LaunchConfigurationWorkingCopy extends LaunchConfiguration implemen private IContainer fContainer; /** + * Parent working copy. + * @since 3.3 + */ + private LaunchConfigurationWorkingCopy fParent = null; + + /** * Constructs a working copy of the specified launch * configuration. * @@ -104,6 +110,23 @@ public class LaunchConfigurationWorkingCopy extends LaunchConfiguration implemen } /** + * Constructs a working copy of the specified launch configuration as its parent. + * + * @param parent launch configuration to make + * a working copy of + * @exception CoreException if unable to initialize this + * working copy's attributes based on the original configuration + */ + protected LaunchConfigurationWorkingCopy(LaunchConfigurationWorkingCopy parent) throws CoreException { + super(parent.getLocation()); + setName(parent.getName()); + copyFrom(parent); + setOriginal((LaunchConfiguration) parent.getOriginal()); + fParent = parent; + fSuppressChange = false; + } + + /** * Constructs a copy of the specified launch * configuration, with the given (new) name. * @@ -150,35 +173,42 @@ public class LaunchConfigurationWorkingCopy extends LaunchConfiguration implemen * @see ILaunchConfigurationWorkingCopy#doSave() */ public synchronized ILaunchConfiguration doSave() throws CoreException { - if (isDirty()) { - boolean useRunnable= true; - if (isLocal()) { - if (isMoved()) { - // If this config was moved from a shared location, saving - // it will delete the original from the workspace. Use runnable. - useRunnable= !isNew() && !getOriginal().isLocal(); + if (fParent == null) { + if (isDirty()) { + boolean useRunnable= true; + if (isLocal()) { + if (isMoved()) { + // If this config was moved from a shared location, saving + // it will delete the original from the workspace. Use runnable. + useRunnable= !isNew() && !getOriginal().isLocal(); + } else { + useRunnable= false; + } + } + + if (useRunnable) { + IWorkspaceRunnable wr = new IWorkspaceRunnable() { + public void run(IProgressMonitor pm) throws CoreException { + doSave0(); + } + }; + + ResourcesPlugin.getWorkspace().run(wr, null, 0, null); } else { - useRunnable= false; + //file is persisted in the metadata not the workspace + doSave0(); } + + getLaunchManager().setMovedFromTo(null, null); } - - if (useRunnable) { - IWorkspaceRunnable wr = new IWorkspaceRunnable() { - public void run(IProgressMonitor pm) throws CoreException { - doSave0(); - } - }; - - ResourcesPlugin.getWorkspace().run(wr, null, 0, null); - } else { - //file is persisted in the metadata not the workspace - doSave0(); - } - - getLaunchManager().setMovedFromTo(null, null); + + return new LaunchConfiguration(getLocation()); + } else { + // save to parent working copy + fParent.setName(getName()); + fParent.copyFrom(this); + return fParent; } - - return new LaunchConfiguration(getLocation()); } @@ -635,6 +665,30 @@ public class LaunchConfigurationWorkingCopy extends LaunchConfiguration implemen catch (CoreException ce) {DebugPlugin.log(ce);} } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.LaunchConfiguration#getWorkingCopy() + */ + public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException { + if (fParent == null) { + return super.getWorkingCopy(); + } else { + return getNestedWorkingCopy(); + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getNestedWorkingCopy() + */ + public ILaunchConfigurationWorkingCopy getNestedWorkingCopy() throws CoreException { + return new LaunchConfigurationWorkingCopy(this); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchConfigurationWorkingCopy#getParent() + */ + public ILaunchConfigurationWorkingCopy getParent() { + return fParent; + } } diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java index 24ca96025..e670ade41 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java @@ -58,6 +58,7 @@ import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; @@ -66,11 +67,13 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; @@ -78,6 +81,7 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationListener; import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchDelegate; import org.eclipse.debug.core.ILaunchListener; import org.eclipse.debug.core.ILaunchManager; @@ -95,6 +99,7 @@ import org.eclipse.debug.core.sourcelookup.ISourcePathComputer; import org.eclipse.debug.internal.core.sourcelookup.SourceContainerType; import org.eclipse.debug.internal.core.sourcelookup.SourcePathComputer; import org.eclipse.osgi.service.environment.Constants; +import org.osgi.service.prefs.BackingStoreException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -172,6 +177,14 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe private StepFilterManager fStepFilterManager = null; /** + * Preference key for a resource's default configuration. + * + * @since 3.3 + */ + private static final String DEFAULT_CONFIGURATION = "defaultConfiguration"; //$NON-NLS-1$ + + + /** * Notifies a launch config listener in a safe runnable to handle * exceptions. */ @@ -2354,4 +2367,100 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe } return fStepFilterManager; } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchManager#getDefaultConfiguration(org.eclipse.core.resources.IResource) + */ + public ILaunchConfiguration getDefaultConfiguration(IResource resource) throws CoreException { + IProject project = resource.getProject(); + if (project != null) { + org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource); + String configValue = projectNode.get(DEFAULT_CONFIGURATION, null); + if (configValue != null) { + // shared config + IFile file = project.getFile(Path.fromPortableString(configValue)); + return getLaunchConfiguration(file); + } else { + org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource); + configValue = instanceNode.get(DEFAULT_CONFIGURATION, null); + if (configValue != null) { + // local config + return getLaunchConfiguration(configValue); + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.ILaunchManager#setDefaultConfiguration(org.eclipse.core.resources.IResource, org.eclipse.debug.core.ILaunchConfiguration) + */ + public void setDefaultConfiguration(IResource resource, ILaunchConfiguration configuration) throws CoreException { + IProject project = resource.getProject(); + if (project == null) { + throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), + DebugPlugin.INTERNAL_ERROR, "Illegal argument: can only set default launch configuration on and within projects.", null)); //$NON-NLS-1$ (internal error) + } + if (configuration != null && !configuration.isLocal()) { + if (!configuration.getFile().getProject().equals(project)) { + throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), + DebugPlugin.INTERNAL_ERROR, DebugCoreMessages.LaunchManager_29, null)); + } + } + + // remove previous settings, if any + org.osgi.service.prefs.Preferences projectNode = getProjectNode(resource); + projectNode.remove(DEFAULT_CONFIGURATION); + flush(projectNode); + org.osgi.service.prefs.Preferences instanceNode = getInstanceNode(resource); + instanceNode.remove(DEFAULT_CONFIGURATION); + flush(instanceNode); + + if (configuration != null) { + org.osgi.service.prefs.Preferences node = null; + String configurationValue = null; + if (configuration.isLocal()) { + // for local configurations, use workspace (instance) scope preferences + node = instanceNode; + if (configuration.isWorkingCopy()) { + configurationValue = ((ILaunchConfigurationWorkingCopy)configuration).getOriginal().getMemento(); + } else { + configurationValue = configuration.getMemento(); + } + } else { + // for shared configurations, use project scope preferences + node = projectNode; + configurationValue = configuration.getFile().getProjectRelativePath().toPortableString(); + } + node.put(DEFAULT_CONFIGURATION, configurationValue); + flush(node); + } + + } + + private void flush(org.osgi.service.prefs.Preferences node) { + try { + node.flush(); + } catch (BackingStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private org.osgi.service.prefs.Preferences getProjectNode(IResource resource) { + org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode(); + ProjectScope scope = new ProjectScope(resource.getProject()); + node = scope.getNode(DebugPlugin.getUniqueIdentifier()); + IProject project = resource.getProject(); + if (!resource.equals(project)) { + node = node.node(resource.getProjectRelativePath().toString()); + } + return node; + } + + private org.osgi.service.prefs.Preferences getInstanceNode(IResource resource) { + org.osgi.service.prefs.Preferences node = Platform.getPreferencesService().getRootNode(); + node = node.node(InstanceScope.SCOPE).node(DebugPlugin.getUniqueIdentifier()); + return node.node(resource.getFullPath().makeRelative().toString()); + } } |