blob: 7cdba66ce7c234a40dffcad25c5cfb208899491f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2018 IBM Corporation 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:
* IBM - Initial API and implementation
* Adolfo Sanchez-Barbudo Herrera (Open Canarias) - Bug 333032
*******************************************************************************/
package org.eclipse.ocl.ecore.tests;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EnvironmentFactory;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.EvaluationVisitor;
import org.eclipse.ocl.LookupException;
import org.eclipse.ocl.OCLInput;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.SemanticException;
import org.eclipse.ocl.TypeResolver;
import org.eclipse.ocl.ecore.CallOperationAction;
import org.eclipse.ocl.ecore.Constraint;
import org.eclipse.ocl.ecore.EcoreEnvironmentFactory;
import org.eclipse.ocl.ecore.EnvironmentWithHiddenOpposites;
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.ecore.SendSignalAction;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.helper.OCLSyntaxHelper;
import org.eclipse.ocl.parser.AbstractOCLParser;
import org.eclipse.ocl.parser.OCLAnalyzer;
import org.eclipse.ocl.parser.OCLFactoryWithHistory;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.utilities.OCLFactory;
import org.eclipse.ocl.utilities.TypedElement;
import org.eclipse.ocl.utilities.UMLReflection;
import org.eclipse.ocl.utilities.Visitor;
/**
* Tests the extensibility of the parser API.
*
* @author Christian W. Damus (cdamus)
*/
@SuppressWarnings("nls")
public class ExtensibilityTest
extends AbstractTestSuite {
/**
* Tests that we can successfully parse with an environment that does not
* implement the optional adapter protocols.
*/
public void test_noAdapters_parseSuccessfully() {
helper.setContext(EcorePackage.Literals.EPACKAGE);
try {
helper.createInvariant("not self.eClassifiers->isEmpty()");
} catch (ParserException e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
try {
ocl.parse(new OCLInput(
"context ecore::EPackage\n" +
"inv: not self.eClassifiers->isEmpty()"));
} catch (ParserException e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests that we can produce warnings with an environment that does not
* implement the optional adapter protocols.
*/
public void test_noAdapters_parseWithWarning() {
helper.setContext(EcorePackage.Literals.EPACKAGE);
try {
helper.createInvariant("not self.\"eClassifiers\"->isEmpty()");
Diagnostic diag = helper.getProblems();
assertNotNull(diag);
assertEquals(Diagnostic.WARNING, diag.getSeverity());
debugPrintln("Got expected warning: " + diag.getMessage());
} catch (ParserException e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
try {
ocl.parse(new OCLInput(
"context ecore::EPackage\n" +
"inv: not self.\"eClassifiers\"->isEmpty()"));
Diagnostic diag = ocl.getProblems();
assertNotNull(diag);
assertEquals(Diagnostic.WARNING, diag.getSeverity());
debugPrintln("Got expected warning: " + diag.getMessage());
} catch (ParserException e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests that we can produce errors with an environment that does not
* implement the optional adapter protocols.
*/
public void test_noAdapters_parseWithError() {
helper.setContext(EcorePackage.Literals.EPACKAGE);
try {
helper.createInvariant("not self.classifiers->isEmpty()");
fail("Should not have parsed");
} catch (ParserException e) {
// success
debugPrintln("Got expected error: " + e.getLocalizedMessage());
}
try {
ocl.parse(new OCLInput(
"context ecore::EPackage\n" +
"inv: not self.classifiers->isEmpty()"));
fail("Should not have parsed");
} catch (ParserException e) {
// success
debugPrintln("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests that we can report lexer problems with an environment that does not
* implement the optional adapter protocols.
*/
public void test_noAdapters_parseWithTokenError() {
helper.setContext(EcorePackage.Literals.EPACKAGE);
try {
helper.createInvariant("not self.;->isEmpty()");
fail("Should not have parsed");
} catch (ParserException e) {
// success
debugPrintln("Got expected error: " + e.getLocalizedMessage());
}
try {
ocl.parse(new OCLInput(
"context ecore::EPackage\n" +
"inv: not self.;->isEmpty()"));
fail("Should not have parsed");
} catch (ParserException e) {
// success
debugPrintln("Got expected error: " + e.getLocalizedMessage());
}
}
//
// Framework methods
//
@Override
protected OCL createOCL() {
return OCL.newInstance(new WrapperEnvironmentFactory());
}
class WrapperEnvironment implements EnvironmentWithHiddenOpposites {
private final EnvironmentWithHiddenOpposites
delegate;
private final EnvironmentWithHiddenOpposites
parent;
private final WrapperEnvironmentFactory factory;
WrapperEnvironment(WrapperEnvironmentFactory factory,
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> delegate) {
this(factory, delegate, null);
}
WrapperEnvironment(WrapperEnvironmentFactory factory,
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> delegate,
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent) {
this.factory = factory;
this.delegate = (EnvironmentWithHiddenOpposites) delegate;
this.parent = (EnvironmentWithHiddenOpposites) parent;
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> getParent() {
return parent;
}
public EnvironmentFactory<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> getFactory() {
return factory;
}
public boolean addElement(String name,
Variable<EClassifier, EParameter> elem, boolean explicit) {
return delegate.addElement(name, elem, explicit);
}
public EStructuralFeature defineAttribute(EClassifier owner,
Variable<EClassifier, EParameter> variable,
Constraint constraint) {
return delegate.defineAttribute(owner, variable, constraint);
}
public EOperation defineOperation(EClassifier owner, String name,
EClassifier type,
List<Variable<EClassifier, EParameter>> params,
Constraint constraint) {
return delegate.defineOperation(owner, name, type, params,
constraint);
}
public void deleteElement(String name) {
delegate.deleteElement(name);
}
public List<EStructuralFeature> getAdditionalAttributes(
EClassifier classifier) {
return delegate.getAdditionalAttributes(classifier);
}
public List<EOperation> getAdditionalOperations(EClassifier classifier) {
return delegate.getAdditionalOperations(classifier);
}
public Constraint getBodyCondition(EOperation operation) {
return delegate.getBodyCondition(operation);
}
public EClassifier getContextClassifier() {
return delegate.getContextClassifier();
}
public EOperation getContextOperation() {
return delegate.getContextOperation();
}
public EPackage getContextPackage() {
return delegate.getContextPackage();
}
public EStructuralFeature getContextProperty() {
return delegate.getContextProperty();
}
public Constraint getDefinition(Object feature) {
return delegate.getDefinition(feature);
}
public Constraint getDeriveConstraint(EStructuralFeature property) {
return delegate.getDeriveConstraint(property);
}
public Constraint getInitConstraint(EStructuralFeature property) {
return delegate.getInitConstraint(property);
}
public OCLFactory getOCLFactory() {
return delegate.getOCLFactory();
}
public OCLStandardLibrary<EClassifier> getOCLStandardLibrary() {
return delegate.getOCLStandardLibrary();
}
public Variable<EClassifier, EParameter> getSelfVariable() {
return delegate.getSelfVariable();
}
public List<EObject> getStates(EClassifier owner,
List<String> pathPrefix) {
return delegate.getStates(owner, pathPrefix);
}
public TypeResolver<EClassifier, EOperation, EStructuralFeature> getTypeResolver() {
return delegate.getTypeResolver();
}
public UMLReflection<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint> getUMLReflection() {
return delegate.getUMLReflection();
}
public Collection<Variable<EClassifier, EParameter>> getVariables() {
return delegate.getVariables();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public boolean isInPostcondition(OCLExpression<EClassifier> exp) {
return delegate.isInPostcondition(exp);
}
public Variable<EClassifier, EParameter> lookup(String name) {
return delegate.lookup(name);
}
public EClassifier lookupAssociationClassReference(EClassifier owner,
String name) {
return delegate.lookupAssociationClassReference(owner, name);
}
public EClassifier lookupClassifier(List<String> names) {
return delegate.lookupClassifier(names);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForAssociationClass(
String name) {
return delegate.lookupImplicitSourceForAssociationClass(name);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForOperation(
String name, List<? extends TypedElement<EClassifier>> args) {
return delegate.lookupImplicitSourceForOperation(name, args);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForProperty(
String name) {
return delegate.lookupImplicitSourceForProperty(name);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForSignal(
String name, List<? extends TypedElement<EClassifier>> args) {
return delegate.lookupImplicitSourceForSignal(name, args);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForState(
List<String> path)
throws LookupException, SemanticException {
return delegate.lookupImplicitSourceForState(path);
}
public Variable<EClassifier, EParameter> lookupLocal(String name) {
return delegate.lookupLocal(name);
}
public EOperation lookupOperation(EClassifier owner, String name,
List<? extends TypedElement<EClassifier>> args) {
return delegate.lookupOperation(owner, name, args);
}
public EPackage lookupPackage(List<String> names) {
return delegate.lookupPackage(names);
}
public EStructuralFeature lookupProperty(EClassifier owner, String name) {
return delegate.lookupProperty(owner, name);
}
public EReference lookupOppositeProperty(EClassifier owner, String name)
throws LookupException {
return delegate.lookupOppositeProperty(owner, name);
}
public EClassifier getOppositePropertyType(EClassifier owner, EReference property) {
return delegate.getOppositePropertyType(owner, property);
}
public EClassifier lookupSignal(EClassifier owner, String name,
List<? extends TypedElement<EClassifier>> args) {
return delegate.lookupSignal(owner, name, args);
}
public EObject lookupState(EClassifier owner, List<String> path)
throws LookupException, SemanticException {
return delegate.lookupState(owner, path);
}
public void setBodyCondition(EOperation operation, Constraint constraint) {
delegate.setBodyCondition(operation, constraint);
}
public void setDeriveConstraint(EStructuralFeature property,
Constraint constraint) {
delegate.setDeriveConstraint(property, constraint);
}
public void setInitConstraint(EStructuralFeature property,
Constraint constraint) {
delegate.setInitConstraint(property, constraint);
}
public void setParent(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
delegate.setParent(env);
}
public void setSelfVariable(Variable<EClassifier, EParameter> var) {
delegate.setSelfVariable(var);
}
public void undefine(Object feature) {
delegate.undefine(feature);
}
public Map<String, EReference> getHiddenOppositeProperties(
EClassifier classifier) {
return delegate.getHiddenOppositeProperties(classifier);
}
public Variable<EClassifier, EParameter> lookupImplicitSourceForOppositeProperty(
String name) {
return delegate.lookupImplicitSourceForOppositeProperty(name);
}
}
class WrapperEnvironmentFactory implements EnvironmentFactory<
EPackage, EClassifier, EOperation, EStructuralFeature,
EEnumLiteral, EParameter,
EObject, CallOperationAction, SendSignalAction, Constraint,
EClass, EObject> {
private final EnvironmentFactory<
EPackage, EClassifier, EOperation, EStructuralFeature,
EEnumLiteral, EParameter,
EObject, CallOperationAction, SendSignalAction, Constraint,
EClass, EObject> delegate;
WrapperEnvironmentFactory(EnvironmentFactory<
EPackage, EClassifier, EOperation, EStructuralFeature,
EEnumLiteral, EParameter,
EObject, CallOperationAction, SendSignalAction, Constraint,
EClass, EObject> delegate) {
this.delegate = delegate;
}
WrapperEnvironmentFactory() {
this(new EcoreEnvironmentFactory());
}
private Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject>
getWrappedEnvironment(Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
if (env instanceof WrapperEnvironment) {
return ((WrapperEnvironment) env).delegate;
} else {
return env;
}
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createAttributeContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent,
EStructuralFeature property) {
return new WrapperEnvironment(this, delegate.createAttributeContext(getWrappedEnvironment(parent), property), parent);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createClassifierContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent,
EClassifier context) {
return new WrapperEnvironment(this, delegate.createClassifierContext(getWrappedEnvironment(parent), context), parent);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createEnvironment() {
return new WrapperEnvironment(this, delegate.createEnvironment());
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createEnvironment(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent) {
return new WrapperEnvironment(this, delegate.createEnvironment(getWrappedEnvironment(parent)), parent);
}
public EvaluationEnvironment<EClassifier, EOperation, EStructuralFeature, EClass, EObject> createEvaluationEnvironment() {
return delegate.createEvaluationEnvironment();
}
public EvaluationEnvironment<EClassifier, EOperation, EStructuralFeature, EClass, EObject> createEvaluationEnvironment(
EvaluationEnvironment<EClassifier, EOperation, EStructuralFeature, EClass, EObject> parent) {
return delegate.createEvaluationEnvironment(parent);
}
public EvaluationVisitor<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createEvaluationVisitor(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
EvaluationEnvironment<EClassifier, EOperation, EStructuralFeature, EClass, EObject> evalEnv,
Map<? extends EClass, ? extends Set<? extends EObject>> extentMap) {
return delegate.createEvaluationVisitor(env, evalEnv, extentMap);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createInstanceContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent,
Object context) {
return new WrapperEnvironment(this, delegate.createInstanceContext(getWrappedEnvironment(parent), context), parent);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createOperationContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent,
EOperation operation) {
return new WrapperEnvironment(this, delegate.createOperationContext(getWrappedEnvironment(parent), operation), parent);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createPackageContext(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> parent,
List<String> pathname) {
return new WrapperEnvironment(this, delegate.createPackageContext(getWrappedEnvironment(parent), pathname), parent);
}
public Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> loadEnvironment(
Resource resource) {
return new WrapperEnvironment(this, delegate.loadEnvironment(resource));
}
public Visitor<Boolean, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint> createValidationVisitor(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
return delegate.createValidationVisitor(env);
}
public OCLAnalyzer<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createOCLAnalyzer(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
String input) {
return delegate.createOCLAnalyzer(env, input);
}
public OCLAnalyzer<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> createOCLAnalyzer(
AbstractOCLParser parser) {
return delegate.createOCLAnalyzer(parser);
}
public OCLFactoryWithHistory createOCLFactoryWithHistory(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
return delegate.createOCLFactoryWithHistory(env);
}
public OCLSyntaxHelper createOCLSyntaxHelper(
Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
return delegate.createOCLSyntaxHelper(env);
}
}
}