Copyright (c) 2000, 2018 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Sebastian Davids - bug 50567 Eclipse native environment support on Win98 Pawel Piech - Bug 82001: When shutting down the IDE, the debugger should first attempt to disconnect debug targets before terminating them Alena Laskavaia - Bug 259281 Marc Khouzam - Bug 313143: Preferred Launch Delegate not recovered from preferences Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
/******************************************************************************* * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Sebastian Davids - bug 50567 Eclipse native environment support on Win98 * Pawel Piech - Bug 82001: When shutting down the IDE, the debugger should first * attempt to disconnect debug targets before terminating them * Alena Laskavaia - Bug 259281 * Marc Khouzam - Bug 313143: Preferred Launch Delegate not recovered from preferences * Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes *******************************************************************************/
package org.eclipse.debug.internal.core; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; 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.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.variables.VariablesPlugin; 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.ILaunchConfigurationListener; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchDelegate; import org.eclipse.debug.core.ILaunchListener; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchMode; import org.eclipse.debug.core.ILaunchesListener; import org.eclipse.debug.core.ILaunchesListener2; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IDisconnect; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; import org.eclipse.debug.core.sourcelookup.ISourceContainerType; 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.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.ibm.icu.text.MessageFormat;
Manages launch configurations, launch configuration types, and registered launches.
See Also:
  • ILaunchManager
