/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.tools.ant.Target;
import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.ant.internal.core.AntCoreUtil;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.launching.AntLaunchingUtil;
import org.eclipse.ant.internal.ui.editor.AntEditor;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.IAntElement;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.ant.internal.ui.model.LocationProvider;
import org.eclipse.ant.launching.IAntLaunchConstants;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.console.FileLink;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.externaltools.internal.launchConfigurations.ExternalToolsUtil;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * General utility class dealing with Ant build files
 */
public final class AntUtil {
	public static final String ATTRIBUTE_SEPARATOR = ","; //$NON-NLS-1$ ;
	public static final char ANT_CLASSPATH_DELIMITER = '*';
	public static final String ANT_HOME_CLASSPATH_PLACEHOLDER = "G"; //$NON-NLS-1$
	public static final String ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER = "UG"; //$NON-NLS-1$
	private static String fgBrowserId;

	/**
	 * No instances allowed
	 */
	private AntUtil() {
		super();
	}

	/**
	 * Returns a single-string of the strings for storage.
	 * 
	 * @param strings
	 *            the array of strings
	 * @return a single-string representation of the strings or <code>null</code> if the array is empty.
	 */
	public static String combineStrings(String[] strings) {
		return AntLaunchingUtil.combineStrings(strings);
	}

	/**
	 * Returns an array of targets to be run, or <code>null</code> if none are specified (indicating the default target or implicit target should be
	 * run).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return array of target names, or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String[] getTargetNames(ILaunchConfiguration configuration) throws CoreException {
		return AntLaunchingUtil.getTargetNames(configuration);
	}

	/**
	 * Returns a map of properties to be defined for the build, or <code>null</code> if none are specified (indicating no additional properties
	 * specified for the build).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return map of properties (name --&gt; value), or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static Map<String, String> getProperties(ILaunchConfiguration configuration) throws CoreException {
		return AntLaunchingUtil.getProperties(configuration);
	}

	/**
	 * Returns a String specifying the Ant home to use for the build.
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return String specifying Ant home to use or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String getAntHome(ILaunchConfiguration configuration) throws CoreException {
		return AntLaunchingUtil.getAntHome(configuration);
	}

	/**
	 * Returns an array of property files to be used for the build, or <code>null</code> if none are specified (indicating no additional property
	 * files specified for the build).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return array of property file names, or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String[] getPropertyFiles(ILaunchConfiguration configuration) throws CoreException {
		String attribute = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, (String) null);
		if (attribute == null) {
			return null;
		}
		String[] propertyFiles = AntUtil.parseString(attribute, ","); //$NON-NLS-1$
		for (int i = 0; i < propertyFiles.length; i++) {
			String propertyFile = propertyFiles[i];
			propertyFile = expandVariableString(propertyFile, AntUIModelMessages.AntUtil_6);
			propertyFiles[i] = propertyFile;
		}
		return propertyFiles;
	}

	public static AntTargetNode[] getTargets(String path, ILaunchConfiguration config) throws CoreException {
		File buildfile = getBuildFile(path);
		if (buildfile == null) {
			return null;
		}
		URL[] urls = getCustomClasspath(config);
		// no lexical, no position, no task
		IAntModel model = getAntModel(buildfile, urls, false, false, false);
		try {
			model.setProperties(getAllProperties(config));
		}
		catch (CoreException ex) {
			// do nothing
		}
		model.setPropertyFiles(getPropertyFiles(config));
		AntProjectNode project = model.getProjectNode(); // forces a reconcile
		model.dispose();
		return getTargets(project);
	}

	private static Map<String, String> getAllProperties(ILaunchConfiguration config) throws CoreException {
		String allArgs = config.getAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, (String) null);
		Map<String, String> properties = new HashMap<>();
		if (allArgs != null) {
			// filter arguments to avoid resolving variables that will prompt the user
			List<String> filtered = new ArrayList<>();
			Pattern pattern = Pattern.compile("\\$\\{.*_prompt.*\\}"); //$NON-NLS-1$
			IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
			for (String arg : ExternalToolsUtil.parseStringIntoList(allArgs)) {
				if (arg.startsWith("-D")) { //$NON-NLS-1$
					if (!pattern.matcher(arg).find()) {
						filtered.add(manager.performStringSubstitution(arg, false));
					}
				}
			}
			AntCoreUtil.processMinusDProperties(filtered, properties);
		}
		Map<String, String> configProperties = getProperties(config);
		if (configProperties != null) {
			Iterator<String> keys = configProperties.keySet().iterator();
			while (keys.hasNext()) {
				String name = keys.next();
				if (properties.get(name) == null) {
					properties.put(name, configProperties.get(name));
				}
			}
		}
		return properties;
	}

	private static AntTargetNode[] getTargets(AntProjectNode project) {
		if (project == null || !project.hasChildren()) {
			return null;
		}
		List<IAntElement> targets = new ArrayList<>();
		for (IAntElement node : project.getChildNodes()) {
			if (node instanceof AntTargetNode) {
				targets.add(node);
			}
		}
		if (targets.isEmpty()) {
			return null;
		}
		return targets.toArray(new AntTargetNode[targets.size()]);
	}

	public static AntTargetNode[] getTargets(String path) {
		File buildfile = getBuildFile(path);
		if (buildfile == null) {
			return null;
		}
		// tasks and position info but no lexical info
		IAntModel model = getAntModel(buildfile, null, false, true, true);
		AntProjectNode project = model.getProjectNode();
		if (project == null) {
			model.dispose();
			return null;
		}
		AntTargetNode[] targets = getTargets(project);
		if (targets == null) {
			Hashtable<String, Target> antTargets = project.getProject().getTargets();
			Target implicitTarget = antTargets.get(IAntCoreConstants.EMPTY_STRING);
			if (implicitTarget != null) {
				AntTargetNode implicitTargetNode = AntTargetNode.newAntTargetNode(implicitTarget);
				project.addChildNode(implicitTargetNode);
				return new AntTargetNode[] { implicitTargetNode };
			}
		}
		return targets;
	}

	public static IAntModel getAntModel(String buildFilePath, boolean needsLexicalResolution, boolean needsPositionResolution, boolean needsTaskResolution) {
		IAntModel model = getAntModel(getBuildFile(buildFilePath), null, needsLexicalResolution, needsPositionResolution, needsTaskResolution);
		return model;
	}

	/**
	 * Return a buildfile from the specified location. If there isn't one return null.
	 */
	private static File getBuildFile(String path) {
		File buildFile = new File(path);
		if (!buildFile.isFile() || !buildFile.exists()) {
			return null;
		}

		return buildFile;
	}

