blob: a9571eff127eeff7d8bd050e824138bbb5bdf229 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 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
* Frits Jalvingh - Contribution for Bug 459831 - [launching] Support attaching
* external annotations to a JRE container
*******************************************************************************/
package org.eclipse.jdt.internal.launching;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jdt.launching.AbstractVMInstall;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.osgi.util.NLS;
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;
/**
* This is a container for VM definitions such as the VM definitions that are
* stored in the workbench preferences.
* <p>
* An instance of this class may be obtained from an XML document by calling
* <code>parseXMLIntoContainer</code>.
* </p>
* <p>
* An instance of this class may be translated into an XML document by calling
* <code>getAsXML</code>.
* </p>
* <p>
* Clients may instantiate this class; it is not intended to be subclassed.
* </p>
*
* @since 2.1
*/
public class VMDefinitionsContainer {
/**
* Map of VMInstallTypes to Lists of corresponding VMInstalls.
*/
private Map<IVMInstallType, List<IVMInstall>> fVMTypeToVMMap;
/**
* Cached list of VMs in this container
*/
private List<IVMInstall> fVMList;
/**
* VMs managed by this container whose install locations don't actually exist.
*/
private List<IVMInstall> fInvalidVMList;
/**
* The composite identifier of the default VM. This consists of the install type ID
* plus an ID for the VM.
*/
private String fDefaultVMInstallCompositeID;
/**
* The identifier of the connector to use for the default VM.
*/
private String fDefaultVMInstallConnectorTypeID;
/**
* Contains any error/information status of parsing XML
*/
private MultiStatus fStatus;
/**
* Constructs an empty VM container
*/
public VMDefinitionsContainer() {
fVMTypeToVMMap = new HashMap<>(10);
fInvalidVMList = new ArrayList<>(10);
fVMList = new ArrayList<>(10);
}
/**
* Add the specified VM to the VM definitions managed by this container.
* <p>
* If distinguishing valid from invalid VMs is important, the specified VM must
* have already had its install location set. An invalid VM is one whose install
* location doesn't exist.
* </p>
*
* @param vm the VM to be added to this container
*/
public void addVM(IVMInstall vm) {
if (!fVMList.contains(vm)) {
IVMInstallType vmInstallType = vm.getVMInstallType();
List<IVMInstall> vmList = fVMTypeToVMMap.get(vmInstallType);
if (vmList == null) {
vmList = new ArrayList<>(3);
fVMTypeToVMMap.put(vmInstallType, vmList);
}
vmList.add(vm);
File installLocation = vm.getInstallLocation();
if (installLocation == null || vmInstallType.validateInstallLocation(installLocation).getSeverity() == IStatus.ERROR) {
fInvalidVMList.add(vm);
}
fVMList.add(vm);
}
}
/**
* Add all VM's in the specified list to the VM definitions managed by this container.
* <p>
* If distinguishing valid from invalid VMs is important, the specified VMs must
* have already had their install locations set. An invalid VM is one whose install
* location doesn't exist.
* </p>
*
* @param vmList a list of VMs to be added to this container
*/
public void addVMList(List<IVMInstall> vmList) {
Iterator<IVMInstall> iterator = vmList.iterator();
while (iterator.hasNext()) {
addVM(iterator.next());
}
}
/**
* Return a mapping of VM install types to lists of VMs. The keys of this map are instances of
* <code>IVMInstallType</code>. The values are instances of <code>java.util.List</code>
* which contain instances of <code>IVMInstall</code>.
*
* @return Map the mapping of VM install types to lists of VMs
*/
public Map<IVMInstallType, List<IVMInstall>> getVMTypeToVMMap() {
return fVMTypeToVMMap;
}
/**
* Return a list of all VMs in this container, including any invalid VMs. An invalid
* VM is one whose install location does not exist on the file system.
* The order of the list is not specified.
*
* @return List the data structure containing all VMs managed by this container
*/
public List<IVMInstall> getVMList() {
return fVMList;
}
/**
* Return a list of all valid VMs in this container. A valid VM is one whose install
* location exists on the file system. The order of the list is not specified.
*
* @return List
*/
public List<IVMInstall> getValidVMList() {
List<IVMInstall> vms = getVMList();
List<IVMInstall> resultList = new ArrayList<>(vms.size());
resultList.addAll(vms);
resultList.removeAll(fInvalidVMList);
return resultList;
}
/**
* Returns the composite ID for the default VM. The composite ID consists
* of an ID for the VM install type together with an ID for VM. This is
* necessary because VM ids by themselves are not necessarily unique across
* VM install types.
*
* @return String returns the composite ID of the current default VM
*/
public String getDefaultVMInstallCompositeID(){
return fDefaultVMInstallCompositeID;
}
/**
* Sets the composite ID for the default VM. The composite ID consists
* of an ID for the VM install type together with an ID for VM. This is
* necessary because VM ids by themselves are not necessarily unique across
* VM install types.
*
* @param id identifies the new default VM using a composite ID
*/
public void setDefaultVMInstallCompositeID(String id){
fDefaultVMInstallCompositeID = id;
}
/**
* Return the default VM's connector type ID.
*
* @return String the current value of the default VM's connector type ID
*/
public String getDefaultVMInstallConnectorTypeID() {
return fDefaultVMInstallConnectorTypeID;
}
/**
* Set the default VM's connector type ID.
*
* @param id the new value of the default VM's connector type ID
*/
public void setDefaultVMInstallConnectorTypeID(String id){
fDefaultVMInstallConnectorTypeID = id;
}
/**
* Return the VM definitions contained in this object as a String of XML. The String
* is suitable for storing in the workbench preferences.
* <p>
* The resulting XML is compatible with the static method <code>parseXMLIntoContainer</code>.
* </p>
* @return String the results of flattening this object into XML
* @throws CoreException if serialization of the XML document failed
*/
public String getAsXML() throws CoreException {
// Create the Document and the top-level node
Document doc = DebugPlugin.newDocument();
Element config = doc.createElement("vmSettings"); //$NON-NLS-1$
doc.appendChild(config);
// Set the defaultVM attribute on the top-level node
if (getDefaultVMInstallCompositeID() != null) {
config.setAttribute("defaultVM", getDefaultVMInstallCompositeID()); //$NON-NLS-1$
}
// Set the defaultVMConnector attribute on the top-level node
if (getDefaultVMInstallConnectorTypeID() != null) {
config.setAttribute("defaultVMConnector", getDefaultVMInstallConnectorTypeID()); //$NON-NLS-1$
}
// Create a node for each install type represented in this container
Set<IVMInstallType> vmInstallTypeSet = getVMTypeToVMMap().keySet();
Iterator<IVMInstallType> keyIterator = vmInstallTypeSet.iterator();
while (keyIterator.hasNext()) {
IVMInstallType vmInstallType = keyIterator.next();
Element vmTypeElement = vmTypeAsElement(doc, vmInstallType);
config.appendChild(vmTypeElement);
}
// Serialize the Document and return the resulting String
return DebugPlugin.serializeDocument(doc);
}
/**
* Create and return a node for the specified VM install type in the specified Document.
*
* @param doc the backing {@link Document}
* @param vmType the {@link IVMInstallType} to create an {@link Element} for
* @return the new {@link Element}
*/
private Element vmTypeAsElement(Document doc, IVMInstallType vmType) {
// Create a node for the VM type and set its 'id' attribute
Element element= doc.createElement("vmType"); //$NON-NLS-1$
element.setAttribute("id", vmType.getId()); //$NON-NLS-1$
// For each VM of the specified type, create a subordinate node for it
List<IVMInstall> vmList = getVMTypeToVMMap().get(vmType);
Iterator<IVMInstall> vmIterator = vmList.iterator();
while (vmIterator.hasNext()) {
IVMInstall vm = vmIterator.next();
Element vmElement = vmAsElement(doc, vm);
element.appendChild(vmElement);
}
return element;
}
/**
* Create and return a node for the specified VM in the specified Document.
*
* @param doc the backing {@link Document}
* @param vm the {@link IVMInstall} to create an {@link Element} for
* @return the new {@link Element} representing the given {@link IVMInstall}
*/
private Element vmAsElement(Document doc, IVMInstall vm) {
// Create the node for the VM and set its 'id' & 'name' attributes
Element element= doc.createElement("vm"); //$NON-NLS-1$
element.setAttribute("id", vm.getId()); //$NON-NLS-1$
element.setAttribute("name", vm.getName()); //$NON-NLS-1$
// Determine and set the 'path' attribute for the VM
String installPath= ""; //$NON-NLS-1$
File installLocation= vm.getInstallLocation();
if (installLocation != null) {
installPath= installLocation.getAbsolutePath();
}
element.setAttribute("path", installPath); //$NON-NLS-1$
// If the 'libraryLocations' attribute is specified, create a node for it
LibraryLocation[] libraryLocations= vm.getLibraryLocations();
if (libraryLocations != null) {
Element libLocationElement = libraryLocationsAsElement(doc, libraryLocations);
element.appendChild(libLocationElement);
}
// Java doc location
URL url = vm.getJavadocLocation();
if (url != null) {
element.setAttribute("javadocURL", url.toExternalForm()); //$NON-NLS-1$
}
if (vm instanceof IVMInstall2) {
String vmArgs = ((IVMInstall2)vm).getVMArgs();
if (vmArgs != null && vmArgs.length() > 0) {
element.setAttribute("vmargs", vmArgs); //$NON-NLS-1$
}
} else {
String[] vmArgs = vm.getVMArguments();
if (vmArgs != null && vmArgs.length > 0) {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < vmArgs.length; i++) {
buffer.append(vmArgs[i] + " "); //$NON-NLS-1$
}
element.setAttribute("vmargs", buffer.toString()); //$NON-NLS-1$
}
}
// VM attributes
if (vm instanceof AbstractVMInstall) {
Map<String, String> attributes = ((AbstractVMInstall)vm).getAttributes();
if (!attributes.isEmpty()) {
Element attrElement = doc.createElement("attributeMap"); //$NON-NLS-1$
Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
Element entryElement = doc.createElement("entry"); //$NON-NLS-1$
entryElement.setAttribute("key", entry.getKey()); //$NON-NLS-1$
entryElement.setAttribute("value", entry.getValue()); //$NON-NLS-1$
attrElement.appendChild(entryElement);
}
element.appendChild(attrElement);
}
}
return element;
}
/**
* Create and return a 'libraryLocations' node. This node owns subordinate nodes that
* list individual library locations.
*
* @param doc the backing {@link Document}
* @param locations the array of {@link LibraryLocation}s to create an {@link Element} for
* @return the new {@link Element} for the given {@link LibraryLocation}s
*/
private static Element libraryLocationsAsElement(Document doc, LibraryLocation[] locations) {
Element root = doc.createElement("libraryLocations"); //$NON-NLS-1$
for (int i = 0; i < locations.length; i++) {
Element element = doc.createElement("libraryLocation"); //$NON-NLS-1$
element.setAttribute("jreJar", locations[i].getSystemLibraryPath().toString()); //$NON-NLS-1$
element.setAttribute("jreSrc", locations[i].getSystemLibrarySourcePath().toString()); //$NON-NLS-1$
IPath annotationsPath = locations[i].getExternalAnnotationsPath();
if (null != annotationsPath && !annotationsPath.isEmpty()) {
element.setAttribute("jreExternalAnns", annotationsPath.toString()); //$NON-NLS-1$
}
IPath packageRootPath = locations[i].getPackageRootPath();
if (packageRootPath != null) {
element.setAttribute("pkgRoot", packageRootPath.toString()); //$NON-NLS-1$
}
URL javadocURL= locations[i].getJavadocLocation();
if (javadocURL != null) {
element.setAttribute("jreJavadoc", javadocURL.toExternalForm()); //$NON-NLS-1$
}
URL indexURL = locations[i].getIndexLocation();
if(indexURL != null) {
element.setAttribute("jreIndex", indexURL.toExternalForm()); //$NON-NLS-1$
}
root.appendChild(element);
}
return root;
}
public static VMDefinitionsContainer parseXMLIntoContainer(InputStream inputStream) throws IOException {
VMDefinitionsContainer container = new VMDefinitionsContainer();
parseXMLIntoContainer(inputStream, container);
return container;
}
/**
* Parse the VM definitions contained in the specified InputStream into the
* specified container.
* <p>
* The VMs in the returned container are instances of <code>VMStandin</code>.
* </p>
* <p>
* This method has no side-effects. That is, no notifications are sent for VM adds,
* changes, deletes, and the workbench preferences are not affected.
* </p>
* <p>
* If the <code>getAsXML</code> method is called on the returned container object,
* the resulting XML will be semantically equivalent (though not necessarily syntactically equivalent) as
* the XML contained in <code>inputStream</code>.
* </p>
* @param inputStream the <code>InputStream</code> containing XML that declares a set of VMs and a default VM
* @param container the container to add the VM definitions to
* @throws IOException if this method fails. Reasons include:<ul>
* <li>the XML in <code>inputStream</code> was badly formatted</li>
* <li>the top-level node was not 'vmSettings'</li>
* </ul>
* @since 3.2
*/
public static void parseXMLIntoContainer(InputStream inputStream, VMDefinitionsContainer container) throws IOException {
// Do the parsing and obtain the top-level node
Element config= null;
// Wrapper the stream for efficient parsing
try (InputStream stream = new BufferedInputStream(inputStream)) {
DocumentBuilder parser= DocumentBuilderFactory.newInstance().newDocumentBuilder();
parser.setErrorHandler(new DefaultHandler());
config = parser.parse(new InputSource(stream)).getDocumentElement();
} catch (SAXException e) {
throw new IOException(LaunchingMessages.JavaRuntime_badFormat);
} catch (ParserConfigurationException e) {
throw new IOException(LaunchingMessages.JavaRuntime_badFormat);
}
// If the top-level node wasn't what we expected, bail out
if (!config.getNodeName().equalsIgnoreCase("vmSettings")) { //$NON-NLS-1$
throw new IOException(LaunchingMessages.JavaRuntime_badFormat);
}
// Populate the default VM-related fields
container.setDefaultVMInstallCompositeID(config.getAttribute("defaultVM")); //$NON-NLS-1$
container.setDefaultVMInstallConnectorTypeID(config.getAttribute("defaultVMConnector")); //$NON-NLS-1$
// Traverse the parsed structure and populate the VMType to VM Map
NodeList list = config.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 vmTypeElement = (Element) node;
if (vmTypeElement.getNodeName().equalsIgnoreCase("vmType")) { //$NON-NLS-1$
populateVMTypes(vmTypeElement, container);
}
}
}
}
/**
* For the specified VM type node, parse all subordinate VM definitions and add them
* to the specified container.
*
* @param vmTypeElement the {@link Element} to populate the {@link VMDefinitionsContainer} from
* @param container the {@link VMDefinitionsContainer} to populate from the {@link Element}
*/
private static void populateVMTypes(Element vmTypeElement, VMDefinitionsContainer container) {
// Retrieve the 'id' attribute and the corresponding VM type object
String id = vmTypeElement.getAttribute("id"); //$NON-NLS-1$
IVMInstallType vmType= JavaRuntime.getVMInstallType(id);
if (vmType != null) {
// For each VM child node, populate the container with a subordinate node
NodeList vmNodeList = vmTypeElement.getElementsByTagName("vm"); //$NON-NLS-1$
for (int i = 0; i < vmNodeList.getLength(); ++i) {
populateVMForType(vmType, (Element) vmNodeList.item(i), container);
}
} else {
// status information for removed VMs (missing VM type)
NodeList vmNodeList = vmTypeElement.getElementsByTagName("vm"); //$NON-NLS-1$
for (int i = 0; i < vmNodeList.getLength(); ++i) {
Element vmElement = (Element) vmNodeList.item(i);
String installPath= vmElement.getAttribute("path"); //$NON-NLS-1$
String name = vmElement.getAttribute("name"); //$NON-NLS-1$
IStatus status = null;
if (name != null) {
status = new Status(IStatus.INFO, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_0, new String[]{name}));
} else if (installPath != null) {
status = new Status(IStatus.INFO, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_0, new String[]{installPath}));
} else {
status = new Status(IStatus.INFO, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_2, new String[]{id}));
}
container.addStatus(status);
}
}
}
/**
* Parse the specified VM node, create a VMStandin for it, and add this to the
* specified container.
*
* @param vmType VM type
* @param vmElement XML element
* @param container container to add VM to
*/
private static void populateVMForType(IVMInstallType vmType, Element vmElement, VMDefinitionsContainer container) {
String id= vmElement.getAttribute("id"); //$NON-NLS-1$
if (id != null) {
// Retrieve the 'path' attribute. If none, skip this node.
String installPath= vmElement.getAttribute("path"); //$NON-NLS-1$
String name = vmElement.getAttribute("name"); //$NON-NLS-1$
if (name == null) {
if (installPath == null) {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_3, new String[]{vmType.getName()})));
return;
}
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN, NLS.bind(LaunchingMessages.VMDefinitionsContainer_4, new String[]{installPath})));
return;
}
if (installPath == null) {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_5, new String[]{name})));
return;
}
// Create a VMStandin for the node and set its 'name' & 'installLocation' attributes
VMStandin vmStandin = new VMStandin(vmType, id);
vmStandin.setName(name);
File installLocation= new File(installPath);
vmStandin.setInstallLocation(installLocation);
String install = installLocation.getAbsolutePath();
//only consider a VM changed it is a standard VM
boolean changed = StandardVMType.ID_STANDARD_VM_TYPE.equals(vmType.getId()) &&
LaunchingPlugin.timeStampChanged(install);
container.addVM(vmStandin);
// Look for subordinate nodes. These may be 'libraryLocation',
// 'libraryLocations' or 'versionInfo'.
if(!changed) {
NodeList list = vmElement.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 subElement = (Element)node;
String subElementName = subElement.getNodeName();
if (subElementName.equals("libraryLocation")) { //$NON-NLS-1$
LibraryLocation loc = getLibraryLocation(subElement);
vmStandin.setLibraryLocations(new LibraryLocation[]{loc});
} else if (subElementName.equals("libraryLocations")) { //$NON-NLS-1$
setLibraryLocations(vmStandin, subElement);
} else if (subElementName.equals("attributeMap")) { //$NON-NLS-1$
NodeList entries = subElement.getElementsByTagName("entry"); //$NON-NLS-1$
for (int j = 0; j < entries.getLength(); j++) {
Node entryNode = entries.item(j);
if (entryNode instanceof Element) {
Element entryElement = (Element) entryNode;
String key = entryElement.getAttribute("key"); //$NON-NLS-1$
String value = entryElement.getAttribute("value"); //$NON-NLS-1$
if (key != null && value != null) {
vmStandin.setAttribute(key, value);
}
}
}
}
}
// javadoc URL
String externalForm = vmElement.getAttribute("javadocURL"); //$NON-NLS-1$
if (externalForm != null && externalForm.length() > 0) {
try {
vmStandin.setJavadocLocation(new URL(externalForm));
} catch (MalformedURLException e) {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_6, new String[]{name}), e));
}
}
}
}
// VM Arguments
String vmArgs = vmElement.getAttribute("vmargs"); //$NON-NLS-1$
if (vmArgs != null && vmArgs.length() >0) {
vmStandin.setVMArgs(vmArgs);
}
} else {
String installPath= vmElement.getAttribute("path"); //$NON-NLS-1$
String name = vmElement.getAttribute("name"); //$NON-NLS-1$
if (name != null) {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_7, new String[]{name})));
} else if (installPath != null) {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_7, new String[]{installPath})));
} else {
container.addStatus(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
NLS.bind(LaunchingMessages.VMDefinitionsContainer_9, new String[]{vmType.getName()})));
}
}
}
/**
* Create & return a LibraryLocation object populated from the attribute values
* in the specified node.
*
* @param libLocationElement the {@link Element} to parse the {@link LibraryLocation} from
* @return the new {@link LibraryLocation} or <code>null</code> if the {@link Element} was malformed
*/
private static LibraryLocation getLibraryLocation(Element libLocationElement) {
String jreJar= libLocationElement.getAttribute("jreJar"); //$NON-NLS-1$
String jreSrc= libLocationElement.getAttribute("jreSrc"); //$NON-NLS-1$
String pkgRoot= libLocationElement.getAttribute("pkgRoot"); //$NON-NLS-1$
String jreJavadoc= libLocationElement.getAttribute("jreJavadoc"); //$NON-NLS-1$
String jreIndex= libLocationElement.getAttribute("jreIndex"); //$NON-NLS-1$
String externalAnns = libLocationElement.getAttribute("jreExternalAnns"); //$NON-NLS-1$
// javadoc URL
URL javadocURL= null;
if (jreJavadoc.length() == 0) {
jreJavadoc= null;
} else {
try {
javadocURL= new URL(jreJavadoc);
} catch (MalformedURLException e) {
LaunchingPlugin.log("Library location javadoc element is specified incorrectly."); //$NON-NLS-1$
}
}
// index URL
URL indexURL= null;
if (jreIndex.length() == 0) {
jreIndex= null;
} else {
try {
indexURL= new URL(jreIndex);
} catch (MalformedURLException e) {
LaunchingPlugin.log("Library location jre index element is specified incorrectly."); //$NON-NLS-1$
}
}
if (jreJar != null && jreSrc != null && pkgRoot != null) {
return new LibraryLocation(new Path(jreJar), new Path(jreSrc), new Path(pkgRoot), javadocURL, indexURL
, externalAnns == null ? null : new Path(externalAnns));
}
LaunchingPlugin.log("Library location element is specified incorrectly."); //$NON-NLS-1$
return null;
}
/**
* Set the LibraryLocations on the specified VM, by extracting the subordinate
* nodes from the specified 'lirbaryLocations' node.
*
* @param vm the {@link IVMInstall} to populate from the given {@link Element}
* @param libLocationsElement the {@link Element} to populate the {@link IVMInstall} with
*/
private static void setLibraryLocations(IVMInstall vm, Element libLocationsElement) {
NodeList list = libLocationsElement.getChildNodes();
int length = list.getLength();
List<LibraryLocation> locations = new ArrayList<>(length);
for (int i = 0; i < length; ++i) {
Node node = list.item(i);
short type = node.getNodeType();
if (type == Node.ELEMENT_NODE) {
Element libraryLocationElement= (Element)node;
if (libraryLocationElement.getNodeName().equals("libraryLocation")) { //$NON-NLS-1$
locations.add(getLibraryLocation(libraryLocationElement));
}
}
}
vm.setLibraryLocations(locations.toArray(new LibraryLocation[locations.size()]));
}
/**
* Removes the VM from this container.
*
* @param vm VM install
*/
public void removeVM(IVMInstall vm) {
fVMList.remove(vm);
fInvalidVMList.remove(vm);
List<IVMInstall> list = fVMTypeToVMMap.get(vm.getVMInstallType());
if (list != null) {
list.remove(vm);
}
}
private void addStatus(IStatus status) {
if (fStatus == null) {
fStatus = new MultiStatus(LaunchingPlugin.ID_PLUGIN, 0, LaunchingMessages.VMDefinitionsContainer_10, null);
}
fStatus.add(status);
}
/**
* Returns status from parsing VM installs or <code>null</code> if none.
*
* @return status or <code>null</code>
*/
public IStatus getStatus() {
return fStatus;
}
}