Skip to content

Commit

Permalink
Support metadata computation in more evaluators
Browse files Browse the repository at this point in the history
Now we compute metadata not only in transformational
evaluator (mostly <script>) but in almost all evaluators.

Along with this change, all evaluators were migrated
under AbstractExpressionEvaluator class and ExpressionEvaluatorUtil
was therefore removed.
  • Loading branch information
mederly committed Aug 24, 2020
1 parent c2a0926 commit 5b0cf8f
Show file tree
Hide file tree
Showing 25 changed files with 457 additions and 269 deletions.
Expand Up @@ -33,13 +33,13 @@ public static <IV extends PrismValue,ID extends ItemDefinition> PrismValueDeltaS
ItemDelta<IV, ID> delta, PrismContext prismContext) throws SchemaException {
if (item == null && delta == null) {
return null;
}
if (delta == null) {
} else if (delta == null) {
PrismValueDeltaSetTriple<IV> triple = prismContext.deltaFactory().createPrismValueDeltaSetTriple();
triple.addAllToZeroSet(PrismValueCollectionsUtil.cloneCollection(item.getValues()));
return triple;
} else {
return delta.toDeltaSetTriple(item);
}
return delta.toDeltaSetTriple(item);
}

// TODO move to Item
Expand Down
Expand Up @@ -17,10 +17,7 @@
import com.evolveum.midpoint.repo.common.expression.ExpressionUtil;
import com.evolveum.midpoint.repo.common.expression.evaluator.AbstractExpressionEvaluator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
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.exception.*;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstExpressionEvaluatorType;

import org.jetbrains.annotations.NotNull;
Expand All @@ -44,7 +41,8 @@ public class ConstExpressionEvaluator<V extends PrismValue, D extends ItemDefini

@Override
public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context, OperationResult result)
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, SecurityViolationException {
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, SecurityViolationException,
CommunicationException, ConfigurationException {
checkEvaluatorProfile(context);

String constName = expressionEvaluatorBean.getValue();
Expand All @@ -62,7 +60,9 @@ public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context,
"Can only provide values of property, not " + output.getClass());
}

return ItemDeltaUtil.toDeltaSetTriple(output, null, prismContext);
PrismValueDeltaSetTriple<V> outputTriple = ItemDeltaUtil.toDeltaSetTriple(output, null, prismContext);
applyValueMetadata(outputTriple, context, result);
return outputTriple;
}

@Override
Expand Down
Expand Up @@ -74,7 +74,9 @@ public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context,
String stringValue = generateStringValue(valuePolicy, context, outputPath, result);
addValueToOutputProperty(output, stringValue);

return ItemDeltaUtil.toDeltaSetTriple(output, null, prismContext);
PrismValueDeltaSetTriple<V> outputTriple = ItemDeltaUtil.toDeltaSetTriple(output, null, prismContext);
applyValueMetadata(outputTriple, context, result);
return outputTriple;
}