	private static IAntModel getAntModel(final File buildFile, URL[] urls, boolean needsLexical, boolean needsPosition, boolean needsTask) {
		if (buildFile == null || !buildFile.exists()) {
			return null;
		}
		IDocument doc = getDocument(buildFile);
		if (doc == null) {
			return null;
		}
		final IFile file = getFileForLocation(buildFile.getAbsolutePath(), null);
		LocationProvider provider = new LocationProvider(null) {
			@Override
			public IFile getFile() {
				return file;
			}

			@Override
			public IPath getLocation() {
				if (file == null) {
					return new Path(buildFile.getAbsolutePath());
				}
				return file.getLocation();
			}
		};
		IAntModel model = new AntModel(doc, null, provider, needsLexical, needsPosition, needsTask);

		if (urls != null) {
			model.setClassLoader(AntCorePlugin.getPlugin().getNewClassLoader(urls));
		}
		return model;
	}

	private static IDocument getDocument(File buildFile) {
		ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
		IPath location = new Path(buildFile.getAbsolutePath());
		boolean connected = false;
		try {
			ITextFileBuffer buffer = manager.getTextFileBuffer(location, LocationKind.NORMALIZE);
			if (buffer == null) {
				// no existing file buffer..create one
				manager.connect(location, LocationKind.NORMALIZE, new NullProgressMonitor());
				connected = true;
				buffer = manager.getTextFileBuffer(location, LocationKind.NORMALIZE);
				if (buffer == null) {
					return null;
				}
			}

			return buffer.getDocument();
		}
		catch (CoreException ce) {
			AntUIPlugin.log(ce.getStatus());
			return null;
		}
		finally {
			if (connected) {
				try {
					manager.disconnect(location, LocationKind.NORMALIZE, new NullProgressMonitor());
				}
				catch (CoreException e) {
					AntUIPlugin.log(e.getStatus());
				}
			}
		}
	}

