blob: f584a1cc9585e423440e313b3eb45f77513a93d9 [file] [log] [blame]
package org.eclipse.uml2.diagram.component.expressions;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.Query;
import org.eclipse.ocl.ecore.EcoreFactory;
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.OperationCallExp;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.helper.OCLHelper;
import org.eclipse.ocl.utilities.AbstractVisitor;
import org.eclipse.ocl.utilities.PredefinedType;
import org.eclipse.uml2.diagram.parser.lookup.OCLLookup;
/**
* @generated
*/
public class UMLOCLFactory {
/**
* @generated
*/
public static OCLLookup.Expression getOCLLookupExpression(String body, EClassifier context) {
final UMLAbstractExpression expression = getExpression(body, context);
if (!expression.getStatus().isOK()) {
throw new IllegalArgumentException("Bad OCL:" + body);
}
return new OCLLookup.Expression() {
public Object evaluate(Object context) {
return expression.evaluate(context);
}
};
}
/**
* @generated
*/
private UMLOCLFactory() {
}
/**
* @generated
*/
public static UMLAbstractExpression getExpression(String body, EClassifier context, Map environment) {
return new Expression(body, context, environment);
}
/**
* @generated
*/
public static UMLAbstractExpression getExpression(String body, EClassifier context) {
return getExpression(body, context, Collections.EMPTY_MAP);
}
/**
* @generated
*/
private static class Expression extends UMLAbstractExpression {
/**
* @generated
*/
private WeakReference queryRef;
/**
* @generated
*/
private final org.eclipse.ocl.ecore.OCL oclInstance;
/**
* @generated
*/
public Expression(String body, EClassifier context, Map environment) {
super(body, context);
oclInstance = org.eclipse.ocl.ecore.OCL.newInstance();
initCustomEnv(oclInstance.getEnvironment(), environment);
}
/**
* @generated
*/
protected Query getQuery() {
Query oclQuery = null;
if (this.queryRef != null) {
oclQuery = (Query) this.queryRef.get();
}
if (oclQuery == null) {
OCLHelper oclHelper = oclInstance.createOCLHelper();
oclHelper.setContext(context());
try {
OCLExpression oclExpression = oclHelper.createQuery(body());
oclQuery = oclInstance.createQuery(oclExpression);
this.queryRef = new WeakReference(oclQuery);
setStatus(IStatus.OK, null, null);
} catch (ParserException e) {
setStatus(IStatus.ERROR, e.getMessage(), e);
}
}
return oclQuery;
}
/**
* @generated
*/
protected Object doEvaluate(Object context, Map env) {
Query oclQuery = getQuery();
if (oclQuery == null) {
return null;
}
EvaluationEnvironment evalEnv = oclQuery.getEvaluationEnvironment();
// init environment
for (Iterator it = env.entrySet().iterator(); it.hasNext();) {
Map.Entry nextEntry = (Map.Entry) it.next();
evalEnv.replace((String) nextEntry.getKey(), nextEntry.getValue());
}
try {
initExtentMap(context);
Object result = oclQuery.evaluate(context);
return (result != oclInstance.getEnvironment().getOCLStandardLibrary().getOclInvalid()) ? result : null;
} finally {
evalEnv.clear();
oclQuery.getExtentMap().clear();
}
}
/**
* @generated
*/
private void initExtentMap(Object context) {
if (!getStatus().isOK() || context == null) {
return;
}
final Query queryToInit = getQuery();
final Object extentContext = context;
queryToInit.getExtentMap().clear();
if (queryToInit.queryText() != null && queryToInit.queryText().indexOf(PredefinedType.ALL_INSTANCES_NAME) >= 0) {
AbstractVisitor visitior = new AbstractVisitor() {
private boolean usesAllInstances = false;
public Object visitOperationCallExp(OperationCallExp oc) {
if (!usesAllInstances) {
usesAllInstances = PredefinedType.ALL_INSTANCES == oc.getOperationCode();
if (usesAllInstances) {
queryToInit.getExtentMap().putAll(oclInstance.getEvaluationEnvironment().createExtentMap(extentContext));
}
}
return super.visitOperationCallExp(oc);
}
};
queryToInit.getExpression().accept(visitior);
}
}
/**
* @generated
*/
private static void initCustomEnv(Environment ecoreEnv, Map environment) {
for (Iterator it = environment.keySet().iterator(); it.hasNext();) {
String varName = (String) it.next();
EClassifier varType = (EClassifier) environment.get(varName);
ecoreEnv.addElement(varName, createVar(ecoreEnv, varName, varType), false);
}
}
/**
* @generated
*/
private static Variable createVar(Environment ecoreEnv, String name, EClassifier type) {
Variable var = EcoreFactory.eINSTANCE.createVariable();
var.setName(name);
var.setType(ecoreEnv.getUMLReflection().getOCLType(type));
return var;
}
}
}