blob: 4d27033fa0dfa19fb681d68ec58796ad7240b053 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2013 E.D.Willink 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
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.xtext.completeocl.validation;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
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.impl.ResourceSetImpl;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.pivot.Root;
import org.eclipse.ocl.examples.pivot.ecore.Ecore2Pivot;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManagerResourceSetAdapter;
import org.eclipse.ocl.examples.pivot.utilities.BaseResource;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.pivot.validation.PivotEObjectValidator;
/**
* 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 MetaModelManager metaModelManager;
protected final @NonNull EPackage ePackage;
protected final @NonNull URI oclURI;
private Ecore2Pivot ecore2Pivot = null;
/**
* Construct a validator to apply the CompleteOCL invariants from oclURI to ePackage.
*/
@Deprecated
public CompleteOCLEObjectValidator(@NonNull EPackage ePackage, @NonNull URI oclURI) {
this(ePackage, oclURI, null);
}
/**
* Construct a validator to apply the CompleteOCL invariants from oclURI to ePackage
* for the meta-models managed by metaModelManager.
*/
public CompleteOCLEObjectValidator(@NonNull EPackage ePackage, @NonNull URI oclURI, @Nullable MetaModelManager metaModelManager) {
if (metaModelManager == null) {
metaModelManager = new MetaModelManager();
}
this.metaModelManager = metaModelManager;
this.ePackage = ePackage;
this.oclURI = oclURI;
ResourceSet resourceSet = ePackage.eResource().getResourceSet();
if (resourceSet != null) {
install(resourceSet, metaModelManager);
}
else {
metaModelManager.loadEPackage(ePackage);
}
}
// @Override
protected EPackage getEPackage() {
return ePackage;
}
public MetaModelManager getMetaModelManager() {
return metaModelManager;
}
/**
* 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;
}
ecore2Pivot = Ecore2Pivot.getAdapter(ecoreResource, metaModelManager);
ResourceSet resourceSet = new ResourceSetImpl();
MetaModelManagerResourceSetAdapter.getAdapter(resourceSet, metaModelManager);
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;
}
Root pivotRoot = ecore2Pivot.getPivotRoot();
errors = pivotRoot.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;
}
BaseResource xtextResource = null;
try {
xtextResource = (BaseResource) resourceSet.getResource(oclURI, true);
}
catch (WrappedException e) {
URI retryURI = null;
Throwable cause = e.getCause();
if (cause instanceof CoreException) {
IStatus status = ((CoreException)cause).getStatus();
if ((status.getCode() == IResourceStatus.RESOURCE_NOT_FOUND) && status.getPlugin().equals(ResourcesPlugin.PI_RESOURCES)) {
if (oclURI.isPlatformResource()) {
retryURI = URI.createPlatformPluginURI(oclURI.toPlatformString(false), false);
}
}
}
if (retryURI != null) {
xtextResource = (BaseResource) resourceSet.getResource(retryURI, true);
}
else {
throw e;
}
}
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(metaModelManager);
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 ((ecore2Pivot == null) && (object instanceof EObject)) {
initialize();
Resource eResource = ((EObject)object).eResource();
if (eResource != null) {
ResourceSet resourceSet = eResource.getResourceSet();
if (resourceSet != null) {
install(resourceSet, metaModelManager);
}
}
}
return super.validatePivot(eClassifier, object, diagnostics, context);
}
}