package com.sap.runlet.interpreter.rucola; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import com.sap.ap.metamodel.utils.MetamodelUtils; import com.sap.runlet.abstractinterpreter.objects.RunletObject; import com.sap.runlet.interpreter.RunletInterpreter; import com.sap.runlet.interpreter.expressions.SignatureCallInterpreter; import com.sap.runlet.interpreter.objects.FunctionObject; import data.classes.AssociationEnd; import data.classes.ClassTypeDefinition; import data.classes.FunctionSignature; import data.classes.Parameter; import data.classes.TypeDefinition; import dataaccess.expressions.FunctionCallExpression; import dataaccess.expressions.SignatureCallExpression; /** * Encapsulates a {@link FunctionObject} that can be invoked. * * @author Axel Uhl D043530 * */ public class Function extends RucolaObject { public Function(Rucola rucola, RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition> functionObject) { super(rucola, functionObject); } protected FunctionObject getObject() { return (FunctionObject) super.getObject(); } public RucolaObject call(Object... args) { FunctionCallExpression fce = MetamodelUtils.createFunctionCallExpression(getResourceSet(), (FunctionSignature) getObject() .getImplementation().getImplementedSignature()); List<RucolaObject> argsAsRucola = new LinkedList<RucolaObject>(); Iterator<Parameter> paramIter = fce.getSignature().getInput().iterator(); for (Object arg : args) { argsAsRucola.add(getRucola().wrap(arg, paramIter.next().getType())); } List<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>> argsAsRiver = new LinkedList<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>>(); for (RucolaObject rucolaArg : argsAsRucola) { argsAsRiver.add(rucolaArg.getObject()); } RucolaCallInterpreter fcInterpreter = new RucolaCallInterpreter(fce, argsAsRiver); try { RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition> riverResult = fcInterpreter.evaluate(getInterpreter()); return getRucola().createRucolaObjectForRiverObject(riverResult); } catch (Exception e) { throw new RucolaException("Error during evaluating function call to " + getObject() + ": " + e.getMessage(), e); } } @Override public Function asFunction() { return this; } private class RucolaCallInterpreter extends SignatureCallInterpreter { private List<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>> params; public RucolaCallInterpreter(SignatureCallExpression sce, List<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>> params) { super(sce); this.params = params; } @Override protected List<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>> getParameterValues(RunletInterpreter interpreter) { return params; } } }