<commit_before>package com.reprezen.swagedit.validation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.reprezen.swagedit.editor.SwaggerDocument;

/**
 * This class contains methods for validating a Swagger YAML document.
 * 
 * Validation is done against the Swagger JSON Schema.
 * 
 * @see SwaggerError
 */
public class Validator {

	private static final Schema schema = new Schema();

	/**
	 * Returns a list or errors if validation fails. 
	 * 
	 * This method accepts as input a swagger YAML document and 
	 * validates it against the swagger JSON Schema.
	 * 
	 * @param content
	 * @return list or errors
	 */
	public List<SwaggerError> validate(SwaggerDocument document) {
		final JsonNode spec = document.getTree();

		if (spec == null) {
			return Collections.singletonList(new SwaggerError(
					IMarker.SEVERITY_ERROR, 
					"Unable to read content.  It may be invalid YAML"));
		} else {
			ProcessingReport report = null;
			try {
				report = schema.getSchema().validate(spec);
			} catch (ProcessingException e) {
				e.printStackTrace();
			}

			return create(report, document.getYaml());
		}
	}

	private List<SwaggerError> create(ProcessingReport report, Node yamlTree) {
		final List<SwaggerError> errors = new ArrayList<>();
		if (report != null) {
			for (Iterator<ProcessingMessage> it = report.iterator(); it.hasNext();) {
				final ProcessingMessage next = it.next();
				final int line = getLine(next, yamlTree);

				errors.add(SwaggerError.create(next, line));
			}
		}

		return errors;
	}

	/*
	 * Returns the line for which an error message has been produced.
	 *
	 *  The error message is a JSON object that contains the path to
	 *  the invalid node. The path is accessible via instance.pointer.
	 *  The path is in the forms:
	 *  - /{id}
	 *  - /{id}/~{nb}
	 *  - /{id}/~{id2}
	 *
	 *  The line number is computed by after parsing the yaml content with
	 *  the yaml parser. This latter returns a tree of Node, each corresponding
	 *  to a yaml construct and including a position.
	 *
	 *  The Node matching the path is found by the methods findNode().
	 */
	private int getLine(ProcessingMessage message, Node yamlTree) {	
		final JsonNode m = message.asJson();
		if (!m.has("instance") || !m.get("instance").has("pointer"))
			return 1;

		String path = m.get("instance").get("pointer").asText();

		if (path == null || path.isEmpty()) 
			return 1;

		path = path.substring(1, path.length());
		String[] strings = path.split("/");

		if (yamlTree instanceof MappingNode) {
			MappingNode mn = (MappingNode) yamlTree;

			Node findNode = findNode(mn, Arrays.asList(strings));
			if (findNode != null) {
				return findNode.getStartMark().getLine() + 1;
			}
		}

		return 1;
	}

	/*
	 * Returns the yaml node that matches the given path.
	 *
	 * The path is given as a list of String. The Node matching the
	 * path is found by traversing the children of the node pass as
	 * first parameter.
	 *
	 */
	private Node findNode(MappingNode root, List<String> paths) {
		if (paths.isEmpty())
			return root;

		String path = paths.get(0);
		if (path.startsWith("/")) {
			path = path.substring(1, path.length());
		}

		final List<String> next = paths.subList(1, paths.size());

		if (path.startsWith("~")) {
			path = path.substring(1, path.length());
			// path positions start at 1
			int pos = Integer.valueOf(path) - 1;
			if (pos >= 0 && pos < root.getValue().size()) {
				NodeTuple nodeTuple = root.getValue().get(pos);
				if (nodeTuple != null) {
					return findNode(nodeTuple, next);
				}
			}
		} else {
			for (NodeTuple child: root.getValue()) {
				if (child.getKeyNode() instanceof ScalarNode) {
					ScalarNode scalar = (ScalarNode) child.getKeyNode();

					if (scalar.getValue().equals(path)) {
						return findNode(child, next);
					}
				}
			}
		}
		return root;
	}

