Skip to content

Commit

Permalink
Merge branch 'support-4.0' of https://github.com/Evolveum/midpoint in…
Browse files Browse the repository at this point in the history
…to support-4.0
  • Loading branch information
katkav committed Mar 16, 2020
2 parents dd7dd75 + d62f0e9 commit ad05c4c
Show file tree
Hide file tree
Showing 26 changed files with 235 additions and 214 deletions.
Expand Up @@ -35,7 +35,7 @@
</span>
</div>
</div>
<div class="row">
<div class="row" style="margin-left: 15px;">
<span wicket:id="feedback" class="text-danger"/>
</div>
</div>
Expand Down
Expand Up @@ -161,10 +161,11 @@ protected void onError(AjaxRequestTarget target, RuntimeException e) {
}

});
feedback.setFilter(new ComponentFeedbackMessageFilter(inputPanel.getValidatableComponent()));
} else {
feedback.setFilter(new ComponentFeedbackMessageFilter(component));
}

feedback.setFilter(new ComponentFeedbackMessageFilter(component));

if (component instanceof InputPanel) {
InputPanel inputPanel = (InputPanel) component;

Expand Down
Expand Up @@ -16,7 +16,7 @@
<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<div wicket:id="list">
<div wicket:id="list" style="margin-top: 5px">
<div wicket:id="message">
</div>
</div>
Expand Down
Expand Up @@ -90,15 +90,13 @@ public TimeIntervalStatusType getValidityStatus(ActivationType activationType, X
XMLGregorianCalendar validTo = activationType.getValidTo();
if (validFrom == null && validTo == null) {
return null;
} else if (validTo != null && referenceTime.compare(validTo) == DatatypeConstants.GREATER) {
return TimeIntervalStatusType.AFTER;
} else if (validFrom != null && referenceTime.compare(validFrom) == DatatypeConstants.LESSER) {
return TimeIntervalStatusType.BEFORE;
} else {
return TimeIntervalStatusType.IN;
}
TimeIntervalStatusType status = TimeIntervalStatusType.IN;
if (validFrom != null && (referenceTime == null || referenceTime.compare(validFrom) == DatatypeConstants.LESSER)) {
status = TimeIntervalStatusType.BEFORE;
}
if (validTo != null && referenceTime.compare(validTo) == DatatypeConstants.GREATER) {
status = TimeIntervalStatusType.AFTER;
}
return status;
}

public void computeEffective(String lifecycleStatus, ActivationType activationType, LifecycleStateModelType stateModel) {
Expand Down
Expand Up @@ -249,10 +249,6 @@ public static ApprovalStageDefinitionType getStageDefinition(ApprovalContextType
}
}

public static List<ApprovalStageDefinitionType> getStages(ApprovalSchemaType approvalSchema) {
return !approvalSchema.getStage().isEmpty() ? approvalSchema.getStage() : null;
}

// we must be strict here; in case of suspicion, throw an exception
@SuppressWarnings("unchecked")
public static <T extends CaseEventType> List<T> getEventsForCurrentStage(@NotNull CaseType aCase, @NotNull Class<T> clazz) {
Expand Down Expand Up @@ -328,7 +324,7 @@ public static void normalizeStages(ApprovalSchemaType schema) {

@NotNull
private static List<ApprovalStageDefinitionType> getSortedStages(ApprovalSchemaType schema) {
List<ApprovalStageDefinitionType> stages = new ArrayList<>(getStages(schema));
List<ApprovalStageDefinitionType> stages = new ArrayList<>(schema.getStage());
stages.sort(Comparator.comparing(stage -> getNumber(stage), Comparator.nullsLast(Comparator.naturalOrder())));
return stages;
}
Expand Down
Expand Up @@ -168,10 +168,13 @@
<xsd:annotation>
<xsd:documentation>
Reference to the task holding workflow context for wf-related cases.
EXPERIMENTAL. Probably will be removed.
DEPRECATED. Not used any more. The relation is defined the other way:
task.objectRef points to this case.
</xsd:documentation>
<xsd:appinfo>
<a:objectReferenceTargetType>tns:TaskType</a:objectReferenceTargetType>
<a:deprecated>true</a:deprecated>
<a:deprecatedSince>4.0.3</a:deprecatedSince>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
Expand Down
Expand Up @@ -47,8 +47,6 @@

/**
* A complex policy-drive role lifecycle scenario (see https://wiki.evolveum.com/display/midPoint/Sample+scenario).
*
* @author mederly
*/
@ContextConfiguration(locations = {"classpath:ctx-certification-test-main.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
Expand Down
Expand Up @@ -636,6 +636,9 @@ private void addToMinusIfNecessary(V originalValue) {

@SuppressWarnings("unused") // todo is this externally used?
public boolean isSatisfyCondition() {
if (conditionOutputTriple == null) {
return true;
}
boolean conditionOutputOld = computeConditionResult(conditionOutputTriple.getNonPositiveValues());
boolean conditionResultOld = conditionOutputOld && conditionMaskOld;

Expand Down
Expand Up @@ -223,7 +223,7 @@ private EvaluationContext(@NotNull EvaluatedAssignmentImpl<AH> evalAssignment,
*/
public EvaluatedAssignmentImpl<AH> evaluate(
ItemDeltaItem<PrismContainerValue<AssignmentType>,PrismContainerDefinition<AssignmentType>> assignmentIdi,
PlusMinusZero primaryAssignmentMode, boolean evaluateOld, ObjectType source, String sourceDescription, boolean forcedAssignment, Task task, OperationResult parentResult)
PlusMinusZero primaryAssignmentMode, boolean evaluateOld, AssignmentHolderType source, String sourceDescription, boolean forcedAssignment, Task task, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, SecurityViolationException, ConfigurationException, CommunicationException {
OperationResult result = parentResult.subresult(OP_EVALUATE)
.setMinor()
Expand Down Expand Up @@ -487,8 +487,12 @@ private <O extends ObjectType> boolean evaluateSegmentContent(AssignmentPathSegm

AssignmentType assignmentType = getAssignmentType(segment, ctx);

boolean isAssignmentValid = LensUtil.isAssignmentValid(focusOdo.getNewObject().asObjectable(), assignmentType,
now, activationComputer, focusStateModel);
// Assignment validity is checked with respect to the assignment source, not to the focus object.
// So, if (e.g.) focus is in "draft" state, only validity of direct assignments should be influenced by this fact.
// Other assignments (e.g. from roles to metaroles) should be considered valid, provided these roles are
// in active lifecycle states. See also MID-6114.
AssignmentHolderType source = segment.isMatchingOrder() ? focusOdo.getNewObject().asObjectable() : segment.getSource();
boolean isAssignmentValid = LensUtil.isAssignmentValid(source, assignmentType, now, activationComputer, focusStateModel);
if (isAssignmentValid || segment.isValidityOverride()) {
// Note: validityOverride is currently the same as "isDirectAssignment" - which is very probably OK.
// Direct assignments are visited even if they are not valid (i.e. effectively disabled).
Expand All @@ -508,7 +512,7 @@ private <O extends ObjectType> boolean evaluateSegmentContent(AssignmentPathSegm
}
}
}
if (assignmentType.getPolicyRule() != null && !loginMode) {
if (!loginMode && assignmentType.getPolicyRule() != null) {
// Here we ignore "reallyValid". It is OK, because reallyValid can be false here only when
// evaluating direct assignments; and invalid ones are marked as such via EvaluatedAssignment.isValid.
// TODO is it ok?
Expand Down Expand Up @@ -986,15 +990,15 @@ private void evaluateAssignment(AssignmentPathSegmentImpl segment, PlusMinusZero
}

private void evaluateInducement(AssignmentPathSegmentImpl segment, PlusMinusZero mode, boolean isValid, EvaluationContext ctx,
AssignmentHolderType targetType, AssignmentType inducement, OperationResult result)
AssignmentHolderType target, AssignmentType inducement, OperationResult result)
throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, SecurityViolationException, ConfigurationException, CommunicationException {

ObjectType orderOneObject = getOrderOneObject(segment);

if (!isInducementApplicableToFocusType(inducement.getFocusType())) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Skipping application of inducement {} because the focusType does not match (specified: {}, actual: {})",
FocusTypeUtil.dumpAssignment(inducement), inducement.getFocusType(), targetType.getClass().getSimpleName());
FocusTypeUtil.dumpAssignment(inducement), inducement.getFocusType(), target.getClass().getSimpleName());
}
return;
}
Expand All @@ -1004,8 +1008,8 @@ private void evaluateInducement(AssignmentPathSegmentImpl segment, PlusMinusZero
}
return;
}
String subSourceDescription = targetType+" in "+segment.sourceDescription;
AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(targetType, subSourceDescription, inducement, false, relationRegistry, prismContext);
String subSourceDescription = target+" in "+segment.sourceDescription;
AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(target, subSourceDescription, inducement, false, relationRegistry, prismContext);
// note that 'old' and 'new' values for assignment in nextSegment are the same
boolean nextIsMatchingOrder = AssignmentPathSegmentImpl.computeMatchingOrder(
segment.getEvaluationOrder(), nextSegment.getAssignmentNew());
Expand All @@ -1031,7 +1035,7 @@ private void evaluateInducement(AssignmentPathSegmentImpl segment, PlusMinusZero
// processMembership attribute to false for these inducements.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("orig EO({}): evaluate {} inducement({}) {}; new EO({})",
segment.getEvaluationOrder().shortDump(), targetType, FocusTypeUtil.dumpInducementConstraints(inducement),
segment.getEvaluationOrder().shortDump(), target, FocusTypeUtil.dumpInducementConstraints(inducement),
FocusTypeUtil.dumpAssignment(inducement), nextEvaluationOrderHolder.getValue().shortDump());
}
assert !ctx.assignmentPath.isEmpty();
Expand Down
Expand Up @@ -26,8 +26,6 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import net.sf.ehcache.store.disk.ods.AATreeSet;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
Expand All @@ -53,7 +51,7 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment {

// "assignment path segment" information

final ObjectType source; // we avoid "getter" notation for some final fields to simplify client code
final AssignmentHolderType source; // we avoid "getter" notation for some final fields to simplify client code
private final ItemDeltaItem<PrismContainerValue<AssignmentType>,PrismContainerDefinition<AssignmentType>> assignmentIdi;
private final boolean isAssignment; // false means inducement
private QName relation;
Expand Down Expand Up @@ -249,7 +247,7 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment {
* is like this: count the number of times the evaluation order for target reached ZERO level. First encounter with
* that level is on "this target". And we assume that each subsequent marks a target that is among "others".
*
* @see AssignmentEvaluator#appliesDirectly
* See AssignmentEvaluator.appliesDirectly
*/
private Boolean isMatchingOrder = null;
private EvaluationOrder evaluationOrder;
Expand All @@ -262,14 +260,14 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment {

private boolean evaluatedForOld;

AssignmentPathSegmentImpl(ObjectType source, String sourceDescription,
AssignmentPathSegmentImpl(AssignmentHolderType source, String sourceDescription,
ItemDeltaItem<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>> assignmentIdi,
boolean isAssignment, boolean evaluatedForOld, @NotNull RelationRegistry relationRegistry,
@NotNull PrismContext prismContext) {
this.source = source;
this.sourceDescription = sourceDescription;
if (assignmentIdi.getDefinition() == null) {
throw new IllegalArgumentException("Attept to set segment assignment IDI withough a definition");
throw new IllegalArgumentException("Attempt to set segment assignment IDI without a definition");
}
this.assignmentIdi = assignmentIdi;
this.isAssignment = isAssignment;
Expand All @@ -278,14 +276,15 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment {
this.prismContext = prismContext;
}

public AssignmentPathSegmentImpl(ObjectType source, String sourceDescription, AssignmentType assignment, boolean isAssignment,
public AssignmentPathSegmentImpl(AssignmentHolderType source, String sourceDescription, AssignmentType assignment, boolean isAssignment,
RelationRegistry relationRegistry, PrismContext prismContext) {
this(source, sourceDescription, createAssignmentIdi(assignment), isAssignment, false, relationRegistry, prismContext);
}

private static ItemDeltaItem<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>> createAssignmentIdi(
AssignmentType assignment) {
try {
//noinspection unchecked,rawtypes
return new ItemDeltaItem<>(LensUtil.createAssignmentSingleValueContainer(assignment), assignment.asPrismContainerValue().getDefinition());
} catch (SchemaException e) {
// should not really occur!
Expand Down Expand Up @@ -344,7 +343,7 @@ public void setTarget(ObjectType target) {
}

@Override
public ObjectType getSource() {
public AssignmentHolderType getSource() {
return source;
}

Expand Down Expand Up @@ -501,6 +500,7 @@ public int hashCode() {
return result;
}

@SuppressWarnings("RedundantIfStatement")
@Override
public boolean equals(Object obj) {
if (this == obj)
Expand Down Expand Up @@ -649,6 +649,7 @@ public boolean matches(@NotNull List<OrderConstraintsType> orderConstraints) {

// preliminary implementation; use only to compare segments in paths (pointing to the same target OID)
// that are to be checked for equivalency
@SuppressWarnings("SimplifiableIfStatement")
@Override
public boolean equivalent(AssignmentPathSegment otherSegment) {
if (!prismContext.relationsEquivalent(relation, otherSegment.getRelation())) {
Expand Down
Expand Up @@ -546,22 +546,20 @@ public static <F extends ObjectType> boolean evaluateIterationCondition(LensCont
/**
* Used for assignments and similar objects that do not have separate lifecycle.
*/
public static boolean isAssignmentValid(AssignmentHolderType focus, AssignmentType assignmentType, XMLGregorianCalendar now,
public static boolean isAssignmentValid(AssignmentHolderType focus, AssignmentType assignment, XMLGregorianCalendar now,
ActivationComputer activationComputer, LifecycleStateModelType focusStateModel) {
ObjectReferenceType targetRef = assignmentType.getTargetRef();
if (targetRef != null) {
if (QNameUtil.match(ArchetypeType.COMPLEX_TYPE, targetRef.getType())) {
// Archetype assignments are always valid, even in non-valid lifecycle states.
// The object cannot lose its (arche)type.
return true;
}
ObjectReferenceType targetRef = assignment.getTargetRef();
if (targetRef != null && QNameUtil.match(ArchetypeType.COMPLEX_TYPE, targetRef.getType())) {
// Archetype assignments are always valid, even in non-valid lifecycle states.
// The object cannot lose its (arche)type.
return true;
}
String focusLifecycleState = focus.getLifecycleState();

if (!activationComputer.lifecycleHasActiveAssignments(focusLifecycleState, focusStateModel)) {
return false;
}
return isValid(assignmentType.getLifecycleState(), assignmentType.getActivation(), now, activationComputer, focusStateModel);
return isValid(assignment.getLifecycleState(), assignment.getActivation(), now, activationComputer, focusStateModel);
}

public static <R extends AbstractRoleType> Collection<AssignmentType> getForcedAssignments(LifecycleStateModelType lifecycleModel, String targetLifecycle,
Expand Down
Expand Up @@ -194,7 +194,7 @@ private <AH extends AssignmentHolderType, F extends FocusType> void processAssig
// Initializing assignment evaluator. This will be used later to process all the assignments including the nested
// assignments (roles).
AssignmentEvaluator<AH> assignmentEvaluator = createAssignmentEvaluator(context, now);
ObjectType source = determineSource(focusContext);
AssignmentHolderType source = determineSource(focusContext);

AssignmentTripleEvaluator<AH> assignmentTripleEvaluator = new AssignmentTripleEvaluator<>();
assignmentTripleEvaluator.setActivationComputer(activationComputer);
Expand Down Expand Up @@ -595,9 +595,9 @@ private <F extends AssignmentHolderType> void checkAssignmentDeltaSanity(LensCon
}
}

private <F extends ObjectType> ObjectType determineSource(LensFocusContext<F> focusContext)
private <AH extends AssignmentHolderType> AssignmentHolderType determineSource(LensFocusContext<AH> focusContext)
throws SchemaException {
ObjectDelta<F> delta = focusContext.getWaveDelta(focusContext.getLensContext().getExecutionWave());
ObjectDelta<AH> delta = focusContext.getWaveDelta(focusContext.getLensContext().getExecutionWave());
if (delta != null && !delta.isEmpty()) {
return focusContext.getObjectNew().asObjectable();
}
Expand Down
Expand Up @@ -63,7 +63,7 @@ public class AssignmentTripleEvaluator<AH extends AssignmentHolderType> {
private static final String OP_EVALUATE_ASSIGNMENT = AssignmentTripleEvaluator.class.getName()+".evaluateAssignment";

private LensContext<AH> context;
private ObjectType source;
private AssignmentHolderType source;
private AssignmentEvaluator<AH> assignmentEvaluator;
private ActivationComputer activationComputer;
private PrismContext prismContext;
Expand All @@ -87,11 +87,11 @@ public void setContext(LensContext<AH> context) {
}
}

public ObjectType getSource() {
public AssignmentHolderType getSource() {
return source;
}

public void setSource(ObjectType source) {
public void setSource(AssignmentHolderType source) {
this.source = source;
}

Expand Down
Expand Up @@ -488,7 +488,7 @@ public <V extends PrismValue, D extends ItemDefinition, T extends ObjectType, F
for (MappingImpl<V,D> mapping: mappings) {
XMLGregorianCalendar mappingNextRecomputeTime = mapping.getNextRecomputeTime();
if (mappingNextRecomputeTime != null) {
if (nextRecomputeTime == null || nextRecomputeTime.compare(mappingNextRecomputeTime) == DatatypeConstants.GREATER) {
if (mapping.isSatisfyCondition() && (nextRecomputeTime == null || nextRecomputeTime.compare(mappingNextRecomputeTime) == DatatypeConstants.GREATER)) {
nextRecomputeTime = mappingNextRecomputeTime;
// TODO: maybe better description? But consider storage requirements. We do not want to store too much.
triggerOriginDescription = mapping.getIdentifier();
Expand Down

0 comments on commit ad05c4c

Please sign in to comment.