@NotNull
Expand Down
Expand Up @@ -9,11 +9,11 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.delta.ItemDeltaUtil;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluator;
import com.evolveum.midpoint.schema.SchemaConstantsGenerated;
import com.evolveum.midpoint.repo.common.expression.evaluator.AbstractExpressionEvaluator;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
Expand All @@ -27,23 +27,18 @@
* @author skublik
*/
public class ProportionalExpressionEvaluator<V extends PrismValue, D extends ItemDefinition>
implements ExpressionEvaluator<V> {
extends AbstractExpressionEvaluator<V, D, ProportionalExpressionEvaluatorType> {

private final ProportionalExpressionEvaluatorType proportionalEvaluatorType;
private final D outputDefinition;
private final PrismContext prismContext;

ProportionalExpressionEvaluator(ProportionalExpressionEvaluatorType proportionalEvaluatorType, D outputDefinition, PrismContext prismContext) {
this.proportionalEvaluatorType = proportionalEvaluatorType;
this.outputDefinition = outputDefinition;
this.prismContext = prismContext;
ProportionalExpressionEvaluator(QName elementName, ProportionalExpressionEvaluatorType proportionalEvaluatorBean,
D outputDefinition, Protector protector, PrismContext prismContext) {
super(elementName, proportionalEvaluatorBean, outputDefinition, protector, prismContext);
}

@Override
public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context, OperationResult result)
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {

ProportionalStyleType style = proportionalEvaluatorType.getStyle();
ProportionalStyleType style = expressionEvaluatorBean.getStyle();

IntegerStatType integerStatType = context.getVariables().getValue(ExpressionConstants.VAR_INPUT, IntegerStatType.class);
if(integerStatType == null) {
Expand Down Expand Up @@ -111,11 +106,6 @@ private void validateInputNumbers(Integer totalItems, Integer actualItems, Propo

@Override
public String shortDebugDump() {
return "const:"+proportionalEvaluatorType.getStyle();
}

@Override
public QName getElementName() {
return SchemaConstantsGenerated.C_PROPORTIONAL;
return "const:"+expressionEvaluatorBean.getStyle();
}
}
Expand Up @@ -11,6 +11,7 @@
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.schema.SchemaConstantsGenerated;

import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -35,6 +36,7 @@
public class ProportionalExpressionEvaluatorFactory extends AbstractAutowiredExpressionEvaluatorFactory {

@Autowired private PrismContext prismContext;
@Autowired private Protector protector;

@Override
public QName getElementName() {
Expand All @@ -49,6 +51,6 @@ public <V extends PrismValue,D extends ItemDefinition> ExpressionEvaluator<V> cr

ProportionalExpressionEvaluatorType evaluatorBean = getSingleEvaluatorBeanRequired(evaluatorElements,
ProportionalExpressionEvaluatorType.class, contextDescription);
return new ProportionalExpressionEvaluator<>(evaluatorBean, outputDefinition, prismContext);
return new ProportionalExpressionEvaluator<>(getElementName(), evaluatorBean, outputDefinition, protector, prismContext);
}
}
Expand Up @@ -13,10 +13,9 @@
import com.evolveum.midpoint.prism.util.DefinitionResolver;
import com.evolveum.midpoint.prism.util.ItemDeltaItem;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.repo.common.expression.evaluator.ExpressionEvaluatorUtil;
import com.evolveum.midpoint.schema.expression.TypedValue;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.*;

import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -44,15 +43,16 @@ class PathExpressionEvaluation<V extends PrismValue, D extends ItemDefinition> {
this.context = context;
}

PrismValueDeltaSetTriple<V> evaluate() throws ExpressionEvaluationException, SchemaException {
pathToResolve = evaluator.path;
PrismValueDeltaSetTriple<V> evaluate(OperationResult result) throws ExpressionEvaluationException, SchemaException,
ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException {
pathToResolve = evaluator.getPath();
resolutionContext = determineInitialResolveContext();
if (resolutionContext == null) {
return null;
}

stepAlongResolvePath();
return prepareOutputTriple();
return prepareOutputTriple(result);
}

private ResolutionContext determineInitialResolveContext() throws ExpressionEvaluationException {
Expand All @@ -75,7 +75,7 @@ private ResolutionContext getInitialResolveContextFromVariable() throws Expressi
String variableName = ItemPath.toVariableName(pathToResolve.first()).getLocalPart();
pathToResolve = pathToResolve.rest();

TypedValue variableValueAndDefinition = ExpressionEvaluatorUtil.findInSourcesAndVariables(context, variableName);
TypedValue variableValueAndDefinition = evaluator.findInSourcesAndVariables(context, variableName);
if (variableValueAndDefinition == null) {
throw new ExpressionEvaluationException("No variable with name "+variableName+" in "+ context.getContextDescription());
}
Expand All @@ -93,14 +93,12 @@ private ResolutionContext getInitialResolveContextFromVariable() throws Expressi
}

@Nullable
private PrismValueDeltaSetTriple<V> prepareOutputTriple() throws SchemaException {
PrismValueDeltaSetTriple<V> outputTriple = resolutionContext.createOutputTriple(evaluator.prismContext);
if (outputTriple == null) {
return null;
} else {
return ExpressionEvaluatorUtil.toOutputTriple(outputTriple, evaluator.outputDefinition,
context.getAdditionalConvertor(), null, evaluator.protector, evaluator.prismContext);
}
private PrismValueDeltaSetTriple<V> prepareOutputTriple(OperationResult result) throws SchemaException,
ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException,
ExpressionEvaluationException {
PrismValueDeltaSetTriple<V> outputTriple = resolutionContext.createOutputTriple(evaluator.getPrismContext());
evaluator.applyValueMetadata(outputTriple, context, result);
return evaluator.finishOutputTriple(outputTriple, context.getAdditionalConvertor(), null);
}

private void stepAlongResolvePath() throws SchemaException, ExpressionEvaluationException {
Expand All @@ -113,7 +111,7 @@ private void stepAlongResolvePath() throws SchemaException, ExpressionEvaluation
// Those may not have a definition. In that case just assume strings.
// In fact, this is a HACK. All such schemas should have a definition.
// Otherwise there may be problems with parameter types for caching compiles scripts and so on.
return evaluator.prismContext.definitionFactory().createPropertyDefinition(path.firstName(), PrimitiveType.STRING.getQname());
return evaluator.getPrismContext().definitionFactory().createPropertyDefinition(path.firstName(), PrimitiveType.STRING.getQname());
} else {
return null;
}
Expand All @@ -128,13 +126,13 @@ private void stepAlongResolvePath() throws SchemaException, ExpressionEvaluation
}

if (resolutionContext == null) {
throw new ExpressionEvaluationException("Cannot find item using path "+evaluator.path+" in "+
throw new ExpressionEvaluationException("Cannot find item using path "+evaluator.getPath()+" in "+
context.getContextDescription());
}

} else if (resolutionContext.isStructuredProperty()) {
resolutionContext = resolutionContext.resolveStructuredProperty(pathToResolve,
(PrismPropertyDefinition) evaluator.outputDefinition, evaluator.prismContext);
(PrismPropertyDefinition) evaluator.getOutputDefinition(), evaluator.getPrismContext());
pathToResolve = ItemPath.EMPTY_PATH;

} else if (resolutionContext.isNull()) {
Expand Down
Expand Up @@ -15,51 +15,41 @@
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluator;
import com.evolveum.midpoint.repo.common.expression.ExpressionUtil;
import com.evolveum.midpoint.repo.common.expression.evaluator.AbstractExpressionEvaluator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;

/**
* Returns value set triple derived from specified (or default) source by resolving specified path.
*
* @author Radovan Semancik
*/
public class PathExpressionEvaluator<V extends PrismValue, D extends ItemDefinition> implements ExpressionEvaluator<V> {
public class PathExpressionEvaluator<V extends PrismValue, D extends ItemDefinition>
extends AbstractExpressionEvaluator<V, D, ItemPathType> {

private final QName elementName;
final ItemPath path;
final PrismContext prismContext;
final D outputDefinition;
final Protector protector;

PathExpressionEvaluator(QName elementName, ItemPath path, D outputDefinition, Protector protector,
PathExpressionEvaluator(QName elementName, ItemPathType path, D outputDefinition, Protector protector,
PrismContext prismContext) {
this.elementName = elementName;
this.path = path;
this.outputDefinition = outputDefinition;
this.prismContext = prismContext;
this.protector = protector;
}

@Override
public QName getElementName() {
return elementName;
super(elementName, path, outputDefinition, protector, prismContext);
}

@Override
public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context, OperationResult result)
throws SchemaException, ExpressionEvaluationException, SecurityViolationException {
throws SchemaException, ExpressionEvaluationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException, CommunicationException {
ExpressionUtil.checkEvaluatorProfileSimple(this, context);

return new PathExpressionEvaluation<>(this, context)
.evaluate();
.evaluate(result);
}

public ItemPath getPath() {
return expressionEvaluatorBean.getItemPath();
}

@Override
public String shortDebugDump() {
return "path: "+path;
return "path: " + getPath();
}
}
Expand Up @@ -66,6 +66,6 @@ public <V extends PrismValue, D extends ItemDefinition> ExpressionEvaluator<V> c
ItemPathType path = Objects.requireNonNull(
getSingleEvaluatorBean(evaluatorElements, ItemPathType.class, contextDescription),
() -> "missing path specification in " + contextDescription);
return new PathExpressionEvaluator<>(ELEMENT_NAME, path.getItemPath(), outputDefinition, protector, prismContext);
return new PathExpressionEvaluator<>(ELEMENT_NAME, path, outputDefinition, protector, prismContext);
}
}
Expand Up @@ -32,6 +32,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionReturnTypeType;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Executes specified script written e.g. in Groovy, JavaScript, Python, etc. Velocity template language is supported as well.
Expand Down Expand Up @@ -60,22 +61,29 @@ protected void checkEvaluatorProfile(ExpressionEvaluationContext context) {
protected List<V> transformSingleValue(ExpressionVariables variables, PlusMinusZero valueDestination, boolean useNew,
ExpressionEvaluationContext eCtx, String contextDescription, Task task, OperationResult result)
throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
ScriptExpressionReturnTypeType returnType = expressionEvaluatorBean.getReturnType();
if (returnType == null && isRelative()) {
returnType = ScriptExpressionReturnTypeType.SCALAR;
}
scriptExpression.setAdditionalConvertor(eCtx.getAdditionalConvertor());
ScriptExpressionEvaluationContext sCtx = new ScriptExpressionEvaluationContext();
sCtx.setVariables(variables);
sCtx.setSuggestedReturnType(returnType);
sCtx.setSuggestedReturnType(getReturnType());
sCtx.setEvaluateNew(useNew);
sCtx.setContextDescription(contextDescription);
sCtx.setAdditionalConvertor(eCtx.getAdditionalConvertor());
sCtx.setTask(task);
sCtx.setResult(result);

//noinspection unchecked
return (List<V>) scriptExpression.evaluate(sCtx);
return scriptExpression.evaluate(sCtx);
}

@Nullable
private ScriptExpressionReturnTypeType getReturnType() {
ScriptExpressionReturnTypeType explicitReturnType = expressionEvaluatorBean.getReturnType();
if (explicitReturnType != null) {
return explicitReturnType;
} else if (isRelative()) {
return ScriptExpressionReturnTypeType.SCALAR;
} else {
return null;
}
}

@Override
Expand Down
Expand Up @@ -1382,12 +1382,12 @@ void traceTimeTo(XMLGregorianCalendar timeTo) {
}
}

// TEMPORARY
List<MetadataMappingType> getMetadataMappings() {
return mappingBean instanceof MappingType ?
((MappingType) mappingBean).getMetadataMapping() : null;
}

// // TEMPORARY
// List<MetadataMappingType> getMetadataMappings() {
// return mappingBean instanceof MappingType ?
// ((MappingType) mappingBean).getMetadataMapping() : null;
// }
//
@NotNull
public ModelCommonBeans getBeans() {
return beans;
Expand Down

0 comments on commit 5b0cf8f

Please sign in to comment.