<commit_before>/*******************************************************************************
 * Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
 * 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
 *******************************************************************************/
package org.eclipse.xtext.mwe;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.mwe.core.WorkflowInterruptedException;
import org.eclipse.emf.mwe.core.issues.Issues;
import org.eclipse.emf.mwe.core.issues.MWEDiagnostic;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.IResourceServiceProvider.Registry;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.Issue;

import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import com.google.inject.internal.Maps;

/**
 * @author <NAME> - Initial contribution and API
 */
public class Validator {
	
	private boolean validateAll = true;

	public void setValidateAll(boolean validateAll) {
		this.validateAll = validateAll;
	}

	private boolean stopOnError = true;

	public void setStopOnError(boolean stopOnError) {
		this.stopOnError = stopOnError;
	}
	
	public boolean isStopOnError() {
		return stopOnError;
	}
	
	public boolean isValidateAll() {
		return validateAll;
	}
	
	public void validate(ResourceSet resourceSet, IResourceServiceProvider.Registry registry, Issues issues) {
		List<Resource> resources = Lists.newArrayList(resourceSet.getResources());
		for (Resource resource : resources) {
			try {
				resource.load(null);
				IResourceServiceProvider provider = registry.getResourceServiceProvider(resource.getURI());
				if (provider!=null) {
					List<Issue> result = provider.getResourceValidator().validate(resource, CheckMode.ALL, null);
					for (Issue issue : result) {
						switch (issue.getSeverity()) {
							case ERROR :
								issues.addError(issue.getMessage(), issue);
								break;
							case WARNING :
								issues.addWarning(issue.getMessage(), issue);
								break;
							case INFO :
								issues.addInfo(issue.getMessage(), issue);
								break;
						}
					}
				}
			} catch (IOException e) {
				throw new WorkflowInterruptedException("Couldn't load resource ("+resource.getURI()+")",e);
			}
		}
		if (isStopOnError() && issues.hasErrors()) {
			String errorMessage = toString(issues);
			throw new WorkflowInterruptedException("Validation problems: \n" + errorMessage);
		}
	}
	
	public String toString(Issues issues) {
		if (!issues.hasErrors() && !issues.hasWarnings())
			return "No issues.";
		StringBuilder result = new StringBuilder();
		if (issues.hasErrors()) {
			MWEDiagnostic[] errors = issues.getErrors();
			if (errors.length == 1) {
				result.append("1 error:\n");
			} else {
				result.append(errors.length).append(" errors:\n");
			}
			appendMessages(result, errors);
		}
		if (issues.hasWarnings()) {
			MWEDiagnostic[] warnings = issues.getWarnings();
			if (issues.hasErrors())
				result.append('\n');
			if (warnings.length == 1) {
				result.append("1 warning:\n");
			} else {
				result.append(warnings.length).append(" warnings:\n");
			}
			appendMessages(result, warnings);
		}
		return result.toString();
	}

	protected void appendMessages(StringBuilder result, MWEDiagnostic[] diagnostics) {
		Multimap<URI, MWEDiagnostic> issuesPerURI = groupByURI(diagnostics);
		boolean first = true;
		for(URI uri: issuesPerURI.keySet()) {
			if (!first)
				result.append('\n');
			first = false;
			result
				.append('\t')
				.append(uri.lastSegment())
				.append(" - ");
			if (uri.isFile())
				result.append(uri.toFileString());
			else
				result.append(uri);
			for(MWEDiagnostic diagnostic: issuesPerURI.get(uri)) {
				Issue issue = (Issue) diagnostic.getElement();
				result.append("\n\t\t").append(issue.getLineNumber()).append(": ").append(diagnostic.getMessage());
			}
		}
	}
	
	protected Multimap<URI, MWEDiagnostic> groupByURI(MWEDiagnostic[] diagnostic) {
		Multimap<URI, MWEDiagnostic> result = Multimaps.newMultimap(Maps.<URI, Collection<MWEDiagnostic>> newLinkedHashMap(), new Supplier<Collection<MWEDiagnostic>>() {
			public Collection<MWEDiagnostic> get() {
				return Sets.newTreeSet(new Comparator<MWEDiagnostic>() {
					public int compare(MWEDiagnostic o1, MWEDiagnostic o2) {
						Issue issue1 = (Issue) o1.getElement();
						Issue issue2 = (Issue) o2.getElement();
						if (issue1.getLineNumber() < issue2.getLineNumber())
							return -1;
						if (issue1.getLineNumber() > issue2.getLineNumber())
							return 1;
						if (issue1.getOffset() < issue2.getOffset())
							return -1;
						if (issue1.getOffset() > issue2.getOffset())
							return 1;
						return o1.getMessage().compareTo(o2.getMessage());
					}
				});
			}
		});
		Multimaps.index(Arrays.asList(diagnostic), new Function<MWEDiagnostic, URI>() {
			public URI apply(MWEDiagnostic from) {
				Issue issue = (Issue) from.getElement();
				return issue.getUriToProblem().trimFragment();
			}
		}, result);
		return result;
	}
	
	public static class Disabled extends Validator {
		@Override
		public void validate(ResourceSet resourceSet, Registry registry, Issues issues) {
			// do nothing
		}
	}
	
}<commit_msg>Avoid NPEs, as syntax errors don't have a uriToProblem.<commit_after>/*******************************************************************************
 * Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
 * 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
 *******************************************************************************/
