package org.eclipse.jdt.internal.launching;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
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.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchesListener;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.launching.sourcelookup.advanced.AdvancedSourceLookupSupport;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry2;
import org.eclipse.jdt.launching.IVMConnector;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallChangedListener;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.jdt.launching.sourcelookup.ArchiveSourceLocation;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.osgi.service.debug.DebugTrace;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;
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;
@SuppressWarnings("deprecation")
public class LaunchingPlugin extends Plugin implements DebugOptionsListener, IEclipsePreferences.IPreferenceChangeListener, IVMInstallChangedListener, IResourceChangeListener, ILaunchesListener, IDebugEventSetListener {
public static boolean DEBUG = false;
public static boolean DEBUG_JRE_CONTAINER = false;
public static final String DEBUG_JRE_CONTAINER_FLAG = "org.eclipse.jdt.launching/debug/classpath/jreContainer";
public static final String DEBUG_FLAG = "org.eclipse.jdt.launching/debug";
public static final String ATTR_LAUNCH_TEMP_FILES = "tempFiles";
public static final String LAUNCH_TEMP_FILE_PREFIX = ".temp-";
private static DebugTrace fgDebugTrace;
public static final String ID_PLUGIN= "org.eclipse.jdt.launching";
public static final String ID_EXTENSION_POINT_VM_CONNECTORS = "vmConnectors";
public static final String ID_EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRIES = "runtimeClasspathEntries";
private static LaunchingPlugin fgLaunchingPlugin;
private HashMap<String, IVMConnector> fVMConnectors = null;
private HashMap<String, IConfigurationElement> fClasspathEntryExtensions = null;
private String fOldVMPrefString = EMPTY_STRING;
private boolean fIgnoreVMDefPropertyChangeEvents = false;
private static final String EMPTY_STRING = "";
private static Map<String, LibraryInfo> fgLibraryInfoMap = null;
private static Map<String, Long> fgInstallTimeMap = null;
private static HashSet<String> fgHasChanged = new HashSet<>();
private static Object installLock = new Object();
private boolean fBatchingChanges = false;
private static DocumentBuilder fgXMLParser = null;
class VMChanges implements IVMInstallChangedListener {
private boolean fDefaultChanged = false;
private HashMap<IPath, IPath> fRenamedContainerIds = new HashMap<>();
private IPath getContainerId(IVMInstall vm) {
if (vm != null) {
String name = vm.getName();
if (name != null) {
IPath path = new Path(JavaRuntime.JRE_CONTAINER);
path = path.append(new Path(vm.getVMInstallType().getId()));
path = path.append(new Path(name));
return path;
}
}
return null;
}
@Override
public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {
fDefaultChanged = true;
}
@Override
public void vmAdded(IVMInstall vm) {
}
@Override
public void vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent event) {
String property = event.getProperty();
IVMInstall vm = (IVMInstall)event.getSource();
if (property.equals(IVMInstallChangedListener.PROPERTY_NAME)) {
IPath newId = getContainerId(vm);
IPath oldId = new Path(JavaRuntime.JRE_CONTAINER);
oldId = oldId.append(vm.getVMInstallType().getId());
String oldName = (String)event.getOldValue();
if (oldName != null) {
oldId = oldId.append(oldName);
fRenamedContainerIds.put(oldId, newId);
try {
ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations();
String container = null;
ILaunchConfigurationWorkingCopy wc = null;
IPath cpath = null;
for(int i = 0; i < configs.length; i++) {
container = configs[i].getAttribute(JavaRuntime.JRE_CONTAINER, (String)null);
if(container != null) {
cpath = new Path(container);
if(cpath.lastSegment().equals(oldName)) {
cpath = cpath.removeLastSegments(1).append(newId.lastSegment()).addTrailingSeparator();
wc = configs[i].getWorkingCopy();
wc.setAttribute(JavaRuntime.JRE_CONTAINER, cpath.toString());
wc.doSave();
}
}
}
} catch (CoreException e) {}
}
}
}
@Override
public void vmRemoved(IVMInstall vm) {
}
public void process() {
JREUpdateJob job = new JREUpdateJob(this);
job.schedule();
}
protected void doit(IProgressMonitor monitor) throws CoreException {
IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor1) throws CoreException {
IJavaProject[] projects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects();
monitor1.beginTask(LaunchingMessages.LaunchingPlugin_0, projects.length + 1);
rebind(monitor1, projects);
monitor1.done();
}
};
JavaCore.run(runnable, null, monitor);
}
private void rebind(IProgressMonitor monitor, IJavaProject[] projects) throws CoreException {
if (fDefaultChanged) {
JavaClasspathVariablesInitializer initializer = new JavaClasspathVariablesInitializer();
initializer.initialize(JavaRuntime.JRELIB_VARIABLE);
initializer.initialize(JavaRuntime.JRESRC_VARIABLE);
initializer.initialize(JavaRuntime.JRESRCROOT_VARIABLE);
}
monitor.worked(1);
int length = projects.length;
Map<IPath, List<IJavaProject>> projectsMap = new HashMap<>();
for (int i = 0; i < length; i++) {
IJavaProject project = projects[i];
IClasspathEntry[] entries = project.getRawClasspath();
boolean replace = false;
for (int j = 0; j < entries.length; j++) {
IClasspathEntry entry = entries[j];
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_CONTAINER:
IPath reference = entry.getPath();
IPath newBinding = null;
String firstSegment = reference.segment(0);
if (JavaRuntime.JRE_CONTAINER.equals(firstSegment)) {
if (reference.segmentCount() > 1) {
IPath renamed = fRenamedContainerIds.get(reference);
if (renamed != null) {
newBinding = renamed;
}
}
if (newBinding == null){
List<IJavaProject> projectsList = projectsMap.get(reference);
if (projectsList == null) {
projectsMap.put(reference, projectsList = new ArrayList<>(length));
}
projectsList.add(project);
} else {
IClasspathEntry newEntry = JavaCore.newContainerEntry(newBinding, entry.isExported());
entries[j] = newEntry;
replace = true;
}
}
break;
default:
break;
}
}
if (replace) {
project.setRawClasspath(entries, null);
}
monitor.worked(1);
}
Iterator<IPath> references = projectsMap.keySet().iterator();
while (references.hasNext()) {
IPath reference = references.next();
List<IJavaProject> projectsList = projectsMap.get(reference);
IJavaProject[] referenceProjects = new IJavaProject[projectsList.size()];
projectsList.toArray(referenceProjects);
JREContainerInitializer initializer = new JREContainerInitializer();
initializer.initialize(reference, referenceProjects);
}
}
}
class JREUpdateJob extends Job {
private VMChanges fChanges;
public JREUpdateJob(VMChanges changes) {
super(LaunchingMessages.LaunchingPlugin_1);
fChanges = changes;
setSystem(true);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
fChanges.doit(monitor);
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
}
public LaunchingPlugin() {
super();
fgLaunchingPlugin = this;
}
public static LibraryInfo getLibraryInfo(String javaInstallPath) {
if (fgLibraryInfoMap == null) {
restoreLibraryInfo();
}
return fgLibraryInfoMap.get(javaInstallPath);
}
public static void setLibraryInfo(String javaInstallPath, LibraryInfo info) {
if (isVMLogging()) {
LaunchingPlugin.log(LaunchingMessages.VMLogging_2 + javaInstallPath);
}
if (fgLibraryInfoMap == null) {
restoreLibraryInfo();
}
if (info == null) {
fgLibraryInfoMap.remove(javaInstallPath);
if(fgInstallTimeMap != null) {
fgInstallTimeMap.remove(javaInstallPath);
writeInstallInfo();
}
} else {
fgLibraryInfoMap.put(javaInstallPath, info);
}
fgHasChanged.remove(javaInstallPath);
saveLibraryInfo();
}
public static boolean isVMLogging() {
String vmLogging = System.getProperty("jdt.debug.launching.vmLogging");
return "true".equalsIgnoreCase(vmLogging);
}
public static File getFileInPlugin(IPath path) {
try {
URL installURL =
new URL(getDefault().getBundle().getEntry("/"), path.toString());
URL localURL = FileLocator.toFileURL(installURL);
return new File(localURL.getFile());
} catch (IOException ioe) {
return null;
}
}
public static String getUniqueIdentifier() {
return ID_PLUGIN;
}
public static LaunchingPlugin getDefault() {
return fgLaunchingPlugin;
}
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
public static void log(String message) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
}
public static void log(Throwable e) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e));
}
@Override
public void stop(BundleContext context) throws Exception {
try {
AdvancedSourceLookupSupport.stop();
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
DebugPlugin.getDefault().removeDebugEventListener(this);
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
ArchiveSourceLocation.closeArchives();
InstanceScope.INSTANCE.getNode(ID_PLUGIN).removePreferenceChangeListener(this);
JavaRuntime.removeVMInstallChangedListener(this);
JavaRuntime.saveVMConfiguration();
fgXMLParser = null;
ResourcesPlugin.getWorkspace().removeSaveParticipant(ID_PLUGIN);
} finally {
super.stop(context);
}
}
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
Hashtable<String, String> props = new Hashtable<>(2);
props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, getUniqueIdentifier());
context.registerService(DebugOptionsListener.class.getName(), this, props);
ResourcesPlugin.getWorkspace().addSaveParticipant(ID_PLUGIN, new ISaveParticipant() {
@Override
public void doneSaving(ISaveContext context1) {}
@Override
public void prepareToSave(ISaveContext context1) throws CoreException {}
@Override
public void rollback(ISaveContext context1) {}
@Override
public void saving(ISaveContext context1) throws CoreException {
try {
InstanceScope.INSTANCE.getNode(ID_PLUGIN).flush();
} catch (BackingStoreException e) {
log(e);
}
writeInstallInfo();
}
});
InstanceScope.INSTANCE.getNode(ID_PLUGIN).addPreferenceChangeListener(this);
JavaRuntime.addVMInstallChangedListener(this);
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_CLOSE);
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
DebugPlugin.getDefault().addDebugEventListener(this);
AdvancedSourceLookupSupport.start();
}
public IVMConnector getVMConnector(String id) {
if (fVMConnectors == null) {
initializeVMConnectors();
}
return fVMConnectors.get(id);
}
public IVMConnector[] getVMConnectors() {
if (fVMConnectors == null) {
initializeVMConnectors();
}
return fVMConnectors.values().toArray(new IVMConnector[fVMConnectors.size()]);
}
private void initializeVMConnectors() {
IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(ID_PLUGIN, ID_EXTENSION_POINT_VM_CONNECTORS);
IConfigurationElement[] configs= extensionPoint.getConfigurationElements();
MultiStatus status= new MultiStatus(getUniqueIdentifier(), IStatus.OK, "Exception occurred reading vmConnectors extensions.", null);
fVMConnectors = new HashMap<>(configs.length);
for (int i= 0; i < configs.length; i++) {
try {
IVMConnector vmConnector= (IVMConnector)configs[i].createExecutableExtension("class");
fVMConnectors.put(vmConnector.getIdentifier(), vmConnector);
} catch (CoreException e) {
status.add(e.getStatus());
}
}
if (!status.isOK()) {
LaunchingPlugin.log(status);
}
}
public IRuntimeClasspathEntry2 newRuntimeClasspathEntry(String id) throws CoreException {
if (fClasspathEntryExtensions == null) {
initializeRuntimeClasspathExtensions();
}
IConfigurationElement config = fClasspathEntryExtensions.get(id);
if (config != null) {
return (IRuntimeClasspathEntry2) config.createExecutableExtension("class");
}
abort(NLS.bind(LaunchingMessages.LaunchingPlugin_32, new String[]{id}), null);
return null;
}
private void initializeRuntimeClasspathExtensions() {
IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(LaunchingPlugin.ID_PLUGIN, ID_EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRIES);
IConfigurationElement[] configs= extensionPoint.getConfigurationElements();
fClasspathEntryExtensions = new HashMap<>(configs.length);
for (int i= 0; i < configs.length; i++) {
fClasspathEntryExtensions.put(configs[i].getAttribute("id"), configs[i]);
}
}
protected void processVMPrefsChanged(String oldValue, String newValue) {
fBatchingChanges = true;
VMChanges vmChanges = null;
try {
String oldPrefString;
String newPrefString;
if (newValue == null || newValue.equals(EMPTY_STRING)) {
fOldVMPrefString = oldValue;
return;
}
else if (oldValue == null || oldValue.equals(EMPTY_STRING)) {
oldPrefString = fOldVMPrefString;
newPrefString = newValue;
}
else {
oldPrefString = oldValue;
newPrefString = newValue;
}
vmChanges = new VMChanges();
JavaRuntime.addVMInstallChangedListener(vmChanges);
VMDefinitionsContainer oldResults = getVMDefinitions(oldPrefString);
VMDefinitionsContainer newResults = getVMDefinitions(newPrefString);
List<IVMInstall> deleted = oldResults.getVMList();
List<IVMInstall> current = newResults.getValidVMList();
deleted.removeAll(current);
Iterator<IVMInstall> deletedIterator = deleted.iterator();
while (deletedIterator.hasNext()) {
VMStandin deletedVMStandin = (VMStandin) deletedIterator.next();
deletedVMStandin.getVMInstallType().disposeVMInstall(deletedVMStandin.getId());
}
Iterator<IVMInstall> iter = current.iterator();
while (iter.hasNext()) {
VMStandin standin = (VMStandin)iter.next();
standin.convertToRealVM();
}
String newDefaultId = newResults.getDefaultVMInstallCompositeID();
if (newDefaultId != null) {
IVMInstall newDefaultVM = JavaRuntime.getVMFromCompositeId(newDefaultId);
if (newDefaultVM != null) {
try {
JavaRuntime.setDefaultVMInstall(newDefaultVM, null, false);
} catch (CoreException ce) {
log(ce);
}
}
}
} finally {
fBatchingChanges = false;
if (vmChanges != null) {
JavaRuntime.removeVMInstallChangedListener(vmChanges);
vmChanges.process();
}
}
}
private VMDefinitionsContainer getVMDefinitions(String xml) {
if (xml.length() > 0) {
try {
ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF8"));
return VMDefinitionsContainer.parseXMLIntoContainer(stream);
} catch (IOException e) {
LaunchingPlugin.log(e);
}
}
return new VMDefinitionsContainer();
}
@Override
public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {
if (!fBatchingChanges) {
VMChanges changes = new VMChanges();
changes.defaultVMInstallChanged(previous, current);
changes.process();
}
}
@Override
public void vmAdded(IVMInstall vm) {
}
@Override
public void vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent event) {
if (!fBatchingChanges) {
VMChanges changes = new VMChanges();
changes.vmChanged(event);
changes.process();
}
}
@Override
public void vmRemoved(IVMInstall vm) {
if (!fBatchingChanges) {
VMChanges changes = new VMChanges();
changes.vmRemoved(vm);
changes.process();
}
}
@Override
public void resourceChanged(IResourceChangeEvent event) {
ArchiveSourceLocation.closeArchives();
}
public void setIgnoreVMDefPropertyChangeEvents(boolean ignore) {
fIgnoreVMDefPropertyChangeEvents = ignore;
}
public boolean isIgnoreVMDefPropertyChangeEvents() {
return fIgnoreVMDefPropertyChangeEvents;
}
private static String getLibraryInfoAsXML() throws CoreException {
Document doc = DebugPlugin.newDocument();
Element config = doc.createElement("libraryInfos");
doc.appendChild(config);
Iterator<String> locations = fgLibraryInfoMap.keySet().iterator();
while (locations.hasNext()) {
String home = locations.next();
LibraryInfo info = fgLibraryInfoMap.get(home);
Element locationElemnet = infoAsElement(doc, info);
locationElemnet.setAttribute("home", home);
config.appendChild(locationElemnet);
}
return DebugPlugin.serializeDocument(doc);
}
private static Element infoAsElement(Document doc, LibraryInfo info) {
Element libraryElement = doc.createElement("libraryInfo");
libraryElement.setAttribute("version", info.getVersion());
appendPathElements(doc, "bootpath", libraryElement, info.getBootpath());
appendPathElements(doc, "extensionDirs", libraryElement, info.getExtensionDirs());
appendPathElements(doc, "endorsedDirs", libraryElement, info.getEndorsedDirs());
return libraryElement;
}
private static void appendPathElements(Document doc, String elementType, Element libraryElement, String[] paths) {
if (paths.length > 0) {
Element child = doc.createElement(elementType);
libraryElement.appendChild(child);
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
Element entry = doc.createElement("entry");
child.appendChild(entry);
entry.setAttribute("path", path);
}
}
}
private static void saveLibraryInfo() {
try {
String xml = getLibraryInfoAsXML();
IPath libPath = getDefault().getStateLocation();
libPath = libPath.append("libraryInfos.xml");
File file = libPath.toFile();
if (!file.exists()) {
file.createNewFile();
}
try (OutputStream stream = new BufferedOutputStream(new FileOutputStream(file))) {
stream.write(xml.getBytes("UTF8"));
}
} catch (IOException e) {
log(e);
} catch (CoreException e) {
log(e);
}
}
private static void restoreLibraryInfo() {
fgLibraryInfoMap = new HashMap<>(10);
IPath libPath = getDefault().getStateLocation();
libPath = libPath.append("libraryInfos.xml");
File file = libPath.toFile();
if (file.exists()) {
try {
InputStream stream = new BufferedInputStream(new FileInputStream(file));
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
parser.setErrorHandler(new DefaultHandler());
Element root = parser.parse(new InputSource(stream)).getDocumentElement();
if(!root.getNodeName().equals("libraryInfos")) {
return;
}
NodeList list = root.getChildNodes();
int length = list.getLength();
for (int i = 0; i < length; ++i) {
Node node = list.item(i);
short type = node.getNodeType();
if (type == Node.ELEMENT_NODE) {
Element element = (Element) node;
String nodeName = element.getNodeName();
if (nodeName.equalsIgnoreCase("libraryInfo")) {
String version = element.getAttribute("version");
String location = element.getAttribute("home");
String[] bootpath = getPathsFromXML(element, "bootpath");
String[] extDirs = getPathsFromXML(element, "extensionDirs");
String[] endDirs = getPathsFromXML(element, "endorsedDirs");
if (location != null) {
if (isVMLogging()) {
LaunchingPlugin.log(LaunchingMessages.VMLogging_1 + location);
}
LibraryInfo info = new LibraryInfo(version, bootpath, extDirs, endDirs);
fgLibraryInfoMap.put(location, info);
}
}
}
}
} catch (IOException e) {
log(e);
} catch (ParserConfigurationException e) {
log(e);
} catch (SAXException e) {
log(e);
}
}
}
public static boolean timeStampChanged(String location) {
synchronized (installLock) {
if(fgHasChanged.contains(location)) {
return true;
}
File file = new File(location);
if(file.exists()) {
if(fgInstallTimeMap == null) {
readInstallInfo();
}
Long stamp = fgInstallTimeMap.get(location);
long fstamp = file.lastModified();
if(stamp != null) {
if(stamp.longValue() == fstamp) {
return false;
}
}
stamp = new Long(fstamp);
fgInstallTimeMap.put(location, stamp);
writeInstallInfo();
fgHasChanged.add(location);
return true;
}
}
return false;
}
private static void readInstallInfo() {
fgInstallTimeMap = new HashMap<>();
IPath libPath = getDefault().getStateLocation();
libPath = libPath.append(".install.xml");
File file = libPath.toFile();
if (file.exists()) {
try {
InputStream stream = new BufferedInputStream(new FileInputStream(file));
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
parser.setErrorHandler(new DefaultHandler());
Element root = parser.parse(new InputSource(stream)).getDocumentElement();
if(root.getNodeName().equalsIgnoreCase("dirs")) {
NodeList nodes = root.getChildNodes();
Node node = null;
Element element = null;
for (int i = 0; i < nodes.getLength(); i++) {
node = nodes.item(i);
if(node.getNodeType() == Node.ELEMENT_NODE) {
element = (Element) node;
if(element.getNodeName().equalsIgnoreCase("entry")) {
String loc = element.getAttribute("loc");
String stamp = element.getAttribute("stamp");
try {
Long l = new Long(stamp);
fgInstallTimeMap.put(loc, l);
}
catch(NumberFormatException nfe) {
}
}
}
}
}
} catch (IOException e) {
log(e);
} catch (ParserConfigurationException e) {
log(e);
} catch (SAXException e) {
log(e);
}
}
}
private static void writeInstallInfo() {
if(fgInstallTimeMap != null) {
try {
Document doc = DebugPlugin.newDocument();
Element root = doc.createElement("dirs");
doc.appendChild(root);
Entry<String, Long> entry = null;
Element e = null;
String key = null;
for(Iterator<Entry<String, Long>> i = fgInstallTimeMap.entrySet().iterator(); i.hasNext();) {
entry = i.next();
key = entry.getKey();
if(fgLibraryInfoMap == null || fgLibraryInfoMap.containsKey(key)) {
e = doc.createElement("entry");
root.appendChild(e);
e.setAttribute("loc", key);
e.setAttribute("stamp", entry.getValue().toString());
}
}
String xml = DebugPlugin.serializeDocument(doc);
IPath libPath = getDefault().getStateLocation();
libPath = libPath.append(".install.xml");
File file = libPath.toFile();
if (!file.exists()) {
file.createNewFile();
}
try (OutputStream stream = new BufferedOutputStream(new FileOutputStream(file))) {
stream.write(xml.getBytes("UTF8"));
}
} catch (IOException e) {
log(e);
} catch (CoreException e) {
log(e);
}
}
}
private static String[] getPathsFromXML(Element lib, String pathType) {
List<String> paths = new ArrayList<>();
NodeList list = lib.getChildNodes();
int length = list.getLength();
for (int i = 0; i < length; ++i) {
Node node = list.item(i);
short type = node.getNodeType();
if (type == Node.ELEMENT_NODE) {
Element element = (Element) node;
String nodeName = element.getNodeName();
if (nodeName.equalsIgnoreCase(pathType)) {
NodeList entries = element.getChildNodes();
int numEntries = entries.getLength();
for (int j = 0; j < numEntries; j++) {
Node n = entries.item(j);
short t = n.getNodeType();
if (t == Node.ELEMENT_NODE) {
Element entryElement = (Element)n;
String name = entryElement.getNodeName();
if (name.equals("entry")) {
String path = entryElement.getAttribute("path");
if (path != null && path.length() > 0) {
paths.add(path);
}
}
}
}
}
}
}
return paths.toArray(new String[paths.size()]);
}
@Override
public void launchesRemoved(ILaunch[] launches) {
ArchiveSourceLocation.closeArchives();
}
@Override
public void launchesAdded(ILaunch[] launches) {
}
@Override
public void launchesChanged(ILaunch[] launches) {
}
@Override
public void handleDebugEvents(DebugEvent[] events) {
for (int i = 0; i < events.length; i++) {
DebugEvent event = events[i];
if (event.getKind() == DebugEvent.TERMINATE) {
Object source = event.getSource();
if (source instanceof IDebugTarget || source instanceof IProcess) {
ArchiveSourceLocation.closeArchives();
IProcess process;
if (source instanceof IProcess) {
process = (IProcess) source;
} else {
process = ((IDebugTarget) source).getProcess();
}
if (process != null) {
deleteProcessTempFiles(process);
}
}
}
}
}
private void deleteProcessTempFiles(IProcess process) {
String tempFiles = process.getAttribute(ATTR_LAUNCH_TEMP_FILES);
if (tempFiles == null) {
return;
}
Arrays.stream(tempFiles.split(File.pathSeparator)).map(path -> new File(path)).filter(file -> isValidProcessTempFile(file)).forEach(file -> file.delete());
}
private boolean isValidProcessTempFile(File file) {
return file.getName().startsWith(LAUNCH_TEMP_FILE_PREFIX);
}
public static DocumentBuilder getParser() throws CoreException {
if (fgXMLParser == null) {
try {
fgXMLParser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
fgXMLParser.setErrorHandler(new DefaultHandler());
} catch (ParserConfigurationException e) {
abort(LaunchingMessages.LaunchingPlugin_34, e);
} catch (FactoryConfigurationError e) {
abort(LaunchingMessages.LaunchingPlugin_34, e);
}
}
return fgXMLParser;
}
protected static void abort(String message, Throwable exception) throws CoreException {
IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), 0, message, exception);
throw new CoreException(status);
}
public static boolean sameURL(URL url1, URL url2) {
if (url1 == url2) {
return true;
}
if (url1 == null ^ url2 == null) {
return false;
}
final boolean isFile1 = "file".equalsIgnoreCase(url1.getProtocol());
final boolean isFile2 = "file".equalsIgnoreCase(url2.getProtocol());
if (isFile1 && isFile2) {
File file1 = new File(url1.getFile());
File file2 = new File(url2.getFile());
return file1.equals(file2);
}
if (isFile1 ^ isFile2) {
return false;
}
return getExternalForm(url1).equals(getExternalForm(url2));
}
private static String getExternalForm(URL url) {
String externalForm = url.toExternalForm();
if (externalForm == null)
{
return "";
}
externalForm = externalForm.trim();
if (externalForm.endsWith("/")) {
externalForm = externalForm.substring(0, externalForm.length() - 1);
}
return externalForm.toLowerCase();
}
@Override
public void preferenceChange(PreferenceChangeEvent event) {
String property = event.getKey();
if (property.equals(JavaRuntime.PREF_VM_XML)) {
if (!isIgnoreVMDefPropertyChangeEvents()) {
processVMPrefsChanged((String)event.getOldValue(), (String)event.getNewValue());
}
}
}
@Override
public void optionsChanged(DebugOptions options) {
DEBUG = options.getBooleanOption(DEBUG_FLAG, false);
DEBUG_JRE_CONTAINER = DEBUG && options.getBooleanOption(DEBUG_JRE_CONTAINER_FLAG, false);
}
public static void trace(String option, String message, Throwable throwable) {
System.out.println(message);
if(fgDebugTrace != null) {
fgDebugTrace.trace(option, message, throwable);
}
}
public static void trace(String message) {
trace(null, message, null);
}
}