| /******************************************************************************* |
| * Copyright (c) 2000, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.launching; |
| |
| import java.io.BufferedInputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.TransformerException; |
| |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.dltk.launching.EnvironmentVariable; |
| import org.eclipse.dltk.launching.IInterpreterInstall; |
| import org.eclipse.dltk.launching.IInterpreterInstallType; |
| import org.eclipse.dltk.launching.InterpreterStandin; |
| import org.eclipse.dltk.launching.LaunchingMessages; |
| import org.eclipse.dltk.launching.LibraryLocation; |
| import org.eclipse.dltk.launching.ScriptRuntime; |
| 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 interpreter definitions such as the interpreter |
| * 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> |
| */ |
| public class InterpreterDefinitionsContainer { |
| |
| private static final String PATH_ATTR = "path"; |
| private static final String INTERPRETER_NAME_ATTR = "name"; |
| private static final String INTERPRETER_TAG = "interpreter"; |
| private static final String INTERPRETER_TYPE_TAG = "interpreterType"; |
| private static final String ID_ATTR = "id"; |
| private static final String NATURE_ATTR = "nature"; |
| private static final String DEFAULT_INTERPRETER_TAG = "defaultInterpreter"; |
| private static final String INTERPRETER_SETTINGS_TAG = "interpreterSettings"; |
| private static final String VARIABLE_VALUE_ATTR = "variableValue"; |
| private static final String VARIABLE_NAME_ATTR = "variableName"; |
| private static final String LIBRARY_PATH_ATTR = "libraryPath"; |
| private static final String IARGS_ATTR = "iargs"; |
| private static final String ENVIRONMENT_VARIABLES_TAG = "environmentVariables"; |
| private static final String ENVIRONMENT_VARIABLE_TAG = "environmentVariable"; |
| private static final String LIBRARY_LOCATIONS_TAG = "libraryLocations"; |
| private static final String LIBRARY_LOCATION_TAG = "libraryLocation"; |
| |
| /** |
| * Map of InterpreterInstallTypes to Lists of corresponding |
| * InterpreterInstalls. |
| */ |
| private Map fInterTypeToInterMap; |
| |
| /** |
| * Cached list of Interpreters in this container |
| */ |
| private List fInterpreterList; |
| |
| /** |
| * Interpreters managed by this container whose install locations don't |
| * actually exist. |
| */ |
| private List fInvalidInterpreterList; |
| |
| /** |
| * The composite identifier of the default Interpreter. This consists of the |
| * install type ID plus an ID for the Interpreter. |
| */ |
| // map bind default interpreter to each nature |
| private Map fDefaultInterpreterInstallCompositeID; |
| |
| /** |
| * The identifier of the connector to use for the default Interpreter. |
| */ |
| // map bind default connector to each nature |
| private Map fDefaultInterpreterInstallConnectorTypeID; |
| |
| /** |
| * Constructs an empty Interpreter container |
| */ |
| public InterpreterDefinitionsContainer() { |
| fInterTypeToInterMap = new HashMap(10); |
| fInvalidInterpreterList = new ArrayList(10); |
| fInterpreterList = new ArrayList(10); |
| fDefaultInterpreterInstallCompositeID = new HashMap(); |
| fDefaultInterpreterInstallConnectorTypeID = new HashMap(); |
| } |
| |
| /** |
| * Returns list of default interpreters natures TODO: rename |
| * |
| * @return |
| */ |
| public String[] getInterpreterNatures() { |
| Set s = fDefaultInterpreterInstallCompositeID.keySet(); |
| return (String[]) s.toArray(new String[s.size()]); |
| } |
| |
| /** |
| * Add the specified Interpreter to the Interpreter definitions managed by |
| * this container. |
| * <p> |
| * If distinguishing valid from invalid Interpreters is important, the |
| * specified Interpreter must have already had its install location set. An |
| * invalid Interpreter is one whose install location doesn't exist. |
| * </p> |
| * |
| * @param Interpreter |
| * the Interpreter to be added to this container |
| */ |
| public void addInterpreter(IInterpreterInstall Interpreter) { |
| if (!fInterpreterList.contains(Interpreter)) { |
| IInterpreterInstallType InterpreterInstallType = Interpreter |
| .getInterpreterInstallType(); |
| List InterpreterList = (List) fInterTypeToInterMap |
| .get(InterpreterInstallType); |
| if (InterpreterList == null) { |
| InterpreterList = new ArrayList(3); |
| fInterTypeToInterMap.put(InterpreterInstallType, |
| InterpreterList); |
| } |
| InterpreterList.add(Interpreter); |
| File installLocation = Interpreter.getInstallLocation(); |
| if (installLocation == null |
| || !InterpreterInstallType.validateInstallLocation( |
| installLocation).isOK()) { |
| fInvalidInterpreterList.add(Interpreter); |
| } |
| fInterpreterList.add(Interpreter); |
| } |
| } |
| |
| /** |
| * Add all Interpreter's in the specified list to the Interpreter |
| * definitions managed by this container. |
| * <p> |
| * If distinguishing valid from invalid Interpreters is important, the |
| * specified Interpreters must have already had their install locations set. |
| * An invalid Interpreter is one whose install location doesn't exist. |
| * </p> |
| * |
| * @param InterpreterList |
| * a list of Interpreters to be added to this container |
| */ |
| public void addInterpreterList(List InterpreterList) { |
| Iterator iterator = InterpreterList.iterator(); |
| while (iterator.hasNext()) { |
| IInterpreterInstall Interpreter = (IInterpreterInstall) iterator |
| .next(); |
| addInterpreter(Interpreter); |
| } |
| } |
| |
| /** |
| * Return a mapping of Interpreter install types to lists of Interpreters. |
| * The keys of this map are instances of |
| * <code>IInterpreterInstallType</code>. The values are instances of |
| * <code>java.util.List</code> which contain instances of |
| * <code>IInterpreterInstall</code>. |
| * |
| * @return Map the mapping of Interpreter install types to lists of |
| * Interpreters |
| */ |
| public Map getInterpreterTypeToInterpreterMap() { |
| return fInterTypeToInterMap; |
| } |
| |
| /** |
| * Return a list of all Interpreters in this container, including any |
| * invalid Interpreters. An invalid Interpreter 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 Interpreters managed by |
| * this container |
| */ |
| public List getInterpreterList() { |
| return fInterpreterList; |
| } |
| |
| /** |
| * Return filtered list of all Interpreters in this container, including any |
| * invalid Interpreters. An invalid Interpreter 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 Interpreters managed by |
| * this container |
| */ |
| public List getInterpreterList(String nature) { |
| List res = new ArrayList(fInterpreterList.size()); |
| for (Iterator iter = fInterpreterList.iterator(); iter.hasNext();) { |
| IInterpreterInstall Interpreter = (IInterpreterInstall) iter.next(); |
| if (Interpreter.getInterpreterInstallType().getNatureId().equals( |
| nature)) |
| res.add(Interpreter); |
| } |
| return res; |
| } |
| |
| /** |
| * Return a list of all valid Interpreters in this container. A valid |
| * Interpreter is one whose install location exists on the file system. The |
| * order of the list is not specified. |
| * |
| * @return List |
| */ |
| public List getValidInterpreterList() { |
| List Interpreters = getInterpreterList(); |
| List resultList = new ArrayList(Interpreters.size()); |
| resultList.addAll(Interpreters); |
| resultList.removeAll(fInvalidInterpreterList); |
| return resultList; |
| } |
| |
| /** |
| * Return filtered list of valid Interpreters in this container. A valid |
| * Interpreter is one whose install location exists on the file system. The |
| * order of the list is not specified. |
| * |
| * @return List |
| */ |
| public List getValidInterpreterList(String nature) { |
| List Interpreters = getInterpreterList(nature); |
| List resultList = new ArrayList(Interpreters.size()); |
| resultList.addAll(Interpreters); |
| resultList.removeAll(fInvalidInterpreterList); |
| return resultList; |
| } |
| |
| /** |
| * Returns the composite ID for the default Interpreter. The composite ID |
| * consists of an ID for the Interpreter install type together with an ID |
| * for Interpreter. This is necessary because Interpreter ids by themselves |
| * are not necessarily unique across Interpreter install types. |
| * |
| * @return String returns the composite ID of the current default |
| * Interpreter |
| */ |
| public String getDefaultInterpreterInstallCompositeID(String nature) { |
| return (String) fDefaultInterpreterInstallCompositeID.get(nature); |
| } |
| |
| public String[] getDefaultInterpreterInstallCompositeID() { |
| Collection ids = fDefaultInterpreterInstallCompositeID.values(); |
| return (String[]) ids.toArray(new String[ids.size()]); |
| } |
| |
| /** |
| * Sets the composite ID for the default Interpreter. The composite ID |
| * consists of an ID for the Interpreter install type together with an ID |
| * for Interpreter. This is necessary because Interpreter ids by themselves |
| * are not necessarily unique across Interpreter install types. |
| * |
| * @param id |
| * identifies the new default Interpreter using a composite ID |
| */ |
| public void setDefaultInterpreterInstallCompositeID(String nature, String id) { |
| if (id != null) |
| fDefaultInterpreterInstallCompositeID.put(nature, id); |
| else |
| fDefaultInterpreterInstallCompositeID.remove(nature); |
| } |
| |
| /** |
| * Return the default Interpreter's connector type ID. |
| * |
| * @return String the current value of the default Interpreter's connector |
| * type ID |
| */ |
| public String getDefaultInterpreterInstallConnectorTypeID(String nature) { |
| return (String) fDefaultInterpreterInstallConnectorTypeID.get(nature); |
| } |
| |
| /** |
| * Set the default Interpreter's connector type ID. |
| * |
| * @param id |
| * the new value of the default Interpreter's connector type ID |
| */ |
| public void setDefaultInterpreterInstallConnectorTypeID(String nature, |
| String id) { |
| fDefaultInterpreterInstallConnectorTypeID.put(nature, id); |
| } |
| |
| /** |
| * Return the Interpreter 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 IOException |
| * if this method fails. Reasons include: |
| * <ul> |
| * <li>serialization of the XML document failed</li> |
| * </ul> |
| * @throws ParserConfigurationException |
| * if creation of the XML document failed |
| * @throws TransformerException |
| * if serialization of the XML document failed |
| */ |
| public String getAsXML() throws ParserConfigurationException, IOException, |
| TransformerException { |
| |
| // Create the Document and the top-level node |
| Document doc = DLTKLaunchingPlugin.getDocument(); |
| Element config = doc.createElement(INTERPRETER_SETTINGS_TAG); //$NON-NLS-1$ |
| doc.appendChild(config); |
| |
| // Set the defaultInterpreter attribute on the top-level node |
| for (Iterator iter = fDefaultInterpreterInstallCompositeID.keySet() |
| .iterator(); iter.hasNext();) { |
| String nature = (String) iter.next(); |
| Element defaulte = doc.createElement(DEFAULT_INTERPRETER_TAG); |
| config.appendChild(defaulte); |
| defaulte.setAttribute(NATURE_ATTR, nature); |
| defaulte.setAttribute(ID_ATTR, |
| (String) fDefaultInterpreterInstallCompositeID.get(nature)); |
| } |
| |
| // Set the defaultInterpreterConnector attribute on the top-level node |
| for (Iterator iter = fDefaultInterpreterInstallConnectorTypeID.keySet() |
| .iterator(); iter.hasNext();) { |
| String nature = (String) iter.next(); |
| Element defaulte = doc.createElement("defaultInterpreterConnector"); |
| config.appendChild(defaulte); |
| defaulte.setAttribute(NATURE_ATTR, nature); |
| defaulte.setAttribute(ID_ATTR, |
| (String) fDefaultInterpreterInstallConnectorTypeID |
| .get(nature)); |
| } |
| |
| // Create a node for each install type represented in this container |
| Set InterpreterInstallTypeSet = getInterpreterTypeToInterpreterMap() |
| .keySet(); |
| Iterator keyIterator = InterpreterInstallTypeSet.iterator(); |
| while (keyIterator.hasNext()) { |
| IInterpreterInstallType InterpreterInstallType = (IInterpreterInstallType) keyIterator |
| .next(); |
| Element InterpreterTypeElement = interpreterTypeAsElement(doc, |
| InterpreterInstallType); |
| config.appendChild(InterpreterTypeElement); |
| } |
| |
| // Serialize the Document and return the resulting String |
| return DLTKLaunchingPlugin.serializeDocument(doc); |
| } |
| |
| /** |
| * Create and return a node for the specified Interpreter install type in |
| * the specified Document. |
| */ |
| private Element interpreterTypeAsElement(Document doc, |
| IInterpreterInstallType InterpreterType) { |
| |
| // Create a node for the Interpreter type and set its 'id' attribute |
| Element element = doc.createElement(INTERPRETER_TYPE_TAG); //$NON-NLS-1$ |
| element.setAttribute(ID_ATTR, InterpreterType.getId()); //$NON-NLS-1$ |
| |
| // For each Interpreter of the specified type, create a subordinate node |
| // for it |
| List InterpreterList = (List) getInterpreterTypeToInterpreterMap().get( |
| InterpreterType); |
| Iterator InterpreterIterator = InterpreterList.iterator(); |
| while (InterpreterIterator.hasNext()) { |
| IInterpreterInstall Interpreter = (IInterpreterInstall) InterpreterIterator |
| .next(); |
| Element InterpreterElement = interpreterAsElement(doc, Interpreter); |
| element.appendChild(InterpreterElement); |
| } |
| |
| return element; |
| } |
| |
| /** |
| * Create and return a node for the specified Interpreter in the specified |
| * Document. |
| */ |
| private Element interpreterAsElement(Document doc, |
| IInterpreterInstall Interpreter) { |
| |
| // Create the node for the Interpreter and set its 'id' & 'name' |
| // attributes |
| Element element = doc.createElement(INTERPRETER_TAG); //$NON-NLS-1$ |
| element.setAttribute(ID_ATTR, Interpreter.getId()); //$NON-NLS-1$ |
| element.setAttribute(INTERPRETER_NAME_ATTR, Interpreter.getName()); //$NON-NLS-1$ |
| |
| // Determine and set the 'path' attribute for the Interpreter |
| String installPath = ""; //$NON-NLS-1$ |
| File installLocation = Interpreter.getRawInstallLocation(); |
| if (installLocation != null) { |
| installPath = installLocation.toString(); |
| } |
| element.setAttribute(PATH_ATTR, installPath); //$NON-NLS-1$ |
| |
| // If the 'libraryLocations' attribute is specified, create a node for |
| // it |
| LibraryLocation[] libraryLocations = Interpreter.getLibraryLocations(); |
| if (libraryLocations != null) { |
| Element libLocationElement = libraryLocationsAsElement(doc, |
| libraryLocations); |
| element.appendChild(libLocationElement); |
| } |
| |
| EnvironmentVariable[] environmentVariables = Interpreter |
| .getEnvironmentVariables(); |
| if (environmentVariables != null) { |
| Element environmentVariableElement = environmentVariablesAsElement( |
| doc, environmentVariables); |
| element.appendChild(environmentVariableElement); |
| } |
| |
| String[] InterpreterArgs = Interpreter.getInterpreterArguments(); |
| if (InterpreterArgs != null && InterpreterArgs.length > 0) { |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0; i < InterpreterArgs.length; i++) { |
| buffer.append(InterpreterArgs[i] + " "); //$NON-NLS-1$ |
| } |
| element.setAttribute(IARGS_ATTR, buffer.toString()); //$NON-NLS-1$ |
| } |
| |
| return element; |
| } |
| |
| /** |
| * Create and return a 'libraryLocations' node. This node owns subordinate |
| * nodes that list individual library locations. |
| */ |
| private static Element libraryLocationsAsElement(Document doc, |
| LibraryLocation[] locations) { |
| Element root = doc.createElement(LIBRARY_LOCATIONS_TAG); //$NON-NLS-1$ |
| for (int i = 0; i < locations.length; i++) { |
| Element element = doc.createElement(LIBRARY_LOCATION_TAG); //$NON-NLS-1$ |
| element.setAttribute(LIBRARY_PATH_ATTR, locations[i] |
| .getLibraryPath().toString()); //$NON-NLS-1$ |
| root.appendChild(element); |
| } |
| return root; |
| } |
| |
| private static Element environmentVariablesAsElement(Document doc, |
| EnvironmentVariable[] variables) { |
| Element root = doc.createElement(ENVIRONMENT_VARIABLES_TAG); //$NON-NLS-1$ |
| for (int i = 0; i < variables.length; i++) { |
| Element element = doc.createElement(ENVIRONMENT_VARIABLE_TAG); //$NON-NLS-1$ |
| element.setAttribute(VARIABLE_NAME_ATTR, variables[i].getName()); //$NON-NLS-1$ |
| element.setAttribute(VARIABLE_VALUE_ATTR, variables[i].getValue()); //$NON-NLS-1$ |
| root.appendChild(element); |
| } |
| return root; |
| } |
| |
| public static InterpreterDefinitionsContainer parseXMLIntoContainer( |
| InputStream inputStream) throws IOException { |
| InterpreterDefinitionsContainer container = new InterpreterDefinitionsContainer(); |
| parseXMLIntoContainer(inputStream, container); |
| return container; |
| } |
| |
| /** |
| * Parse the Interpreter definitions contained in the specified InputStream |
| * into the specified container. |
| * <p> |
| * The Interpreters in the returned container are instances of |
| * <code>InterpreterStandin</code>. |
| * </p> |
| * <p> |
| * This method has no side-effects. That is, no notifications are sent for |
| * Interpreter 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 sematically 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 Interpreters and a default Interpreter |
| * @param container |
| * the container to add the Interpreter defs to |
| * @return InterpreterDefinitionsContainer a container for the Interpreter |
| * objects declared in <code>inputStream</code> |
| * @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 'InterpreterSettings'</li> |
| * </ul> |
| * |
| */ |
| public static void parseXMLIntoContainer(InputStream inputStream, |
| InterpreterDefinitionsContainer container) throws IOException { |
| |
| // Wrapper the stream for efficient parsing |
| InputStream stream = new BufferedInputStream(inputStream); |
| |
| // Do the parsing and obtain the top-level node |
| Element config = null; |
| try { |
| DocumentBuilder parser = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder(); |
| parser.setErrorHandler(new DefaultHandler()); |
| config = parser.parse(new InputSource(stream)).getDocumentElement(); |
| } catch (SAXException e) { |
| throw new IOException(LaunchingMessages.ScriptRuntime_badFormat); |
| } catch (ParserConfigurationException e) { |
| stream.close(); |
| throw new IOException(LaunchingMessages.ScriptRuntime_badFormat); |
| } finally { |
| stream.close(); |
| } |
| |
| // If the top-level node wasn't what we expected, bail out |
| if (!config.getNodeName().equalsIgnoreCase(INTERPRETER_SETTINGS_TAG)) { //$NON-NLS-1$ |
| throw new IOException(LaunchingMessages.ScriptRuntime_badFormat); |
| } |
| |
| // Traverse the parsed structure and populate the InterpreterType to |
| // Interpreter 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 InterpreterTypeElement = (Element) node; |
| if (InterpreterTypeElement.getNodeName().equalsIgnoreCase( |
| INTERPRETER_TYPE_TAG)) { //$NON-NLS-1$ |
| populateInterpreterTypes(InterpreterTypeElement, container); |
| } |
| if (InterpreterTypeElement.getNodeName().equalsIgnoreCase( |
| DEFAULT_INTERPRETER_TAG)) { //$NON-NLS-1$ |
| String nature = InterpreterTypeElement |
| .getAttribute(NATURE_ATTR); |
| String id = InterpreterTypeElement.getAttribute(ID_ATTR); |
| container.setDefaultInterpreterInstallCompositeID(nature, |
| id); |
| } |
| if (InterpreterTypeElement.getNodeName().equalsIgnoreCase( |
| "defaultInterpreterConnector")) { //$NON-NLS-1$ |
| String nature = InterpreterTypeElement |
| .getAttribute(NATURE_ATTR); |
| String id = InterpreterTypeElement.getAttribute(ID_ATTR); |
| container.setDefaultInterpreterInstallConnectorTypeID( |
| nature, id); |
| } |
| } |
| } |
| } |
| |
| /** |
| * For the specified Interpreter type node, parse all subordinate |
| * Interpreter definitions and add them to the specified container. |
| */ |
| private static void populateInterpreterTypes( |
| Element InterpreterTypeElement, |
| InterpreterDefinitionsContainer container) { |
| |
| // Retrieve the 'id' attribute and the corresponding Interpreter type |
| // object |
| String id = InterpreterTypeElement.getAttribute(ID_ATTR); //$NON-NLS-1$ |
| IInterpreterInstallType InterpreterType = ScriptRuntime |
| .getInterpreterInstallType(id); |
| if (InterpreterType != null) { |
| |
| // For each Interpreter child node, populate the container with a |
| // subordinate node |
| NodeList InterpreterNodeList = InterpreterTypeElement |
| .getChildNodes(); |
| for (int i = 0; i < InterpreterNodeList.getLength(); ++i) { |
| Node InterpreterNode = InterpreterNodeList.item(i); |
| short type = InterpreterNode.getNodeType(); |
| if (type == Node.ELEMENT_NODE) { |
| Element InterpreterElement = (Element) InterpreterNode; |
| if (InterpreterElement.getNodeName().equalsIgnoreCase( |
| INTERPRETER_TAG)) { //$NON-NLS-1$ |
| populateInterpreterForType(InterpreterType, |
| InterpreterElement, container); |
| } |
| } |
| } |
| } else { |
| DLTKLaunchingPlugin |
| .log("Interpreter type element with unknown id."); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Parse the specified Interpreter node, create a InterpreterStandin for it, |
| * and add this to the specified container. |
| */ |
| private static void populateInterpreterForType( |
| IInterpreterInstallType installType, Element element, |
| InterpreterDefinitionsContainer container) { |
| String id = element.getAttribute(ID_ATTR); //$NON-NLS-1$ |
| if (id != null) { |
| |
| // Retrieve the 'path' attribute. If none, skip this node. |
| String installPath = element.getAttribute(PATH_ATTR); //$NON-NLS-1$ |
| if (installPath == null) { |
| return; |
| } |
| |
| // Create a InterpreterStandin for the node and set its 'name' & |
| // 'installLocation' attributes |
| InterpreterStandin standin = new InterpreterStandin(installType, id); |
| standin.setName(element.getAttribute(INTERPRETER_NAME_ATTR)); //$NON-NLS-1$ |
| File installLocation = new File(installPath); |
| standin.setInstallLocation(installLocation); |
| container.addInterpreter(standin); |
| |
| // Look for subordinate nodes. These may be 'libraryLocation', |
| // 'libraryLocations' or 'versionInfo'. |
| NodeList list = element.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(LIBRARY_LOCATION_TAG)) { //$NON-NLS-1$ |
| LibraryLocation loc = getLibraryLocation(subElement); |
| standin |
| .setLibraryLocations(new LibraryLocation[] { loc }); |
| } else if (subElementName.equals(LIBRARY_LOCATIONS_TAG)) { //$NON-NLS-1$ |
| setLibraryLocations(standin, subElement); |
| } else if (subElementName.equals(ENVIRONMENT_VARIABLE_TAG)) { |
| EnvironmentVariable var = getEnvironmentVariable(subElement); |
| standin |
| .setEnvironmentVariables(new EnvironmentVariable[] { var }); |
| } else if (subElementName.equals(ENVIRONMENT_VARIABLES_TAG)) { |
| setEnvironmentVariables(standin, subElement); |
| } |
| } |
| } |
| |
| // Interpreter Arguments |
| String args = element.getAttribute(IARGS_ATTR); //$NON-NLS-1$ |
| if (args != null && args.length() > 0) { |
| standin.setInterpreterArgs(args); |
| } |
| } else { |
| DLTKLaunchingPlugin |
| .log("id attribute missing from Interpreter element specification."); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Create & return a LibraryLocation object populated from the attribute |
| * values in the specified node. |
| */ |
| private static LibraryLocation getLibraryLocation(Element libLocationElement) { |
| String interpreterEnvironmentArchive = libLocationElement |
| .getAttribute(LIBRARY_PATH_ATTR); //$NON-NLS-1$ |
| if (interpreterEnvironmentArchive != null) { |
| return new LibraryLocation(new Path(interpreterEnvironmentArchive)); |
| } |
| DLTKLaunchingPlugin |
| .log("Library location element is specified incorrectly."); //$NON-NLS-1$ |
| return null; |
| } |
| |
| private static EnvironmentVariable getEnvironmentVariable( |
| Element libLocationElement) { |
| String name = libLocationElement.getAttribute(VARIABLE_NAME_ATTR); //$NON-NLS-1$ |
| String value = libLocationElement.getAttribute(VARIABLE_VALUE_ATTR); //$NON-NLS-1$ |
| if (name != null && value != null) { |
| return new EnvironmentVariable(name, value); |
| } |
| DLTKLaunchingPlugin |
| .log("Environment variable element is specified incorrectly."); //$NON-NLS-1$ |
| return null; |
| } |
| |
| /** |
| * Set the LibraryLocations on the specified Interpreter, by extracting the |
| * subordinate nodes from the specified 'lirbaryLocations' node. |
| */ |
| private static void setLibraryLocations(IInterpreterInstall Interpreter, |
| Element libLocationsElement) { |
| NodeList list = libLocationsElement.getChildNodes(); |
| int length = list.getLength(); |
| List 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( |
| LIBRARY_LOCATION_TAG)) { //$NON-NLS-1$ |
| locations.add(getLibraryLocation(libraryLocationElement)); |
| } |
| } |
| } |
| Interpreter.setLibraryLocations((LibraryLocation[]) locations |
| .toArray(new LibraryLocation[locations.size()])); |
| } |
| |
| private static void setEnvironmentVariables( |
| IInterpreterInstall Interpreter, Element environmentVariablesElement) { |
| NodeList list = environmentVariablesElement.getChildNodes(); |
| int length = list.getLength(); |
| List variables = 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 envVarElement = (Element) node; |
| if (envVarElement.getNodeName().equals( |
| ENVIRONMENT_VARIABLE_TAG)) { //$NON-NLS-1$ |
| variables.add(getEnvironmentVariable(envVarElement)); |
| } |
| } |
| } |
| Interpreter.setEnvironmentVariables((EnvironmentVariable[]) variables |
| .toArray(new EnvironmentVariable[variables.size()])); |
| } |
| |
| /** |
| * Removes the Interpreter from this container. |
| * |
| * @param Interpreter |
| * Interpreter intall |
| */ |
| public void removeInterpreter(IInterpreterInstall Interpreter) { |
| fInterpreterList.remove(Interpreter); |
| fInvalidInterpreterList.remove(Interpreter); |
| List list = (List) fInterTypeToInterMap.get(Interpreter |
| .getInterpreterInstallType()); |
| if (list != null) { |
| list.remove(Interpreter); |
| } |
| } |
| |
| } |