use of com.evolveum.midpoint.prism.path.PathKeyedMap in project midpoint by Evolveum.
the class ItemLimitationsChecker method checkItemsLimitations.
/**
* @pre Focus context is recomputed.
*/
<O extends ObjectType> void checkItemsLimitations(LensFocusContext<O> focusContext) throws SchemaException {
PathKeyedMap<ObjectTemplateItemDefinitionType> itemDefinitionsMap = focusContext.getItemDefinitionsMap();
PrismObject<O> objectNew = focusContext.getObjectNew();
if (objectNew == null) {
// nothing to check on DELETE operation
return;
}
for (Map.Entry<ItemPath, ObjectTemplateItemDefinitionType> entry : itemDefinitionsMap.entrySet()) {
for (PropertyLimitationsType limitation : entry.getValue().getLimitations()) {
if (!limitation.getLayer().contains(LayerType.MODEL)) {
// or should we apply SCHEMA-layer limitations as well?
continue;
}
checkItemLimitations(objectNew, entry.getKey(), limitation);
}
}
}
use of com.evolveum.midpoint.prism.path.PathKeyedMap in project midpoint by Evolveum.
the class AssignmentProcessor method evaluateFocusMappings.
private <AH extends AssignmentHolderType> void evaluateFocusMappings(LensContext<AH> context, XMLGregorianCalendar now, LensFocusContext<AH> focusContext, DeltaSetTriple<EvaluatedAssignmentImpl<AH>> evaluatedAssignmentTriple, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, PolicyViolationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, CommunicationException {
OperationResult result = parentResult.subresult(OP_EVALUATE_FOCUS_MAPPINGS).setMinor().build();
try {
LOGGER.trace("Starting evaluation of assignment-held mappings");
ObjectDeltaObject<AH> focusOdoRelative = focusContext.getObjectDeltaObjectRelative();
List<AssignedFocusMappingEvaluationRequest> allRequests = new ArrayList<>();
for (EvaluatedAssignmentImpl<AH> evaluatedAssignment : evaluatedAssignmentTriple.getAllValues()) {
allRequests.addAll(evaluatedAssignment.getFocusMappingEvaluationRequests());
}
FocalMappingSetEvaluation.TripleCustomizer<?, ?> customizer = (triple, abstractRequest) -> {
if (triple == null) {
return null;
}
DeltaSetTriple<ItemValueWithOrigin<PrismValue, ItemDefinition<?>>> rv = prismContext.deltaFactory().createDeltaSetTriple();
AssignedFocusMappingEvaluationRequest request = (AssignedFocusMappingEvaluationRequest) abstractRequest;
// noinspection unchecked
EvaluatedAssignmentImpl<AH> evaluatedAssignment = (EvaluatedAssignmentImpl<AH>) request.getEvaluatedAssignment();
PlusMinusZero relativeMode = request.getRelativeMode();
Set<PlusMinusZero> presence = new HashSet<>();
PlusMinusZero resultingMode = null;
if (evaluatedAssignmentTriple.presentInPlusSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.PLUS, relativeMode);
presence.add(PlusMinusZero.PLUS);
}
if (evaluatedAssignmentTriple.presentInMinusSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.MINUS, relativeMode);
presence.add(PlusMinusZero.MINUS);
}
if (evaluatedAssignmentTriple.presentInZeroSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.ZERO, relativeMode);
presence.add(PlusMinusZero.ZERO);
}
LOGGER.trace("triple customizer: presence = {}, relativeMode = {}, resultingMode = {}", presence, relativeMode, resultingMode);
if (presence.isEmpty()) {
throw new IllegalStateException("Evaluated assignment is not present in any of plus/minus/zero sets " + "of the triple. Assignment = " + evaluatedAssignment + ", triple = " + triple);
} else if (presence.size() > 1) {
// TODO think about this
throw new IllegalStateException("Evaluated assignment is present in more than one plus/minus/zero sets " + "of the triple: " + presence + ". Assignment = " + evaluatedAssignment + ", triple = " + triple);
}
if (resultingMode != null) {
switch(resultingMode) {
case PLUS:
// MID-6403
rv.addAllToPlusSet(triple.getNonNegativeValues());
break;
case MINUS:
// MID-6403
rv.addAllToMinusSet(triple.getNonPositiveValues());
break;
case ZERO:
rv = triple;
break;
}
}
return rv;
};
FocalMappingSetEvaluation.EvaluatedMappingConsumer mappingConsumer = (mapping, abstractRequest) -> {
AssignedFocusMappingEvaluationRequest request = (AssignedFocusMappingEvaluationRequest) abstractRequest;
request.getEvaluatedAssignment().addFocusMapping(mapping);
};
TargetObjectSpecification<AH> targetSpecification = new FixedTargetSpecification<>(focusOdoRelative.getNewObject(), true);
MappingEvaluationEnvironment env = new MappingEvaluationEnvironment("focus mappings in assignments of " + focusContext.getHumanReadableName(), now, task);
FocalMappingSetEvaluation<AH, AH> mappingSetEvaluation = new FocalMappingSetEvaluationBuilder<AH, AH>().context(context).evaluationRequests(allRequests).phase(null).focusOdo(focusOdoRelative).targetSpecification(targetSpecification).tripleCustomizer(customizer).mappingConsumer(mappingConsumer).iteration(focusContext.getIteration()).iterationToken(focusContext.getIterationToken()).beans(beans).env(env).result(result).build();
mappingSetEvaluation.evaluateMappingsToTriples();
PathKeyedMap<DeltaSetTriple<ItemValueWithOrigin<?, ?>>> focusOutputTripleMap = mappingSetEvaluation.getOutputTripleMap();
logOutputTripleMap(focusOutputTripleMap);
DeltaSetTripleMapConsolidation<AH> consolidation = new DeltaSetTripleMapConsolidation<>(focusOutputTripleMap, focusOdoRelative.getNewObject(), focusOdoRelative.getObjectDelta(), context::primaryFocusItemDeltaExists, null, null, focusContext.getObjectDefinition(), env, beans, context, result);
consolidation.computeItemDeltas();
Collection<ItemDelta<?, ?>> focusDeltas = consolidation.getItemDeltas();
LOGGER.trace("Computed focus deltas: {}", focusDeltas);
focusContext.swallowToSecondaryDelta(focusDeltas);
focusContext.recompute();
} catch (Throwable t) {
result.recordFatalError(t.getMessage(), t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}
use of com.evolveum.midpoint.prism.path.PathKeyedMap in project midpoint by Evolveum.
the class MappedItem method createMappings.
/**
* Creates the respective mapping(s).
*/
void createMappings(@NotNull PathKeyedMap<List<InboundMappingInContext<?, ?>>> mappingsMap) throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectNotFoundException {
boolean fromAbsoluteState = processingMode == ProcessingMode.ABSOLUTE_STATE || processingMode == ProcessingMode.ABSOLUTE_STATE_IF_KNOWN;
if (fromAbsoluteState && !source.isAbsoluteStateAvailable()) {
LOGGER.trace("Skipping inbound mapping(s) for {} as they should be processed from absolute state, but we don't" + " have one", itemDescription);
return;
}
Item<V, D> currentProjectionItem = itemProvider.provide();
if (postProcessor != null) {
postProcessor.postProcess(itemAPrioriDelta, currentProjectionItem);
}
LOGGER.trace("Creating {} inbound mapping(s) for {} in {} ({}). Relevant values are:\n" + "- a priori item delta:\n{}\n" + "- current item:\n{}", mappingBeans.size(), itemDescription, source.getProjectionHumanReadableNameLazy(), fromAbsoluteState ? "absolute mode" : "relative mode", DebugUtil.debugDumpLazily(itemAPrioriDelta, 1), DebugUtil.debugDumpLazily(currentProjectionItem, 1));
if (currentProjectionItem != null && currentProjectionItem.hasRaw()) {
throw new SystemException("Property " + currentProjectionItem + " has raw parsing state," + " such property cannot be used in inbound expressions");
}
source.setValueMetadata(currentProjectionItem, itemAPrioriDelta);
ResourceType resource = source.getResource();
// Value for the $shadow ($projection, $account) variable.
// TODO Why do we use "object new" here? (We should perhaps go with ODO, shouldn't we?)
// Bear in mind that the value might not contain the full shadow (for example)
PrismObject<ShadowType> shadowVariableValue = source.getResourceObjectNew();
PrismObjectDefinition<ShadowType> shadowVariableDef = getShadowDefinition(shadowVariableValue);
Source<V, D> defaultSource = new Source<>(currentProjectionItem, itemAPrioriDelta, null, ExpressionConstants.VAR_INPUT_QNAME, itemDefinition);
defaultSource.recompute();
for (MappingType mappingBean : mappingBeans) {
String channel = source.getChannel();
if (!MappingImpl.isApplicableToChannel(mappingBean, channel)) {
LOGGER.trace("Mapping is not applicable to channel {}", channel);
continue;
}
MappingBuilder<V, D> builder = beans.mappingFactory.<V, D>createMappingBuilder().mappingBean(mappingBean).mappingKind(MappingKindType.INBOUND).implicitSourcePath(implicitSourcePath).contextDescription("inbound expression for " + itemDescription + " in " + resource).defaultSource(defaultSource).targetContext(target.focusDefinition).addVariableDefinition(ExpressionConstants.VAR_USER, target.focus, target.focusDefinition).addVariableDefinition(ExpressionConstants.VAR_FOCUS, target.focus, target.focusDefinition).addAliasRegistration(ExpressionConstants.VAR_USER, ExpressionConstants.VAR_FOCUS).addVariableDefinition(ExpressionConstants.VAR_ACCOUNT, shadowVariableValue, shadowVariableDef).addVariableDefinition(ExpressionConstants.VAR_SHADOW, shadowVariableValue, shadowVariableDef).addVariableDefinition(ExpressionConstants.VAR_PROJECTION, shadowVariableValue, shadowVariableDef).addAliasRegistration(ExpressionConstants.VAR_ACCOUNT, ExpressionConstants.VAR_PROJECTION).addAliasRegistration(ExpressionConstants.VAR_SHADOW, ExpressionConstants.VAR_PROJECTION).addVariableDefinition(ExpressionConstants.VAR_RESOURCE, resource, resource.asPrismObject().getDefinition()).addVariableDefinition(ExpressionConstants.VAR_CONFIGURATION, context.getSystemConfiguration(), getSystemConfigurationDefinition()).addVariableDefinition(ExpressionConstants.VAR_OPERATION, context.getOperation(), String.class).variableResolver(variableProducer).valuePolicySupplier(context.createValuePolicySupplier()).originType(OriginType.INBOUND).originObject(resource).now(context.env.now);
if (!target.isFocusBeingDeleted()) {
assert target.focus != null;
TypedValue<PrismObject<F>> targetContext = new TypedValue<>(target.focus);
builder.originalTargetValues(ExpressionUtil.computeTargetValues(mappingBean.getTarget(), targetContext, builder.getVariables(), beans.mappingFactory.getObjectResolver(), "resolving target values", beans.prismContext, context.env.task, context.result));
}
MappingImpl<V, D> mapping = builder.build();
if (checkWeakSkip(mapping)) {
LOGGER.trace("Skipping because of mapping is weak and focus property has already a value");
continue;
}
InboundMappingInContext<V, D> mappingStruct = source.createInboundMappingInContext(mapping);
ItemPath targetFocusItemPath = mapping.getOutputPath();
if (ItemPath.isEmpty(targetFocusItemPath)) {
throw new ConfigurationException("Empty target path in " + mapping.getContextDescription());
}
checkTargetItemDefinitionKnown(targetFocusItemPath);
mappingsMap.computeIfAbsent(targetFocusItemPath, k -> new ArrayList<>()).add(mappingStruct);
}
}
Aggregations