package org.eclipse.xtext.mwe;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.mwe.core.WorkflowInterruptedException;
import org.eclipse.emf.mwe.core.issues.Issues;
import org.eclipse.emf.mwe.core.issues.MWEDiagnostic;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.IResourceServiceProvider.Registry;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.Issue;

import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import com.google.inject.internal.Maps;

/**
 * @author <NAME> - Initial contribution and API
 */
public class Validator {

	private boolean validateAll = true;

	public void setValidateAll(boolean validateAll) {
		this.validateAll = validateAll;
	}

	private boolean stopOnError = true;

	public void setStopOnError(boolean stopOnError) {
		this.stopOnError = stopOnError;
	}

	public boolean isStopOnError() {
		return stopOnError;
	}

	public boolean isValidateAll() {
		return validateAll;
	}

	public void validate(ResourceSet resourceSet, IResourceServiceProvider.Registry registry, Issues issues) {
		List<Resource> resources = Lists.newArrayList(resourceSet.getResources());
		for (Resource resource : resources) {
			try {
				resource.load(null);
				IResourceServiceProvider provider = registry.getResourceServiceProvider(resource.getURI());
				if (provider != null) {
					List<Issue> result = provider.getResourceValidator().validate(resource, CheckMode.ALL, null);
					for (Issue issue : result) {
						switch (issue.getSeverity()) {
							case ERROR:
								issues.addError(issue.getMessage(), issue);
								break;
							case WARNING:
								issues.addWarning(issue.getMessage(), issue);
								break;
							case INFO:
								issues.addInfo(issue.getMessage(), issue);
								break;
						}
					}
				}
			} catch (IOException e) {
				throw new WorkflowInterruptedException("Couldn't load resource (" + resource.getURI() + ")", e);
			}
		}
		if (isStopOnError() && issues.hasErrors()) {
			String errorMessage = toString(issues);
			throw new WorkflowInterruptedException("Validation problems: \n" + errorMessage);
		}
	}

	public String toString(Issues issues) {
		if (!issues.hasErrors() && !issues.hasWarnings())
			return "No issues.";
		StringBuilder result = new StringBuilder();
		if (issues.hasErrors()) {
			MWEDiagnostic[] errors = issues.getErrors();
			if (errors.length == 1) {
				result.append("1 error:\n");
			} else {
				result.append(errors.length).append(" errors:\n");
			}
			appendMessages(result, errors);
		}
		if (issues.hasWarnings()) {
			MWEDiagnostic[] warnings = issues.getWarnings();
			if (issues.hasErrors())
				result.append('\n');
			if (warnings.length == 1) {
				result.append("1 warning:\n");
			} else {
				result.append(warnings.length).append(" warnings:\n");
			}
			appendMessages(result, warnings);
		}
		return result.toString();
	}

	protected void appendMessages(StringBuilder result, MWEDiagnostic[] diagnostics) {
		Multimap<URI, MWEDiagnostic> issuesPerURI = groupByURI(diagnostics);
		boolean first = true;
		for (URI uri : issuesPerURI.keySet()) {
			if (!first)
				result.append('\n');
			first = false;
			if (uri != null) {
				result.append('\t').append(uri.lastSegment()).append(" - ");
				if (uri.isFile())
					result.append(uri.toFileString());
				else
					result.append(uri);
			}
			for (MWEDiagnostic diagnostic : issuesPerURI.get(uri)) {
				Issue issue = (Issue) diagnostic.getElement();
				result.append("\n\t\t").append(issue.getLineNumber()).append(": ").append(diagnostic.getMessage());
			}
		}
	}

	protected Multimap<URI, MWEDiagnostic> groupByURI(MWEDiagnostic[] diagnostic) {
		Multimap<URI, MWEDiagnostic> result = Multimaps.newMultimap(
				Maps.<URI, Collection<MWEDiagnostic>> newLinkedHashMap(), new Supplier<Collection<MWEDiagnostic>>() {
					public Collection<MWEDiagnostic> get() {
						return Sets.newTreeSet(new Comparator<MWEDiagnostic>() {
							public int compare(MWEDiagnostic o1, MWEDiagnostic o2) {
								Issue issue1 = (Issue) o1.getElement();
								Issue issue2 = (Issue) o2.getElement();
								if (issue1.getLineNumber() < issue2.getLineNumber())
									return -1;
								if (issue1.getLineNumber() > issue2.getLineNumber())
									return 1;
								if (issue1.getOffset() < issue2.getOffset())
									return -1;
								if (issue1.getOffset() > issue2.getOffset())
									return 1;
								return o1.getMessage().compareTo(o2.getMessage());
							}
						});
					}
				});
		Multimaps.index(Arrays.asList(diagnostic), new Function<MWEDiagnostic, URI>() {
			public URI apply(MWEDiagnostic from) {
				Issue issue = (Issue) from.getElement();
				URI uriToProblem = issue.getUriToProblem();
				return uriToProblem != null ? uriToProblem.trimFragment() : null;
			}
		}, result);
		return result;
	}

	public static class Disabled extends Validator {
		@Override
		public void validate(ResourceSet resourceSet, Registry registry, Issues issues) {
			// do nothing
		}
	}

}
{'fraction_non_alphanumeric': 0.15269688528741454, 'fraction_numerical': 0.005402211530345235, 'mean_word_length': 4.035274118147046, 'pattern_counts': {'":': 2, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, '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': '6440168', 'n_tokens_mistral': 4267, 'n_tokens_neox': 3560, 'n_words': 759}