/*******************************************************************************
 * Copyright (c) 2007, 2020 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.pde.api.tools.internal;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

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.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.Factory;
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
import org.eclipse.pde.api.tools.internal.provisional.IApiJavadocTag;
import org.eclipse.pde.api.tools.internal.provisional.RestrictionModifiers;
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IFieldDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.scanner.ScannerMessages;
import org.eclipse.pde.api.tools.internal.util.Signatures;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.eclipse.text.edits.TextEdit;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Provides tools for scanning/loading/parsing component.xml files.
 *
 * @since 1.0.0
 */
public class ApiDescriptionProcessor {

	/**
	 * Visits each type, collecting all members before processing the type.
	 */
	static class DescriptionVisitor extends ApiDescriptionVisitor {

		/**
		 * The API description associated with the project.
		 */
		private IApiDescription apiDescription = null;

		/**
		 * Java project to resolve types in
		 */
		private IJavaProject project = null;

		/**
		 * List to collect text edits
		 */
		private Map<IFile, Set<TextEdit>> fCollector = null;

		/**
		 * Members collected from current type.
		 */
		private List<IElementDescriptor> members = new ArrayList<>();

		/**
		 * List of exception statuses that occurred, or <code>null</code> if
		 * none.
		 */
		private List<IStatus> exceptions = null;

		/**
		 * Constructs a new visitor to collect tag updates in a java project.
		 *
		 * @param jp project to update
		 * @param cd project's API description
		 * @param collector collection to place text edits into
		 */
		DescriptionVisitor(IJavaProject jp, IApiDescription cd, Map<IFile, Set<TextEdit>> collector) {
			project = jp;
			apiDescription = cd;
			fCollector = collector;
		}

		@Override
		public boolean visitElement(IElementDescriptor element, IApiAnnotations description) {
			switch (element.getElementType()) {
				case IElementDescriptor.PACKAGE: {
					return true;
				}
				case IElementDescriptor.TYPE: {
					members.clear();
					members.add(element);
					return true;
				}
				default: {
					members.add(element);
				}
			}
			return false;
		}

		@Override
		public void endVisitElement(IElementDescriptor element, IApiAnnotations description) {
			if (element.getElementType() == IElementDescriptor.TYPE) {
				IReferenceTypeDescriptor refType = (IReferenceTypeDescriptor) element;
				try {
					IReferenceTypeDescriptor topLevelType = refType.getEnclosingType();
					while (topLevelType != null) {
						refType = topLevelType;
						topLevelType = refType.getEnclosingType();
					}
					IType type = project.findType(refType.getQualifiedName(), new NullProgressMonitor());
					IType typeInProject = Util.getTypeInSameJavaProject(type, refType.getQualifiedName(), project);
					if (typeInProject != null) {
						type = typeInProject;
					}
					if (type != null) {
						processTagUpdates(type, refType, apiDescription, members, fCollector);
					}
				} catch (CoreException e) {
					addStatus(e.getStatus());
				} catch (BadLocationException e) {
					addStatus(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, ScannerMessages.ComponentXMLScanner_0 + element.toString(), e));
				}
				members.clear();
			}
		}

		/**
		 * Adds a status to the current listing of messages
		 *
		 * @param status
		 */
		private void addStatus(IStatus status) {
			if (exceptions == null) {
				exceptions = new ArrayList<>();
			}
			exceptions.add(status);
		}

