All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.xtext.mwe.Validator Maven / Gradle / Ivy

There is a newer version: 2.4.3
Show newest version
/*******************************************************************************
 * 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.util.Strings;
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.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;

/**
 * @author Sven Efftinge - 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 resources = Lists.newArrayList(resourceSet.getResources());
		for (Resource resource : resources) {
			try {
				resource.load(null);
				IResourceServiceProvider provider = registry.getResourceServiceProvider(resource.getURI());
				if (provider != null) {
					List 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 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 groupByURI(MWEDiagnostic[] diagnostic) {
		Multimap result = Multimaps.newMultimap(
				Maps.> newLinkedHashMap(), new Supplier>() {
					public Collection get() {
						return Sets.newTreeSet(getDiagnosticComparator());
					}
				});
		result.putAll(Multimaps.index(Arrays.asList(diagnostic), new Function() {
			public URI apply(MWEDiagnostic from) {
				Issue issue = (Issue) from.getElement();
				URI uriToProblem = issue.getUriToProblem();
				return uriToProblem != null ? uriToProblem.trimFragment() : NullURI;
			}
		}));
		return result;
	}
	
	private final static URI NullURI = URI.createURI("no/uri");

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

	protected Comparator getDiagnosticComparator() {
		return new MWEDiagnosticComparator();
	}

	public static class MWEDiagnosticComparator implements Comparator {
		public int compare(MWEDiagnostic o1, MWEDiagnostic o2) {
			Issue issue1 = (Issue) o1.getElement();
			Issue issue2 = (Issue) o2.getElement();
			int lineNumberCompare = nullSafeCompare(issue1.getLineNumber(), issue2.getLineNumber());
			if (lineNumberCompare != 0) {
				return lineNumberCompare;
			}
			int offsetCompare = nullSafeCompare(issue1.getOffset(), issue2.getOffset());
			if (offsetCompare != 0) {
				return offsetCompare;
			}
			return Strings.notNull(o1.getMessage()).compareTo(Strings.notNull(o2.getMessage()));
		}

		protected int nullSafeCompare(Integer x, Integer y) {
			return notNull(x).compareTo(notNull(y));
		}

		protected Integer notNull(Integer x) {
			return x != null ? x : Integer.valueOf(-1);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy