| /******************************************************************************* |
| * Copyright (c) 2000, 2013 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 - derived implementation |
| * Martin Karpisek - bug 195840 |
| *******************************************************************************/ |
| |
| package org.eclipse.ant.internal.ui.editor.utils; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.UnsupportedEncodingException; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.Location; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.ProjectHelperRepository; |
| import org.apache.tools.ant.RuntimeConfigurable; |
| import org.apache.tools.ant.Target; |
| import org.apache.tools.ant.Task; |
| import org.apache.tools.ant.UnknownElement; |
| import org.apache.tools.ant.helper.AntXMLContext; |
| import org.apache.tools.ant.helper.ProjectHelper2; |
| import org.apache.tools.ant.util.FileUtils; |
| import org.apache.tools.ant.util.JAXPUtils; |
| import org.eclipse.ant.internal.core.IAntCoreConstants; |
| import org.eclipse.ant.internal.ui.model.IAntModel; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.XMLReader; |
| import org.xml.sax.ext.LexicalHandler; |
| |
| /** |
| * Derived from the original Ant ProjectHelper2 with help from the JAXPUtils class. This class provides parsing for using a String as a source and |
| * provides handlers that will continue parsing to completion upon hitting errors. |
| */ |
| public class ProjectHelper extends ProjectHelper2 { |
| |
| /** |
| * helper for path -> URI and URI -> path conversions. |
| */ |
| private static FileUtils fu = null; |
| |
| /** |
| * The build file that is to be parsed. Must be set if parsing is to be successful. |
| */ |
| private File buildFile = null; |
| |
| private static String currentEntityName = null; |
| private static String currentEntityPath = null; |
| |
| private static int currentImportStackSize = 1; |
| |
| /** |
| * The Ant Model |
| */ |
| private static IAntModel fgAntModel; |
| |
| /** |
| * The current Ant parsing context |
| */ |
| private static AntXMLContext fgAntContext; |
| |
| private static AntHandler elementHandler = new ElementHandler(); |
| private static AntHandler projectHandler = new ProjectHandler(); |
| private static AntHandler targetHandler = new TargetHandler(); |
| private static AntHandler mainHandler = new MainHandler(); |
| private static LexicalHandler lexicalHandler = new LexHandler(); |
| |
| private static XMLReader fgXMLReader = null; |
| |
| public static class ElementHandler extends ProjectHelper2.ElementHandler { |
| |
| private UnknownElement task = null; |
| private Task currentTask = null; |
| |
| private Map<String, String> fNormalizedFileNames = new HashMap<>(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) { |
| return ProjectHelper.elementHandler; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) { |
| try { |
| RuntimeConfigurable wrapper = context.currentWrapper(); |
| currentTask = null; |
| task = null; |
| if (wrapper != null) { |
| currentTask = (Task) wrapper.getProxy(); |
| } |
| onStartElement0(uri, tag, qname, attrs, context); |
| |
| Locator locator = context.getLocator(); |
| getAntModel().addTask(task, currentTask, attrs, locator.getLineNumber(), locator.getColumnNumber()); |
| |
| } |
| catch (BuildException be) { |
| Locator locator = context.getLocator(); |
| getAntModel().addTask(task, currentTask, attrs, locator.getLineNumber(), locator.getColumnNumber()); |
| getAntModel().error(be); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, |
| * org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onEndElement(String uri, String tag, AntXMLContext context) { |
| super.onEndElement(uri, tag, context); |
| |
| Locator locator = context.getLocator(); |
| if (getAntModel().canGetTaskInfo()) { |
| getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| } |
| |
| private void onStartElement0(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) { |
| |
| RuntimeConfigurable parentWrapper = context.currentWrapper(); |
| Object parent = null; |
| |
| if (parentWrapper != null) { |
| parent = parentWrapper.getProxy(); |
| } |
| |
| /* |
| * UnknownElement is used for tasks and data types - with delayed eval |
| */ |
| task = new UnknownElement(tag); |
| task.setProject(context.getProject()); |
| task.setNamespace(uri); |
| task.setQName(qname); |
| task.setTaskType(org.apache.tools.ant.ProjectHelper.genComponentName(task.getNamespace(), tag)); |
| task.setTaskName(qname); |
| |
| Locator contextLocator = context.getLocator(); |
| String fileName = contextLocator.getSystemId(); |
| String normalizedFileName = fNormalizedFileNames.get(fileName); |
| if (normalizedFileName == null) { |
| if (fileName.startsWith(IAntCoreConstants.FILE_PROTOCOL)) { |
| normalizedFileName = getFileUtils().fromURI(fileName); |
| fNormalizedFileNames.put(fileName, normalizedFileName); |
| } else { |
| normalizedFileName = fileName; |
| } |
| } |
| |
| Target currentTarget = context.getCurrentTarget(); |
| Location location = new Location(normalizedFileName, contextLocator.getLineNumber(), contextLocator.getColumnNumber()); |
| task.setLocation(location); |
| task.setOwningTarget(currentTarget); |
| |
| if (parent != null) { |
| // Nested element |
| ((UnknownElement) parent).addChild(task); |
| } else { |
| // Task included in a target ( including the default one ). |
| currentTarget.addTask(task); |
| } |
| |
| // do not configure the id of an augment node, it is resolved |
| // when it is configured |
| if (!IAntCoreConstants.AUGMENT.equals(task.getQName())) { |
| context.configureId(task, attrs); |
| } |
| |
| // container.addTask(task); |
| // This is a nop in UE: task.init(); |
| |
| RuntimeConfigurable wrapper = new RuntimeConfigurable(task, task.getTaskName()); |
| |
| for (int i = 0; i < attrs.getLength(); i++) { |
| String attrUri = attrs.getURI(i); |
| if (attrUri != null && attrUri.length() != 0 && !attrUri.equals(uri)) { |
| continue; // Ignore attributes from unknown uris |
| } |
| String name = attrs.getLocalName(i); |
| String value = attrs.getValue(i); |
| // PR: Hack for ant-type value |
| // an ant-type is a component name which can |
| // be namespaced, need to extract the name |
| // and convert from qualified name to uri/name |
| if (name.equals("ant-type")) { //$NON-NLS-1$ |
| int index = value.indexOf(':'); |
| if (index != -1) { |
| String prefix = value.substring(0, index); |
| String mappedUri = context.getPrefixMapping(prefix); |
| if (mappedUri == null) { |
| throw new BuildException("Unable to find XML NS prefix " + prefix); //$NON-NLS-1$ |
| } |
| value = org.apache.tools.ant.ProjectHelper.genComponentName(mappedUri, value.substring(index + 1)); |
| } |
| } |
| wrapper.setAttribute(name, value); |
| } |
| |
| if (parentWrapper != null) { |
| parentWrapper.addChild(wrapper); |
| } |
| |
| context.pushWrapper(wrapper); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void characters(char[] buf, int start, int count, AntXMLContext context) { |
| try { |
| super.characters(buf, start, count, context); |
| } |
| catch (SAXParseException e) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, e); |
| } |
| catch (BuildException be) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, be); |
| } |
| } |
| |
| public void reset() { |
| task = null; |
| currentTask = null; |
| fNormalizedFileNames.clear(); |
| } |
| } |
| |
| public static class MainHandler extends ProjectHelper2.MainHandler { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) throws SAXParseException { |
| if (name.equals("project") //$NON-NLS-1$ |
| && (uri.length() == 0 || uri.equals(ANT_CORE_URI))) { |
| return ProjectHelper.projectHandler; |
| } |
| try { |
| return super.onStartChild(uri, name, qname, attrs, context); |
| } |
| catch (SAXParseException e) { |
| getAntModel().error(e); |
| throw e; |
| } |
| } |
| } |
| |
| public static class ProjectHandler extends ProjectHelper2.ProjectHandler { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) { |
| if ((name.equals("target") || name.equals("extension-point"))//$NON-NLS-1$ //$NON-NLS-2$ |
| && (uri.length() == 0 || uri.equals(ANT_CORE_URI))) { |
| return ProjectHelper.targetHandler; |
| } |
| return ProjectHelper.elementHandler; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, |
| * org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onEndElement(String uri, String tag, AntXMLContext context) { |
| super.onEndElement(uri, tag, context); |
| if (currentImportStackSize == 1) { |
| Locator locator = context.getLocator(); |
| getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) { |
| try { |
| super.onStartElement(uri, tag, qname, attrs, context); |
| } |
| catch (SAXParseException e) { |
| getAntModel().error(e); |
| } |
| catch (BuildException be) { |
| getAntModel().error(be); |
| } |
| if (context.getCurrentTarget() == null) { |
| // exception occurred creating the project |
| context.getProject().addTarget(IAntCoreConstants.EMPTY_STRING, context.getImplicitTarget()); |
| context.setCurrentTarget(context.getImplicitTarget()); |
| } |
| if (currentImportStackSize == 1) { |
| Locator locator = context.getLocator(); |
| getAntModel().addProject(context.getProject(), locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void characters(char[] buf, int start, int count, AntXMLContext context) { |
| try { |
| super.characters(buf, start, count, context); |
| } |
| catch (SAXParseException e) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, e); |
| } |
| catch (BuildException be) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, be); |
| } |
| } |
| } |
| |
| public static class TargetHandler extends ProjectHelper2.TargetHandler { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) { |
| return ProjectHelper.elementHandler; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, |
| * org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) { |
| try { |
| super.onStartElement(uri, tag, qname, attrs, context); |
| Target newTarget = context.getCurrentTarget(); |
| Locator locator = context.getLocator(); |
| getAntModel().addTarget(newTarget, locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| catch (SAXParseException e) { |
| handleErrorInTarget(context, e); |
| } |
| catch (BuildException be) { |
| handleErrorInTarget(context, be); |
| } |
| } |
| |
| private void handleErrorInTarget(AntXMLContext context, Exception e) { |
| Target newTarget = context.getCurrentTarget(); |
| Locator locator = context.getLocator(); |
| getAntModel().addTarget(newTarget, locator.getLineNumber(), locator.getColumnNumber()); |
| getAntModel().errorFromElement(e, null, locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, |
| * org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void onEndElement(String uri, String tag, AntXMLContext context) { |
| super.onEndElement(uri, tag, context); |
| Locator locator = context.getLocator(); |
| getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext) |
| */ |
| @Override |
| public void characters(char[] buf, int start, int count, AntXMLContext context) { |
| try { |
| super.characters(buf, start, count, context); |
| } |
| catch (SAXParseException e) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, e); |
| } |
| catch (BuildException be) { |
| ErrorHelper.handleErrorFromElementText(start, count, context, be); |
| } |
| } |
| } |
| |
| public static class RootHandler extends ProjectHelper2.RootHandler { |
| |
| public RootHandler(AntXMLContext context, AntHandler rootHandler) { |
| super(context, rootHandler); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) |
| */ |
| @Override |
| public void error(SAXParseException e) { |
| getAntModel().error(e); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) |
| */ |
| @Override |
| public void fatalError(SAXParseException e) { |
| getAntModel().fatalError(e); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) |
| */ |
| @Override |
| public void warning(SAXParseException e) { |
| getAntModel().warning(e); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String) |
| */ |
| @Override |
| public InputSource resolveEntity(String publicId, String systemId) { |
| InputSource source = super.resolveEntity(publicId, systemId); |
| if (source != null) { |
| String path = getFileUtils().fromURI(source.getSystemId()); |
| if (currentEntityName == null) { |
| currentEntityPath = path; |
| } else { |
| getAntModel().addEntity(currentEntityName, path); |
| currentEntityName = null; |
| } |
| } |
| return source; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String) |
| */ |
| @Override |
| public void startPrefixMapping(String prefix, String uri) { |
| |
| super.startPrefixMapping(prefix, uri); |
| getAntModel().addPrefixMapping(prefix, uri); |
| } |
| } |
| |
| private static class ErrorHelper { |
| public static void handleErrorFromElementText(int start, int count, AntXMLContext context, Exception e) { |
| Locator locator = context.getLocator(); |
| int columnNumber = locator.getColumnNumber(); |
| if (columnNumber > -1) { |
| int offset = start; |
| try { |
| offset = getAntModel().getOffset(locator.getLineNumber(), 1); |
| } |
| catch (BadLocationException e1) { |
| // do nothing |
| } |
| getAntModel().errorFromElementText(e, offset, locator.getColumnNumber()); |
| } else { |
| getAntModel().errorFromElementText(e, start, count); |
| } |
| } |
| } |
| |
| private static class LexHandler implements LexicalHandler { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#endCDATA() |
| */ |
| @Override |
| public void endCDATA() throws SAXException { |
| // do nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#endDTD() |
| */ |
| @Override |
| public void endDTD() throws SAXException { |
| if (getAntModel().canGetLexicalInfo()) { |
| AntXMLContext context = getContext(); |
| Locator locator = context.getLocator(); |
| getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#startCDATA() |
| */ |
| @Override |
| public void startCDATA() throws SAXException { |
| // do nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int) |
| */ |
| @Override |
| public void comment(char[] ch, int start, int length) throws SAXException { |
| if (getAntModel().canGetLexicalInfo()) { |
| AntXMLContext context = getContext(); |
| Locator locator = context.getLocator(); |
| if (locator != null) { |
| getAntModel().addComment(locator.getLineNumber(), locator.getColumnNumber(), length); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String) |
| */ |
| @Override |
| public void endEntity(String name) throws SAXException { |
| // do nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String) |
| */ |
| @Override |
| public void startEntity(String name) throws SAXException { |
| if (currentEntityPath == null) { |
| currentEntityName = name; |
| } else { |
| getAntModel().addEntity(name, currentEntityPath); |
| currentEntityPath = null; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String) |
| */ |
| @Override |
| public void startDTD(String name, String publicId, String systemId) throws SAXException { |
| if (getAntModel().canGetLexicalInfo()) { |
| AntXMLContext context = getContext(); |
| Locator locator = context.getLocator(); |
| getAntModel().addDTD(name, locator.getLineNumber(), locator.getColumnNumber()); |
| } |
| } |
| } |
| |
| public ProjectHelper(IAntModel model) { |
| setAntModel(model); |
| } |
| |
| /** |
| * Constructor |
| * <p> |
| * This constructor is only to be used by the {@link ProjectHelperRepository} when loading instances of registered helpers. |
| * </p> |
| * |
| * @since 3.7 |
| * @noreference This constructor is not intended to be referenced by clients. |
| */ |
| public ProjectHelper() { |
| } |
| |
| /** |
| * Parses the project file, configuring the project as it goes. |
| * |
| * @param project |
| * the current project |
| * @param source |
| * the XML source or a {@link File} |
| * @param handler |
| * the root handler to use (contains the current context) |
| * @exception BuildException |
| * if the configuration is invalid or cannot be read |
| */ |
| @Override |
| public void parse(Project project, Object source, ProjectHelper2.RootHandler handler) throws BuildException { |
| if (!(source instanceof String) && !(source instanceof File)) { |
| // this should only occur with a source URL and that should not be possible currently |
| // as Antlib hard codes using ProjectHelper2 (bug 152793) |
| super.parse(project, source, handler); |
| return; |
| } |
| AntXMLContext context = (AntXMLContext) project.getReference("ant.parsing.context"); //$NON-NLS-1$ |
| // switch to using "our" handler so parsing will continue on hitting errors. |
| handler = new RootHandler(context, mainHandler); |
| InputStream stream = null; |
| try { |
| InputSource inputSource = null; |
| if ((source instanceof File)) { |
| buildFile = (File) source; |
| buildFile = getFileUtils().normalize(buildFile.getAbsolutePath()); |
| stream = new FileInputStream(buildFile); |
| inputSource = new InputSource(stream); |
| } else if (source instanceof String) { |
| IAntModel model = getAntModel(); |
| String encoding = IAntCoreConstants.UTF_8; |
| if (model != null) { |
| encoding = model.getEncoding(); |
| } |
| stream = new ByteArrayInputStream(((String) source).getBytes(encoding)); |
| inputSource = new InputSource(stream); |
| } |
| |
| /** |
| * SAX 2 style parser used to parse the given file. |
| */ |
| // We cannot use the JAXPUtils support here as the underlying parser factory is cached and |
| // will not reflect classpath changes that effect which XML parser will be returned. |
| // see bug 59764 |
| // XMLReader parser = JAXPUtils.getNamespaceXMLReader(); |
| XMLReader parser = getNamespaceXMLReader(); |
| if (parser == null) { |
| throw new BuildException(ProjectHelperMessages.ProjectHelper_0); |
| } |
| String uri = null; |
| if (buildFile != null) { |
| uri = getFileUtils().toURI(buildFile.getAbsolutePath()); |
| } |
| |
| if (uri != null) { |
| inputSource.setSystemId(uri); |
| } |
| |
| context.setBuildFile(buildFile); |
| |
| parser.setContentHandler(handler); |
| parser.setEntityResolver(handler); |
| parser.setErrorHandler(handler); |
| parser.setDTDHandler(handler); |
| parser.setProperty("http://xml.org/sax/properties/lexical-handler", lexicalHandler); //$NON-NLS-1$ |
| |
| parser.parse(inputSource); |
| } |
| catch (SAXParseException exc) { |
| getAntModel().fatalError(exc); |
| } |
| catch (SAXException exc) { |
| // ignore as we will be parsing incomplete source |
| } |
| catch (FileNotFoundException exc) { |
| throw new BuildException(exc); |
| } |
| catch (UnsupportedEncodingException exc) { |
| throw new BuildException(exc); |
| } |
| catch (IOException exc) { |
| throw new BuildException(exc); |
| } |
| finally { |
| try { |
| if (stream != null) { |
| stream.close(); |
| } |
| } |
| catch (IOException ioe) { |
| // ignore this |
| } |
| } |
| } |
| |
| /** |
| * Sets the buildfile that is about to be parsed or <code>null</code> if parsing has completed. |
| * |
| * @param file |
| * The buildfile about to be parsed |
| */ |
| public void setBuildFile(File file) { |
| buildFile = file; |
| currentImportStackSize = 1; |
| } |
| |
| /* |
| * (non-Javadoc) We override this method from ProjectHelper2 as we do not want to execute the implicit target or any other target for that matter |
| * as it could hang Eclipse. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=50795 for more details. |
| * |
| * @see org.apache.tools.ant.ProjectHelper#parse(org.apache.tools.ant.Project, java.lang.Object) |
| */ |
| @Override |
| public void parse(Project project, Object source) throws BuildException { |
| AntXMLContext context = (AntXMLContext) project.getReference("ant.parsing.context"); //$NON-NLS-1$ |
| if (context == null) { |
| getImportStack().removeAllElements(); |
| context = new AntXMLContext(project); |
| project.addReference("ant.parsing.context", context); //$NON-NLS-1$ |
| project.addReference("ant.targets", context.getTargets()); //$NON-NLS-1$ |
| fgAntContext = context; |
| } |
| getImportStack().addElement(source); |
| currentImportStackSize = getImportStack().size(); |
| if (getImportStack().size() > 1) { |
| // we are in an imported file. |
| context.setIgnoreProjectTag(true); |
| Target currentTarget = context.getCurrentTarget(); |
| Target currentImplicit = context.getImplicitTarget(); |
| Map<String, Target> currentTargets = context.getCurrentTargets(); |
| |
| try { |
| Target newCurrent = new Target(); |
| newCurrent.setProject(project); |
| newCurrent.setName(IAntCoreConstants.EMPTY_STRING); |
| context.setCurrentTarget(newCurrent); |
| context.setCurrentTargets(new HashMap<String, Target>()); |
| context.setImplicitTarget(newCurrent); |
| parse(project, source, new RootHandler(context, mainHandler)); |
| } |
| finally { |
| context.setCurrentTarget(currentTarget); |
| context.setImplicitTarget(currentImplicit); |
| context.setCurrentTargets(currentTargets); |
| } |
| } else { |
| // top level file |
| context.setCurrentTargets(new HashMap<String, Target>()); |
| parse(project, source, new RootHandler(context, mainHandler)); |
| } |
| } |
| |
| public static void reset() { |
| fgXMLReader = null; |
| fu = null; |
| } |
| |
| public static void setAntModel(IAntModel antModel) { |
| fgAntModel = antModel; |
| ((ProjectHelper.ElementHandler) elementHandler).reset(); |
| fu = null; |
| fgAntContext = null; |
| } |
| |
| public static IAntModel getAntModel() { |
| return fgAntModel; |
| } |
| |
| public static AntXMLContext getContext() { |
| return fgAntContext; |
| } |
| |
| private static FileUtils getFileUtils() { |
| if (fu == null) { |
| fu = FileUtils.getFileUtils(); |
| } |
| return fu; |
| } |
| |
| /** |
| * Returns a newly created SAX 2 XMLReader, which is namespace aware |
| * |
| * @return a SAX 2 XMLReader. |
| * @since Ant 1.6 from org.apache.tools.ant.util.JAXPUtils |
| */ |
| private XMLReader getNamespaceXMLReader() throws BuildException { |
| if (fgXMLReader == null) { |
| try { |
| fgXMLReader = newSAXParser(getNSParserFactory()).getXMLReader(); |
| } |
| catch (SAXException e) { |
| // do nothing |
| } |
| } |
| return fgXMLReader; |
| } |
| |
| /** |
| * Returns the parser factory to use to create namespace aware parsers. |
| * |
| * @return a SAXParserFactory to use which supports manufacture of namespace aware parsers |
| * |
| * @since Ant 1.6 from org.apache.tools.ant.util.JAXPUtils |
| */ |
| private SAXParserFactory getNSParserFactory() throws BuildException { |
| |
| SAXParserFactory nsParserFactory = JAXPUtils.newParserFactory(); |
| nsParserFactory.setNamespaceAware(true); |
| |
| return nsParserFactory; |
| } |
| |
| /** |
| * @return a new SAXParser instance as helper for getParser and getXMLReader. |
| * |
| * @since Ant 1.5 from org.apache.tools.ant.util.JAXPUtils |
| */ |
| private SAXParser newSAXParser(SAXParserFactory factory) { |
| try { |
| return factory.newSAXParser(); |
| } |
| catch (ParserConfigurationException e) { |
| // do nothing |
| } |
| catch (SAXException e) { |
| // do nothing |
| } |
| return null; |
| } |
| } |