use of com.evolveum.midpoint.model.api.context.EvaluatedHasAssignmentTrigger in project midpoint by Evolveum.
the class HasAssignmentConstraintEvaluator method evaluate.
@Override
public <AH extends AssignmentHolderType> EvaluatedHasAssignmentTrigger evaluate(@NotNull JAXBElement<HasAssignmentPolicyConstraintType> constraintElement, @NotNull PolicyRuleEvaluationContext<AH> ctx, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
OperationResult result = parentResult.subresult(OP_EVALUATE).setMinor().build();
try {
boolean shouldExist = QNameUtil.match(constraintElement.getName(), PolicyConstraintsType.F_HAS_ASSIGNMENT);
HasAssignmentPolicyConstraintType constraint = constraintElement.getValue();
ObjectReferenceType constraintTargetRef = constraint.getTargetRef();
if (constraintTargetRef == null) {
throw new SchemaException("No targetRef in hasAssignment constraint");
}
DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = ctx.lensContext.getEvaluatedAssignmentTriple();
if (evaluatedAssignmentTriple == null) {
return createTriggerIfShouldNotExist(shouldExist, constraintElement, ctx, result);
}
boolean allowMinus = ctx.state == ObjectState.BEFORE;
boolean allowZero = true;
boolean allowPlus = ctx.state == ObjectState.AFTER;
boolean allowDirect = !Boolean.FALSE.equals(constraint.isDirect());
boolean allowIndirect = !Boolean.TRUE.equals(constraint.isDirect());
boolean allowEnabled = !Boolean.FALSE.equals(constraint.isEnabled());
boolean allowDisabled = !Boolean.TRUE.equals(constraint.isEnabled());
ConstraintReferenceMatcher<AH> refMatcher = new ConstraintReferenceMatcher<>(ctx, constraintTargetRef, expressionFactory, result, LOGGER);
List<PrismObject<?>> matchingTargets = new ArrayList<>();
for (EvaluatedAssignmentImpl<?> evaluatedAssignment : evaluatedAssignmentTriple.getNonNegativeValues()) {
// MID-6403
AssignmentOrigin origin = evaluatedAssignment.getOrigin();
boolean assignmentIsAdded = origin.isBeingAdded();
boolean assignmentIsDeleted = origin.isBeingDeleted();
boolean assignmentIsKept = origin.isBeingKept();
DeltaSetTriple<EvaluatedAssignmentTargetImpl> targetsTriple = evaluatedAssignment.getRoles();
for (EvaluatedAssignmentTargetImpl target : targetsTriple.getNonNegativeValues()) {
// MID-6403
if (!target.appliesToFocus()) {
continue;
}
if (!(allowDirect && target.isDirectlyAssigned() || allowIndirect && !target.isDirectlyAssigned())) {
continue;
}
if (!(allowEnabled && target.isValid() || allowDisabled && !target.isValid())) {
continue;
}
if (!relationMatches(constraintTargetRef.getRelation(), constraint.getRelation(), target.getAssignment())) {
continue;
}
boolean targetIsInPlusSet = targetsTriple.presentInPlusSet(target);
boolean targetIsInZeroSet = targetsTriple.presentInZeroSet(target);
boolean targetIsInMinusSet = targetsTriple.presentInMinusSet(target);
// TODO check these computations
boolean isPlus = assignmentIsAdded || assignmentIsKept && targetIsInPlusSet;
boolean isZero = assignmentIsKept && targetIsInZeroSet;
boolean isMinus = assignmentIsDeleted || assignmentIsKept && targetIsInMinusSet;
// noinspection ConstantConditions
if (!(allowPlus && isPlus || allowZero && isZero || allowMinus && isMinus)) {
continue;
}
if (refMatcher.refMatchesTarget(target.getTarget(), "hasAssignment constraint")) {
// TODO more specific trigger, containing information on matching assignment; see ExclusionConstraintEvaluator
matchingTargets.add(target.getTarget());
}
}
}
if (!matchingTargets.isEmpty()) {
if (shouldExist) {
PrismObject<?> anyTargetObject = matchingTargets.get(0);
return new EvaluatedHasAssignmentTrigger(PolicyConstraintKindType.HAS_ASSIGNMENT, constraint, matchingTargets, createPositiveMessage(constraintElement, ctx, anyTargetObject, result), createPositiveShortMessage(constraintElement, ctx, anyTargetObject, result));
} else {
// we matched something but the constraint was "has no assignment"
return null;
}
} else {
return createTriggerIfShouldNotExist(shouldExist, constraintElement, ctx, result);
}
} catch (Throwable t) {
result.recordFatalError(t.getMessage(), t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}
Aggregations