/**
* Copyright (c) 2011-2012 Eclipse contributors 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.emf.ecore.xcore.validation;
import java.util.List;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreValidator;
import org.eclipse.emf.ecore.xcore.XClass;
import org.eclipse.emf.ecore.xcore.XGenericType;
import org.eclipse.emf.ecore.xcore.XOperation;
import org.eclipse.emf.ecore.xcore.XTypeParameter;
import org.eclipse.emf.ecore.xcore.XTypedElement;
import org.eclipse.emf.ecore.xcore.XcorePackage;
import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.util.IAcceptor;
import org.eclipse.xtext.validation.AbstractValidationDiagnostic;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.validation.Issue.IssueImpl;
import org.eclipse.xtext.xtext.XtextDiagnosticConverter;
import com.google.inject.Inject;
public class XcoreDiagnosticConverter extends XtextDiagnosticConverter
{
@Inject
private XcoreMapper mapper;
protected boolean isEcoreConstraint(Diagnostic diagnostic)
{
return EcoreValidator.DIAGNOSTIC_SOURCE.equals(diagnostic.getSource());
}
protected boolean isEObjectConstraint(Diagnostic diagnostic)
{
return EObjectValidator.DIAGNOSTIC_SOURCE.equals(diagnostic.getSource());
}
@Override
public void convertValidatorDiagnostic(Diagnostic diagnostic, IAcceptor<Issue> acceptor)
{
if (diagnostic.getSeverity() != Diagnostic.OK)
{
if (isEObjectConstraint(diagnostic))
{
switch (diagnostic.getCode())
{
case EcoreValidator.EOBJECT__EVERY_MULTIPCITY_CONFORMS:
{
// Ignore the warning about the attribute/reference type not being set; there's always another root cause.
//
List<?> data = diagnostic.getData();
if (data.contains(EcorePackage.Literals.EATTRIBUTE__EATTRIBUTE_TYPE) || data.contains(EcorePackage.Literals.EREFERENCE__EREFERENCE_TYPE))
{
return;
}
break;
}
}
}
IssueImpl issue = new Issue.IssueImpl();
switch (diagnostic.getSeverity())
{
case Diagnostic.INFO:
{
issue.setSeverity(Severity.INFO);
break;
}
case Diagnostic.WARNING:
{
issue.setSeverity(Severity.WARNING);
break;
}
default:
{
issue.setSeverity(Severity.ERROR);
break;
}
}
IssueLocation locationData = getLocationData(diagnostic);
if (locationData != null)
{
issue.setLineNumber(locationData.lineNumber);
issue.setOffset(locationData.offset);
issue.setLength(locationData.length);
}
EObject causer = getCauser(diagnostic);
if (causer != null)
{
issue.setUriToProblem(EcoreUtil.getURI(causer));
}
if (diagnostic instanceof AbstractValidationDiagnostic)
{
AbstractValidationDiagnostic abstractValidationDiagnostic = (AbstractValidationDiagnostic) diagnostic;
issue.setType(abstractValidationDiagnostic.getCheckType());
issue.setCode(abstractValidationDiagnostic.getIssueCode());
issue.setData(abstractValidationDiagnostic.getIssueData());
}
else
{
issue.setType(CheckType.FAST);
issue.setCode(diagnostic.getSource() + "." + diagnostic.getCode());
}
issue.setMessage(diagnostic.getMessage());
acceptor.accept(issue);
}
}
@Override
protected IssueLocation getLocationData(Diagnostic diagnostic)
{
if (isEcoreConstraint(diagnostic))
{
switch (diagnostic.getCode())
{
case EcoreValidator.CONSISTENT_BOUNDS:
case EcoreValidator.SINGLE_CONTAINER:
{
EObject causer = getCauser(diagnostic);
return getLocationData(causer, XcorePackage.Literals.XTYPED_ELEMENT__MULTIPLICITY);
}
case EcoreValidator.CONSISTENT_OPPOSITE_BAD_TRANSIENT:
case EcoreValidator.CONSISTENT_OPPOSITE_BOTH_CONTAINMENT:
case EcoreValidator.CONSISTENT_OPPOSITE_NOT_MATCHING:
{
EObject causer = getCauser(diagnostic);
return getLocationData(causer, XcorePackage.Literals.XREFERENCE__OPPOSITE);
}
}
}
return super.getLocationData(diagnostic);
}
protected EObject getCauser(EObject eObject)
{
if (eObject instanceof ENamedElement)
{
return mapper.getToXcoreMapping(eObject).getXcoreElement();
}
else if (eObject instanceof EGenericType)
{
EObject eContainer = eObject.eContainer();
if (eContainer != null)
{
EObject causerContainer = getCauser(eContainer);
EReference eContainmentFeature = eObject.eContainmentFeature();
if (eContainmentFeature == EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)
{
return ((XTypedElement)causerContainer).getType();
}
else if (eContainmentFeature == EcorePackage.Literals.EOPERATION__EGENERIC_EXCEPTIONS)
{
return ((XOperation)causerContainer).getExceptions().get(((EOperation)eContainer).getEGenericExceptions().indexOf(eObject));
}
else if (eContainmentFeature == EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES)
{
return ((XClass)causerContainer).getSuperTypes().get(((EClass)eContainer).getEGenericSuperTypes().indexOf(eObject));
}
else if (eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS)
{
return ((XGenericType)causerContainer).getTypeArguments().get(((EGenericType)eContainer).getETypeArguments().indexOf(eObject));
}
else if (eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND)
{
return ((XGenericType)causerContainer).getLowerBound();
}
else if (eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND)
{
return ((XGenericType)causerContainer).getUpperBound();
}
else if (eContainmentFeature == EcorePackage.Literals.ETYPE_PARAMETER__EBOUNDS)
{
return ((XTypeParameter)causerContainer).getBounds().get(((ETypeParameter)eContainer).getEBounds().indexOf(eObject));
}
}
return eObject;
}
else
{
return eObject;
}
}
@Override
protected EObject getCauser(Diagnostic diagnostic)
{
if (isEcoreConstraint(diagnostic))
{
switch (diagnostic.getCode())
{
case EcoreValidator.UNIQUE_CLASSIFIER_NAMES:
case EcoreValidator.UNIQUE_ENUMERATOR_LITERALS:
case EcoreValidator.UNIQUE_ENUMERATOR_NAMES:
{
return getCauser((EObject)diagnostic.getData().get(2));
}
}
}
EObject result = super.getCauser(diagnostic);
if (result.eClass().getEPackage() == EcorePackage.eINSTANCE)
{
result = getCauser(result);
}
return result;
}
}