	private Node findNode(NodeTuple child, List<String> paths) {
		if (child.getValueNode() instanceof MappingNode) {
			return findNode((MappingNode) child.getValueNode(), paths);
		}
		return child.getKeyNode();
	}

}
<commit_msg>[#12] Save fails when saving after renaming an element<commit_after>package com.reprezen.swagedit.validation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.reprezen.swagedit.editor.SwaggerDocument;

/**
 * This class contains methods for validating a Swagger YAML document.
 * 
 * Validation is done against the Swagger JSON Schema.
 * 
 * @see SwaggerError
 */
public class Validator {

	private static final Schema schema = new Schema();

	/**
	 * Returns a list or errors if validation fails. 
	 * 
	 * This method accepts as input a swagger YAML document and 
	 * validates it against the swagger JSON Schema.
	 * 
	 * @param content
	 * @return list or errors
	 */
	public List<SwaggerError> validate(SwaggerDocument document) {
		final JsonNode spec = document.getTree();

		if (spec == null) {
			return Collections.singletonList(new SwaggerError(
					IMarker.SEVERITY_ERROR, 
					"Unable to read content.  It may be invalid YAML"));
		} else {
			ProcessingReport report = null;
			try {
				report = schema.getSchema().validate(spec);
			} catch (ProcessingException e) {
				e.printStackTrace();
			}

			return create(report, document.getYaml());
		}
	}

	private List<SwaggerError> create(ProcessingReport report, Node yamlTree) {
		final List<SwaggerError> errors = new ArrayList<>();
		if (report != null) {
			for (Iterator<ProcessingMessage> it = report.iterator(); it.hasNext();) {
				final ProcessingMessage next = it.next();
				final int line = getLine(next, yamlTree);

				errors.add(SwaggerError.create(next, line));
			}
		}

		return errors;
	}

	/*
	 * Returns the line for which an error message has been produced.
	 *
	 *  The error message is a JSON object that contains the path to
	 *  the invalid node. The path is accessible via instance.pointer.
	 *  The path is in the forms:
	 *  - /{id}
	 *  - /{id}/~{nb}
	 *  - /{id}/~{id2}
	 *
	 *  The line number is computed by after parsing the yaml content with
	 *  the yaml parser. This latter returns a tree of Node, each corresponding
	 *  to a yaml construct and including a position.
	 *
	 *  The Node matching the path is found by the methods findNode().
	 */
	private int getLine(ProcessingMessage message, Node yamlTree) {	
		final JsonNode m = message.asJson();
		if (!m.has("instance") || !m.get("instance").has("pointer"))
			return 1;

		String path = m.get("instance").get("pointer").asText();

		if (path == null || path.isEmpty()) 
			return 1;

		path = path.substring(1, path.length());
		String[] strings = path.split("/");

		if (yamlTree instanceof MappingNode) {
			MappingNode mn = (MappingNode) yamlTree;

			Node findNode = findNode(mn, Arrays.asList(strings));
			if (findNode != null) {
				return findNode.getStartMark().getLine() + 1;
			}
		}

		return 1;
	}

	/*
	 * Returns the yaml node that matches the given path.
	 *
	 * The path is given as a list of String. The Node matching the
	 * path is found by traversing the children of the node pass as
	 * first parameter.
	 *
	 */
	private Node findNode(MappingNode root, List<String> paths) {
		if (paths.isEmpty())
			return root;

		String path = paths.get(0);
		if (path.startsWith("/")) {
			path = path.substring(1, path.length());
		}

		final List<String> next = paths.subList(1, paths.size());
		// ~1 seems to be used to escape /
		if (path.startsWith("~1")) {		
			path = "/" + path.substring(2, path.length());
		}

		for (NodeTuple child: root.getValue()) {
			if (child.getKeyNode() instanceof ScalarNode) {
				ScalarNode scalar = (ScalarNode) child.getKeyNode();

				if (scalar.getValue().equals(path)) {
					return findNode(child, next);
				}
			}
		}

		return root;
	}

	private Node findNode(NodeTuple child, List<String> paths) {
		if (child.getValueNode() instanceof MappingNode) {
			return findNode((MappingNode) child.getValueNode(), paths);
		}
		return child.getKeyNode();
	}

}

{'fraction_non_alphanumeric': 0.12205638474295191, 'fraction_numerical': 0.0029850746268656717, 'mean_word_length': 3.550301810865191, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '7251642', 'n_tokens_mistral': 3137, 'n_tokens_neox': 2736, 'n_words': 831}