diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/FunctionExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/FunctionExpressionEvaluator.java index a132b7dc738..02c525b094e 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/FunctionExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/FunctionExpressionEvaluator.java @@ -15,7 +15,9 @@ */ package com.evolveum.midpoint.model.common.expression.evaluator; +import java.util.Collection; import java.util.List; +import java.util.Map.Entry; import java.util.stream.Collectors; import javax.xml.namespace.QName; @@ -35,9 +37,12 @@ import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; +import com.evolveum.midpoint.repo.common.expression.Source; import com.evolveum.midpoint.repo.common.expression.evaluator.AbstractExpressionEvaluator; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.expression.ExpressionProfile; +import com.evolveum.midpoint.schema.expression.TypedValue; +import com.evolveum.midpoint.schema.expression.VariablesMap; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; @@ -131,27 +136,31 @@ public PrismValueDeltaSetTriple evaluate(ExpressionEvaluationContext context) ExpressionFactory factory = context.getExpressionFactory(); // TODO: expression profile should be determined from the function library archetype - Expression expression; + Expression functionExpression; try { - expression = factory.makeExpression(functionToExecute, outputDefinition, MiscSchemaUtil.getExpressionProfile(), "function execution", task, functionExpressionResult); + functionExpression = factory.makeExpression(functionToExecute, outputDefinition, MiscSchemaUtil.getExpressionProfile(), "function execution", task, functionExpressionResult); functionExpressionResult.recordSuccess(); } catch (SchemaException | ObjectNotFoundException e) { functionExpressionResult.recordFatalError("Cannot make expression for " + functionToExecute + ". Reason: " + e.getMessage(), e); throw e; } - - ExpressionVariables originVariables = context.getVariables(); - + ExpressionEvaluationContext functionContext = context.shallowClone(); ExpressionVariables functionVariables = new ExpressionVariables(); for (ExpressionParameterType param : getExpressionEvaluatorType().getParameter()) { - ExpressionType valueExpression = param.getExpression(); + ExpressionType valueExpressionType = param.getExpression(); OperationResult variableResult = result.createMinorSubresult(FunctionExpressionEvaluator.class.getSimpleName() + ".resolveVariable"); + Expression valueExpression = null; try { - variableResult.addArbitraryObjectAsParam("valueExpression", valueExpression); + variableResult.addArbitraryObjectAsParam("valueExpression", valueExpressionType); D variableOutputDefinition = determineVariableOutputDefinition(functionToExecute, param.getName(), context); - ExpressionUtil.evaluateExpression(originVariables, variableOutputDefinition, valueExpression, expressionProfile, context.getExpressionFactory(), "resolve variable", task, variableResult); + + valueExpression = factory.makeExpression(valueExpressionType, variableOutputDefinition, MiscSchemaUtil.getExpressionProfile(), "parameters execution", task, variableResult); + functionExpressionResult.recordSuccess(); + PrismValueDeltaSetTriple evaluatedValue = valueExpression.evaluate(context); + V value = ExpressionUtil.getExpressionOutputValue(evaluatedValue, " evaluated value for paramter"); + functionVariables.addVariableDefinition(param.getName(), value, variableOutputDefinition); variableResult.recordSuccess(); } catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException e) { @@ -160,9 +169,10 @@ public PrismValueDeltaSetTriple evaluate(ExpressionEvaluationContext context) } } + functionContext.setVariables(functionVariables); - return expression.evaluate(context); + return functionExpression.evaluate(functionContext); } private ExpressionType determineFunctionToExecute(List filteredExpressions) { diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/PathExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/PathExpressionEvaluator.java index a1e57532a74..a4cf677cc74 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/PathExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/PathExpressionEvaluator.java @@ -42,12 +42,16 @@ import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; /** * @author Radovan Semancik */ public class PathExpressionEvaluator implements ExpressionEvaluator { + private static final transient Trace LOGGER = TraceManager.getTrace(PathExpressionEvaluator.class); + private final QName elementName; private final ItemPath path; private final ObjectResolver objectResolver; @@ -81,6 +85,7 @@ public PrismValueDeltaSetTriple evaluate(ExpressionEvaluationContext context) ItemDeltaItem resolveContext = null; + ItemPath resolvePath = path; if (context.getSources() != null && context.getSources().size() == 1) { Source source = context.getSources().iterator().next(); if (path.isEmpty()) { @@ -88,14 +93,17 @@ public PrismValueDeltaSetTriple evaluate(ExpressionEvaluationContext context) return outputTriple.clone(); } resolveContext = source; + //FIXME quite a hack, but should work for now. + if (QNameUtil.match(path.firstName(), source.getName())) { + resolvePath = path.rest(); + } } Map variablesAndSources = ExpressionUtil.compileVariablesAndSources(context); - ItemPath resolvePath = path; Object first = path.first(); if (ItemPath.isVariable(first)) { - String variableName = ItemPath.toVariableName(first).getLocalPart(); + String variableName = ItemPath.toVariableName(first).getLocalPart(); TypedValue variableValueAndDefinition = variablesAndSources.get(variableName); if (variableValueAndDefinition == null) { throw new ExpressionEvaluationException("No variable with name "+variableName+" in "+ context.getContextDescription()); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 1479574aa5f..d286a69fb73 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -517,7 +517,7 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final String DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME = "sea"; protected static final String DUMMY_ACCOUNT_ATTRIBUTE_MATE_NAME = "mate"; protected static final String DUMMY_ACCOUNT_ATTRIBUTE_LOCKER_NAME = "locker"; - + protected static final String INTENT_TEST = "test"; protected static final String INTENT_DUMMY_GROUP = "group"; protected static final String INTENT_DUMMY_PRIVILEGE = "privilege"; diff --git a/model/model-intest/src/test/resources/common/custom-library.xml b/model/model-intest/src/test/resources/common/custom-library.xml index 11e2f1bcbce..7061d835d2d 100644 --- a/model/model-intest/src/test/resources/common/custom-library.xml +++ b/model/model-intest/src/test/resources/common/custom-library.xml @@ -26,12 +26,12 @@ getName - name + username xsd:string t:PolyStringType @@ -41,9 +41,14 @@ getLocality location - xsd:string + t:PolyStringType - + t:PolyStringType diff --git a/model/model-intest/src/test/resources/common/resource-dummy.xml b/model/model-intest/src/test/resources/common/resource-dummy.xml index a56b1f83737..4a15aba0b57 100644 --- a/model/model-intest/src/test/resources/common/resource-dummy.xml +++ b/model/model-intest/src/test/resources/common/resource-dummy.xml @@ -104,7 +104,7 @@ Full Name - $user/fullName + fullName diff --git a/model/model-intest/src/test/resources/mapping/resource-dummy-custom-function-crimson.xml b/model/model-intest/src/test/resources/mapping/resource-dummy-custom-function-crimson.xml index 15b92a47faa..722307d2255 100644 --- a/model/model-intest/src/test/resources/mapping/resource-dummy-custom-function-crimson.xml +++ b/model/model-intest/src/test/resources/mapping/resource-dummy-custom-function-crimson.xml @@ -70,7 +70,7 @@