Best way for evaluating an operation with parameters [message #1389147] |
Fri, 27 June 2014 11:56 |
Olivier Melois Messages: 14 Registered: March 2012 |
Junior Member |
|
|
Hello,
In Java, I'm trying to invoke an operation that takes parameters, described in CompleteOCL. For instance :
context UML::Element
def: getSomething(conf : ecore::EObject) = ...
Now I've parsed my CompleteOCL file and manage to retrieve the org.eclipse.ocl.examples.pivot.Operation instance. For parameter-less operations, what I usually do is :
OCLHelper helper = ocl.createOCLHelper(operation);
ExpressionInOCL queryExpression = helper.createQuery(operation.getName() + "()" );
ocl.evaluate(context, queryExpression)
From my understanding, in order to invoke an operation with parameters, the first thing I should do would be to add variables to the nested environment contained by the OCLHelper, each variable matching a parameter of the operation.
What I don't get is how to set values to each variable once this is done before calling the OCL#evaluate. In the old API (Indigo), what I used to do was to get the EvaluationEnvironment of the OCL object and use the "add" to bind an object to a variable name. Is there any way to do this in a clean way to perform this with the new API ?
Regards,
Olivier Mélois
|
|
|
Re: Best way for evaluating an operation with parameters [message #1389264 is a reply to message #1389147] |
Fri, 27 June 2014 15:04 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi
The new API is very similar. The difference is you now bind
VariableDeclarations to values rather than Strings to values. This
avoids name clash hazards.
So you bind the various operation.getOwnedParameter() declarations to
their values using EvaluationEnvironment.add(DomainTypedElement
referredVariable, Object value);
Regards
Ed Willink
On 27/06/2014 12:56, Olivier Melois wrote:
> Hello,
> In Java, I'm trying to invoke an operation that takes parameters,
> described in CompleteOCL. For instance :
>
> context UML::Element
> def: getSomething(conf : ecore::EObject) = ...
>
> Now I've parsed my CompleteOCL file and manage to retrieve the
> org.eclipse.ocl.examples.pivot.Operation instance. For parameter-less
> operations, what I usually do is :
>
> OCLHelper helper = ocl.createOCLHelper(operation);
> ExpressionInOCL queryExpression =
> helper.createQuery(operation.getName() + "()" );
> ocl.evaluate(context, queryExpression)
>
>
> From my understanding, in order to invoke an operation with
> parameters, the first thing I should do would be to add variables to
> the nested environment contained by the OCLHelper, each variable
> matching a parameter of the operation.
> What I don't get is how to set values to each variable once this is
> done before calling the OCL#evaluate. In the old API (Indigo), what I
> used to do was to get the EvaluationEnvironment of the OCL object and
> use the "add" to bind an object to a variable name. Is there any way
> to do this in a clean way to perform this with the new API ?
> Regards,
> Olivier Mélois
|
|
|
Re: Best way for evaluating an operation with parameters [message #1391018 is a reply to message #1389264] |
Mon, 30 June 2014 10:27 |
Olivier Melois Messages: 14 Registered: March 2012 |
Junior Member |
|
|
Thank you for tip. Here's a pretty badly coded class for anyone who might have to do something similar (i.e evaluating operations with arguments)
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.domain.values.Value;
import org.eclipse.ocl.examples.pivot.Environment;
import org.eclipse.ocl.examples.pivot.ExpressionInOCL;
import org.eclipse.ocl.examples.pivot.OCL;
import org.eclipse.ocl.examples.pivot.OpaqueExpression;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.Parameter;
import org.eclipse.ocl.examples.pivot.ParserException;
import org.eclipse.ocl.examples.pivot.PivotFactory;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.Variable;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.examples.pivot.helper.OCLHelper;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
public class OCLEvaluator {
private final Map<String, Operation> operations = Maps.newHashMap();
private OCL ocl;
private URI uri;
public OCLEvaluator(URI uri) {
this.uri = uri;
ocl = OCL.newInstance(EPackage.Registry.INSTANCE);
final Resource oclResource = ocl.parse(uri);
Iterable<Operation> oclOperations = Iterables.filter(new Iterable<EObject>() {
@Override
public Iterator<EObject> iterator() {
return oclResource.getAllContents();
}
}, Operation.class);
for(Operation operation : oclOperations) {
operations.put(operation.getName(), operation);
}
}
public Object evaluateOperation(String operationName, EObject context, List<?> args) throws ParserException, InvocationTargetException {
Operation operation = operations.get(operationName);
OCLHelper helper = ocl.createOCLHelper(operation);
OpaqueExpression bodyExpression = operation.getBodyExpression();
ExpressionInOCL expressionInOCL = bodyExpression.getExpressionInOCL();
Environment environment = helper.getEnvironment();
DomainModelManager modelManager = ocl.getModelManager();
EvaluationVisitor evaluationVisitor = environment.getFactory().createEvaluationVisitor(environment, context, expressionInOCL, modelManager);
EvaluationEnvironment evaluationEnvironment = evaluationVisitor.getEvaluationEnvironment();
int i = 0;
for(Parameter param : operation.getOwnedParameter()) {
Type type = param.getType();
String paramName = param.getName();
Variable var = PivotFactory.eINSTANCE.createVariable();
var.setName(paramName);
var.setType(type);
evaluationEnvironment.add(var, args.get(i));
i += 1;
}
Object result = expressionInOCL.accept(evaluationVisitor);
if(result instanceof Value) {
result = ((Value)result).asObject();
}
evaluationEnvironment.clear();
return result;
}
}
|
|
|
Powered by
FUDForum. Page generated in 0.03078 seconds