| /******************************************************************************* |
| * Copyright (c) 2002, 2004 GEBIT Gesellschaft fuer EDV-Beratung |
| * und Informatik-Technologien mbH, |
| * Berlin, Duesseldorf, Frankfurt (Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation |
| * IBM Corporation - bug fixes |
| *******************************************************************************/ |
| |
| package org.eclipse.ant.internal.ui.editor; |
| |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.eclipse.ant.internal.ui.model.AntUIPlugin; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.Text; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * The <code>TaskDescriptionProvider</code> provides the additional descriptions |
| * for tasks and attributes for the code assist. |
| * <P> |
| * Descriptions for task are originally provided with the XML file |
| * <code>TASKS_DESCRIPTION_XML_FILE_NAME</code>. This file is parsed by the |
| * provider and requested descriptions are returned. |
| * <P> |
| * Check out the documentation for the public methods of this class. |
| * |
| */ |
| public class TaskDescriptionProvider { |
| |
| /** |
| * The file that contains all task descriptions. |
| */ |
| public static String TASKS_DESCRIPTION_XML_FILE_NAME = "/anttasks_1.6.0.xml"; //$NON-NLS-1$ |
| |
| public static String XML_TAG_TASKS = "tasks"; //$NON-NLS-1$ |
| public static String XML_TAG_TASK = "task"; //$NON-NLS-1$ |
| public static String XML_TAG_ELEMENTS = "elements"; //$NON-NLS-1$ |
| public static String XML_TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$ |
| public static String XML_TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$ |
| public static String XML_TAG_ELEMENT = "element"; //$NON-NLS-1$ |
| public static String XML_TAG_STRUCTURE = "structure"; //$NON-NLS-1$ |
| public static String XML_TAG_DESCRIPTION = "description"; //$NON-NLS-1$ |
| public static String XML_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ |
| public static String XML_ATTRIBUTE_REQUIRED = "required"; //$NON-NLS-1$ |
| |
| private static TaskDescriptionProvider fgDefault; |
| |
| protected Map taskNodes = new HashMap(); |
| |
| /** |
| * Meant to be a singleton |
| */ |
| private TaskDescriptionProvider() { |
| initialize(); |
| } |
| |
| public static TaskDescriptionProvider getDefault() { |
| if (fgDefault == null) { |
| fgDefault= new TaskDescriptionProvider(); |
| } |
| return fgDefault; |
| } |
| |
| /** |
| * Parses the task description xml file and stores the information. |
| */ |
| protected void initialize() { |
| Document tempDocument = parseFile(TASKS_DESCRIPTION_XML_FILE_NAME); |
| Node tempRootNode = tempDocument.getDocumentElement(); |
| NodeList tempChildNodes = tempRootNode.getChildNodes(); |
| for(int i=0; i<tempChildNodes.getLength(); i++) { |
| Node tempNode = tempChildNodes.item(i); |
| if(tempNode.getNodeType() == Node.ELEMENT_NODE) { |
| String tempTagName = tempNode.getNodeName(); |
| if(tempTagName.equals(XML_TAG_TASK)) { |
| NamedNodeMap tempAttributes = tempNode.getAttributes(); |
| Node tempAttributeNode = tempAttributes.getNamedItem(XML_ATTRIBUTE_NAME); |
| if(tempAttributeNode != null) { |
| String tempTaskName = tempAttributeNode.getNodeValue(); |
| if(tempTaskName != null) { |
| taskNodes.put(tempTaskName, tempNode); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| /** |
| * Returns the (DOM) document as a result of parsing the file with the |
| * specified file name. |
| * <P> |
| * The file will be loaded as resource, thus must begin with '/' and must |
| * be relative to the classpath. |
| */ |
| protected Document parseFile(String aFileName) { |
| Document tempDocument = null; |
| |
| DocumentBuilderFactory tempFactory = DocumentBuilderFactory.newInstance(); |
| tempFactory.setIgnoringComments(true); |
| tempFactory.setIgnoringElementContentWhitespace(true); |
| tempFactory.setCoalescing(true); |
| |
| try { |
| DocumentBuilder tempDocBuilder = tempFactory.newDocumentBuilder(); |
| URL tempURL = getClass().getResource(aFileName); |
| InputSource tempInputSource = new InputSource(tempURL.toExternalForm()); |
| tempDocument = tempDocBuilder.parse(tempInputSource); |
| } catch (ParserConfigurationException e) { |
| AntUIPlugin.log(e); |
| } |
| catch (IOException ioException) { |
| AntUIPlugin.log(ioException); |
| } |
| catch (SAXException saxException) { |
| AntUIPlugin.log(saxException); |
| } |
| |
| return tempDocument; |
| } |
| |
| /** |
| * Returns the description string for the specified task. |
| * |
| * @return description string or <code>null</code> if task not known or |
| * no description available. |
| */ |
| public String getDescriptionForTask(String aTaskName) { |
| Element taskElement = (Element)taskNodes.get(aTaskName); |
| if(taskElement != null) { |
| return getDescriptionOfNode(taskElement); |
| } |
| return null; |
| } |
| |
| |
| /** |
| * Returns the description of the specified node. |
| * <P> |
| * The node must be either one of task node or attribute node. |
| */ |
| protected String getDescriptionOfNode(Node aNode) { |
| NodeList tempChildNodes = aNode.getChildNodes(); |
| for (int i=0; i<tempChildNodes.getLength(); i++) { |
| Node tempNode = tempChildNodes.item(i); |
| if(tempNode instanceof Element && XML_TAG_DESCRIPTION.equals(tempNode.getNodeName())) { |
| Element tempDescriptionElement = (Element)tempNode; |
| Node tempChildNode = tempDescriptionElement.getFirstChild(); |
| if(tempChildNode instanceof Text) { |
| return ((Text)tempChildNode).getData(); |
| } |
| break; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the Required value of the specified node. |
| * <P> |
| * Currently the XML file has Required defined as NOTDEFINED in |
| * some cases. If so the value returned is an empty string |
| */ |
| protected String getRequiredOfNode(Node aNode) { |
| |
| String tmpNodeName = aNode.getNodeName(); |
| String tmpRequiredValue = null; |
| |
| if(aNode.getNodeType() == Node.ELEMENT_NODE && |
| (XML_TAG_ATTRIBUTE.equals(tmpNodeName) || XML_TAG_ELEMENT.equals(tmpNodeName)) ) { |
| |
| tmpRequiredValue = aNode.getAttributes().getNamedItem(XML_ATTRIBUTE_REQUIRED).getNodeValue(); |
| } |
| |
| if(tmpRequiredValue == null || tmpRequiredValue.equals("NOTDEFINED")) { //$NON-NLS-1$ |
| return ""; //$NON-NLS-1$ |
| } |
| |
| return tmpRequiredValue; |
| |
| } |
| |
| |
| /** |
| * Returns the description string for the specified attribute of the |
| * specified task. |
| * |
| * @return description string or <code>null</code> if task or attribute |
| * not known or no description available. |
| */ |
| public String getDescriptionForTaskAttribute(String aTaskName, String anAttributeName) { |
| |
| String tmpDescription = null; |
| |
| Node tmpAttributesNode = getAttributesNode(aTaskName); |
| |
| if(tmpAttributesNode != null) { |
| |
| tmpDescription = getDescriptionForNodeNamedWithNameInNodeList( XML_TAG_ATTRIBUTE, anAttributeName, |
| tmpAttributesNode.getChildNodes()); |
| //If Description is null we try the elements section else we're satisfied. |
| if( tmpDescription != null ) { |
| return tmpDescription; |
| } |
| } |
| //Not yet found. Try the elements Node |
| tmpAttributesNode = getElementsNode(aTaskName); |
| if(tmpAttributesNode != null) { |
| tmpDescription = getDescriptionForNodeNamedWithNameInNodeList( XML_TAG_ELEMENT, anAttributeName, |
| tmpAttributesNode.getChildNodes()); |
| |
| return tmpDescription; |
| |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the required string value for the specified attribute of the |
| * specified task. |
| * |
| * @return required string or <code>null</code> if task or attribute not |
| * known or no description available. |
| */ |
| public String getRequiredAttributeForTaskAttribute(String aTaskName, String anAttributeName) { |
| |
| String tmpRequired = null; |
| |
| Node tmpAttributesNode = getAttributesNode(aTaskName); |
| |
| if(tmpAttributesNode != null) { |
| |
| tmpRequired = getRequiredForNodeNamedWithNameInNodeList( XML_TAG_ATTRIBUTE, anAttributeName, |
| tmpAttributesNode.getChildNodes()); |
| |
| //If Required is null we try the elements section else we're satisfied. |
| if( tmpRequired != null ) { |
| return tmpRequired; |
| } |
| } |
| |
| //Not yet found. Try the elements Node |
| tmpAttributesNode = getElementsNode(aTaskName); |
| if(tmpAttributesNode != null) { |
| tmpRequired = getDescriptionForNodeNamedWithNameInNodeList( XML_TAG_ELEMENT, anAttributeName, |
| tmpAttributesNode.getChildNodes()); |
| //Return it even if its null |
| return tmpRequired; |
| |
| } |
| |
| //Not found return null |
| return null; |
| } |
| |
| /** |
| * Returns the Elements Node of the specified TaskName |
| * |
| * @param aTaskName The name of the task |
| * @return The Elements Node of the Task. |
| */ |
| protected Node getElementsNode(String aTaskName) { |
| |
| Node tmpStructureNode = getStructureNode(aTaskName); |
| if(tmpStructureNode != null) { |
| return getChildNodeNamedOfTypeFromNode(XML_TAG_ELEMENTS, Node.ELEMENT_NODE, |
| tmpStructureNode); |
| } |
| else { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the Attributes Node of the specified TaskName |
| * |
| * @param aTaskName The name of the task |
| * @return The Attributes Node of the Task or <code>null</code> if one |
| * does not exist. |
| */ |
| protected Node getAttributesNode(String aTaskName) { |
| |
| Node tmpStructureNode = getStructureNode(aTaskName); |
| if(tmpStructureNode != null){ |
| return getChildNodeNamedOfTypeFromNode(XML_TAG_ATTRIBUTES, Node.ELEMENT_NODE, |
| tmpStructureNode); |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the Structure Node of the specified TaskName |
| * |
| * @param aTaskName The name of the task |
| * @return The Structure Node of the Task. |
| */ |
| protected Node getStructureNode(String aTaskName) { |
| Element taskElement = (Element)taskNodes.get(aTaskName); |
| if(taskElement != null) { |
| //Dig us down to the Structure node |
| Node structureNode = getChildNodeNamedOfTypeFromNode(XML_TAG_STRUCTURE, Node.ELEMENT_NODE, |
| taskElement); |
| return structureNode; |
| } |
| else { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the Description for a Node satisfying the criterias in the |
| * NodeList given as Argument. |
| * |
| * @param aNodeName The Name of the Node |
| * @param anAttributeName The string of the Name value |
| * @param anAttributesNodeList The NodeList to search in. |
| * @return The Description found or null if none is found |
| */ |
| protected String getDescriptionForNodeNamedWithNameInNodeList( String aNodeName, String anAttributeName, |
| NodeList anAttributesNodeList) { |
| for (int i=0; i<anAttributesNodeList.getLength(); i++) { |
| Node tempNode = anAttributesNodeList.item(i); |
| if(tempNode.getNodeType() == Node.ELEMENT_NODE && aNodeName.equals(tempNode.getNodeName())) { |
| if( anAttributeName.equals(getTaskAttributeName(tempNode)) ) { |
| return getDescriptionOfNode(tempNode); |
| } |
| } |
| } |
| |
| //Not found |
| return null; |
| } |
| |
| |
| /** |
| * Returns the Name of Task Attribute. |
| * |
| * @return The Name of the Attribute. |
| */ |
| public String getTaskAttributeName(Node aTaskAttributeNode) { |
| NamedNodeMap tmpNamedNodeMap = aTaskAttributeNode.getAttributes(); |
| return tmpNamedNodeMap.getNamedItem(XML_ATTRIBUTE_NAME).getNodeValue(); |
| } |
| |
| /** |
| * Returns the ChildNode of the node defined by the Arguments. The |
| * first child found matching the criterias is returned. |
| * |
| * @param aNodeName The Name of the Node to return. |
| * @param aType The Type of the node @see Node |
| * @param aParentNode The Node to get the child from |
| * |
| * @return The First Child Node found matching the criterias, |
| * or null if none is found. |
| */ |
| protected Node getChildNodeNamedOfTypeFromNode(String aNodeName, short aNodeType, Node aParentNode) { |
| |
| NodeList tmpNodeList = aParentNode.getChildNodes(); |
| for(int i=0; i<tmpNodeList.getLength(); ++i ) { |
| Node tmpNode = tmpNodeList.item(i); |
| if( (tmpNode.getNodeType() == aNodeType) && aNodeName.equals(tmpNode.getNodeName()) ) { |
| return tmpNode; |
| } |
| } |
| //Not found |
| return null; |
| } |
| |
| /** |
| * Returns the Required Field for a Node satisfying the criterias in the |
| * NodeList given as Argument. |
| * |
| * @param aNodeName The Name of the Node |
| * @param anAttributeName The string of the Name value |
| * @param anAttributesNodeList The NodeList to search in. |
| * @return The Description found or null if none is found |
| */ |
| protected String getRequiredForNodeNamedWithNameInNodeList( String aNodeName, String anAttributeName, |
| NodeList anAttributesNodeList) { |
| for (int i=0; i<anAttributesNodeList.getLength(); i++) { |
| Node tempNode = anAttributesNodeList.item(i); |
| if(tempNode.getNodeType() == Node.ELEMENT_NODE && aNodeName.equals(tempNode.getNodeName())) { |
| if( anAttributeName.equals(getTaskAttributeName(tempNode)) ) { |
| return getRequiredOfNode(tempNode); |
| } |
| } |
| } |
| |
| //Not found |
| return null; |
| } |
| } |