		/**
		 * Returns the status of processing the project. Status is OK if no
		 * errors occurred.
		 *
		 * @return status
		 */
		public IStatus getStatus() {
			if (exceptions == null) {
				return Status.OK_STATUS;
			}
			return new MultiStatus(ApiPlugin.PLUGIN_ID, 0, exceptions.toArray(new IStatus[exceptions.size()]), ScannerMessages.ComponentXMLScanner_1, null);
		}

	}

	/**
	 * Visitor used for finding the nodes to update the javadoc tags for, if
	 * needed
	 */
	static class ASTTagVisitor extends ASTVisitor {
		private List<IElementDescriptor> apis = null;
		private IApiDescription description = null;
		private ASTRewrite rewrite = null;
		private Stack<Integer> typeStack;

		/**
		 * Constructor
		 *
		 * @param APIs a listing of {@link IElementDescriptor}s that we care
		 *            about for this visit
		 */
		public ASTTagVisitor(List<IElementDescriptor> apis, IApiDescription description, ASTRewrite rewrite) {
			this.apis = apis;
			this.description = description;
			this.rewrite = rewrite;
			typeStack = new Stack<>();
		}

		@Override
		public boolean visit(TypeDeclaration node) {
			int type = IApiJavadocTag.TYPE_CLASS;
			if (node.isInterface()) {
				type = IApiJavadocTag.TYPE_INTERFACE;
			}
			typeStack.push(Integer.valueOf(type));
			updateDocNode(findDescriptorByName(node.getName().getFullyQualifiedName(), null), node, getType(), IApiJavadocTag.MEMBER_NONE);
			return true;
		}

		@Override
		public void endVisit(TypeDeclaration node) {
			typeStack.pop();
		}

		/**
		 * Returns the kind of type being visited.
		 *
		 * @return <code>TYPE_CLASS</code> or <code>TYPE_INTERFACE</code>
		 */
		private int getType() {
			return (typeStack.peek()).intValue();
		}

		@Override
		public boolean visit(FieldDeclaration node) {
			List<VariableDeclarationFragment> fields = node.fragments();
			VariableDeclarationFragment fragment = null;
			for (Iterator<VariableDeclarationFragment> iter = fields.iterator(); iter.hasNext();) {
				fragment = iter.next();
				updateDocNode(findDescriptorByName(fragment.getName().getFullyQualifiedName(), null), node, getType(), IApiJavadocTag.MEMBER_FIELD);
			}
			return false;
		}

		@Override
		public boolean visit(MethodDeclaration node) {
			String signature = Signatures.getMethodSignatureFromNode(node, true);
			if (signature != null) {
				updateDocNode(findDescriptorByName(node.getName().getFullyQualifiedName(), signature), node, getType(), IApiJavadocTag.MEMBER_METHOD);
			}
			return false;
		}

		/**
		 * Updates the specified javadoc node if needed, creates a new doc node
		 * if one is not present
		 *
		 * @param element the element to get API information from
		 * @param docnode the doc node to update
		 * @param type one of <code>CLASS</code> or <code>INTERFACE</code>
		 * @param member one of <code>METHOD</code> or <code>FIELD</code> or
		 *            <code>NONE</code>
		 */
		private void updateDocNode(IElementDescriptor element, BodyDeclaration body, int type, int member) {
			if (element != null) {
				// check for missing tags first, might not need to do any work
				IApiAnnotations api = description.resolveAnnotations(element);
				if (api != null) {
					Javadoc docnode = body.getJavadoc();
					AST ast = body.getAST();
					boolean newnode = docnode == null;
					if (docnode == null) {
						docnode = ast.newJavadoc();
					}
					String[] missingtags = collectMissingTags(api, docnode.tags(), type, member);
					if (missingtags.length == 0) {
						return;
					} else if (newnode) {
						// we do not want to create a new empty Javadoc node in
						// the AST if there are no missing tags
						rewrite.set(body, body.getJavadocProperty(), docnode, null);
					}
					ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY);
					TagElement newtag = null;
					for (String missingtag : missingtags) {
						newtag = createNewTagElement(ast, missingtag);
						lrewrite.insertLast(newtag, null);
					}
				}
			}
		}

		/**
		 * Creates a new {@link TagElement} against the specified {@link AST}
		 * and returns it
		 *
		 * @param ast the {@link AST} to create the {@link TagElement} against
		 * @param tagname the name of the new tag
		 * @return a new {@link TagElement} with the given name
		 */
		private TagElement createNewTagElement(AST ast, String tagname) {
			TagElement newtag = ast.newTagElement();
			newtag.setTagName(tagname);
			return newtag;
		}

		/**
		 * Collects the missing javadoc tags from based on the given listing of
		 * {@link TagElement}s
		 *
		 * @param api
		 * @param tags
		 * @param type one of <code>CLASS</code> or <code>INTERFACE</code>
		 * @param member one of <code>METHOD</code> or <code>FIELD</code> or
		 *            <code>NONE</code>
		 * @return an array of the missing {@link TagElement}s or an empty
		 *         array, never <code>null</code>
		 */
		private String[] collectMissingTags(IApiAnnotations api, List<TagElement> tags, int type, int member) {
			int res = api.getRestrictions();
			ArrayList<String> missing = new ArrayList<>();
			JavadocTagManager jtm = ApiPlugin.getJavadocTagManager();
			switch (member) {
				case IApiJavadocTag.MEMBER_FIELD:
					if (RestrictionModifiers.isReferenceRestriction(res)) {
						if (!containsRestrictionTag(tags, "@noreference")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_REFERENCE_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					break;
				case IApiJavadocTag.MEMBER_METHOD:
					if (RestrictionModifiers.isReferenceRestriction(res)) {
						if (!containsRestrictionTag(tags, "@noreference")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_REFERENCE_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					if (RestrictionModifiers.isOverrideRestriction(res)) {
						if (!containsRestrictionTag(tags, "@nooverride")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_OVERRIDE_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					break;
				case IApiJavadocTag.MEMBER_NONE:
					if (RestrictionModifiers.isImplementRestriction(res)) {
						if (!containsRestrictionTag(tags, "@noimplement")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_IMPLEMENT_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					if (RestrictionModifiers.isInstantiateRestriction(res)) {
						if (!containsRestrictionTag(tags, "@noinstantiate")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_INSTANTIATE_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					if (RestrictionModifiers.isExtendRestriction(res)) {
						if (!containsRestrictionTag(tags, "@noextend")) { //$NON-NLS-1$
							IApiJavadocTag tag = jtm.getTag(IApiJavadocTag.NO_EXTEND_TAG_ID);
							missing.add(tag.getCompleteTag(type, member));
						}
					}
					break;
				default:
					break;
			}
			return missing.toArray(new String[missing.size()]);
		}

		/**
		 * Determines if the specified tag appears in the {@link TagElement}
		 * listing given
		 *
		 * @param tags
		 * @param tag
		 * @return true if the listing of {@link TagElement}s contains the given
		 *         tag
		 */
		private boolean containsRestrictionTag(List<TagElement> tags, String tag) {
			TagElement tagelement = null;
			for (int i = 0; i < tags.size(); i++) {
				tagelement = tags.get(i);
				if (tag.equals(tagelement.getTagName())) {
					return true;
				}
			}
			return false;
		}

		/**
		 * Finds the {@link IElementDescriptor} that matches the specified name
		 * and signature
		 *
		 * @param name
		 * @param signature
		 * @return the matching {@link IElementDescriptor} or <code>null</code>
		 */
		private IElementDescriptor findDescriptorByName(String name, String signature) {
			IElementDescriptor desc = null;
			for (int i = 0; i < apis.size(); i++) {
				desc = apis.get(i);
				switch (desc.getElementType()) {
					case IElementDescriptor.TYPE: {
						if (((IReferenceTypeDescriptor) desc).getName().equals(name)) {
							return desc;
						}
						break;
					}
					case IElementDescriptor.METHOD: {
						IMethodDescriptor method = (IMethodDescriptor) desc;
						if (method.getName().equals(name) && method.getSignature().equals(signature)) {
							return desc;
						}
						break;
					}
					case IElementDescriptor.FIELD: {
						if (((IFieldDescriptor) desc).getName().equals(name)) {
							return desc;
						}
						break;
					}
					default:
						break;
				}
			}
			return null;
		}
	}

	/**
	 * Constructor can not be instantiated directly
	 */
	private ApiDescriptionProcessor() {
	}

	/**
	 * Parses a component XML into a string. The location may be a jar,
	 * directory containing the component.xml file, or the component.xml file
	 * itself
	 *
	 * @param location root location of the component.xml file, or the
	 *            component.xml file itself
	 * @return component XML as a string or <code>null</code> if none
	 * @throws IOException if unable to parse
	 */
	public static String serializeComponentXml(File location) {
		if (location.exists()) {
			ZipFile jarFile = null;
			InputStream stream = null;
			try {
				String extension = new Path(location.getName()).getFileExtension();
				if (extension != null && extension.equals("jar") && location.isFile()) { //$NON-NLS-1$
					jarFile = new ZipFile(location, ZipFile.OPEN_READ);
					ZipEntry manifestEntry = jarFile.getEntry(IApiCoreConstants.COMPONENT_XML_NAME);
					if (manifestEntry != null) {
						stream = jarFile.getInputStream(manifestEntry);
					}
				} else if (location.isDirectory()) {
					File file = new File(location, IApiCoreConstants.COMPONENT_XML_NAME);
					if (file.exists()) {
						stream = new FileInputStream(file);
					}
				} else if (location.isFile()) {
					if (location.getName().equals(IApiCoreConstants.COMPONENT_XML_NAME)) {
						stream = new FileInputStream(location);
					}
				}
				if (stream != null) {
					return new String(Util.getInputStreamAsCharArray(stream, StandardCharsets.UTF_8));
				}
			} catch (IOException e) {
				ApiPlugin.log(e);
			} finally {
				try {
					if (stream != null) {
						stream.close();
					}
				} catch (IOException e) {
					ApiPlugin.log(e);
				}
				try {
					if (jarFile != null) {
						jarFile.close();
					}
				} catch (IOException e) {
					ApiPlugin.log(e);
				}
			}
		}
		return null;
	}

	/**
	 * This method updates the javadoc for members of the specified java source
	 * files with information retrieved from the the specified component.xml
	 * file.
	 *
	 * @param project the java project to update
	 * @param componentxml the component.xml file to update from
	 * @param collector
	 * @throws CoreException
	 * @throws IOException
	 */
	public static void collectTagUpdates(IJavaProject project, File componentxml, Map<IFile, Set<TextEdit>> collector) throws CoreException, IOException {
		IApiDescription description = new ApiDescription(null);
		annotateApiSettings(project, description, serializeComponentXml(componentxml));
		// visit the types
		DescriptionVisitor visitor = new DescriptionVisitor(project, description, collector);
		description.accept(visitor, null);
		IStatus status = visitor.getStatus();
		if (!status.isOK()) {
			throw new CoreException(status);
		}
	}

	/**
	 * Given the type, the parent type descriptor and an annotated description,
	 * update the javadoc comments for the type and all members of the type
	 * found in the description.
	 *
	 * @param type
	 * @param desc
	 * @param description
	 * @param members members with API annotations
	 * @param collector
	 * @throws CoreException
	 * @throws BadLocationException
	 */
	static void processTagUpdates(IType type, IReferenceTypeDescriptor desc, IApiDescription description, List<IElementDescriptor> members, Map<IFile, Set<TextEdit>> collector) throws CoreException, BadLocationException {
		ASTParser parser = ASTParser.newParser(AST.JLS15);
		ICompilationUnit cunit = type.getCompilationUnit();
		if (cunit != null) {
			parser.setSource(cunit);
			Map<String, String> options = cunit.getJavaProject().getOptions(true);
			options.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
			parser.setCompilerOptions(options);
			CompilationUnit cast = (CompilationUnit) parser.createAST(new NullProgressMonitor());
			cast.recordModifications();
			ASTRewrite rewrite = ASTRewrite.create(cast.getAST());
			ASTTagVisitor visitor = new ASTTagVisitor(members, description, rewrite);
			cast.accept(visitor);
			ITextFileBufferManager bm = FileBuffers.getTextFileBufferManager();
			IPath path = cast.getJavaElement().getPath();
			try {
				bm.connect(path, LocationKind.IFILE, null);
				ITextFileBuffer tfb = bm.getTextFileBuffer(path, LocationKind.IFILE);
				IDocument document = tfb.getDocument();
				TextEdit edit = rewrite.rewriteAST(document, null);
				if (edit.getChildrenSize() > 0 || edit.getLength() != 0) {
					IFile file = (IFile) cunit.getUnderlyingResource();
					Set<TextEdit> edits = collector.get(file);
					if (edits == null) {
						edits = new HashSet<>(3);
						collector.put(file, edits);
					}
					edits.add(edit);
				}
			} finally {
				bm.disconnect(path, LocationKind.IFILE, null);
			}
		}
	}

	/**
	 * Throws an exception with the given message and underlying exception.
	 *
	 * @param message error message
	 * @param exception underlying exception, or <code>null</code>
	 * @throws CoreException
	 */
	private static void abort(String message, Throwable exception) throws CoreException {
		IStatus status = new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, message, exception);
		throw new CoreException(status);
	}

	/**
	 * Parses the given xml document (in string format), and annotates the
	 * specified {@link IApiDescription} with {@link IPackageDescriptor}s,
	 * {@link IReferenceTypeDescriptor}s, {@link IMethodDescriptor}s and
	 * {@link IFieldDescriptor}s.
	 *
	 * @param settings API settings to annotate
	 * @param xml XML used to generate settings
	 * @throws CoreException
	 */
	public static void annotateApiSettings(IJavaProject project, IApiDescription settings, String xml) throws CoreException {
		Element root = null;
		try {
			root = Util.parseDocument(xml);
		} catch (CoreException ce) {
			abort("Failed to parse API description xml file", ce); //$NON-NLS-1$
		}
		if (!root.getNodeName().equals(IApiXmlConstants.ELEMENT_COMPONENT)) {
			abort(ScannerMessages.ComponentXMLScanner_0, null);
		}
		String version = root.getAttribute(IApiXmlConstants.ATTR_VERSION);
		ApiDescription desc = (ApiDescription) settings;
		desc.setEmbeddedVersion(version);
		// TODO for now this compares to 1.2, since the change from 1.1 -> 1.2
		// denotes the
		// @noextend change, not 1.1 -> current version
		boolean earlierversion = desc.compareEmbeddedVersionTo("1.2") == 1; //$NON-NLS-1$
		NodeList packages = root.getElementsByTagName(IApiXmlConstants.ELEMENT_PACKAGE);
		NodeList types = null;
		IPackageDescriptor packdesc = null;
		Element type = null;
		for (int i = 0; i < packages.getLength(); i++) {
			Element pkg = (Element) packages.item(i);
			// package visibility comes from the MANIFEST.MF
			String pkgName = pkg.getAttribute(IApiXmlConstants.ATTR_NAME);
			packdesc = Factory.packageDescriptor(pkgName);
			types = pkg.getElementsByTagName(IApiXmlConstants.ELEMENT_TYPE);
			for (int j = 0; j < types.getLength(); j++) {
				type = (Element) types.item(j);
				String name = type.getAttribute(IApiXmlConstants.ATTR_NAME);
				if (name.length() == 0) {
					abort("Missing type name", null); //$NON-NLS-1$
				}
				IReferenceTypeDescriptor typedesc = packdesc.getType(name);
				annotateDescriptor(project, settings, typedesc, type, earlierversion);
				annotateMethodSettings(project, settings, typedesc, type, earlierversion);
				annotateFieldSettings(project, settings, typedesc, type, earlierversion);
			}
		}
	}

	/**
	 * Annotates the backing {@link IApiDescription} from the given
	 * {@link Element}, by adding the visibility and restriction attributes to
	 * the specified {@link IElementDescriptor}
	 *
	 * @param settings the settings to annotate
	 * @param descriptor the current descriptor context
	 * @param element the current element to annotate from
	 * @param earlierversion if the version read from XML is older than the
	 *            current tooling version
	 */
	private static void annotateDescriptor(IJavaProject project, IApiDescription settings, IElementDescriptor descriptor, Element element, boolean earlierversion) {
		int typeVis = getVisibility(element);
		if (typeVis != -1) {
			settings.setVisibility(descriptor, typeVis);
		}
		settings.setRestrictions(descriptor, getRestrictions(project, element, descriptor, earlierversion));
	}

	/**
	 * Returns restriction settings described in the given element.
	 *
	 * @param project the {@link IJavaProject} context
	 * @param element XML element
	 * @param descriptor the {@link IElementDescriptor} to get the restrictions
	 *            for
	 * @param earlierversion if the version read from XML is older than the
	 *            current tooling version
	 * @return restriction settings
	 */
	private static int getRestrictions(final IJavaProject project, final Element element, final IElementDescriptor descriptor, boolean earlierversion) {
		int res = RestrictionModifiers.NO_RESTRICTIONS;
		if (element.hasAttribute(IApiXmlConstants.ATTR_RESTRICTIONS)) {
			res = Integer.parseInt(element.getAttribute(IApiXmlConstants.ATTR_RESTRICTIONS));
		} else {
			switch (descriptor.getElementType()) {
				case IElementDescriptor.FIELD: {
					res = annotateRestriction(element, IApiXmlConstants.ATTR_REFERENCE, RestrictionModifiers.NO_REFERENCE, res);
					break;
				}
				case IElementDescriptor.METHOD: {
					IMethodDescriptor method = (IMethodDescriptor) descriptor;
					res = annotateRestriction(element, IApiXmlConstants.ATTR_REFERENCE, RestrictionModifiers.NO_REFERENCE, res);
					if (!method.isConstructor()) {
						res = annotateRestriction(element, IApiXmlConstants.ATTR_OVERRIDE, RestrictionModifiers.NO_OVERRIDE, res);
					}
					break;
				}
				case IElementDescriptor.TYPE: {
					IReferenceTypeDescriptor rtype = (IReferenceTypeDescriptor) descriptor;
					res = annotateRestriction(element, IApiXmlConstants.ATTR_IMPLEMENT, RestrictionModifiers.NO_IMPLEMENT, res);
					if (earlierversion && RestrictionModifiers.isImplementRestriction(res)) {
						res |= RestrictionModifiers.NO_EXTEND;
					}
					res = annotateRestriction(element, IApiXmlConstants.ATTR_EXTEND, RestrictionModifiers.NO_EXTEND, res);
					if (!RestrictionModifiers.isExtendRestriction(res)) {
						res = annotateRestriction(element, IApiXmlConstants.ATTR_SUBCLASS, RestrictionModifiers.NO_EXTEND, res);
					}
					res = annotateRestriction(element, IApiXmlConstants.ATTR_INSTANTIATE, RestrictionModifiers.NO_INSTANTIATE, res);
					IType type = null;
					if (project != null) {
						try {
							type = project.findType(rtype.getQualifiedName());
							IType typeInProject = Util.getTypeInSameJavaProject(type, rtype.getQualifiedName(), project);
							if (typeInProject != null) {
								type = typeInProject;
							}
						} catch (JavaModelException e) {
							ApiPlugin.log("Failed to find type for " + rtype.getQualifiedName(), e); //$NON-NLS-1$
						}
						if (type != null) {
							try {
								if (Flags.isInterface(type.getFlags())) {
									res &= ~RestrictionModifiers.NO_INSTANTIATE;
								} else {
									res &= ~RestrictionModifiers.NO_IMPLEMENT;
									if (Flags.isFinal(type.getFlags())) {
										res &= ~RestrictionModifiers.NO_EXTEND;
									}
									if (Flags.isAbstract(type.getFlags())) {
										res &= ~RestrictionModifiers.NO_INSTANTIATE;
									}
								}
							} catch (JavaModelException e) {
								ApiPlugin.log("Failed to read type flags for " + type, e); //$NON-NLS-1$
							}
						}
					}
					break;
				}
				default:
					break;
			}
		}
		return res;
	}

	/**
	 * Tests if the given restriction exists for the given element and returns
	 * an updated restrictions flag.
	 *
	 * @param element XML element
	 * @param name attribute to test
	 * @param flag bit mask for attribute
	 * @param res flag to combine with
	 * @return updated flags
	 */
	private static int annotateRestriction(Element element, String name, int flag, int res) {
		String value = element.getAttribute(name);
		int lres = res;
		if (value.length() > 0) {
			if (!Boolean.parseBoolean(value)) {
				lres = res | flag;
			}
		}
		return lres;
	}

	/**
	 * Returns visibility settings described in the given element or -1 if none.
	 *
	 * @param element XML element
	 * @return visibility settings or -1 if none
	 */
	private static int getVisibility(Element element) {
		String attribute = element.getAttribute(IApiXmlConstants.ATTR_VISIBILITY);
		if (attribute != null && attribute.isEmpty()) {
			return -1;
		}
		try {
			return Integer.parseInt(attribute);
		} catch (NumberFormatException nfe) {
			if ("API".equals(attribute)) { //$NON-NLS-1$
				return VisibilityModifiers.API;
			}
			if ("PRIVATE".equals(attribute)) { //$NON-NLS-1$
				return VisibilityModifiers.PRIVATE;
			}
			if ("PRIVATE_PERMISSABLE".equals(attribute)) { //$NON-NLS-1$
				return VisibilityModifiers.PRIVATE_PERMISSIBLE;
			}
			if ("SPI".equals(attribute)) { //$NON-NLS-1$
				return VisibilityModifiers.SPI;
			}
			return -1;
		}
	}

	/**
	 * Annotates the supplied {@link IApiDescription} from all of the field
	 * elements that are direct children of the specified {@link Element}.
	 * {@link IFieldDescriptor}s are created as needed and added as children of
	 * the specified {@link IReferenceTypeDescriptor}.
	 *
	 * @param settings the {@link IApiDescription} to add the new
	 *            {@link IFieldDescriptor} to
	 * @param typedesc the containing type descriptor for this field
	 * @param type the parent {@link Element}
	 * @param earlierversion if the version read from XML is older than the
	 *            current tooling version
	 * @throws CoreException
	 */
	private static void annotateFieldSettings(IJavaProject project, IApiDescription settings, IReferenceTypeDescriptor typedesc, Element type, boolean earlierversion) throws CoreException {
		NodeList fields = type.getElementsByTagName(IApiXmlConstants.ELEMENT_FIELD);
		Element field = null;
		IFieldDescriptor fielddesc = null;
		String name = null;
		for (int i = 0; i < fields.getLength(); i++) {
			field = (Element) fields.item(i);
			name = field.getAttribute(IApiXmlConstants.ATTR_NAME);
			if (name == null) {
				abort(ScannerMessages.ComponentXMLScanner_1, null);
			}
			fielddesc = typedesc.getField(name);
			annotateDescriptor(project, settings, fielddesc, field, earlierversion);
		}
	}

	/**
	 * Annotates the supplied {@link IApiDescription} from all of the method
	 * elements that are direct children of the specified {@link Element}.
	 * {@link IMethodDescriptor}s are created as needed and added as children of
	 * the specified {@link IReferenceTypeDescriptor}.
	 *
	 * @param settings the {@link IApiDescription} to add the new
	 *            {@link IMethodDescriptor} to
	 * @param typedesc the containing type descriptor for this method
	 * @param type the parent {@link Element}
	 * @param earlierversion if the version read from XML is older than the
	 *            current tooling version
	 * @throws CoreException
	 */
	private static void annotateMethodSettings(IJavaProject project, IApiDescription settings, IReferenceTypeDescriptor typedesc, Element type, boolean earlierversion) throws CoreException {
		NodeList methods = type.getElementsByTagName(IApiXmlConstants.ELEMENT_METHOD);
		Element method = null;
		IMethodDescriptor methoddesc = null;
		String name, signature;
		for (int i = 0; i < methods.getLength(); i++) {
			method = (Element) methods.item(i);
			name = method.getAttribute(IApiXmlConstants.ATTR_NAME);
			if (name == null) {
				abort(ScannerMessages.ComponentXMLScanner_2, null);
			}
			signature = method.getAttribute(IApiXmlConstants.ATTR_SIGNATURE);
			if (signature == null) {
				abort(ScannerMessages.ComponentXMLScanner_3, null);
			}
			// old files might use '.' instead of '/'
			signature = signature.replace('.', '/');
			methoddesc = typedesc.getMethod(name, signature);
			annotateDescriptor(project, settings, methoddesc, method, earlierversion);
		}
	}
}
