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;
public class LaunchManager extends PlatformObject implements ILaunchManager, IResourceChangeListener {
protected static final String PREF_PREFERRED_DELEGATES = DebugPlugin.getUniqueIdentifier() + ".PREFERRED_DELEGATES";
private static final String DEBUG_UI = "org.eclipse.debug.ui";
static final String[] UNSUPPORTED_WIN32_CONFIG_NAMES = new String[] {"aux", "clock$", "com1", "com2", "com3", "com4",
"com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2",
"lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"};
static final char[] DISALLOWED_CONFIG_NAME_CHARS = new char[] { '@', '&','\\', '/', ':', '*', '?', '"', '<', '>', '|', '\0' };
protected static final IStatus promptStatus = new Status(IStatus.INFO, DEBUG_UI, 200, IInternalDebugCoreConstants.EMPTY_STRING, null);
private StepFilterManager fStepFilterManager = null;
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);
DebugPlugin.log(status);
}
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;
}
}
}
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);
DebugPlugin.log(status);
}
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;
}
}
}
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;
}
}
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;
}
}
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);
DebugPlugin.log(status);
}
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;
}
}
}
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;
}
}
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;
}
}
public static final int ADDED = 0;
public static final int REMOVED= 1;
public static final int CHANGED= 2;
public static final int TERMINATE= 3;
private static HashMap<String, String> fgNativeEnv = null;
private static HashMap<String, String> fgNativeEnvCasePreserved = null;
public static final IPath LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH =
DebugPlugin.getDefault().getStateLocation().append(".launches");
public static Document getDocument() throws ParserConfigurationException {
DocumentBuilderFactory dfactory= DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder= dfactory.newDocumentBuilder();
Document doc= docBuilder.newDocument();
return doc;
}
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");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult outputTarget = new StreamResult(s);
transformer.transform(source, outputTarget);
return s.toString("UTF8");
}
private List<ILaunchConfigurationType> fLaunchConfigurationTypes = null;
private Map<ILaunchConfiguration, LaunchConfigurationInfo> fLaunchConfigurations = new HashMap<>(10);
private volatile String[] fSortedConfigNames = null;
private List<ILaunchConfiguration> fLaunchConfigurationIndex = null;
private Map<String, LaunchConfigurationComparator> fComparators = null;
private Map<String, ILaunchMode> fLaunchModes = null;
private HashMap<String, LaunchDelegate> fLaunchDelegates = null;
private Set<PreferredDelegate> fPreferredDelegates = null;
private List<ILaunch> fLaunches = new ArrayList<>(10);
private Set<ILaunch> fLaunchSet = new HashSet<>(10);
private ListenerList<ILaunchListener> fListeners = new ListenerList<>();
private ListenerList<ILaunchesListener> fLaunchesListeners = new ListenerList<>();
private LaunchManagerVisitor fgVisitor;
private MappedResourceVisitor fgMRVisitor;
private boolean fListening = false;
private ListenerList<ILaunchConfigurationListener> fLaunchConfigurationListeners = new ListenerList<>();
private Map<String, IConfigurationElement> fSourceLocators = null;
private ILaunchConfiguration fFrom;
private ILaunchConfiguration fTo;
private Map<String, ISourceContainerType> sourceContainerTypes;
private Map<String, ISourcePathComputer> sourcePathComputers;
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);
}
private void cacheNativeEnvironment(Map<String, String> cache) {
try {
String nativeCommand= null;
boolean isWin9xME= false;
String fileName= null;
if (Platform.getOS().equals(Constants.OS_WIN32)) {
String osName= System.getProperty("os.name");
isWin9xME= osName != null && (osName.startsWith("Windows 9") || osName.startsWith("Windows ME"));
if (isWin9xME) {
IPath stateLocation= DebugPlugin.getDefault().getStateLocation();
fileName= stateLocation.toOSString() + File.separator + "env.txt";
nativeCommand= "command.com /C set > " + fileName;
} else {
nativeCommand= "cmd.exe /C set";
}
} else if (!Platform.getOS().equals(Constants.OS_UNKNOWN)){
nativeCommand= "env";
}
if (nativeCommand == null) {
return;
}
Process process= Runtime.getRuntime().exec(nativeCommand);
if (isWin9xME) {
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();
}
for (Entry<Object, Object> entry : p.entrySet()) {
String key = (String) entry.getKey();
cache.put(key, (String) p.get(key));
}
}
} else {
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");
while (line != null) {
int func = line.indexOf("=()");
if (func > 0) {
key = line.substring(0, func);
value = line.substring(func + 1);
while (line != null && !line.equals("}")) {
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) {
while (line.indexOf('=') < 0 || (line.length() > 0 && !Character.isJavaIdentifierStart(line.charAt(0)))) {
value += newLine + line;
line = reader.readLine();
if (line == null) {
break;
}
}
}
}
}
if (key != null) {
cache.put(key, value);
key = null;
value = null;
} else {
line = reader.readLine();
}
}
}
}
} catch (IOException e) {
}
}
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;
}
protected synchronized void clearConfigNameCache() {
fSortedConfigNames = null;
}
protected DebugException createDebugException(String message, Throwable throwable) {
return new DebugException(
new Status(
IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, message, throwable
)
);
}
protected LaunchConfigurationInfo createInfoFromXML(InputStream stream) throws CoreException,
ParserConfigurationException,
IOException,
SAXException {
return createInfoFromXML(stream, false);
}
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;
}
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) {
}
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;
}
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;
}
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;
}
public void fireUpdate(ILaunch launch, int update) {
new LaunchNotifier().notify(launch, update);
}
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(" (");
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;
}
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(" (");
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(" (");
buffer.append(String.valueOf(index));
index++;
buffer.append(')');
newname = buffer.toString();
}
return newname;
}
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;
}
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;
}
protected Comparator<Object> getComparator(String attributeName) {
Map<String, LaunchConfigurationComparator> map = getComparators();
return map.get(attributeName);
}
protected Map<String, LaunchConfigurationComparator> getComparators() {
initializeComparators();
return fComparators;
}
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")) {
throw invalidFormat;
}
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")) {
throw invalidFormat;
}
memento = entry.getAttribute("memento");
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()]);
}
}
private LaunchManagerVisitor getDeltaVisitor() {
if (fgVisitor == null) {
fgVisitor= new LaunchManagerVisitor();
}
return fgVisitor;
}
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<>();
boolean append = configuration.getAttribute(ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
if (append) {
env.putAll(getNativeEnvironmentCasePreserved());
}
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();
if (value != null) {
value = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value);
}
boolean added= false;
if (win32) {
nativeValue = env.get(key);
if (nativeValue != null) {
env.put(key, value);
} else {
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()]);
}
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;
}
private boolean isPrototype(IFileStore store) {
if (store.getName().endsWith("." + ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION)) {
return true;
}
return false;
}
private boolean isPrototype(File file) {
if (file.getName().endsWith("." + ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION)) {
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)) {
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()]);
}
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()]);
}
public ILaunchDelegate[] getLaunchDelegates() {
initializeLaunchDelegates();
Collection<LaunchDelegate> col = fLaunchDelegates.values();
return col.toArray(new ILaunchDelegate[col.size()]);
}
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()]);
}
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;
}
private synchronized void initializeLaunchDelegates() {
if(fLaunchDelegates == null) {
fLaunchDelegates = new HashMap<>();
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);
}
extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LAUNCH_CONFIGURATION_TYPES);
infos = extensionPoint.getConfigurationElements();
for(int i = 0; i < infos.length; i++) {
if(infos[i].getAttribute(IConfigurationElementConstants.DELEGATE) != null) {
delegate = new LaunchDelegate(infos[i]);
fLaunchDelegates.put(delegate.getId(), delegate);
}
}
}
}
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(",");
modeset = new HashSet<>(Arrays.asList(modes));
LaunchDelegate delegate = getLaunchDelegateExtension(typeid, delegateid, modeset);
if (delegate != null) {
if(!IInternalDebugCoreConstants.EMPTY_STRING.equals(typeid) & modeset != null) {
fPreferredDelegates.add(new PreferredDelegate(delegate, typeid, modeset));
}
}
}
}
catch (CoreException e) {DebugPlugin.log(e);}
}
}
}
protected void resetPreferredDelegates() {
fPreferredDelegates = null;
}
protected ILaunchDelegate getPreferredDelegate(String typeid, Set<String> modes) {
initializePreferredDelegates();
for (PreferredDelegate pd : fPreferredDelegates) {
if(pd.getModes().equals(modes) & pd.getTypeId().equals(typeid)) {
return pd.getDelegate();
}
}
String preferred = Platform.getPreferencesService().getString(DebugPlugin.getUniqueIdentifier(), "//" + LaunchManager.PREF_PREFERRED_DELEGATES + '/' + typeid, IInternalDebugCoreConstants.EMPTY_STRING, null);
if (preferred != null && preferred.length() != 0) {
StringTokenizer tokenizer = new StringTokenizer(preferred, ";");
while(tokenizer.hasMoreTokens()) {
StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), ",");
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;
}
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;
}
protected synchronized List<ILaunchConfiguration> getLocalLaunchConfigurations() {
List<ILaunchConfiguration> configs = new ArrayList<>();
for (ILaunchConfiguration config : getAllLaunchConfigurations()) {
if (config.isLocal()) {
configs.add(config);
}
}
return configs;
}
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) {
return configuration.getType().getSourcePathComputer();
}
return getSourcePathComputer(id);
}
@Override
public ISourcePathComputer getSourcePathComputer(String id) {
initializeSourceContainerTypes();
return sourcePathComputers.get(id);
}
private synchronized void hookResourceChangeListener() {
if (!fListening) {
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE);
fListening = true;
}
}
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");
if (attr != null) {
fComparators.put(attr, new LaunchConfigurationComparator(configurationElement));
} else {
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);
DebugPlugin.log(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]));
}
}
}
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);}
}
}
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]));
}
}
}
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 {
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);
DebugPlugin.log(s);
}
}
}
}
protected boolean internalAddLaunch(ILaunch launch) {
getStepFilterManager();
synchronized (fLaunches) {
if (fLaunches.contains(launch)) {
return false;
}
fLaunches.add(launch);
fLaunchSet.add(launch);
return true;
}
}
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;
}
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;
}
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);
}
}
protected boolean isValid(ILaunchConfiguration config) {
try {
config.getType();
} catch (CoreException e) {
if (e.getStatus().getCode() != DebugException.MISSING_LAUNCH_CONFIGURATION_TYPE) {
DebugPlugin.log(e);
}
return false;
}
return true;
}
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);
}
}
protected void launchConfigurationChanged(ILaunchConfiguration config) {
synchronized(this) {
fLaunchConfigurations.remove(config);
}
clearConfigNameCache();
if (isValid(config)) {
launchConfigurationAdded(config);
getConfigurationNotifier().notify(config, CHANGED);
} else {
launchConfigurationDeleted(config);
}
}
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");
if (sourceLocator instanceof AbstractSourceLookupDirector) {
((AbstractSourceLookupDirector)sourceLocator).setId(identifier);
}
return sourceLocator;
}
protected void projectClosed(IProject project) {
terminateMappedConfigurations(project);
for (ILaunchConfiguration config : getLaunchConfigurations(project)) {
launchConfigurationDeleted(config);
}
}
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);
}
@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());
}
}
}
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;
}
protected void setMovedFromTo(ILaunchConfiguration from, ILaunchConfiguration to) {
fFrom = from;
fTo = to;
}
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);
}
public void persistPreferredLaunchDelegates() {
ILaunchConfigurationType[] types = getLaunchConfigurationTypes();
for(int i = 0; i < types.length; i++) {
persistPreferredLaunchDelegate((LaunchConfigurationType)types[i]);
}
}
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);
}
Preferences.setToDefault(DebugPlugin.getUniqueIdentifier(), PREF_PREFERRED_DELEGATES);
}
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);}
}
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);
}
protected void verifyConfigurations(List<ILaunchConfiguration> verify, List<ILaunchConfiguration> valid) {
for (ILaunchConfiguration config : verify) {
if (!valid.contains(config) && isValid(config)) {
valid.add(config);
}
}
}
public String getLaunchModeName(String id) {
ILaunchMode launchMode = getLaunchMode(id);
if (launchMode != null) {
return removeAccelerators(launchMode.getLabel());
}
return null;
}
public static String removeAccelerators(String label) {
String title = label;
if (title != null) {
int index = title.indexOf('&');
if (index == 0) {
title = title.substring(1);
} else if (index > 0) {
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;
}
public synchronized StepFilterManager getStepFilterManager() {
if (fStepFilterManager == null) {
fStepFilterManager = new StepFilterManager();
}
return fStepFilterManager;
}
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));
}
}
}
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);
}
}
}
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) {
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";
}
}
}
for (int i = 0; i < DISALLOWED_CONFIG_NAME_CHARS.length; i++) {
name = name.replace(DISALLOWED_CONFIG_NAME_CHARS[i], '_');
}
}
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;
}
}