blob: 90dbb134f46eea0fcb1b91f7079e46a2c744e005 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2018 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.xtext.completeocl.validation;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.internal.ecore.es2as.Ecore2AS;
import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.internal.validation.PivotEObjectValidator;
import org.eclipse.ocl.pivot.resource.CSResource;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
/**
* A CompleteOCLEObjectValidator validates CompleteOCL invariants during an EMF validation, provided
* an CompleteOCLEObjectValidator instance has been registered as a validator in the EValidator.Registry.
*
* Loading of the Complete OCL occurs during @link{initialize()} which may be called explicitly
* or lazily during validation.
*/
public class CompleteOCLEObjectValidator extends PivotEObjectValidator
{
private static final Logger logger = Logger.getLogger(CompleteOCLEObjectValidator.class);
protected final @NonNull EnvironmentFactoryInternal environmentFactory;
protected final @NonNull EPackage ePackage;
protected final @NonNull URI oclURI;
private Ecore2AS ecore2as = null;
/**
* Construct a validator to apply the CompleteOCL invariants from oclURI to ePackage
* for the meta-models managed by a newly created environmentFactory.
*
* @deprecated Use the three argument constructor
*/
@Deprecated
public CompleteOCLEObjectValidator(@NonNull EPackage ePackage, @NonNull URI oclURI) {
this(ePackage, oclURI, OCL.newInstance().getEnvironmentFactory());
}
/**
* Construct a validator to apply the CompleteOCL invariants from oclURI to ePackage
* for the meta-models managed by environmentFactory.
*/
public CompleteOCLEObjectValidator(@NonNull EPackage ePackage, @NonNull URI oclURI, @NonNull EnvironmentFactory environmentFactory) {
super(null);
this.environmentFactory = (EnvironmentFactoryInternal) environmentFactory;
this.ePackage = ePackage;
if (EMFPlugin.IS_ECLIPSE_RUNNING) {
URIConverter uriConverter = this.environmentFactory.getResourceSet().getURIConverter();
this.oclURI = uriConverter.normalize(oclURI); // Convert platform:/resource to platform:/plugin if no project
}
else {
this.oclURI = oclURI;
}
ResourceSet resourceSet = ePackage.eResource().getResourceSet();
if (resourceSet != null) {
install(resourceSet, this.environmentFactory);
}
else {
this.environmentFactory.loadEPackage(ePackage);
}
}
// @Override
protected EPackage getEPackage() {
return ePackage;
}
public @NonNull PivotMetamodelManager getMetamodelManager() {
return environmentFactory.getMetamodelManager();
}
/**
* Perform the loading and installation of the Complete OCL, returning true if successful.
*/
public boolean initialize() {
Resource ecoreResource = ePackage.eResource();
if (ecoreResource == null) {
return false;
}
ecore2as = Ecore2AS.getAdapter(ecoreResource, environmentFactory);
ResourceSet resourceSet = new ResourceSetImpl();
environmentFactory.adapt(resourceSet);
List<Diagnostic> errors = ecoreResource.getErrors();
assert errors != null;
String message = PivotUtil.formatResourceDiagnostics(errors, "", "\n");
if (message != null) {
logger.error("Failed to load Ecore '" + ecoreResource.getURI() + message);
return false;
}
Model pivotModel = ecore2as.getASModel();
errors = pivotModel.eResource().getErrors();
assert errors != null;
message = PivotUtil.formatResourceDiagnostics(errors, "", "\n");
if (message != null) {
logger.error("Failed to load Pivot from '" + ecoreResource.getURI() + message);
return false;
}
CSResource xtextResource = (CSResource) resourceSet.getResource(oclURI, true);
errors = xtextResource.getErrors();
assert errors != null;
message = PivotUtil.formatResourceDiagnostics(errors, "", "\n");
if (message != null) {
logger.error("Failed to load '" + oclURI + message);
return false;
}
Resource asResource = xtextResource.getASResource();
errors = asResource.getErrors();
assert errors != null;
message = PivotUtil.formatResourceDiagnostics(errors, "", "\n");
if (message != null) {
logger.error("Failed to load Pivot from '" + oclURI + message);
return false;
}
return true;
}
@Override
protected boolean validatePivot(@NonNull EClassifier eClassifier, @Nullable Object object,
@Nullable DiagnosticChain diagnostics, Map<Object, Object> context) {
if (ecore2as == null) {
initialize();
}
ResourceSet resourceSet = getResourceSet(eClassifier, object, diagnostics);
if (resourceSet != null) {
ValidationAdapter validationAdapter = ValidationAdapter.findAdapter(resourceSet);
if (validationAdapter == null) {
validationAdapter = install(resourceSet, environmentFactory);
}
boolean allOk = validationAdapter.validate(eClassifier, object, complementingModels, diagnostics, context);
return allOk || (diagnostics != null);
}
return true;
}
}