| /******************************************************************************* |
| * 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; |
| } |
| } |