| 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; |
| } |
| } |
| } |