<commit_before>/*******************************************************************************
 * Copyright (c) 2011 <NAME>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:      
 *     <NAME> <<EMAIL>> - initial API and implementation
 *******************************************************************************/
package org.eclipse.angularjs.core.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.angularjs.core.AngularProject;
import org.eclipse.angularjs.core.DOMSSEDirectiveProvider;
import org.eclipse.angularjs.core.documentModel.dom.IAngularDOMAttr;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocument;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import tern.angular.modules.Directive;
import tern.angular.modules.DirectiveParameter;

/**
 * Utilities for SSE DOM node {@link IDOMNode}.
 * 
 */
public class DOMUtils {

	/**
	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the
	 * {@link IDocument} document and null if not found.
	 * 
	 * @param document
	 *            the document.
	 * @param offset
	 *            the offset.
	 * @return
	 */
	public static final IDOMNode getNodeByOffset(IDocument document, int offset) {
		IStructuredModel model = null;
		try {
			model = StructuredModelManager.getModelManager()
					.getExistingModelForRead(document);
			return getNodeByOffset(model, offset);
		} finally {
			if (model != null)
				model.releaseFromRead();
		}
	}

	/**
	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the
	 * {@link IStructuredModel} SSE mode and null if not found.
	 * 
	 * @param model
	 *            the SSE model.
	 * @param offset
	 *            the offset.
	 * @return
	 */
	public static final IDOMNode getNodeByOffset(IStructuredModel model,
			int offset) {
		IndexedRegion node = null;
		if (model != null) {
			node = model.getIndexedRegion(offset);
			if (node instanceof IDOMNode) {
				return (IDOMNode) node;
			}

			if (model != null) {
				int lastOffset = offset;
				node = model.getIndexedRegion(offset);
				while (node == null && lastOffset >= 0) {
					lastOffset--;
					node = model.getIndexedRegion(lastOffset);
				}
			}
		}
		return (IDOMNode) node;
	}

	/**
	 * Returns the SSE DOM Attribute {@link IDOMAttr} by region from the SSE DOM
	 * element {@link IDOMElement}.
	 * 
	 * @param element
	 *            the SSE DOM element {@link IDOMElement}.
	 * @param region
	 *            the region.
	 * @return
	 */
	public static IDOMAttr getAttrByRegion(IDOMNode element, ITextRegion region) {
		IStructuredDocumentRegion structuredDocumentRegionElement = element
				.getFirstStructuredDocumentRegion();

		// 1) Get attribute name region
		ITextRegionList elementRegions = structuredDocumentRegionElement
				.getRegions();
		int index = elementRegions.indexOf(region);
		if (index < 0) {
			return null;
		}

		ITextRegion attrNameRegion = null;
		while (index >= 0) {
			attrNameRegion = elementRegions.get(index--);
			if (attrNameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
				break;
			}
		}
		if (attrNameRegion == null) {
			return null;
		}
		String attrName = structuredDocumentRegionElement
				.getText(attrNameRegion);
		return (IDOMAttr) element.getAttributes().getNamedItem(attrName);
	}

	/**
	 * Returns the SSE DOM Attribute {@link IDOMAttr} by offset from the SSE DOM
	 * node {@link IDOMNode}.<commit_msg>Check if region is a attribute region.<commit_after>/*******************************************************************************
 * Copyright (c) 2011 <NAME>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:      
 *     <NAME> <<EMAIL>> - initial API and implementation
 *******************************************************************************/
package org.eclipse.angularjs.core.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.angularjs.core.AngularProject;
import org.eclipse.angularjs.core.DOMSSEDirectiveProvider;
import org.eclipse.angularjs.core.documentModel.dom.IAngularDOMAttr;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocument;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import tern.angular.modules.Directive;
import tern.angular.modules.DirectiveParameter;

/**
 * Utilities for SSE DOM node {@link IDOMNode}.
 * 
 */
public class DOMUtils {

	/**
	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the
	 * {@link IDocument} document and null if not found.
	 * 
	 * @param document
	 *            the document.
	 * @param offset
	 *            the offset.
	 * @return
	 */
	public static final IDOMNode getNodeByOffset(IDocument document, int offset) {
		IStructuredModel model = null;
		try {
			model = StructuredModelManager.getModelManager()
					.getExistingModelForRead(document);
			return getNodeByOffset(model, offset);
		} finally {
			if (model != null)
				model.releaseFromRead();
		}
	}

	/**
	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the
	 * {@link IStructuredModel} SSE mode and null if not found.
	 * 
	 * @param model
	 *            the SSE model.
	 * @param offset
	 *            the offset.
	 * @return
	 */
	public static final IDOMNode getNodeByOffset(IStructuredModel model,
			int offset) {
		IndexedRegion node = null;
		if (model != null) {
			node = model.getIndexedRegion(offset);
			if (node instanceof IDOMNode) {
				return (IDOMNode) node;
			}

			if (model != null) {
				int lastOffset = offset;
				node = model.getIndexedRegion(offset);
				while (node == null && lastOffset >= 0) {
					lastOffset--;
					node = model.getIndexedRegion(lastOffset);
				}
			}
		}
		return (IDOMNode) node;
	}

	/**
	 * Returns the SSE DOM Attribute {@link IDOMAttr} by region from the SSE DOM
	 * element {@link IDOMElement}.
	 * 
	 * @param element
	 *            the SSE DOM element {@link IDOMElement}.
	 * @param region
	 *            the region.
	 * @return
	 */
	public static IDOMAttr getAttrByRegion(IDOMNode element, ITextRegion region) {
		if (!isAttrRegion(region)) {
			return null;
		}

		IStructuredDocumentRegion structuredDocumentRegionElement = element
				.getFirstStructuredDocumentRegion();

		// 1) Get attribute name region
		ITextRegionList elementRegions = structuredDocumentRegionElement
				.getRegions();
		int index = elementRegions.indexOf(region);
		if (index < 0) {
			return null;
		}

		ITextRegion attrNameRegion = null;
		while (index >= 0) {
			attrNameRegion = elementRegions.get(index--);
			if (attrNameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
				break;
			}
		}
		if (attrNameRegion == null) {
			return null;
		}
		String attrName = structuredDocumentRegionElement
				.getText(attrNameRegion);
		return (IDOMAttr) element.getAttributes().getNamedItem(attrName);
	}

	private static boolean isAttrRegion(ITextRegion region) {
		if (region == null) {
			return false;
		}
		String type = region.getType();
		return DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)
				|| DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS.equals(type)
				|| DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type);
	}

	/**
	 * Returns the SSE DOM Attribute {@link IDOMAttr} by offset from the SSE DOM
	 * node {@link IDOMNode}.
{'fraction_non_alphanumeric': 0.13542806005767127, 'fraction_numerical': 0.003977329223426469, 'mean_word_length': 4.0039800995024875, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6101405', 'n_tokens_mistral': 3393, 'n_tokens_neox': 3039, 'n_words': 714}