/*******************************************************************************
 * Copyright (c) 2000, 2019 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.core.resources.IFile;
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 -&gt; URI and URI -&gt; 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;
	/*
	 * Required to remember the project names (in case they are required for target-prefixing). The build file(s) are parsed anyway and hence the
	 * project name is added to this map when it gets parsed.
	 */
	private static Map<String, String> parsedProjectNames = 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;
			}
		}
	}

	/**
	 * Gets the associated project name by the absolute build-file path
	 *
	 * @param buildFile
	 *            The file
	 * @return The project name
	 */
	public static String getProjectNameOfBuildFile(IFile buildFile) {
		return parsedProjectNames.get(getBuildFileKey(buildFile));
	}

	/**
	 * Builds the hash-map's build-file key
	 *
	 * @param buildFile
	 *            The build file
	 * @return The key as string
	 */
	private static String getBuildFileKey(IFile buildFile) {
		return buildFile.getLocation().toFile().getAbsolutePath();
	}

	/**
	 * Adds a parsed project-name to the property-holder (and initializes the collection if necessary)
	 *
	 * @param key
	 *            The key (file-path).
	 * @param projectName
	 *            The projectname to add.
	 */
	public static void storeParsedProjectName(String key, String projectName) {
		// init if required
		if (parsedProjectNames == null) {
			parsedProjectNames = new HashMap<>();
		}
		parsedProjectNames.put(key, projectName);
	}

	/**
	 * Clear the parsed project-holder to avoid potential memory leaks.
	 */
	public static void clearAdditionalPropertyHolders() {
		/*
		 * Currently only this "property-holder" is used. Extend if necessary.
		 */
		if (parsedProjectNames != null) {
			parsedProjectNames.clear();
			parsedProjectNames = null;
		}
	}

	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);
				// add project-name to property holder (if no aliases are used, the project name is required for target prefixing)
				String currentProjectName = context.getCurrentProjectName();
				// just an additional check if the name is non-empty
				if (this.isCurrentProjectNameValid(currentProjectName)) {
					String buildFilePath = context.getBuildFile().getAbsolutePath();
					storeParsedProjectName(buildFilePath, currentProjectName);
				}
			}
			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());
			}
		}

		/**
		 * Checks if the parsed value is a valid project name (i.e. is non-empty: It doesn't make sense to store empty project-names)
		 *
		 * @param currentProjectName
		 *            The current project name
		 * @return If the given project name is valid or not.
		 */
		private boolean isCurrentProjectNameValid(String currentProjectName) {
			return currentProjectName != null && !currentProjectName.equals(""); //$NON-NLS-1$
		}

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