use of com.evolveum.midpoint.prism.delta.PlusMinusZero in project midpoint by Evolveum.
the class AssignmentEvaluator method evaluateSegmentTarget.
private void evaluateSegmentTarget(AssignmentPathSegmentImpl segment, PlusMinusZero relativeMode, boolean isValid, FocusType targetType, QName relation, EvaluationContext ctx) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException {
assertSourceNotNull(segment.source, ctx.evalAssignment);
assert ctx.assignmentPath.last() == segment;
segment.setTarget(targetType);
// probably not needed
segment.setRelation(relation);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Evaluating segment TARGET:\n{}", segment.debugDump(1));
}
checkRelationWithTarget(segment, targetType, relation);
if (!LensUtil.isFocusValid(targetType, now, activationComputer)) {
LOGGER.trace("Skipping evaluation of {} because it is not valid", targetType);
return;
}
if (targetType instanceof AbstractRoleType) {
MappingType roleCondition = ((AbstractRoleType) targetType).getCondition();
if (roleCondition != null) {
AssignmentPathVariables assignmentPathVariables = LensUtil.computeAssignmentPathVariables(ctx.assignmentPath);
PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> conditionTriple = evaluateCondition(roleCondition, null, segment.source, assignmentPathVariables, ctx);
boolean condOld = ExpressionUtil.computeConditionResult(conditionTriple.getNonPositiveValues());
boolean condNew = ExpressionUtil.computeConditionResult(conditionTriple.getNonNegativeValues());
PlusMinusZero modeFromCondition = ExpressionUtil.computeConditionResultMode(condOld, condNew);
if (modeFromCondition == null) {
// removed "|| (condMode == PlusMinusZero.ZERO && !condNew)" because it's always false
LOGGER.trace("Skipping evaluation of {} because of condition result ({} -> {}: null)", targetType, condOld, condNew);
return;
}
PlusMinusZero origMode = relativeMode;
relativeMode = PlusMinusZero.compute(relativeMode, modeFromCondition);
LOGGER.trace("Evaluated condition in {}: {} -> {}: {} + {} = {}", targetType, condOld, condNew, origMode, modeFromCondition, relativeMode);
}
}
EvaluatedAssignmentTargetImpl evalAssignmentTarget = new EvaluatedAssignmentTargetImpl(targetType.asPrismObject(), // evaluateConstructions: exact meaning of this is to be revised
segment.isMatchingOrder(), ctx.assignmentPath.clone(), segment.getAssignment(), isValid);
ctx.evalAssignment.addRole(evalAssignmentTarget, relativeMode);
if ((isNonNegative(relativeMode)) && segment.isProcessMembership()) {
collectMembership(targetType, relation, ctx);
}
if (targetType instanceof AbstractRoleType) {
for (AssignmentType roleInducement : ((AbstractRoleType) targetType).getInducement()) {
evaluateInducement(segment, relativeMode, isValid, ctx, targetType, roleInducement);
}
}
for (AssignmentType roleAssignment : targetType.getAssignment()) {
evaluateAssignment(segment, relativeMode, isValid, ctx, targetType, relation, roleAssignment);
}
//boolean matchesOrder = AssignmentPathSegmentImpl.computeMatchingOrder(segment.getEvaluationOrder(), 1, Collections.emptyList());
if (segment.isMatchingOrder() && targetType instanceof AbstractRoleType && isNonNegative(relativeMode)) {
for (AuthorizationType authorizationType : ((AbstractRoleType) targetType).getAuthorization()) {
Authorization authorization = createAuthorization(authorizationType, targetType.toString());
if (!ctx.evalAssignment.getAuthorizations().contains(authorization)) {
ctx.evalAssignment.addAuthorization(authorization);
}
}
AdminGuiConfigurationType adminGuiConfiguration = ((AbstractRoleType) targetType).getAdminGuiConfiguration();
if (adminGuiConfiguration != null && !ctx.evalAssignment.getAdminGuiConfigurations().contains(adminGuiConfiguration)) {
ctx.evalAssignment.addAdminGuiConfiguration(adminGuiConfiguration);
}
PolicyConstraintsType policyConstraints = ((AbstractRoleType) targetType).getPolicyConstraints();
if (policyConstraints != null) {
ctx.evalAssignment.addLegacyPolicyConstraints(policyConstraints, ctx.assignmentPath.clone(), targetType);
}
}
LOGGER.trace("Evaluating segment target DONE for {}", segment);
}
use of com.evolveum.midpoint.prism.delta.PlusMinusZero in project midpoint by Evolveum.
the class AssignmentEvaluator method evaluateFromSegment.
/**
* @param relativeMode
*
* Where to put constructions and target roles/orgs/services (PLUS/MINUS/ZERO/null; null means "nowhere").
* This is a mode relative to the primary assignment. It does NOT tell whether the assignment as a whole
* is added or removed. It tells whether the part of the assignment that we are processing is to be
* added or removed. This may happen, e.g. if a condition in an existing assignment turns from false to true.
* In that case the primary assignment mode is ZERO, but the relative mode is PLUS.
* The relative mode always starts at ZERO, even for added or removed assignments.
*
* This depends on the status of conditions. E.g. if condition evaluates 'false -> true' (i.e. in old
* state the value is false, and in new state the value is true), then the mode is PLUS.
*
* This "triples algebra" is based on the following two methods:
*
* @see ExpressionUtil#computeConditionResultMode(boolean, boolean) - Based on condition values "old+new" determines
* into what set (PLUS/MINUS/ZERO/none) should the result be placed. Irrespective of what is the current mode. So,
* in order to determine "real" place where to put it (i.e. the new mode) the following method is used.
*
* @see PlusMinusZero#compute(PlusMinusZero, PlusMinusZero) - Takes original mode and the mode from recent condition
* and determines the new mode (commutatively):
*
* PLUS + PLUS/ZERO = PLUS
* MINUS + MINUS/ZERO = MINUS
* ZERO + ZERO = ZERO
* PLUS + MINUS = none
*
* This is quite straightforward, although the last rule deserves a note. If we have an assignment that was originally
* disabled and becomes enabled by the current delta (i.e. PLUS), and that assignment contains an inducement that was originally
* enabled and becomes disabled (i.e. MINUS), the result is that the (e.g.) constructions within the inducement were not
* present in the old state (because assignment was disabled) and are not present in the new state (because inducement is disabled).
*
* Note: this parameter could be perhaps renamed to "tripleMode" or "destination" or something like that.
*/
private void evaluateFromSegment(AssignmentPathSegmentImpl segment, PlusMinusZero relativeMode, EvaluationContext ctx) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("*** Evaluate from segment: {}", segment);
LOGGER.trace("*** Evaluation order - standard: {}, matching: {}", segment.getEvaluationOrder(), segment.isMatchingOrder());
LOGGER.trace("*** Evaluation order - for target: {}, matching: {}", segment.getEvaluationOrderForTarget(), segment.isMatchingOrderForTarget());
LOGGER.trace("*** mode: {}, process membership: {}", relativeMode, segment.isProcessMembership());
LOGGER.trace("*** path to source valid: {}, validity override: {}", segment.isPathToSourceValid(), segment.isValidityOverride());
}
assertSourceNotNull(segment.source, ctx.evalAssignment);
checkSchema(segment, ctx);
ctx.assignmentPath.add(segment);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("*** Path (with current segment already added):\n{}", ctx.assignmentPath.debugDump());
}
boolean evaluateContent = true;
AssignmentType assignmentType = getAssignmentType(segment, ctx);
MappingType assignmentCondition = assignmentType.getCondition();
if (assignmentCondition != null) {
AssignmentPathVariables assignmentPathVariables = LensUtil.computeAssignmentPathVariables(ctx.assignmentPath);
PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> conditionTriple = evaluateCondition(assignmentCondition, assignmentType, segment.source, assignmentPathVariables, ctx);
boolean condOld = ExpressionUtil.computeConditionResult(conditionTriple.getNonPositiveValues());
boolean condNew = ExpressionUtil.computeConditionResult(conditionTriple.getNonNegativeValues());
PlusMinusZero modeFromCondition = ExpressionUtil.computeConditionResultMode(condOld, condNew);
if (modeFromCondition == null) {
// removed "|| (condMode == PlusMinusZero.ZERO && !condNew)" as it is always false
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Skipping evaluation of {} because of condition result ({} -> {}: {})", FocusTypeUtil.dumpAssignment(assignmentType), condOld, condNew, null);
}
evaluateContent = false;
} else {
PlusMinusZero origMode = relativeMode;
relativeMode = PlusMinusZero.compute(relativeMode, modeFromCondition);
LOGGER.trace("Evaluated condition in assignment {} -> {}: {} + {} = {}", condOld, condNew, origMode, modeFromCondition, relativeMode);
}
}
boolean isValid = evaluateContent && evaluateSegmentContent(segment, relativeMode, ctx);
ctx.assignmentPath.removeLast(segment);
if (ctx.assignmentPath.isEmpty()) {
// direct assignment
ctx.evalAssignment.setValid(isValid);
}
}
use of com.evolveum.midpoint.prism.delta.PlusMinusZero in project midpoint by Evolveum.
the class ConstructionCollector method collectToConstructionMapFromEvaluatedConstructions.
private void collectToConstructionMapFromEvaluatedConstructions(EvaluatedAssignmentImpl<AH> evaluatedAssignment, Collection<EC> evaluatedConstructions, PlusMinusZero mode1, PlusMinusZero mode2, PlusMinusZero mode3) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
for (EC evaluatedConstruction : evaluatedConstructions) {
AbstractConstruction<AH, ?, ?> construction = evaluatedConstruction.getConstruction();
if (construction.isIgnored()) {
LOGGER.trace("Construction {} is ignored, skipping {}", construction, evaluatedConstruction);
continue;
}
PlusMinusZero mode = PlusMinusZero.compute(PlusMinusZero.compute(mode1, mode2), mode3);
if (mode == null) {
continue;
}
// FIXME MID-6404
if (mode == PlusMinusZero.ZERO) {
if (!construction.getWasValid() && construction.isValid()) {
mode = PlusMinusZero.PLUS;
} else if (construction.getWasValid() && !construction.isValid()) {
mode = PlusMinusZero.MINUS;
}
}
Map<K, EvaluatedConstructionPack<EC>> evaluatedConstructionMap = evaluatedConstructionMapTriple.getMap(mode);
if (evaluatedConstructionMap == null) {
// should not occur
continue;
}
K key = keyGenerator.apply(evaluatedConstruction);
EvaluatedConstructionPack<EC> evaluatedConstructionPack;
if (evaluatedConstructionMap.containsKey(key)) {
evaluatedConstructionPack = evaluatedConstructionMap.get(key);
} else {
evaluatedConstructionPack = new EvaluatedConstructionPack<>();
evaluatedConstructionMap.put(key, evaluatedConstructionPack);
}
evaluatedConstructionPack.add(evaluatedConstruction);
if (evaluatedAssignment.isValid()) {
evaluatedConstructionPack.setHasValidAssignment(true);
}
if (evaluatedAssignment.isForceRecon()) {
evaluatedConstructionPack.setForceRecon(true);
}
}
}
use of com.evolveum.midpoint.prism.delta.PlusMinusZero in project midpoint by Evolveum.
the class ConstructionProcessor method collectToConstructionMapFromEvaluatedConstructions.
private <F extends FocusType, K, T extends AbstractConstruction> void collectToConstructionMapFromEvaluatedConstructions(LensContext<F> context, EvaluatedAssignmentImpl<F> evaluatedAssignment, Collection<T> evaluatedConstructions, DeltaMapTriple<K, ConstructionPack<T>> constructionMapTriple, FailableLensFunction<T, K> keyGenerator, PlusMinusZero mode1, PlusMinusZero mode2, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
for (T construction : evaluatedConstructions) {
PlusMinusZero mode = PlusMinusZero.compute(mode1, mode2);
Map<K, ConstructionPack<T>> constructionMap = constructionMapTriple.getMap(mode);
if (constructionMap == null) {
continue;
}
K key = keyGenerator.apply(construction);
ConstructionPack<T> constructionPack;
if (constructionMap.containsKey(key)) {
constructionPack = constructionMap.get(key);
} else {
constructionPack = new ConstructionPack<>();
constructionMap.put(key, constructionPack);
}
constructionPack.add(new PrismPropertyValue<>(construction));
if (evaluatedAssignment.isValid()) {
constructionPack.setHasValidAssignment(true);
}
if (evaluatedAssignment.isForceRecon()) {
constructionPack.setForceRecon(true);
}
}
}
use of com.evolveum.midpoint.prism.delta.PlusMinusZero in project midpoint by Evolveum.
the class AbstractValueTransformationExpressionEvaluator method evaluateRelativeExpression.
private PrismValueDeltaSetTriple<V> evaluateRelativeExpression(final List<SourceTriple<?, ?>> sourceTriples, final ExpressionVariables variables, final boolean skipEvaluationMinus, final boolean skipEvaluationPlus, final Boolean includeNulls, final ExpressionEvaluationContext evaluationContext, final String contextDescription, final Task task, final OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
List<Collection<? extends PrismValue>> valueCollections = new ArrayList<>(sourceTriples.size());
for (SourceTriple<?, ?> sourceTriple : sourceTriples) {
Collection<? extends PrismValue> values = sourceTriple.union();
if (values.isEmpty()) {
// No values for this source. Add null instead. It will make sure that the expression will
// be evaluate at least once.
values.add(null);
}
valueCollections.add(values);
}
final PrismValueDeltaSetTriple<V> outputTriple = new PrismValueDeltaSetTriple<>();
Processor<Collection<? extends PrismValue>> processor = pvalues -> {
if (includeNulls != null && !includeNulls && MiscUtil.isAllNull(pvalues)) {
return;
}
Map<QName, Object> sourceVariables = new HashMap<>();
Iterator<SourceTriple<PrismValue, ?>> sourceTriplesIterator = (Iterator) sourceTriples.iterator();
boolean hasMinus = false;
boolean hasZero = false;
boolean hasPlus = false;
for (PrismValue pval : pvalues) {
SourceTriple<PrismValue, ?> sourceTriple = sourceTriplesIterator.next();
QName name = sourceTriple.getName();
sourceVariables.put(name, getRealContent(pval, sourceTriple.getResidualPath()));
if (sourceTriple.presentInPlusSet(pval)) {
hasPlus = true;
} else if (sourceTriple.presentInZeroSet(pval)) {
hasZero = true;
} else if (sourceTriple.presentInMinusSet(pval)) {
hasMinus = true;
}
}
if (!hasPlus && !hasMinus && !hasZero && !MiscUtil.isAllNull(pvalues)) {
throw new IllegalStateException("Internal error! The impossible has happened! pvalues=" + pvalues + "; source triples: " + sourceTriples + "; in " + contextDescription);
}
if (hasPlus && hasMinus) {
return;
}
if (hasPlus && skipEvaluationPlus) {
return;
} else if (hasMinus && skipEvaluationMinus) {
return;
}
ExpressionVariables scriptVariables = new ExpressionVariables();
scriptVariables.addVariableDefinitions(sourceVariables);
PlusMinusZero valueDestination = null;
boolean useNew = false;
if (hasPlus) {
scriptVariables.addVariableDefinitionsNew(variables);
valueDestination = PlusMinusZero.PLUS;
useNew = true;
} else if (hasMinus) {
scriptVariables.addVariableDefinitionsOld(variables);
valueDestination = PlusMinusZero.MINUS;
} else {
scriptVariables.addVariableDefinitionsNew(variables);
valueDestination = PlusMinusZero.ZERO;
useNew = true;
}
List<V> scriptResults;
try {
scriptResults = transformSingleValue(scriptVariables, valueDestination, useNew, evaluationContext, contextDescription, task, result);
} catch (ExpressionEvaluationException e) {
throw new TunnelException(new ExpressionEvaluationException(e.getMessage() + "(" + dumpSourceValues(sourceVariables) + ") in " + contextDescription, e));
} catch (ObjectNotFoundException e) {
throw new TunnelException(new ObjectNotFoundException(e.getMessage() + "(" + dumpSourceValues(sourceVariables) + ") in " + contextDescription, e));
} catch (SchemaException e) {
throw new TunnelException(new SchemaException(e.getMessage() + "(" + dumpSourceValues(sourceVariables) + ") in " + contextDescription, e));
} catch (RuntimeException e) {
throw new TunnelException(new RuntimeException(e.getMessage() + "(" + dumpSourceValues(sourceVariables) + ") in " + contextDescription, e));
}
outputTriple.addAllToSet(valueDestination, scriptResults);
};
try {
MiscUtil.carthesian((Collection) valueCollections, (Processor) processor);
} catch (TunnelException e) {
Throwable originalException = e.getCause();
if (originalException instanceof ExpressionEvaluationException) {
throw (ExpressionEvaluationException) originalException;
} else if (originalException instanceof ObjectNotFoundException) {
throw (ObjectNotFoundException) originalException;
} else if (originalException instanceof SchemaException) {
throw (SchemaException) originalException;
} else if (originalException instanceof RuntimeException) {
throw (RuntimeException) originalException;
} else {
throw new IllegalStateException("Unexpected exception: " + e + ": " + e.getMessage(), e);
}
}
cleanupTriple(outputTriple);
return outputTriple;
}
Aggregations