blob: a039504cc4fb4be87e44a57d303f96a98e7156e6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2015 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
*******************************************************************************/
package org.eclipse.jdt.internal.launching;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.core.runtime.preferences.PreferenceModifyListener;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;
import org.osgi.service.prefs.BackingStoreException;
/**
* Manages import of installed JREs. Merges valid imported JREs with existing JREs.
*
* @since 3.1
*/
public class JREPreferenceModifyListener extends PreferenceModifyListener {
class Visitor implements IPreferenceNodeVisitor {
@Override
public boolean visit(IEclipsePreferences node) throws BackingStoreException {
if (node.name().equals(LaunchingPlugin.getUniqueIdentifier())) {
String jresXML = node.get(JavaRuntime.PREF_VM_XML, null);
if (jresXML != null) {
VMDefinitionsContainer vms = new VMDefinitionsContainer();
String pref = InstanceScope.INSTANCE.getNode(LaunchingPlugin.ID_PLUGIN).get(JavaRuntime.PREF_VM_XML, ""); //$NON-NLS-1$
// names -> existing vm's
Map<String, IVMInstall> names = new HashMap<>();
Set<String> ids = new HashSet<>();
if (pref.length() > 0) {
try {
VMDefinitionsContainer container = VMDefinitionsContainer.parseXMLIntoContainer(new ByteArrayInputStream(pref.getBytes("UTF8"))); //$NON-NLS-1$
List<IVMInstall> validVMList = container.getValidVMList();
Iterator<IVMInstall> iterator = validVMList.iterator();
while (iterator.hasNext()) {
IVMInstall vm = iterator.next();
names.put(vm.getName(), vm);
ids.add(vm.getId());
vms.addVM(vm);
}
vms.setDefaultVMInstallCompositeID(container.getDefaultVMInstallCompositeID());
vms.setDefaultVMInstallConnectorTypeID(container.getDefaultVMInstallConnectorTypeID());
} catch (IOException e) {
LaunchingPlugin.log(e);
return false;
}
}
// merge valid VMs with existing VMs
try {
ByteArrayInputStream inputStream = new ByteArrayInputStream(jresXML.getBytes("UTF8")); //$NON-NLS-1$
VMDefinitionsContainer container = VMDefinitionsContainer.parseXMLIntoContainer(inputStream);
List<IVMInstall> validVMList = container.getValidVMList();
Iterator<IVMInstall> iterator = validVMList.iterator();
while (iterator.hasNext()) {
IVMInstall vm = iterator.next();
IVMInstall existing = names.get(vm.getName());
if (existing != null) {
// VM with same name already exists - replace with imported VM
vms.removeVM(existing);
ids.remove(existing.getId());
}
boolean collision = ids.contains(vm.getId());
if (collision) {
// conflicting id, create a new one with unique id
long unique = System.currentTimeMillis();
while(ids.contains(String.valueOf(unique))){
unique++;
}
vm = new VMStandin(vm, String.valueOf(unique));
ids.add(vm.getId());
}
vms.addVM(vm);
}
// update default VM if it exists
String defaultVMInstallCompositeID = container.getDefaultVMInstallCompositeID();
validVMList = vms.getValidVMList();
iterator = validVMList.iterator();
while (iterator.hasNext()) {
IVMInstall vm = iterator.next();
if (JavaRuntime.getCompositeIdFromVM(vm).equals(defaultVMInstallCompositeID)) {
vms.setDefaultVMInstallCompositeID(defaultVMInstallCompositeID);
break;
}
}
} catch (IOException e) {
LaunchingPlugin.log(e);
return false;
}
try {
String xml = vms.getAsXML();
node.put(JavaRuntime.PREF_VM_XML, xml);
} catch (CoreException e) {
LaunchingPlugin.log(e);
return false;
}
}
return false;
}
return true;
}
}
@Override
public IEclipsePreferences preApply(IEclipsePreferences node) {
try {
// force VMs to be initialized before we import the new VMs
JavaRuntime.getVMInstallTypes();
node.accept(new Visitor());
} catch (BackingStoreException e) {
LaunchingPlugin.log(e);
}
return node;
}
}