	/**
	 * Returns the list of URLs that define the custom classpath for the Ant build, or <code>null</code> if the global classpath is to be used.
	 * 
	 * @param config
	 *            launch configuration
	 * @return a list of <code>URL</code>
	 * 
	 * @throws CoreException
	 *             if file does not exist, IO problems, or invalid format.
	 */
	public static URL[] getCustomClasspath(ILaunchConfiguration config) throws CoreException {
		return AntLaunchingUtil.getCustomClasspath(config);
	}

	private static String expandVariableString(String variableString, String invalidMessage) throws CoreException {
		String expandedString = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(variableString);
		if (expandedString == null || expandedString.length() == 0) {
			String msg = MessageFormat.format(invalidMessage, new Object[] { variableString });
			throw new CoreException(new Status(IStatus.ERROR, IAntUIConstants.PLUGIN_ID, 0, msg, null));
		}

		return expandedString;
	}

	/**
	 * Returns the list of target names to run
	 * 
	 * @param extraAttibuteValue
	 *            the external tool's extra attribute value for the run targets key.
	 * @return a list of target names
	 */
	public static String[] parseRunTargets(String extraAttibuteValue) {
		return AntLaunchingUtil.parseRunTargets(extraAttibuteValue);
	}

	/**
	 * Returns the list of Strings that were delimiter separated.
	 * 
	 * @param delimString
	 *            the String to be tokenized based on the delimiter
	 * @param delim
	 *            the delimiter
	 * @return a list of Strings
	 */
	public static String[] parseString(String delimString, String delim) {
		return AntLaunchingUtil.parseString(delimString, delim);
	}

	/**
	 * Returns an IFile with the given fully qualified path (relative to the workspace root). The returned IFile may or may not exist.
	 * 
	 * @param fullPath
	 *            the path to look up
	 * @return the {@link IFile} which may or may not exist
	 */
	public static IFile getFile(String fullPath) {
		return AntLaunchingUtil.getFile(fullPath);
	}

	public static IHyperlink getLocationLink(String path, File buildFileParent) {
		path = path.trim();
		if (path.length() == 0) {
			return null;
		}
		if (path.startsWith(IAntCoreConstants.FILE_PROTOCOL)) {
			// remove "file:"
			path = path.substring(5, path.length());
		}
		// format is file:F:L: where F is file path, and L is line number
		int index = path.lastIndexOf(':');
		if (index == -1) {
			// incorrect format
			return null;
		}
		if (index == path.length() - 1) {
			// remove trailing ':'
			path = path.substring(0, index);
			index = path.lastIndexOf(':');
		}
		// split file and line number
		String fileName = path.substring(0, index);
		try {
			String lineNumber = path.substring(index + 1);
			int line = Integer.parseInt(lineNumber);
			IFile file = getFileForLocation(fileName, buildFileParent);
			if (file != null) {
				return new FileLink(file, null, -1, -1, line);
			}
		}
		catch (NumberFormatException e) {
			// do nothing
		}

		return null;
	}

	/**
	 * Returns the workspace file associated with the given path in the local file system, or <code>null</code> if none. If the path happens to be a
	 * relative path, then the path is interpreted as relative to the specified parent file.
	 * 
	 * Attempts to handle linked files; the first found linked file with the correct path is returned.
	 * 
	 * @param path
	 * @param buildFileParent
	 * @return file or <code>null</code>
	 * @see org.eclipse.core.resources.IWorkspaceRoot#findFilesForLocation(IPath)
	 */
	public static IFile getFileForLocation(String path, File buildFileParent) {
		return AntLaunchingUtil.getFileForLocation(path, buildFileParent);
	}

	/**
	 * Migrates the classpath in the given configuration from the old format to the new format. The old format is not preserved. Instead, the default
	 * classpath will be used. However, ANT_HOME settings are preserved.
	 * 
	 * @param configuration
	 *            a configuration to migrate
	 * @throws CoreException
	 *             if unable to migrate
	 * @since 3.0
	 */
	public static void migrateToNewClasspathFormat(ILaunchConfiguration configuration) throws CoreException {
		AntLaunchingUtil.migrateToNewClasspathFormat(configuration);
	}