/** * Manages launch configurations, launch configuration types, and registered launches. * * @see ILaunchManager */
public class LaunchManager extends PlatformObject implements ILaunchManager, IResourceChangeListener {
Preferred launch delegate preference name.

Prior to 3.5 this preferred launch delegates for all launch configuration types were serialized into a single XML string and stored in this preference.

Since 3.5, the preferred launch delegates are stored in a separate preference for each launch configuration type. The name of this preference is composed of the prefix, followed by a slash, followed by the launch configuration type id. The values contain a set of launch delegates, delimited by a semicolon, and each delegate entry contains the delegate ID, followed by a comma, followed by comma-delimited launch modes.

Since:3.3
/** * Preferred launch delegate preference name. * <p> * Prior to 3.5 this preferred launch delegates for all launch * configuration types were serialized into a single XML string * and stored in this preference. * </p> * <p> * Since 3.5, the preferred launch delegates are stored in a separate * preference for each launch configuration type. The name of this * preference is composed of the prefix, followed by a slash, followed by * the launch configuration type id. The values contain a set of launch * delegates, delimited by a semicolon, and each delegate entry contains * the delegate ID, followed by a comma, followed by comma-delimited * launch modes. * * @since 3.3 */
protected static final String PREF_PREFERRED_DELEGATES = DebugPlugin.getUniqueIdentifier() + ".PREFERRED_DELEGATES"; //$NON-NLS-1$
Constant to define debug.ui for the status codes
Since:3.2
/** * Constant to define debug.ui for the status codes * * @since 3.2 */
private static final String DEBUG_UI = "org.eclipse.debug.ui"; //$NON-NLS-1$
Listing of unsupported launch configuration names for the Win 32 platform
Since:3.5
/** * Listing of unsupported launch configuration names for the Win 32 platform * @since 3.5 */
static final String[] UNSUPPORTED_WIN32_CONFIG_NAMES = new String[] {"aux", "clock$", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ "com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
Disallowed characters for launch configuration names '@' and '&' are disallowed because they corrupt menu items.
Since:3.5
/** * Disallowed characters for launch configuration names * '@' and '&' are disallowed because they corrupt menu items. * * @since 3.5 */
static final char[] DISALLOWED_CONFIG_NAME_CHARS = new char[] { '@', '&','\\', '/', ':', '*', '?', '"', '<', '>', '|', '\0' };
Status code for which a UI prompter is registered.
Since:3.2
/** * Status code for which a UI prompter is registered. * * @since 3.2 */
protected static final IStatus promptStatus = new Status(IStatus.INFO, DEBUG_UI, 200, IInternalDebugCoreConstants.EMPTY_STRING, null);
Step filter manager
/** * Step filter manager */
private StepFilterManager fStepFilterManager = null;
Notifies a launch config listener in a safe runnable to handle exceptions.
/** * Notifies a launch config listener in a safe runnable to handle * exceptions. */
class ConfigurationNotifier implements ISafeRunnable { private ILaunchConfigurationListener fListener; private int fType; private ILaunchConfiguration fConfiguration; @Override public void handleException(Throwable exception) { IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during launch configuration change notification.", exception); //$NON-NLS-1$ DebugPlugin.log(status); }
Notifies the given listener of the add/change/remove
Params:
  • configuration – the configuration that has changed
  • update – the type of change
/** * Notifies the given listener of the add/change/remove * * @param configuration the configuration that has changed * @param update the type of change */
public void notify(ILaunchConfiguration configuration, int update) { fConfiguration = configuration; fType = update; for (ILaunchConfigurationListener iLaunchConfigurationListener : fLaunchConfigurationListeners) { fListener = iLaunchConfigurationListener; SafeRunner.run(this); } fConfiguration = null; fListener = null; } @Override public void run() throws Exception { switch (fType) { case ADDED: fListener.launchConfigurationAdded(fConfiguration); break; case REMOVED: fListener.launchConfigurationRemoved(fConfiguration); break; case CHANGED: fListener.launchConfigurationChanged(fConfiguration); break; default: break; } } }
Notifies a launch listener (multiple launches) in a safe runnable to handle exceptions.
/** * Notifies a launch listener (multiple launches) in a safe runnable to * handle exceptions. */
class LaunchesNotifier implements ISafeRunnable { private ILaunchesListener fListener; private int fType; private ILaunch[] fNotifierLaunches; private ILaunch[] fRegistered; @Override public void handleException(Throwable exception) { IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during launch change notification.", exception); //$NON-NLS-1$ DebugPlugin.log(status); }
Notifies the given listener of the adds/changes/removes
Params:
  • launches – the launches that changed
  • update – the type of change
/** * Notifies the given listener of the adds/changes/removes * * @param launches the launches that changed * @param update the type of change */
public void notify(ILaunch[] launches, int update) { fNotifierLaunches = launches; fType = update; fRegistered = null; for (ILaunchesListener iLaunchesListener : fLaunchesListeners) { fListener = iLaunchesListener; SafeRunner.run(this); } fNotifierLaunches = null; fRegistered = null; fListener = null; } @Override public void run() throws Exception { switch (fType) { case ADDED: fListener.launchesAdded(fNotifierLaunches); break; case REMOVED: fListener.launchesRemoved(fNotifierLaunches); break; case CHANGED: case TERMINATE: if (fRegistered == null) { List<ILaunch> registered = null; for (int j = 0; j < fNotifierLaunches.length; j++) { if (isRegistered(fNotifierLaunches[j])) { if (registered != null) { registered.add(fNotifierLaunches[j]); } } else { if (registered == null) { registered = new ArrayList<>(fNotifierLaunches.length); for (int k = 0; k < j; k++) { registered.add(fNotifierLaunches[k]); } } } } if (registered == null) { fRegistered = fNotifierLaunches; } else { fRegistered = registered.toArray(new ILaunch[registered.size()]); } } if (fRegistered.length > 0) { if (fType == CHANGED) { fListener.launchesChanged(fRegistered); } if (fType == TERMINATE && fListener instanceof ILaunchesListener2) { ((ILaunchesListener2)fListener).launchesTerminated(fRegistered); } } break; default: break; } } }
Visitor for handling a resource begin deleted, and the need to check mapped configurations for auto-deletion
Since:3.4
/** * Visitor for handling a resource begin deleted, and the need to check mapped configurations * for auto-deletion * @since 3.4 */
class MappedResourceVisitor implements IResourceDeltaVisitor { @Override public boolean visit(IResourceDelta delta) throws CoreException { if (0 != (delta.getFlags() & IResourceDelta.OPEN)) { return false; } if(delta.getKind() == IResourceDelta.REMOVED && delta.getFlags() != IResourceDelta.MOVED_TO) { ArrayList<ILaunchConfiguration> configs = collectAssociatedLaunches(delta.getResource()); for (ILaunchConfiguration config : configs) { try { config.delete(); } catch (CoreException e) { DebugPlugin.log(e.getStatus()); } } return false; } return true; } }
Visitor for handling resource deltas.
/** * Visitor for handling resource deltas. */
class LaunchManagerVisitor implements IResourceDeltaVisitor { @Override public boolean visit(IResourceDelta delta) { if (delta == null) { return false; } if (0 != (delta.getFlags() & IResourceDelta.OPEN)) { if (delta.getResource() instanceof IProject) { IProject project = (IProject)delta.getResource(); if (project.isOpen()) { LaunchManager.this.projectOpened(project); } else { LaunchManager.this.projectClosed(project); } } return false; } IResource resource = delta.getResource(); if (resource instanceof IFile) { IFile file = (IFile)resource; if (ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION.equals(file.getFileExtension()) || ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION.equals(file.getFileExtension())) { ILaunchConfiguration handle = new LaunchConfiguration(file); switch (delta.getKind()) { case IResourceDelta.ADDED : LaunchManager.this.launchConfigurationAdded(handle); break; case IResourceDelta.REMOVED : LaunchManager.this.launchConfigurationDeleted(handle); break; case IResourceDelta.CHANGED : LaunchManager.this.launchConfigurationChanged(handle); break; default: break; } } return false; } return true; } }
Notifies a launch listener (single launch) in a safe runnable to handle exceptions.
/** * Notifies a launch listener (single launch) in a safe runnable to handle * exceptions. */
class LaunchNotifier implements ISafeRunnable { private ILaunchListener fListener; private int fType; private ILaunch fLaunch; @Override public void handleException(Throwable exception) { IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during launch change notification.", exception); //$NON-NLS-1$ DebugPlugin.log(status); }
Notifies listeners of the add/change/remove
Params:
  • launch – the launch that has changed
  • update – the type of change
/** * Notifies listeners of the add/change/remove * * @param launch the launch that has changed * @param update the type of change */
public void notify(ILaunch launch, int update) { fLaunch = launch; fType = update; for (ILaunchListener iLaunchListener : fListeners) { fListener = iLaunchListener; SafeRunner.run(this); } fLaunch = null; fListener = null; } @Override public void run() throws Exception { switch (fType) { case ADDED: fListener.launchAdded(fLaunch); break; case REMOVED: fListener.launchRemoved(fLaunch); break; case CHANGED: if (isRegistered(fLaunch)) { fListener.launchChanged(fLaunch); } break; default: break; } } }
Collects files whose extension matches the launch configuration file extension.
/** * Collects files whose extension matches the launch configuration file * extension. */
class ResourceProxyVisitor implements IResourceProxyVisitor { private List<IResource> fList; protected ResourceProxyVisitor(List<IResource> list) { fList= list; } @Override public boolean visit(IResourceProxy proxy) { if (proxy.getType() == IResource.FILE) { if (ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION.equalsIgnoreCase(proxy.requestFullPath().getFileExtension()) | ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION.equalsIgnoreCase(proxy.requestFullPath().getFileExtension())) { fList.add(proxy.requestResource()); } return false; } return true; } }
Internal class used to hold information about a preferred delegate
Since:3.3
/** * Internal class used to hold information about a preferred delegate * * @since 3.3 */
class PreferredDelegate { private ILaunchDelegate fDelegate = null; private String fTypeid = null; private Set<String> fModes = null; public PreferredDelegate(ILaunchDelegate delegate, String typeid, Set<String> modes) { fDelegate = delegate; fTypeid = typeid; fModes = modes; } public String getTypeId() { return fTypeid; } public Set<String> getModes() { return fModes; } public ILaunchDelegate getDelegate() { return fDelegate; } }
Types of notifications
/** * Types of notifications */
public static final int ADDED = 0; public static final int REMOVED= 1; public static final int CHANGED= 2; public static final int TERMINATE= 3;
The collection of native environment variables on the user's system. Cached after being computed once as the environment cannot change.
/** * The collection of native environment variables on the user's system. Cached * after being computed once as the environment cannot change. */
private static HashMap<String, String> fgNativeEnv = null; private static HashMap<String, String> fgNativeEnvCasePreserved = null;
Path to the local directory where local launch configurations are stored with the workspace.
/** * Path to the local directory where local launch configurations * are stored with the workspace. */
public static final IPath LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH = DebugPlugin.getDefault().getStateLocation().append(".launches"); //$NON-NLS-1$
Returns a Document that can be used to build a DOM tree
Throws:
Returns:the Document
Since:3.0
/** * Returns a Document that can be used to build a DOM tree * @return the Document * @throws ParserConfigurationException if an exception occurs creating the document builder * @since 3.0 */
public static Document getDocument() throws ParserConfigurationException { DocumentBuilderFactory dfactory= DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder= dfactory.newDocumentBuilder(); Document doc= docBuilder.newDocument(); return doc; }
Serializes a XML document into a string - encoded in UTF8 format, with platform line separators.
Params:
  • doc – document to serialize
Throws:
Returns:the document as a string
/** * Serializes a XML document into a string - encoded in UTF8 format, * with platform line separators. * * @param doc document to serialize * @return the document as a string * @throws TransformerException if an unrecoverable error occurs during the serialization * @throws IOException if the encoding attempted to be used is not supported */
public static String serializeDocument(Document doc) throws TransformerException, IOException { ByteArrayOutputStream s = new ByteArrayOutputStream(); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ DOMSource source = new DOMSource(doc); StreamResult outputTarget = new StreamResult(s); transformer.transform(source, outputTarget); return s.toString("UTF8"); //$NON-NLS-1$ }
Collection of defined launch configuration type extensions.
/** * Collection of defined launch configuration type * extensions. */
private List<ILaunchConfigurationType> fLaunchConfigurationTypes = null;
Launch configuration cache. Keys are LaunchConfiguration, values are LaunchConfigurationInfo.
/** * Launch configuration cache. Keys are <code>LaunchConfiguration</code>, * values are <code>LaunchConfigurationInfo</code>. */
private Map<ILaunchConfiguration, LaunchConfigurationInfo> fLaunchConfigurations = new HashMap<>(10);
A cache of launch configuration names currently in the workspace.
/** * A cache of launch configuration names currently in the workspace. */
private volatile String[] fSortedConfigNames = null;
Collection of all launch configurations in the workspace. List of ILaunchConfiguration.
/** * Collection of all launch configurations in the workspace. * <code>List</code> of <code>ILaunchConfiguration</code>. */
private List<ILaunchConfiguration> fLaunchConfigurationIndex = null;
Launch configuration comparator extensions, keyed by attribute name.
/** * Launch configuration comparator extensions, * keyed by attribute name. */
private Map<String, LaunchConfigurationComparator> fComparators = null;
Registered launch modes, or null if not initialized. Keys are mode identifiers, values are ILaunchModes.
/** * Registered launch modes, or <code>null</code> if not initialized. * Keys are mode identifiers, values are <code>ILaunchMode</code>s. */
private Map<String, ILaunchMode> fLaunchModes = null;
A map of LaunchDelegate objects stored by id of delegate, or launch config type
/** * A map of LaunchDelegate objects stored by id of delegate, or launch config type */
private HashMap<String, LaunchDelegate> fLaunchDelegates = null;
Initial startup cache of preferred delegate so that the debug preferences are only parsed once
Since:3.3
/** * Initial startup cache of preferred delegate so that the debug preferences are only parsed once * * @since 3.3 */
private Set<PreferredDelegate> fPreferredDelegates = null;
Collection of launches
/** * Collection of launches */
private List<ILaunch> fLaunches = new ArrayList<>(10);
Set of launches for efficient 'isRegistered()' check TODO remove this - Launches don't implement hashCode() or equals() - so its no more efficient than walking the other collection
/** * Set of launches for efficient 'isRegistered()' check TODO remove this - * Launches don't implement hashCode() or equals() - so its no more * efficient than walking the other collection */
private Set<ILaunch> fLaunchSet = new HashSet<>(10);
Collection of listeners
/** * Collection of listeners */
private ListenerList<ILaunchListener> fListeners = new ListenerList<>();
Collection of "plural" listeners.
Since:2.1
/** * Collection of "plural" listeners. * @since 2.1 */
private ListenerList<ILaunchesListener> fLaunchesListeners = new ListenerList<>();
Visitor used to process resource deltas, to update launch configuration index.
/** * Visitor used to process resource deltas, * to update launch configuration index. */
private LaunchManagerVisitor fgVisitor;
Visitor used to process a deleted resource, to remove mapped launch configurations in the event auto-removal of launch configurations is enabled
Since:3.4
/** * Visitor used to process a deleted resource, * to remove mapped launch configurations in the event * auto-removal of launch configurations is enabled * * @since 3.4 */
private MappedResourceVisitor fgMRVisitor;
Whether this manager is listening for resource change events
/** * Whether this manager is listening for resource change events */
private boolean fListening = false;
Launch configuration listeners
/** * Launch configuration listeners */
private ListenerList<ILaunchConfigurationListener> fLaunchConfigurationListeners = new ListenerList<>();
Table of source locator extensions. Keys are identifiers, and values are associated configuration elements.
/** * Table of source locator extensions. Keys * are identifiers, and values are associated * configuration elements. */
private Map<String, IConfigurationElement> fSourceLocators = null;
The handles of launch configurations being moved, or null
/** * The handles of launch configurations being moved, or <code>null</code> */
private ILaunchConfiguration fFrom; private ILaunchConfiguration fTo;
Map of source container type extensions. Keys are extension ids and values are associated configuration elements.
/** * Map of source container type extensions. Keys are extension ids * and values are associated configuration elements. */
private Map<String, ISourceContainerType> sourceContainerTypes;
Map of source path computer extensions. Keys are extension ids and values are associated configuration elements.
/** * Map of source path computer extensions. Keys are extension ids * and values are associated configuration elements. */
private Map<String, ISourcePathComputer> sourcePathComputers;
TODO, we can probably remove this too
/** * TODO, we can probably remove this too */
private Set<String> fActiveModes; @Override public void addLaunch(ILaunch launch) { if (internalAddLaunch(launch)) { fireUpdate(launch, ADDED); fireUpdate(new ILaunch[] {launch}, ADDED); } } @Override public void addLaunchConfigurationListener(ILaunchConfigurationListener listener) { fLaunchConfigurationListeners.add(listener); } @Override public void addLaunches(ILaunch[] launches) { List<ILaunch> added = new ArrayList<>(launches.length); for (int i = 0; i < launches.length; i++) { if (internalAddLaunch(launches[i])) { added.add(launches[i]); } } if (!added.isEmpty()) { ILaunch[] addedLaunches = added.toArray(new ILaunch[added.size()]); fireUpdate(addedLaunches, ADDED); for (int i = 0; i < addedLaunches.length; i++) { fireUpdate(launches[i], ADDED); } } } @Override public void addLaunchListener(ILaunchesListener listener) { fLaunchesListeners.add(listener); } @Override public void addLaunchListener(ILaunchListener listener) { fListeners.add(listener); }
Computes and caches the native system environment variables as a map of variable names and values (Strings) in the given map.

Note that WIN32 system environment preserves the case of variable names but is otherwise case insensitive. Depending on what you intend to do with the environment, the lack of normalization may or may not be create problems. This method preserves mixed-case keys using the variable names recorded by the OS.

Params:
  • cache – the map
Since:3.1
/** * Computes and caches the native system environment variables as a map of * variable names and values (Strings) in the given map. * <p> * Note that WIN32 system environment preserves * the case of variable names but is otherwise case insensitive. * Depending on what you intend to do with the environment, the * lack of normalization may or may not be create problems. This * method preserves mixed-case keys using the variable names * recorded by the OS. * </p> * @param cache the map * @since 3.1 */
private void cacheNativeEnvironment(Map<String, String> cache) { try { String nativeCommand= null; boolean isWin9xME= false; //see bug 50567 String fileName= null; if (Platform.getOS().equals(Constants.OS_WIN32)) { String osName= System.getProperty("os.name"); //$NON-NLS-1$ isWin9xME= osName != null && (osName.startsWith("Windows 9") || osName.startsWith("Windows ME")); //$NON-NLS-1$ //$NON-NLS-2$ if (isWin9xME) { // Win 95, 98, and ME // SET might not return therefore we pipe into a file IPath stateLocation= DebugPlugin.getDefault().getStateLocation(); fileName= stateLocation.toOSString() + File.separator + "env.txt"; //$NON-NLS-1$ nativeCommand= "command.com /C set > " + fileName; //$NON-NLS-1$ } else { // Win NT, 2K, XP nativeCommand= "cmd.exe /C set"; //$NON-NLS-1$ } } else if (!Platform.getOS().equals(Constants.OS_UNKNOWN)){ nativeCommand= "env"; //$NON-NLS-1$ } if (nativeCommand == null) { return; } Process process= Runtime.getRuntime().exec(nativeCommand); if (isWin9xME) { //read piped data on Win 95, 98, and ME Properties p= new Properties(); File file= new File(fileName); try(InputStream stream = new BufferedInputStream(new FileInputStream(file))){ p.load(stream); if (!file.delete()) { file.deleteOnExit(); // if delete() fails try again on VM close } for (Entry<Object, Object> entry : p.entrySet()) { // Win32's environment variables are case insensitive. Put everything // to uppercase so that (for example) the "PATH" variable will match // "pAtH" correctly on Windows. String key = (String) entry.getKey(); //no need to cast value cache.put(key, (String) p.get(key)); } } } else { //read process directly on other platforms //we need to parse out matching '{' and '}' for function declarations in .bash environments // pattern is [func name]=() { and we must find the '}' on its own line with no trailing ';' try (InputStream stream = process.getInputStream(); InputStreamReader isreader = new InputStreamReader(stream); BufferedReader reader = new BufferedReader(isreader)) { String line = reader.readLine(); String key = null; String value = null; String newLine = System.getProperty("line.separator"); //$NON-NLS-1$ while (line != null) { int func = line.indexOf("=()"); //$NON-NLS-1$ if (func > 0) { key = line.substring(0, func); // scan until we find the closing '}' with no // following chars value = line.substring(func + 1); while (line != null && !line.equals("}")) { //$NON-NLS-1$ line = reader.readLine(); if (line != null) { value += newLine + line; } } line = reader.readLine(); } else { int separator = line.indexOf('='); if (separator > 0) { key = line.substring(0, separator); value = line.substring(separator + 1); line = reader.readLine(); if (line != null) { // this line has a '=' read ahead to check // next line for '=', might be broken on // more than one line // also if line starts with non-identifier - // it is remainder of previous variable while (line.indexOf('=') < 0 || (line.length() > 0 && !Character.isJavaIdentifierStart(line.charAt(0)))) { value += newLine + line; line = reader.readLine(); if (line == null) { // if next line read is the end of // the file quit the loop break; } } } } } if (key != null) { cache.put(key, value); key = null; value = null; } else { line = reader.readLine(); } } } } } catch (IOException e) { // Native environment-fetching code failed. // This can easily happen and is not useful to log. } }
Clears all launch configurations (if any have been accessed)
/** * Clears all launch configurations (if any have been accessed) */
private void clearAllLaunchConfigurations() { if (fLaunchConfigurationTypes != null) { fLaunchConfigurationTypes.clear(); } if (fLaunchConfigurationIndex != null) { fLaunchConfigurationIndex.clear(); } } @Override public String getEncoding(ILaunchConfiguration configuration) throws CoreException { String encoding = configuration.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, (String)null); if(encoding == null) { IResource[] resources = configuration.getMappedResources(); if(resources != null && resources.length > 0) { IResource res = resources[0]; if(res instanceof IFile) { return ((IFile)res).getCharset(); } else if(res instanceof IContainer) { return ((IContainer)res).getDefaultCharset(); } } else { return ResourcesPlugin.getEncoding(); } } return encoding; }
The launch config name cache is cleared when a config is added, deleted or changed.
/** * The launch config name cache is cleared when a config is added, deleted or changed. */
protected synchronized void clearConfigNameCache() { fSortedConfigNames = null; }
Return an instance of DebugException containing the specified message and Throwable.
Params:
Returns:the new DebugException
/** * Return an instance of DebugException containing the specified message and Throwable. * @param message the message for the new {@link DebugException} * @param throwable the underlying {@link Exception} * @return the new {@link DebugException} */
protected DebugException createDebugException(String message, Throwable throwable) { return new DebugException( new Status( IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, message, throwable ) ); }
Return a LaunchConfigurationInfo object initialized from XML contained in the specified stream. Simply pass out any exceptions encountered so that caller can deal with them. This is important since caller may need access to the actual exception.
Params:
Throws:
Returns:the new LaunchConfigurationInfo
/** * Return a LaunchConfigurationInfo object initialized from XML contained in * the specified stream. Simply pass out any exceptions encountered so that * caller can deal with them. This is important since caller may need access to the * actual exception. * * @param stream the {@link InputStream} to read from * @return the new {@link LaunchConfigurationInfo} * @throws CoreException if a problem is encountered * @throws ParserConfigurationException if the stream fails to parse * @throws IOException if there is a problem handling the given stream or writing the new info file * @throws SAXException if there is a SAX parse exception */
protected LaunchConfigurationInfo createInfoFromXML(InputStream stream) throws CoreException, ParserConfigurationException, IOException, SAXException { return createInfoFromXML(stream, false); }
Return a LaunchConfigurationInfo object initialized from XML contained in the specified stream. Simply pass out any exceptions encountered so that caller can deal with them. This is important since caller may need access to the actual exception.
Params:
  • stream – the InputStream to read from
  • isPrototype – if the XML corresponds to a prototype
Throws:
Returns:the new LaunchConfigurationInfo
Since:3.12
/** * Return a LaunchConfigurationInfo object initialized from XML contained in * the specified stream. Simply pass out any exceptions encountered so that * caller can deal with them. This is important since caller may need access * to the actual exception. * * @param stream the {@link InputStream} to read from * @param isPrototype if the XML corresponds to a prototype * @return the new {@link LaunchConfigurationInfo} * @throws CoreException if a problem is encountered * @throws ParserConfigurationException if the stream fails to parse * @throws IOException if there is a problem handling the given stream or * writing the new info file * @throws SAXException if there is a SAX parse exception * * @since 3.12 */
protected LaunchConfigurationInfo createInfoFromXML(InputStream stream, boolean isPrototype) throws CoreException, ParserConfigurationException, IOException, SAXException { Element root = null; DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); parser.setErrorHandler(new DefaultHandler()); root = parser.parse(new InputSource(stream)).getDocumentElement(); LaunchConfigurationInfo info = new LaunchConfigurationInfo(); info.initializeFromXML(root, isPrototype); return info; }
Finds and returns all launch configurations in the given container (and sub-containers)
Params:
  • container – the container to search
Returns:all launch configurations in the given container
/** * Finds and returns all launch configurations in the given * container (and sub-containers) * * @param container the container to search * @return all launch configurations in the given container */
protected List<ILaunchConfiguration> findLaunchConfigurations(IContainer container) { if (container instanceof IProject && !((IProject)container).isOpen()) { return Collections.EMPTY_LIST; } List<IResource> list = new ArrayList<>(10); ResourceProxyVisitor visitor= new ResourceProxyVisitor(list); try { container.accept(visitor, IResource.NONE); } catch (CoreException ce) { //Closed project...should not be possible with previous check } List<ILaunchConfiguration> configs = new ArrayList<>(list.size()); for (IResource resource : list) { ILaunchConfiguration config = getLaunchConfiguration((IFile) resource); if(config != null && config.exists()) { configs.add(config); } } return configs; }
Searches for the ILaunchConfiguration with the given name
Params:
  • name – the name to search for
Returns:the ILaunchConfiguration with the given name or null
Since:3.8
/** * Searches for the {@link ILaunchConfiguration} with the given name * @param name the name to search for * @return the {@link ILaunchConfiguration} with the given name or <code>null</code> * @since 3.8 */
public ILaunchConfiguration findLaunchConfiguration(String name) { if(name != null) { ILaunchConfiguration[] configs = getLaunchConfigurations(); for (int i = 0; i < configs.length; i++) { if(name.equals(configs[i].getName())) { return configs[i]; } } } return null; }
Finds and returns all local launch configurations.
Returns:all local launch configurations
/** * Finds and returns all local launch configurations. * * @return all local launch configurations */
protected List<ILaunchConfiguration> findLocalLaunchConfigurations() { IPath containerPath = LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH; final File directory = containerPath.toFile(); if (directory.isDirectory()) { List<ILaunchConfiguration> configs = new ArrayList<>(); FilenameFilter configFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return dir.equals(directory) && name.endsWith(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION); } }; File[] configFiles = directory.listFiles(configFilter); if (configFiles != null && configFiles.length > 0) { LaunchConfiguration config = null; for (int i = 0; i < configFiles.length; i++) { config = new LaunchConfiguration(LaunchConfiguration.getSimpleName(configFiles[i].getName()), null, false); configs.add(config); } } FilenameFilter prototypeFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return dir.equals(directory) && name.endsWith(ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION); } }; File[] prototypeFiles = directory.listFiles(prototypeFilter); if (prototypeFiles != null && prototypeFiles.length > 0) { LaunchConfiguration config = null; for (int i = 0; i < prototypeFiles.length; i++) { config = new LaunchConfiguration(LaunchConfiguration.getSimpleName(prototypeFiles[i].getName()), null, true); configs.add(config); } } return configs; } return Collections.EMPTY_LIST; }
Fires notification to (single) listeners that a launch has been added/changed/removed.
Params:
  • launch – launch that has changed
  • update – type of change
/** * Fires notification to (single) listeners that a launch has been * added/changed/removed. * * @param launch launch that has changed * @param update type of change */
public void fireUpdate(ILaunch launch, int update) { new LaunchNotifier().notify(launch, update); }
Fires notification to (plural) listeners that a launch has been added/changed/removed.
Params:
  • launches – launches that have changed
  • update – type of change
/** * Fires notification to (plural) listeners that a launch has been * added/changed/removed. * * @param launches launches that have changed * @param update type of change */
public void fireUpdate(ILaunch[] launches, int update) { new LaunchesNotifier().notify(launches, update); } @Override public String generateUniqueLaunchConfigurationNameFrom(String baseName) { int index = 1; int length = baseName.length(); int copyIndex = baseName.lastIndexOf(" ("); //$NON-NLS-1$ String base = baseName; if (copyIndex > -1 && length > copyIndex + 2 && baseName.charAt(length - 1) == ')') { String trailer = baseName.substring(copyIndex + 2, length - 1); if (isNumber(trailer)) { try { index = Integer.parseInt(trailer); base = baseName.substring(0, copyIndex); } catch (NumberFormatException nfe) {} } } String newName = base; while (isExistingLaunchConfigurationName(newName)) { newName = MessageFormat.format(DebugCoreMessages.LaunchManager_31, new Object[] { base, Integer.toString(index) }); index++; } return newName; }
Return a String that can be used as the name of a launch configuration. The name is guaranteed to be unique (no existing or temporary launch configurations will have this name). The name that is returned uses the basename as a starting point. If there is no existing launch configuration with this name, then basename is returned. Otherwise, the value returned consists of the specified base plus some suffix that guarantees uniqueness. Passing null as the set of reserved names will cause this method to return generateUniqueLaunchConfigurationNameFrom(String baseName). By specifying a set of reserved names, you can further constrain the name that will be generated by this method. For example you can give a base name of 'test' and a reserved set of [test(1), test(2)], which will result in a name of 'test(3)' being returned iff a configuration with the name 'test' already exists.
Params:
  • basename – the String that the returned name must begin with
  • reservednames – a set of strings that is further used to constrain what names can be generated
Returns:launch configuration name
Since:3.3
/** * Return a String that can be used as the name of a launch configuration. The name * is guaranteed to be unique (no existing or temporary launch configurations will have this name). * The name that is returned uses the <code>basename</code> as a starting point. If * there is no existing launch configuration with this name, then <code>basename</code> * is returned. Otherwise, the value returned consists of the specified base plus * some suffix that guarantees uniqueness. Passing <code>null</code> as the set of reserved names will cause this * method to return <code>generateUniqueLaunchConfigurationNameFrom(String baseName)</code>. * * By specifying a set of reserved names, you can further constrain the name that will be generated * by this method. For example you can give a base name of 'test' and a reserved set of [test(1), test(2)], * which will result in a name of 'test(3)' being returned iff a configuration with the name 'test' already exists. * * @return launch configuration name * @param basename the String that the returned name must begin with * @param reservednames a set of strings that is further used to constrain what names can be generated * @since 3.3 */
public String generateUniqueLaunchConfigurationNameFrom(String basename, Set<String> reservednames) { if(reservednames == null) { return generateUniqueLaunchConfigurationNameFrom(basename); } int index = 1; int length= basename.length(); String base = basename; int copyIndex = base.lastIndexOf(" ("); //$NON-NLS-1$ if (copyIndex > -1 && length > copyIndex + 2 && base.charAt(length - 1) == ')') { String trailer = base.substring(copyIndex + 2, length -1); if (isNumber(trailer)) { try { index = Integer.parseInt(trailer); base = base.substring(0, copyIndex); } catch (NumberFormatException nfe) {} } } String newname = base; StringBuilder buffer = null; while (isExistingLaunchConfigurationName(newname) || reservednames.contains(newname)) { buffer = new StringBuilder(base); buffer.append(" ("); //$NON-NLS-1$ buffer.append(String.valueOf(index)); index++; buffer.append(')'); newname = buffer.toString(); } return newname; }
Returns a collection of all launch configuration handles in the workspace. This collection is initialized lazily.
Returns:all launch configuration handles
/** * Returns a collection of all launch configuration handles in * the workspace. This collection is initialized lazily. * * @return all launch configuration handles */
private synchronized List<ILaunchConfiguration> getAllLaunchConfigurations() { if (fLaunchConfigurationIndex == null) { try { fLaunchConfigurationIndex = new ArrayList<>(20); List<ILaunchConfiguration> configs = findLocalLaunchConfigurations(); verifyConfigurations(configs, fLaunchConfigurationIndex); configs = findLaunchConfigurations(ResourcesPlugin.getWorkspace().getRoot()); verifyConfigurations(configs, fLaunchConfigurationIndex); } finally { hookResourceChangeListener(); } } return fLaunchConfigurationIndex; }
Return a sorted array of the names of all ILaunchConfigurations in the workspace. These are cached, and cache is cleared when a new config is added, deleted or changed.
Returns:the sorted array of ILaunchConfiguration names
/** * Return a sorted array of the names of all <code>ILaunchConfiguration</code>s in * the workspace. These are cached, and cache is cleared when a new config is added, * deleted or changed. * @return the sorted array of {@link ILaunchConfiguration} names */
protected synchronized String[] getAllSortedConfigNames() { if (fSortedConfigNames == null) { List<ILaunchConfiguration> collection = getAllLaunchConfigurations(); ILaunchConfiguration[] configs = collection.toArray(new ILaunchConfiguration[collection.size()]); fSortedConfigNames = new String[configs.length]; for (int i = 0; i < configs.length; i++) { fSortedConfigNames[i] = configs[i].getName(); } Arrays.sort(fSortedConfigNames); } return fSortedConfigNames; }
Returns the comparator registered for the given attribute, or null if none.
Params:
  • attributeName – attribute for which a comparator is required
Returns:comparator, or null if none
/** * Returns the comparator registered for the given attribute, or * <code>null</code> if none. * * @param attributeName attribute for which a comparator is required * @return comparator, or <code>null</code> if none */
protected Comparator<Object> getComparator(String attributeName) { Map<String, LaunchConfigurationComparator> map = getComparators(); return map.get(attributeName); }
Returns comparators, loading if required
Returns:the complete map of ILaunchConfiguration Comparators
/** * Returns comparators, loading if required * @return the complete map of {@link ILaunchConfiguration} {@link Comparator}s */
protected Map<String, LaunchConfigurationComparator> getComparators() { initializeComparators(); return fComparators; }
Returns the launch configurations specified by the given XML document.
Params:
  • root – XML document
Throws:
Returns:list of launch configurations
/** * Returns the launch configurations specified by the given * XML document. * * @param root XML document * @return list of launch configurations * @throws CoreException if a problem is encountered */
protected List<ILaunchConfiguration> getConfigsFromXML(Element root) throws CoreException { DebugException invalidFormat = new DebugException( new Status( IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchManager_Invalid_launch_configuration_index__18, null ) ); if (!root.getNodeName().equalsIgnoreCase("launchConfigurations")) { //$NON-NLS-1$ throw invalidFormat; } // read each launch configuration List<ILaunchConfiguration> configs = new ArrayList<>(4); NodeList list = root.getChildNodes(); int length = list.getLength(); Node node = null; Element entry = null; String memento = null; for (int i = 0; i < length; ++i) { node = list.item(i); short type = node.getNodeType(); if (type == Node.ELEMENT_NODE) { entry = (Element) node; if (!entry.getNodeName().equals("launchConfiguration")) { //$NON-NLS-1$ throw invalidFormat; } memento = entry.getAttribute("memento"); //$NON-NLS-1$ if (memento == null) { throw invalidFormat; } configs.add(getLaunchConfiguration(memento)); } } return configs; } protected ConfigurationNotifier getConfigurationNotifier() { return new ConfigurationNotifier(); } @Override public IDebugTarget[] getDebugTargets() { synchronized (fLaunches) { List<IDebugTarget> allTargets = new ArrayList<>(fLaunches.size()); IDebugTarget[] targets = null; for (ILaunch launch : fLaunches) { targets = launch.getDebugTargets(); Collections.addAll(allTargets, targets); } return allTargets.toArray(new IDebugTarget[allTargets.size()]); } }
Returns the resource delta visitor for the launch manager.
Returns:the resource delta visitor for the launch manager
/** * Returns the resource delta visitor for the launch manager. * * @return the resource delta visitor for the launch manager */
private LaunchManagerVisitor getDeltaVisitor() { if (fgVisitor == null) { fgVisitor= new LaunchManagerVisitor(); } return fgVisitor; }
Returns the resource delta visitor for auto-removal of mapped launch configurations
Returns:the resource delta visitor for auto-removal of mapped launch configurations
Since:3.4
/** * Returns the resource delta visitor for auto-removal of mapped launch configurations * @return the resource delta visitor for auto-removal of mapped launch configurations * * @since 3.4 */
private MappedResourceVisitor getMappedResourceVisitor() { if(fgMRVisitor == null) { fgMRVisitor = new MappedResourceVisitor(); } return fgMRVisitor; } @Override public String[] getEnvironment(ILaunchConfiguration configuration) throws CoreException { Map<String, String> configEnv = configuration.getAttribute(ATTR_ENVIRONMENT_VARIABLES, (Map<String, String>) null); if (configEnv == null) { return null; } Map<String, String> env = new HashMap<>(); // build base environment boolean append = configuration.getAttribute(ATTR_APPEND_ENVIRONMENT_VARIABLES, true); if (append) { env.putAll(getNativeEnvironmentCasePreserved()); } // Add variables from config boolean win32= Platform.getOS().equals(Constants.OS_WIN32); String key = null; String value = null; Object nativeValue = null; String nativeKey = null; for (Entry<String, String> entry : configEnv.entrySet()) { key = entry.getKey(); value = entry.getValue(); // translate any string substitution variables if (value != null) { value = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value); } boolean added= false; if (win32) { // First, check if the key is an exact match for an existing key. nativeValue = env.get(key); if (nativeValue != null) { // If an exact match is found, just replace the value env.put(key, value); } else { // Win32 variables are case-insensitive. If an exact match isn't found, iterate to // check for a case-insensitive match. We maintain the key's case (see bug 86725), // but do a case-insensitive comparison (for example, "pAtH" will still override "PATH"). for (Entry<String, String> nativeEntry : env.entrySet()) { nativeKey = (nativeEntry).getKey(); if (nativeKey.equalsIgnoreCase(key)) { nativeEntry.setValue(value); added = true; break; } } } } if (!added) { env.put(key, value); } } List<String> strings = new ArrayList<>(env.size()); StringBuilder buffer = null; for (Entry<String, String> entry : env.entrySet()) { buffer = new StringBuilder(entry.getKey()); buffer.append('=').append(entry.getValue()); strings.add(buffer.toString()); } return strings.toArray(new String[strings.size()]); }
Returns the info object for the specified launch configuration. If the configuration exists, but is not yet in the cache, an info object is built and added to the cache.
Params:
Throws:
Returns:the LaunchConfigurationInfo object from the given ILaunchConfiguration
Since:3.5
/** * Returns the info object for the specified launch configuration. * If the configuration exists, but is not yet in the cache, * an info object is built and added to the cache. * @param config the {@link ILaunchConfiguration} to get the info object from * @return the {@link LaunchConfigurationInfo} object from the given {@link ILaunchConfiguration} * * @exception CoreException if an exception occurs building * the info object * @exception DebugException if the config does not exist * @since 3.5 */
protected LaunchConfigurationInfo getInfo(LaunchConfiguration config) throws CoreException { LaunchConfigurationInfo info = fLaunchConfigurations.get(config); if (info == null) { IFileStore store = config.getFileStore(); if (config.exists()) { BufferedInputStream stream = null; try { stream = new BufferedInputStream(store.openInputStream(EFS.NONE, null)); info = createInfoFromXML(stream, isPrototype(store)); synchronized (this) { fLaunchConfigurations.put(config, info); } } catch (FileNotFoundException e) { throwException(config, e); } catch (SAXException e) { throwException(config, e); } catch (ParserConfigurationException e) { throwException(config, e); } catch (IOException e) { throwException(config, e); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { throwException(config, e); } } } } else { if (store != null){ throw createDebugException(MessageFormat.format(DebugCoreMessages.LaunchManager_does_not_exist, new Object[] { config.getName(), store.toURI().toString() }), null); } else { throw createDebugException(MessageFormat.format(DebugCoreMessages.LaunchManager_does_not_exist_no_store_found, new Object[] { config.getName() }), null); } } } return info; }
Check if the given IFileStore is a prototype.
Params:
Returns:true if the given IFileStore is a prototype, false otherwise.
Since:3.12
/** * Check if the given {@link IFileStore} is a prototype. * * @param store the given {@link IFileStore} * @return <code>true</code> if the given {@link IFileStore} is a prototype, * <code>false</code> otherwise. * * @since 3.12 */
private boolean isPrototype(IFileStore store) { if (store.getName().endsWith("." + ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION)) { //$NON-NLS-1$ return true; } return false; }
Check if the given File is a prototype.
Params:
  • file – the given File
Returns:true if the given File is a prototype, false otherwise.
Since:3.12
/** * Check if the given {@link File} is a prototype. * * @param file the given {@link File} * @return <code>true</code> if the given {@link File} is a prototype, * <code>false</code> otherwise. * * @since 3.12 */
private boolean isPrototype(File file) { if (file.getName().endsWith("." + ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION)) { //$NON-NLS-1$ return true; } return false; } @Override public ILaunchConfiguration getLaunchConfiguration(IFile file) { hookResourceChangeListener(); return new LaunchConfiguration(file); } @Override public ILaunchConfiguration getLaunchConfiguration(String memento) throws CoreException { hookResourceChangeListener(); return new LaunchConfiguration(memento); } @Override public synchronized ILaunchConfiguration[] getLaunchConfigurations() { return getLaunchConfigurations(ILaunchConfiguration.CONFIGURATION); } @Override public ILaunchConfiguration[] getLaunchConfigurations(int kinds) { List<ILaunchConfiguration> allConfigs = getAllLaunchConfigurations(); if (((kinds & ILaunchConfiguration.CONFIGURATION) > 0) && ((kinds & ILaunchConfiguration.PROTOTYPE) > 0)) { // all kinds return allConfigs.toArray(new ILaunchConfiguration[allConfigs.size()]); } else { List<ILaunchConfiguration> select = new ArrayList<>(allConfigs.size()); Iterator<ILaunchConfiguration> iterator = allConfigs.iterator(); while (iterator.hasNext()) { ILaunchConfiguration config = iterator.next(); try { if ((config.getKind() & kinds) > 0) { select.add(config); } } catch (CoreException e) { DebugPlugin.log(e); } } return select.toArray(new ILaunchConfiguration[select.size()]); } } @Override public synchronized ILaunchConfiguration[] getLaunchConfigurations(ILaunchConfigurationType type) throws CoreException { return getLaunchConfigurations(type, ILaunchConfiguration.CONFIGURATION); } @Override public synchronized ILaunchConfiguration[] getLaunchConfigurations(ILaunchConfigurationType type, int kinds) throws CoreException { List<ILaunchConfiguration> configs = new ArrayList<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { if (config.getType().equals(type) && ((config.getKind() & kinds) > 0)) { configs.add(config); } } return configs.toArray(new ILaunchConfiguration[configs.size()]); }
Returns all launch configurations that are stored as resources in the given project.
Params:
  • project – a project
Returns:collection of launch configurations that are stored as resources in the given project
/** * Returns all launch configurations that are stored as resources * in the given project. * * @param project a project * @return collection of launch configurations that are stored as resources * in the given project */
protected synchronized List<ILaunchConfiguration> getLaunchConfigurations(IProject project) { List<ILaunchConfiguration> configs = new ArrayList<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { IFile file = config.getFile(); if (file != null && file.getProject().equals(project)) { configs.add(config); } } return configs; } @Override public ILaunchConfigurationType getLaunchConfigurationType(String id) { ILaunchConfigurationType[] types = getLaunchConfigurationTypes(); for(int i = 0; i < types.length; i++) { if (types[i].getIdentifier().equals(id)) { return types[i]; } } return null; } @Override public ILaunchConfigurationType[] getLaunchConfigurationTypes() { initializeLaunchConfigurationTypes(); return fLaunchConfigurationTypes.toArray(new ILaunchConfigurationType[fLaunchConfigurationTypes.size()]); } @Override public ILaunch[] getLaunches() { synchronized (fLaunches) { return fLaunches.toArray(new ILaunch[fLaunches.size()]); } } @Override public ILaunchMode getLaunchMode(String mode) { initializeLaunchModes(); return fLaunchModes.get(mode); } @Override public ILaunchMode[] getLaunchModes() { initializeLaunchModes(); Collection<ILaunchMode> collection = fLaunchModes.values(); return collection.toArray(new ILaunchMode[collection.size()]); }
Returns all of the launch delegates. The returned listing of delegates cannot be directly used to launch, instead the method IlaunchDelegate.getDelegate must be used to acquire an executable form of the delegate, allowing us to maintain lazy loading of the delegates themselves.
Returns:all of the launch delegates
Since:3.3
/** * Returns all of the launch delegates. The returned listing of delegates cannot be directly used to launch, * instead the method <code>IlaunchDelegate.getDelegate</code> must be used to acquire an executable form of * the delegate, allowing us to maintain lazy loading of the delegates themselves. * @return all of the launch delegates * * @since 3.3 */
public ILaunchDelegate[] getLaunchDelegates() { initializeLaunchDelegates(); Collection<LaunchDelegate> col = fLaunchDelegates.values(); return col.toArray(new ILaunchDelegate[col.size()]); }
Returns the listing of launch delegates that apply to the specified ILaunchConfigurationType id
Params:
  • typeid – the id of the launch configuration type to get delegates for
Returns:An array of LaunchDelegates that apply to the specified launch configuration type, or an empty array, never null
Since:3.3
/** * Returns the listing of launch delegates that apply to the specified * <code>ILaunchConfigurationType</code> id * @param typeid the id of the launch configuration type to get delegates for * @return An array of <code>LaunchDelegate</code>s that apply to the specified launch configuration * type, or an empty array, never <code>null</code> * * @since 3.3 */
public LaunchDelegate[] getLaunchDelegates(String typeid) { initializeLaunchDelegates(); ArrayList<LaunchDelegate> list = new ArrayList<>(); for (Entry<String, LaunchDelegate> entry : fLaunchDelegates.entrySet()) { LaunchDelegate ld = entry.getValue(); if (ld.getLaunchConfigurationTypeId().equals(typeid)) { list.add(ld); } } return list.toArray(new LaunchDelegate[list.size()]); }
This method returns the ILaunchDelegate instance corresponding to the id of the launch delegate specified
Params:
  • id – the id of the ILaunchDelegate to find
Returns:the ILaunchDelegate or null if not found
Since:3.3
/** * This method returns the <code>ILaunchDelegate</code> instance corresponding to the id * of the launch delegate specified * @param id the id of the <code>ILaunchDelegate</code> to find * @return the <code>ILaunchDelegate</code> or <code>null</code> if not found * * @since 3.3 */
public ILaunchDelegate getLaunchDelegate(String id) { if(id != null) { ILaunchDelegate[] delegates = getLaunchDelegates(); for(int i = 0; i < delegates.length; i++) { if(id.equals(delegates[i].getId())) { return delegates[i]; } } } return null; }
Initializes the listing of delegates available to the launching framework
Since:3.3
/** * Initializes the listing of delegates available to the launching framework * * @since 3.3 */
private synchronized void initializeLaunchDelegates() { if(fLaunchDelegates == null) { fLaunchDelegates = new HashMap<>(); //get all launch delegate contributions IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_DELEGATES); IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); LaunchDelegate delegate = null; for(int i = 0; i < infos.length; i++) { delegate = new LaunchDelegate(infos[i]); fLaunchDelegates.put(delegate.getId(), delegate); } //get all delegates from launch configuration type contributions extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_CONFIGURATION_TYPES); infos = extensionPoint.getConfigurationElements(); for(int i = 0; i < infos.length; i++) { //must check to see if delegate is provided in contribution if(infos[i].getAttribute(IConfigurationElementConstants.DELEGATE) != null) { delegate = new LaunchDelegate(infos[i]); fLaunchDelegates.put(delegate.getId(), delegate); } } } }
This method is used to initialize a simple listing of all preferred delegates, which is then used by each ILaunchConfigurationType to find if they have preferred delegates. Once an ILaunchConfigurationType has used this listing to initialize its preferred delegates it will maintain changes to its preferred delegate, which are then written back to the preference store only when the launch manager shuts down.

This cache is not synchronized with the runtime preferred delegates stored in launch configuration types.

Since:3.3
/** * This method is used to initialize a simple listing of all preferred delegates, which is then used by each * <code>ILaunchConfigurationType</code> to find if they have preferred delegates. Once an <code>ILaunchConfigurationType</code> * has used this listing to initialize its preferred delegates it will maintain changes to its preferred delegate, which are * then written back to the preference store only when the launch manager shuts down. * <p> * This cache is not synchronized with the runtime preferred delegates stored in launch configuration types. * </p> * @since 3.3 */
private synchronized void initializePreferredDelegates() { if(fPreferredDelegates == null) { fPreferredDelegates = new HashSet<>(); String preferred = Platform.getPreferencesService().getString(DebugPlugin.getUniqueIdentifier(), LaunchManager.PREF_PREFERRED_DELEGATES, IInternalDebugCoreConstants.EMPTY_STRING, null); if(!IInternalDebugCoreConstants.EMPTY_STRING.equals(preferred)) { try { Element root = DebugPlugin.parseDocument(preferred); NodeList nodes = root.getElementsByTagName(IConfigurationElementConstants.DELEGATE); Element element = null; String typeid = null; Set<String> modeset = null; for(int i = 0; i < nodes.getLength(); i++) { element = (Element) nodes.item(i); String delegateid = element.getAttribute(IConfigurationElementConstants.ID); typeid = element.getAttribute(IConfigurationElementConstants.TYPE_ID); String[] modes = element.getAttribute(IConfigurationElementConstants.MODES).split(","); //$NON-NLS-1$ modeset = new HashSet<>(Arrays.asList(modes)); LaunchDelegate delegate = getLaunchDelegateExtension(typeid, delegateid, modeset); if (delegate != null) { //take type id, modeset, delegate and create entry if(!IInternalDebugCoreConstants.EMPTY_STRING.equals(typeid) & modeset != null) { fPreferredDelegates.add(new PreferredDelegate(delegate, typeid, modeset)); } } } } catch (CoreException e) {DebugPlugin.log(e);} } } }
Allows internal access to reset preferred delegates when re-importing preferences.
Since:3.6
/** * Allows internal access to reset preferred delegates when re-importing * preferences. * * @since 3.6 */
protected void resetPreferredDelegates() { fPreferredDelegates = null; }
Allows internal access to a preferred delegate for a given type and mode set
Params:
  • typeid – the id of the ILaunchConfigurationType to find a delegate for
  • modes – the set of modes for the delegate
Returns:the preferred delegate for the specified type id and mode set, or null if none
Since:3.3
/** * Allows internal access to a preferred delegate for a given type and mode set * @param typeid the id of the <code>ILaunchConfigurationType</code> to find a delegate for * @param modes the set of modes for the delegate * @return the preferred delegate for the specified type id and mode set, or <code>null</code> if none * * @since 3.3 */
protected ILaunchDelegate getPreferredDelegate(String typeid, Set<String> modes) { // Retrieve preferred delegates using legacy mechanism for backward // compatibility. initializePreferredDelegates(); for (PreferredDelegate pd : fPreferredDelegates) { if(pd.getModes().equals(modes) & pd.getTypeId().equals(typeid)) { return pd.getDelegate(); } } // @since 3.5 // If the legacy mechanism didn't work, try the new preference name for // the given launch type. String preferred = Platform.getPreferencesService().getString(DebugPlugin.getUniqueIdentifier(), "//" + LaunchManager.PREF_PREFERRED_DELEGATES + '/' + typeid, IInternalDebugCoreConstants.EMPTY_STRING, null); //$NON-NLS-1$ if (preferred != null && preferred.length() != 0) { StringTokenizer tokenizer = new StringTokenizer(preferred, ";"); //$NON-NLS-1$ while(tokenizer.hasMoreTokens()) { StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), ","); //$NON-NLS-1$ String delegateId = tokenizer2.nextToken(); HashSet<String> modeset = new HashSet<>(); while(tokenizer2.hasMoreTokens()) { modeset.add(tokenizer2.nextToken()); } LaunchDelegate delegate = getLaunchDelegateExtension(typeid, delegateId, modeset); if (delegate != null && modeset.equals(modes)) { return delegate; } } } return null; }
Returns the launch delegate extension that matches the given type, delegate ID, and set of modes.
Params:
  • typeId – Launch configuration type.
  • id – Launch delegate ID.
  • modeset – Set of modes that the launch delegate applies to.
Returns:The launch delegate matching the specified parameters, or null if not found.
Since:3.5
/** * Returns the launch delegate extension that matches the given type, delegate ID, and * set of modes. * * @param typeId Launch configuration type. * @param id Launch delegate ID. * @param modeset Set of modes that the launch delegate applies to. * @return The launch delegate matching the specified parameters, or * <code>null</code> if not found. * * @since 3.5 */
private LaunchDelegate getLaunchDelegateExtension(String typeId, String id, Set<String> modeset) { LaunchDelegate[] extensions = getLaunchDelegates(typeId); for(int j = 0; j < extensions.length; j++) { if(id.equals(extensions[j].getId())) { List<Set<String>> modesets = extensions[j].getModes(); if(modesets.contains(modeset)) { return extensions[j]; } } } return null; }
Returns all launch configurations that are stored locally.
Returns:collection of launch configurations stored locally
/** * Returns all launch configurations that are stored locally. * * @return collection of launch configurations stored locally */
protected synchronized List<ILaunchConfiguration> getLocalLaunchConfigurations() { List<ILaunchConfiguration> configs = new ArrayList<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { if (config.isLocal()) { configs.add(config); } } return configs; }
Returns the launch configurations mapping to the specified resource
Params:
  • resource – the resource to collect mapped launch configurations for
Returns:a list of launch configurations if found or an empty list, never null
Since:3.2
/** * Returns the launch configurations mapping to the specified resource * @param resource the resource to collect mapped launch configurations for * @return a list of launch configurations if found or an empty list, never null * @since 3.2 */
public ILaunchConfiguration[] getMappedConfigurations(IResource resource) { List<ILaunchConfiguration> configurations = new ArrayList<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { try { IResource[] resources = config.getMappedResources(); if(resources != null) { for(int j = 0; j < resources.length; j++) { if(resources[j].equals(resource)) { configurations.add(config); break; } else if (resource.getType() == IResource.PROJECT && resources[j].getType() == IResource.FILE){ if (resources[j].getProject().equals(resource)) { configurations.add(config); break; } } } } } catch (CoreException ce) { DebugPlugin.log(ce); } } return configurations.toArray(new ILaunchConfiguration[configurations.size()]); } @Override public ILaunchConfiguration[] getMigrationCandidates() throws CoreException { List<ILaunchConfiguration> configs = new ArrayList<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { if (!config.isReadOnly() && config.isMigrationCandidate()) { configs.add(config); } } return configs.toArray(new ILaunchConfiguration[configs.size()]); } @Override public ILaunchConfiguration getMovedFrom(ILaunchConfiguration addedConfiguration) { if (addedConfiguration.equals(fTo)) { return fFrom; } return null; } @Override public ILaunchConfiguration getMovedTo(ILaunchConfiguration removedConfiguration) { if (removedConfiguration.equals(fFrom)) { return fTo; } return null; } @Override public synchronized Map<String, String> getNativeEnvironment() { if (fgNativeEnv == null) { Map<String, String> casePreserved = getNativeEnvironmentCasePreserved(); if (Platform.getOS().equals(Constants.OS_WIN32)) { fgNativeEnv = new HashMap<>(); for (Entry<String, String> entry : casePreserved.entrySet()) { fgNativeEnv.put(entry.getKey().toUpperCase(), entry.getValue()); } } else { fgNativeEnv = new HashMap<>(casePreserved); } } return new HashMap<>(fgNativeEnv); } @Override public synchronized Map<String, String> getNativeEnvironmentCasePreserved() { if (fgNativeEnvCasePreserved == null) { fgNativeEnvCasePreserved = new HashMap<>(); cacheNativeEnvironment(fgNativeEnvCasePreserved); } return new HashMap<>(fgNativeEnvCasePreserved); } @Override public IProcess[] getProcesses() { synchronized (fLaunches) { List<IProcess> allProcesses = new ArrayList<>(fLaunches.size()); IProcess[] processes = null; for (ILaunch launch : fLaunches) { processes = launch.getProcesses(); Collections.addAll(allProcesses, processes); } return allProcesses.toArray(new IProcess[allProcesses.size()]); } } @Override public ISourceContainerType getSourceContainerType(String id) { initializeSourceContainerTypes(); return sourceContainerTypes.get(id); } @Override public ISourceContainerType[] getSourceContainerTypes() { initializeSourceContainerTypes(); Collection<ISourceContainerType> containers = sourceContainerTypes.values(); return containers.toArray(new ISourceContainerType[containers.size()]); } @Override public ISourcePathComputer getSourcePathComputer(ILaunchConfiguration configuration) throws CoreException { String id = null; id = configuration.getAttribute(ISourcePathComputer.ATTR_SOURCE_PATH_COMPUTER_ID, (String)null); if (id == null) { //use default computer for configuration type, if any return configuration.getType().getSourcePathComputer(); } return getSourcePathComputer(id); } @Override public ISourcePathComputer getSourcePathComputer(String id) { initializeSourceContainerTypes(); return sourcePathComputers.get(id); }
Starts listening for resource change events
/** * Starts listening for resource change events */
private synchronized void hookResourceChangeListener() { if (!fListening) { ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE); fListening = true; } }
Load comparator extensions.
/** * Load comparator extensions. */
private synchronized void initializeComparators() { if (fComparators == null) { IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_CONFIGURATION_COMPARATORS); IConfigurationElement[] infos= extensionPoint.getConfigurationElements(); fComparators = new HashMap<>(infos.length); IConfigurationElement configurationElement = null; String attr = null; for (int i= 0; i < infos.length; i++) { configurationElement = infos[i]; attr = configurationElement.getAttribute("attribute"); //$NON-NLS-1$ if (attr != null) { fComparators.put(attr, new LaunchConfigurationComparator(configurationElement)); } else { // invalid status handler IStatus s = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.INTERNAL_ERROR, MessageFormat.format("Invalid launch configuration comparator extension defined by plug-in {0} - attribute not specified.", configurationElement.getContributor().getName()), null); //$NON-NLS-1$ DebugPlugin.log(s); } } } }
Initializes the listing of LaunchConfigurationTypes.
/** * Initializes the listing of <code>LaunchConfigurationType</code>s. */
private synchronized void initializeLaunchConfigurationTypes() { if (fLaunchConfigurationTypes == null) { hookResourceChangeListener(); IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_CONFIGURATION_TYPES); IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); fLaunchConfigurationTypes = new ArrayList<>(infos.length); for (int i= 0; i < infos.length; i++) { fLaunchConfigurationTypes.add(new LaunchConfigurationType(infos[i])); } } }
Load comparator extensions.
/** * Load comparator extensions. */
private synchronized void initializeLaunchModes() { if (fLaunchModes == null) { try { IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_MODES); IConfigurationElement[] infos= extensionPoint.getConfigurationElements(); fLaunchModes = new HashMap<>(); ILaunchMode mode = null; for (int i= 0; i < infos.length; i++) { mode = new LaunchMode(infos[i]); fLaunchModes.put(mode.getIdentifier(), mode); } } catch (CoreException e) {DebugPlugin.log(e);} } }
Initializes source container type and source path computer extensions.
/** * Initializes source container type and source path computer extensions. */
private synchronized void initializeSourceContainerTypes() { if (sourceContainerTypes == null) { IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_SOURCE_CONTAINER_TYPES); IConfigurationElement[] extensions = extensionPoint.getConfigurationElements(); sourceContainerTypes = new HashMap<>(); for (int i = 0; i < extensions.length; i++) { sourceContainerTypes.put( extensions[i].getAttribute(IConfigurationElementConstants.ID), new SourceContainerType(extensions[i])); } extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_SOURCE_PATH_COMPUTERS); extensions = extensionPoint.getConfigurationElements(); sourcePathComputers = new HashMap<>(); for (int i = 0; i < extensions.length; i++) { sourcePathComputers.put( extensions[i].getAttribute(IConfigurationElementConstants.ID), new SourcePathComputer(extensions[i])); } } }
Register source locators.
/** * Register source locators. */
private synchronized void initializeSourceLocators() { if (fSourceLocators == null) { IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_SOURCE_LOCATORS); IConfigurationElement[] infos= extensionPoint.getConfigurationElements(); fSourceLocators = new HashMap<>(infos.length); IConfigurationElement configurationElement = null; String id = null; for (int i= 0; i < infos.length; i++) { configurationElement = infos[i]; id = configurationElement.getAttribute(IConfigurationElementConstants.ID); if (id != null) { fSourceLocators.put(id,configurationElement); } else { // invalid status handler IStatus s = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.INTERNAL_ERROR, MessageFormat.format("Invalid source locator extension defined by plug-in \"{0}\": \"id\" not specified.", configurationElement.getContributor().getName()), null); //$NON-NLS-1$ DebugPlugin.log(s); } } } }
Adds the given launch object to the list of registered launches, and returns whether the launch was added.
Params:
  • launch – launch to register
Returns:whether the launch was added
/** * Adds the given launch object to the list of registered launches, * and returns whether the launch was added. * * @param launch launch to register * @return whether the launch was added */
protected boolean internalAddLaunch(ILaunch launch) { // ensure the step filter manager is created on the first launch getStepFilterManager(); synchronized (fLaunches) { if (fLaunches.contains(launch)) { return false; } fLaunches.add(launch); fLaunchSet.add(launch); return true; } }
Removes the given launch object from the collection of registered launches. Returns whether the launch was removed.
Params:
  • launch – the launch to remove
Returns:whether the launch was removed
/** * Removes the given launch object from the collection of registered * launches. Returns whether the launch was removed. * * @param launch the launch to remove * @return whether the launch was removed */
protected boolean internalRemoveLaunch(ILaunch launch) { if (launch == null) { return false; } synchronized (fLaunches) { fLaunchSet.remove(launch); return fLaunches.remove(launch); } } @Override public boolean isExistingLaunchConfigurationName(String name) { String[] sortedConfigNames = getAllSortedConfigNames(); int index = Arrays.binarySearch(sortedConfigNames, name); if (index < 0) { return false; } return true; }
Returns whether the given String is composed solely of digits
Params:
  • string – the String to check
Returns:true if the given String is a number false otherwise
/** * Returns whether the given String is composed solely of digits * @param string the {@link String} to check * @return <code>true</code> if the given {@link String} is a number <code>false</code> otherwise */
private boolean isNumber(String string) { int numChars= string.length(); if (numChars == 0) { return false; } for (int i= 0; i < numChars; i++) { if (!Character.isDigit(string.charAt(i))) { return false; } } return true; }
Returns whether the user has selected to delete associated configurations when a project is deleted.
Returns:whether to auto-delete configurations
/** * Returns whether the user has selected to delete associated configurations when a * project is deleted. * * @return whether to auto-delete configurations */
private boolean isDeleteConfigurations() { return Platform.getPreferencesService().getBoolean(DebugPlugin.getUniqueIdentifier(), DebugPlugin.PREF_DELETE_CONFIGS_ON_PROJECT_DELETE, true, null); } @Override public boolean isRegistered(ILaunch launch) { synchronized (fLaunches) { return fLaunchSet.contains(launch); } }
Returns whether the given launch configuration passes a basic integrity test by retrieving its type.
Params:
  • config – the configuration to verify
Returns:whether the config meets basic integrity constraints
/** * Returns whether the given launch configuration passes a basic * integrity test by retrieving its type. * * @param config the configuration to verify * @return whether the config meets basic integrity constraints */
protected boolean isValid(ILaunchConfiguration config) { try { config.getType(); } catch (CoreException e) { if (e.getStatus().getCode() != DebugException.MISSING_LAUNCH_CONFIGURATION_TYPE) { // only log warnings due to something other than a missing // launch config type DebugPlugin.log(e); } return false; } return true; }
Notifies the launch manager that a launch configuration has been added. The configuration is added to the index of configurations by project, and listeners are notified.
Params:
  • config – the launch configuration that was added
/** * Notifies the launch manager that a launch configuration * has been added. The configuration is added to the index of * configurations by project, and listeners are notified. * * @param config the launch configuration that was added */
protected void launchConfigurationAdded(ILaunchConfiguration config) { if (config.isWorkingCopy()) { return; } if (isValid(config)) { boolean added = false; synchronized (this) { List<ILaunchConfiguration> allConfigs = getAllLaunchConfigurations(); if (!allConfigs.contains(config)) { allConfigs.add(config); added = true; } } if (added) { getConfigurationNotifier().notify(config, ADDED); clearConfigNameCache(); } } else { launchConfigurationDeleted(config); } }
Notifies the launch manager that a launch configuration has been changed. The configuration is removed from the cache of info objects such that the new attributes will be updated on the next access. Listeners are notified of the change.
Params:
  • config – the launch configuration that was changed
/** * Notifies the launch manager that a launch configuration * has been changed. The configuration is removed from the * cache of info objects such that the new attributes will * be updated on the next access. Listeners are notified of * the change. * * @param config the launch configuration that was changed */
protected void launchConfigurationChanged(ILaunchConfiguration config) { synchronized(this) { fLaunchConfigurations.remove(config); } clearConfigNameCache(); if (isValid(config)) { // in case the config has been refreshed and it was removed from the // index due to 'out of synch with local file system' (see bug 36147), // add it back (will only add if required) launchConfigurationAdded(config); getConfigurationNotifier().notify(config, CHANGED); } else { launchConfigurationDeleted(config); } }
Notifies the launch manager that a launch configuration has been deleted. The configuration is removed from the cache of info and from the index of configurations by project, and listeners are notified.
Params:
  • config – the launch configuration that was deleted
/** * Notifies the launch manager that a launch configuration * has been deleted. The configuration is removed from the * cache of info and from the index of configurations by * project, and listeners are notified. * * @param config the launch configuration that was deleted */
protected void launchConfigurationDeleted(ILaunchConfiguration config) { boolean removed = false; synchronized (this) { Object key = fLaunchConfigurations.remove(config); removed = key != null; getAllLaunchConfigurations().remove(config); } if (removed) { getConfigurationNotifier().notify(config, REMOVED); clearConfigNameCache(); } } @Override public IPersistableSourceLocator newSourceLocator(String identifier) throws CoreException { initializeSourceLocators(); IConfigurationElement config = fSourceLocators.get(identifier); if (config == null) { throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugException.INTERNAL_ERROR, MessageFormat.format(DebugCoreMessages.LaunchManager_Source_locator_does_not_exist___0__13, new Object[] { identifier }), null)); } IPersistableSourceLocator sourceLocator = (IPersistableSourceLocator)config.createExecutableExtension("class"); //$NON-NLS-1$ if (sourceLocator instanceof AbstractSourceLookupDirector) { ((AbstractSourceLookupDirector)sourceLocator).setId(identifier); } return sourceLocator; }
The specified project has just closed - remove its launch configurations from the cached index.
Params:
  • project – the project that has been closed
/** * The specified project has just closed - remove its * launch configurations from the cached index. * * @param project the project that has been closed */
protected void projectClosed(IProject project) { // bug 12134 terminateMappedConfigurations(project); for (ILaunchConfiguration config : getLaunchConfigurations(project)) { launchConfigurationDeleted(config); } }
The specified project has just opened - add all launch configs in the project to the index of all configs.
Params:
  • project – the project that has been opened
/** * The specified project has just opened - add all launch * configs in the project to the index of all configs. * * @param project the project that has been opened */
protected void projectOpened(IProject project) { for (ILaunchConfiguration config : findLaunchConfigurations(project)) { launchConfigurationAdded(config); } } @Override public void removeLaunch(final ILaunch launch) { if (internalRemoveLaunch(launch)) { fireUpdate(launch, REMOVED); fireUpdate(new ILaunch[] {launch}, REMOVED); } } @Override public void removeLaunchConfigurationListener(ILaunchConfigurationListener listener) { fLaunchConfigurationListeners.remove(listener); } @Override public void removeLaunches(ILaunch[] launches) { List<ILaunch> removed = new ArrayList<>(launches.length); for (int i = 0; i < launches.length; i++) { if (internalRemoveLaunch(launches[i])) { removed.add(launches[i]); } } if (!removed.isEmpty()) { ILaunch[] removedLaunches = removed.toArray(new ILaunch[removed.size()]); fireUpdate(removedLaunches, REMOVED); for (int i = 0; i < removedLaunches.length; i++) { fireUpdate(removedLaunches[i], REMOVED); } } } @Override public void removeLaunchListener(ILaunchesListener listener) { fLaunchesListeners.remove(listener); } @Override public void removeLaunchListener(ILaunchListener listener) { fListeners.remove(listener); }
Traverses the delta looking for added/removed/changed launch configuration files.
See Also:
  • resourceChanged.resourceChanged(IResourceChangeEvent)
/** * Traverses the delta looking for added/removed/changed launch * configuration files. * * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) */
@Override public void resourceChanged(IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); if (delta != null) { LaunchManagerVisitor visitor = getDeltaVisitor(); MappedResourceVisitor v = null; if (isDeleteConfigurations()) { v = getMappedResourceVisitor(); } try { delta.accept(visitor); if (v != null) { delta.accept(v); } } catch (CoreException e) { DebugPlugin.log(e.getStatus()); } } }
Gets the launch configuration associated with the specified IResource. This method relies on the resource mapping existing, if no such mapping exists the launch configuration is ignored.
Params:
  • resource – the resource to collect launch configurations for
Returns:the list of associated launch configurations
/** * Gets the launch configuration associated with the specified <code>IResource</code>. * This method relies on the resource mapping existing, if no such mapping * exists the launch configuration is ignored. * * @param resource the resource to collect launch configurations for * @return the list of associated launch configurations */
private ArrayList<ILaunchConfiguration> collectAssociatedLaunches(IResource resource) { ArrayList<ILaunchConfiguration> list = new ArrayList<>(); try { ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(); IResource[] resources = null; for(int i = 0; i < configs.length; i++) { if(configs[i].isLocal()) { resources = configs[i].getMappedResources(); if(resources != null) { for(int j = 0; j < resources.length; j++){ if(resource.equals(resources[j]) || resource.getFullPath().isPrefixOf(resources[j].getFullPath())) { list.add(configs[i]); break; } } } } } } catch (CoreException e) { DebugPlugin.log(e); } return list; }
Indicates the given launch configuration is being moved from the given location to the new location.
Params:
  • from – the location a launch configuration is being moved from, or null
  • to – the location a launch configuration is being moved to, or null
/** * Indicates the given launch configuration is being moved from the given * location to the new location. * * @param from the location a launch configuration is being moved from, or * <code>null</code> * @param to the location a launch configuration is being moved to, * or <code>null</code> */
protected void setMovedFromTo(ILaunchConfiguration from, ILaunchConfiguration to) { fFrom = from; fTo = to; }
Terminates/Disconnects any active debug targets/processes. Clears launch configuration types.
/** * Terminates/Disconnects any active debug targets/processes. * Clears launch configuration types. */
public void shutdown() { fListeners = new ListenerList<>(); fLaunchesListeners = new ListenerList<>(); fLaunchConfigurationListeners = new ListenerList<>(); ILaunch[] launches = getLaunches(); ILaunch launch = null; for (int i= 0; i < launches.length; i++) { launch = launches[i]; if(launch != null) { try { if (launch instanceof IDisconnect) { IDisconnect disconnect = (IDisconnect)launch; if (disconnect.canDisconnect()) { disconnect.disconnect(); } } if (launch.canTerminate()) { launch.terminate(); } } catch (DebugException e) { DebugPlugin.log(e); } } } persistPreferredLaunchDelegates(); clearAllLaunchConfigurations(); fStepFilterManager = null; ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); }
Saves the listings of preferred launch delegates from all of the launch configuration types
Since:3.3
/** * Saves the listings of preferred launch delegates from all of the launch configuration types * * @since 3.3 */
public void persistPreferredLaunchDelegates() { ILaunchConfigurationType[] types = getLaunchConfigurationTypes(); for(int i = 0; i < types.length; i++) { persistPreferredLaunchDelegate((LaunchConfigurationType)types[i]); } }
Persists the given launch configuration delegate.
Params:
  • type – Launch configuration type to persist
Since:3.6
/** * Persists the given launch configuration delegate. * @param type Launch configuration type to persist * * @since 3.6 */
public void persistPreferredLaunchDelegate(LaunchConfigurationType type) { String preferenceName = PREF_PREFERRED_DELEGATES + '/' + type.getIdentifier(); Map<Set<String>, ILaunchDelegate> preferred = type.getPreferredDelegates(); if(preferred != null && preferred.size() > 0) { StringBuilder str = new StringBuilder(); for (Entry<Set<String>, ILaunchDelegate> entry : preferred.entrySet()) { Set<String> modes = entry.getKey(); ILaunchDelegate delegate = entry.getValue(); if (delegate != null) { str.append(delegate.getId()); str.append(','); for (String mode : modes) { str.append(mode).append(','); } str.append(';'); } } Preferences.setString(DebugPlugin.getUniqueIdentifier(), preferenceName, str.toString(), null); } else { Preferences.setToDefault(DebugPlugin.getUniqueIdentifier(), preferenceName); } // Reset the legacy preference string. Preferences.setToDefault(DebugPlugin.getUniqueIdentifier(), PREF_PREFERRED_DELEGATES); }
finds and terminates any running launch configurations associated with the given resource
Params:
  • resource – the resource to search for launch configurations and hence launches for
Since:3.2
/** * finds and terminates any running launch configurations associated with the given resource * @param resource the resource to search for launch configurations and hence launches for * @since 3.2 */
protected void terminateMappedConfigurations(IResource resource) { ILaunch[] launches = getLaunches(); ILaunchConfiguration[] configs = getMappedConfigurations(resource); try { for(int i = 0; i < launches.length; i++) { for(int j = 0; j < configs.length; j++) { if(configs[j].equals(launches[i].getLaunchConfiguration()) & launches[i].canTerminate()) { launches[i].terminate(); } } } } catch(CoreException e) {DebugPlugin.log(e);} }
Throws a debug exception with the given throwable that occurred while processing the given configuration.
Params:
Throws:
Since:3.5
/** * Throws a debug exception with the given throwable that occurred * while processing the given configuration. * @param config the {@link ILaunchConfiguration} causing the exception * @param e the {@link Exception} to throw * @throws DebugException the new {@link DebugException} wrapping the given {@link Exception} and {@link ILaunchConfiguration} * @since 3.5 */
private void throwException(LaunchConfiguration config, Throwable e) throws DebugException { String uri = config.getName(); try { IFileStore store = config.getFileStore(); if (store != null) { uri = store.toString(); } } catch (CoreException ce) { } throw createDebugException(MessageFormat.format(DebugCoreMessages.LaunchManager__0__occurred_while_reading_launch_configuration_file__1___1, new Object[] { e.toString(), uri }), e); }
Verify basic integrity of launch configurations in the given list, adding valid configurations to the collection of all launch configurations. Exceptions are logged for invalid configurations.
Params:
  • verify – the list of configurations to verify
  • valid – the list to place valid configurations in
/** * Verify basic integrity of launch configurations in the given list, * adding valid configurations to the collection of all launch configurations. * Exceptions are logged for invalid configurations. * * @param verify the list of configurations to verify * @param valid the list to place valid configurations in */
protected void verifyConfigurations(List<ILaunchConfiguration> verify, List<ILaunchConfiguration> valid) { for (ILaunchConfiguration config : verify) { if (!valid.contains(config) && isValid(config)) { valid.add(config); } } }
Returns the name of the given launch mode with accelerators removed, or null if none.
Params:
  • id – launch mode identifier
Returns:launch mode name with accelerators removed or null
/** * Returns the name of the given launch mode with accelerators removed, * or <code>null</code> if none. * * @param id launch mode identifier * @return launch mode name with accelerators removed or <code>null</code> */
public String getLaunchModeName(String id) { ILaunchMode launchMode = getLaunchMode(id); if (launchMode != null) { return removeAccelerators(launchMode.getLabel()); } return null; }
Returns the label with any accelerators removed.
Params:
  • label – label to process
Returns:label without accelerators
/** * Returns the label with any accelerators removed. * * @param label label to process * @return label without accelerators */
public static String removeAccelerators(String label) { String title = label; if (title != null) { // strip out any '&' (accelerators) int index = title.indexOf('&'); if (index == 0) { title = title.substring(1); } else if (index > 0) { //DBCS languages use "(&X)" format if (title.charAt(index - 1) == '(' && title.length() >= index + 3 && title.charAt(index + 2) == ')') { String first = title.substring(0, index - 1); String last = title.substring(index + 3); title = first + last; } else if (index < (title.length() - 1)) { String first = title.substring(0, index); String last = title.substring(index + 1); title = first + last; } } } return title; }
Returns the singleton step filter manager.
Returns:the step filter manager
/** * Returns the singleton step filter manager. * * @return the step filter manager */
public synchronized StepFilterManager getStepFilterManager() { if (fStepFilterManager == null) { fStepFilterManager = new StepFilterManager(); } return fStepFilterManager; }
Imports launch configurations represented by the given local files, overwriting any existing configurations. Sends launch configuration change notification as required (i.e. added or changed).

If a file is imported that has the same name as a configuration in the workspace (i.e. a shared configuration), the shared configuration is deleted (becomes local).

Params:
  • files – files to import
  • monitor – progress monitor or null
Throws:
  • CoreException – if an exception occurs while importing configurations
Since:3.4.0
/** * Imports launch configurations represented by the given local files, overwriting * any existing configurations. Sends launch configuration change notification * as required (i.e. added or changed). * <p> * If a file is imported that has the same name as a configuration in the workspace * (i.e. a shared configuration), the shared configuration is deleted (becomes local). * </p> * @param files files to import * @param monitor progress monitor or <code>null</code> * @throws CoreException if an exception occurs while importing configurations * @since 3.4.0 */
public void importConfigurations(File[] files, IProgressMonitor monitor) throws CoreException { Map<String, ILaunchConfiguration> sharedConfigs = new HashMap<>(); for (ILaunchConfiguration config : getAllLaunchConfigurations()) { if (!config.isLocal()) { StringBuilder buf = new StringBuilder(config.getName()); buf.append('.'); if (config.isPrototype()) { buf.append(ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION); } else { buf.append(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION); } sharedConfigs.put(buf.toString(), config); } } List<Status> stati = null; SubMonitor lmonitor = SubMonitor.convert(monitor, DebugCoreMessages.LaunchManager_29, files.length); for (int i = 0; i < files.length; i++) { if (lmonitor.isCanceled()) { break; } File source = files[i]; lmonitor.subTask(MessageFormat.format(DebugCoreMessages.LaunchManager_28, new Object[] { source.getName() })); IPath location = new Path(LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH.toOSString()).append(source.getName()); File target = location.toFile(); IPath locationdir = location.removeLastSegments(1); if(!locationdir.toFile().exists()) { locationdir.toFile().mkdirs(); } boolean added = !target.exists(); try { copyFile(source, target); ILaunchConfiguration configuration = new LaunchConfiguration(LaunchConfiguration.getSimpleName(source.getName()), null, isPrototype(source)); ILaunchConfiguration shared = sharedConfigs.get(target.getName()); if (shared != null) { setMovedFromTo(shared, configuration); shared.delete(); launchConfigurationChanged(configuration); } else if (added) { launchConfigurationAdded(configuration); } else { launchConfigurationChanged(configuration); } } catch (IOException e) { if (stati == null) { stati = new ArrayList<>(); } stati.add(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR, MessageFormat.format(DebugCoreMessages.LaunchManager_27, source.getPath()), e)); } lmonitor.worked(1); } if (!lmonitor.isCanceled()) { lmonitor.done(); } if (stati != null) { if (stati.size() > 1) { MultiStatus multi = new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR, DebugCoreMessages.LaunchManager_26, null); for (Status status : stati) { multi.add(status); } throw new CoreException(multi); } else { throw new CoreException(stati.get(0)); } } }
Copies a file from one location to another, replacing any existing file.
Params:
  • in – the file to copy
  • out – the file to be copied out to
Throws:
Since:3.4.0
/** * Copies a file from one location to another, replacing any existing file. * * @param in the file to copy * @param out the file to be copied out to * @throws IOException if the file read fails * @since 3.4.0 */
private void copyFile(File in, File out) throws IOException { try (FileInputStream fis = new FileInputStream(in); FileOutputStream fos = new FileOutputStream(out)) { byte[] buf = new byte[1024]; int i = 0; while ((i = fis.read(buf)) != -1) { fos.write(buf, 0, i); } } }
Returns whether any launch config supports the given mode.
Params:
  • mode – launch mode
Returns:whether any launch config supports the given mode
/** * Returns whether any launch config supports the given mode. * * @param mode launch mode * @return whether any launch config supports the given mode */
public synchronized boolean launchModeAvailable(String mode) { if (fActiveModes == null) { ILaunchConfigurationType[] types = getLaunchConfigurationTypes(); ILaunchMode[] modes = getLaunchModes(); fActiveModes = new HashSet<>(3); for (int i = 0; i < types.length; i++) { for (int j = 0; j < modes.length; j++) { if (types[i].supportsMode(modes[j].getIdentifier())) { fActiveModes.add(modes[j].getIdentifier()); } } } } return fActiveModes.contains(mode); } @Override public String generateLaunchConfigurationName(String namePrefix) { String name = generateUniqueLaunchConfigurationNameFrom(namePrefix); try { isValidLaunchConfigurationName(name); return name; } catch(IllegalArgumentException iae) { //blanket change all reserved names if(Platform.OS_WIN32.equals(Platform.getOS())) { for(int i = 0; i < UNSUPPORTED_WIN32_CONFIG_NAMES.length; i++) { if(UNSUPPORTED_WIN32_CONFIG_NAMES[i].equals(name)) { name = "launch_configuration"; //$NON-NLS-1$ } } } //blanket replace all invalid chars for (int i = 0; i < DISALLOWED_CONFIG_NAME_CHARS.length; i++) { name = name.replace(DISALLOWED_CONFIG_NAME_CHARS[i], '_'); } } //run it through the generator once more in case a replaced name has already been done return generateUniqueLaunchConfigurationNameFrom(name); } @Override public boolean isValidLaunchConfigurationName(String configname) throws IllegalArgumentException { if(Platform.OS_WIN32.equals(Platform.getOS())) { for(int i = 0; i < UNSUPPORTED_WIN32_CONFIG_NAMES.length; i++) { if(configname.equals(UNSUPPORTED_WIN32_CONFIG_NAMES[i])) { throw new IllegalArgumentException(MessageFormat.format(DebugCoreMessages.LaunchManager_invalid_config_name, new Object[] { configname })); } } } for (int i = 0; i < DISALLOWED_CONFIG_NAME_CHARS.length; i++) { if (configname.indexOf(DISALLOWED_CONFIG_NAME_CHARS[i]) > -1) { throw new IllegalArgumentException(MessageFormat.format(DebugCoreMessages.LaunchManager_invalid_config_name_char, new Object[] { String.valueOf(DISALLOWED_CONFIG_NAME_CHARS[i]) })); } } return true; } }