	private static int getOffset(int line, int column, ITextEditor editor) {
		IDocumentProvider provider = editor.getDocumentProvider();
		IEditorInput input = editor.getEditorInput();
		try {
			provider.connect(input);
		}
		catch (CoreException e) {
			return -1;
		}
		try {
			IDocument document = provider.getDocument(input);
			if (document != null) {
				if (column > -1) {
					// column marks the length..adjust to 0 index and to be within the element's source range
					return document.getLineOffset(line - 1) + column - 1 - 2;
				}
				return document.getLineOffset(line - 1);
			}
		}
		catch (BadLocationException e) {
			// do nothing
		}
		finally {
			provider.disconnect(input);
		}
		return -1;
	}

	/**
	 * Opens the given editor on the buildfile of the provided node and selects that node in the editor.
	 * 
	 * @param page
	 *            the page to open the editor in
	 * @param editorDescriptor
	 *            the editor descriptor, or <code>null</code> for the system editor
	 * @param node
	 *            the node from the buildfile to open and then select in the editor
	 */
	public static void openInEditor(IWorkbenchPage page, IEditorDescriptor editorDescriptor, AntElementNode node) {
		IEditorPart editorPart = null;
		IFile fileResource = node.getIFile();
		try {
			if (editorDescriptor == null) {
				editorPart = page.openEditor(new FileEditorInput(fileResource), IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
			} else {
				editorPart = page.openEditor(new FileEditorInput(fileResource), editorDescriptor.getId());
			}
		}
		catch (PartInitException e) {
			AntUIPlugin.log(MessageFormat.format(AntUIModelMessages.AntUtil_0, new Object[] { fileResource.getLocation().toOSString() }), e);
		}

		if (editorPart instanceof AntEditor) {
			AntEditor editor = (AntEditor) editorPart;
			if (node.getImportNode() != null) {
				AntModel model = editor.getAntModel();
				AntProjectNode project = model.getProjectNode();
				if (project == null) {
					return;
				}
				int[] info = node.getExternalInfo();
				int offset = getOffset(info[0], info[1], editor);
				node = project.getNode(offset);
			}
			editor.setSelection(node, true);
		}
	}

	/**
	 * Opens an editor on the buildfile of the provided node and selects that node in the editor.
	 * 
	 * @param page
	 *            the page to open the editor in
	 * @param node
	 *            the node from the buildfile to open and then select in the editor
	 */
	public static void openInEditor(IWorkbenchPage page, AntElementNode node) {
		IFile file = node.getIFile();
		IEditorDescriptor editorDesc;
		try {
			editorDesc = IDE.getEditorDescriptor(file, true, true);
		}
		catch (PartInitException e) {
			return;
		}
		openInEditor(page, editorDesc, node);
	}

	/**
	 * Opens an external browser on the provided <code>urlString</code>
	 *
	 * @param urlString
	 *            The url to open
	 * @param shell
	 *            the shell
	 * @param errorDialogTitle
	 *            the title of any error dialog
	 */
	public static void openBrowser(final String urlString, final Shell shell, final String errorDialogTitle) {
		shell.getDisplay().syncExec(() -> {
			IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
			try {
				IWebBrowser browser = support.createBrowser(fgBrowserId);
				fgBrowserId = browser.getId();
				browser.openURL(new URL(urlString));
				return;
			}
			catch (PartInitException e1) {
				AntUIPlugin.log(e1.getStatus());
			}
			catch (MalformedURLException e2) {
				AntUIPlugin.log(e2);
			}

			String platform = SWT.getPlatform();
			boolean succeeded = true;
			if ("motif".equals(platform) || "gtk".equals(platform)) { //$NON-NLS-1$ //$NON-NLS-2$
				Program program = Program.findProgram("html"); //$NON-NLS-1$
				if (program == null) {
					program = Program.findProgram("htm"); //$NON-NLS-1$
				}
				if (program != null) {
					succeeded = program.execute(urlString.toString());
				}
			} else {
				succeeded = Program.launch(urlString.toString());
			}
			if (!succeeded) {
				MessageDialog.openInformation(shell, errorDialogTitle, AntUIModelMessages.AntUtil_1);
			}
		});
	}

	public static boolean isSeparateJREAntBuild(ILaunchConfiguration configuration) {
		return AntLaunchingUtil.isSeparateJREAntBuild(configuration);
	}

	/**
	 * Returns if the given extension is a known extension to Ant i.e. a supported content type extension.
	 *
	 * @param resource
	 * @return true if the file extension is supported false otherwise
	 *
	 * @since 3.6
	 */
	public static boolean isKnownAntFile(IResource resource) {
		if (resource != null) {
			// workspace file
			IFile file = null;
			if (resource.getType() == IResource.FILE) {
				file = (IFile) resource;
			} else {
				file = resource.getAdapter(IFile.class);
			}
			if (file != null) {
				IContentType fileType = IDE.getContentType(file);
				if (fileType == null) {
					return false;
				}
				IContentType antType = Platform.getContentTypeManager().getContentType(AntCorePlugin.ANT_BUILDFILE_CONTENT_TYPE);
				if (antType != null) {
					return fileType.isKindOf(antType);
				}
			}
		}
		return false;
	}

	/**
	 * Returns if the given extension is a known extension to Ant i.e. a supported content type extension.
	 * 
	 * @param file
	 * @return true if the file extension is supported false otherwise
	 * 
	 * @since 3.8
	 */
	public static boolean isKnownAntFile(File file) {
		if (file != null && !file.isDirectory()) {
			String filename = file.getName();
			IContentType type = Platform.getContentTypeManager().findContentTypeFor(filename);
			if (type != null) {
				IContentType antType = Platform.getContentTypeManager().getContentType(AntCorePlugin.ANT_BUILDFILE_CONTENT_TYPE);
				if (antType != null) {
					return type.isKindOf(antType);
				}
			}
			String[] names = getKnownBuildfileNames();
			for (int i = 0; names != null && i < names.length; i++) { // names can be null!
				if (filename.endsWith(names[i])) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Returns an array of build file names from the ant preference store
	 * 
	 * @return an array of build file names
	 * @since 3.6
	 */
	public static String[] getKnownBuildfileNames() {
		IPreferenceStore prefs = AntUIPlugin.getDefault().getPreferenceStore();
		String buildFileNames = prefs.getString(IAntUIPreferenceConstants.ANT_FIND_BUILD_FILE_NAMES);
		if (buildFileNames.length() == 0) {
			// the user has not specified any names to look for
			return null;
		}
		return parseString(buildFileNames, ","); //$NON-NLS-1$
	}

	/**
	 * Returns if the given file is a known build file name, based on the given names from the Ant &gt; Names preference
	 * 
	 * @param filename
	 * @return true if the name of the file is given in the Ant &gt; Names preference, false otherwise
	 * @since 3.6
	 */
	public static boolean isKnownBuildfileName(String filename) {
		String[] names = getKnownBuildfileNames();
		for (int i = 0; names != null && i < names.length; i++) { // names can be null!
			if (names[i].equalsIgnoreCase(filename)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * A helper method to extract the build filename extensions as defined in the extender of the content-types extension-point.
	 * 
	 * @return An empty array or list of filename extensions as specified in the content-types extension
	 * @since 3.8
	 */
	public static String[] getKnownBuildFileExtensions() {
		IContentType antType = null;
		String[] result = null;
		try {
			antType = Platform.getContentTypeManager().getContentType(AntCorePlugin.ANT_BUILDFILE_CONTENT_TYPE);
			if (antType != null) {
				result = antType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
			}
		}
		catch (Exception e) {
			// Empty block and fall-thru is intentional!
		}
		return result == null ? new String[0] : result;
	}

	/**
	 * A helper method to construct a RegEx pattern out of the extensions
	 * 
	 * @return A String that is a RegEx pattern representing the extensions
	 * @since 3.8
	 */
	public static String getKnownBuildFileExtensionsAsPattern() {
		String[] extns = AntUtil.getKnownBuildFileExtensions();
		if (extns.length == 0) {
			return IAntCoreConstants.XML_EXTENSION;
		}
		return String.join(String.valueOf('|'), extns);
	}

	/**
	 * Returns if the given file name is known as a build file. This method consults all of the known file extensions from the Ant-defined content
	 * types
	 * 
	 * @param name
	 * @return <code>true</code> if the file name matches an Ant build file pattern <code>false</code> otherwise
	 * @since 3.8
	 */
	public static boolean isKnownAntFileName(String name) {
		StringBuilder buf = new StringBuilder(".*.("); //$NON-NLS-1$
		buf.append(getKnownBuildFileExtensionsAsPattern());
		buf.append(")"); //$NON-NLS-1$
		try {
			Pattern p = Pattern.compile(buf.toString());
			return p.matcher(name).matches();
		}
		catch (PatternSyntaxException pse) {
			return false;
		}
	}
}