Search in sources :

Example 6 with Mapping

use of com.evolveum.midpoint.model.common.mapping.Mapping in project midpoint by Evolveum.

the class Construction method evaluateAttribute.

private <T> Mapping<PrismPropertyValue<T>, ResourceAttributeDefinition<T>> evaluateAttribute(ResourceAttributeDefinitionType attribudeDefinitionType, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
    QName attrName = ItemPathUtil.getOnlySegmentQName(attribudeDefinitionType.getRef());
    if (attrName == null) {
        throw new SchemaException("Missing 'ref' in attribute construction in account construction in " + getSource());
    }
    if (!attribudeDefinitionType.getInbound().isEmpty()) {
        throw new SchemaException("Cannot process inbound section in definition of attribute " + attrName + " in account construction in " + getSource());
    }
    MappingType outboundMappingType = attribudeDefinitionType.getOutbound();
    if (outboundMappingType == null) {
        throw new SchemaException("No outbound section in definition of attribute " + attrName + " in account construction in " + getSource());
    }
    ResourceAttributeDefinition<T> outputDefinition = findAttributeDefinition(attrName);
    if (outputDefinition == null) {
        throw new SchemaException("Attribute " + attrName + " not found in schema for account type " + getIntent() + ", " + getResource(task, result) + " as definied in " + getSource(), attrName);
    }
    Mapping.Builder<PrismPropertyValue<T>, ResourceAttributeDefinition<T>> builder = mappingFactory.createMappingBuilder(outboundMappingType, "for attribute " + PrettyPrinter.prettyPrint(attrName) + " in " + getSource());
    Mapping<PrismPropertyValue<T>, ResourceAttributeDefinition<T>> evaluatedMapping = evaluateMapping(builder, attrName, outputDefinition, null, task, result);
    LOGGER.trace("Evaluated mapping for attribute " + attrName + ": " + evaluatedMapping);
    return evaluatedMapping;
}
Also used : MappingType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ResourceAttributeDefinition(com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition) QName(javax.xml.namespace.QName) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue)

Example 7 with Mapping

use of com.evolveum.midpoint.model.common.mapping.Mapping in project midpoint by Evolveum.

the class LensUtil method consolidateTripleToDelta.

/**
	 * Consolidate the mappings of a single item to a delta. It takes the convenient structure of ItemValueWithOrigin triple.
	 * It produces the delta considering the mapping exclusion, authoritativeness and strength.
     *
     * filterExistingValues: if true, then values that already exist in the item are not added (and those that don't exist are not removed)
	 */
@NotNull
public static <V extends PrismValue, D extends ItemDefinition, I extends ItemValueWithOrigin<V, D>> ItemDelta<V, D> consolidateTripleToDelta(ItemPath itemPath, DeltaSetTriple<I> triple, D itemDefinition, ItemDelta<V, D> aprioriItemDelta, PrismContainer<?> itemContainer, ValueMatcher<?> valueMatcher, Comparator<V> comparator, boolean addUnchangedValues, boolean filterExistingValues, boolean isExclusiveStrong, String contextDescription, boolean applyWeak) throws ExpressionEvaluationException, PolicyViolationException, SchemaException {
    ItemDelta<V, D> itemDelta = itemDefinition.createEmptyDelta(itemPath);
    Item<V, D> itemExisting = null;
    if (itemContainer != null) {
        itemExisting = itemContainer.findItem(itemPath);
    }
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Consolidating {} triple:\n{}\nApriori Delta:\n{}\nExisting item:\n{}", itemPath, triple.debugDump(1), DebugUtil.debugDump(aprioriItemDelta, 1), DebugUtil.debugDump(itemExisting, 1));
    }
    Collection<V> allValues = collectAllValues(triple, valueMatcher);
    final MutableBoolean itemHasStrongMutable = new MutableBoolean(false);
    SimpleVisitor<I> visitor = pvwo -> {
        if (pvwo.getMapping().getStrength() == MappingStrengthType.STRONG) {
            itemHasStrongMutable.setValue(true);
        }
    };
    triple.accept(visitor);
    boolean ignoreNormalMappings = itemHasStrongMutable.booleanValue() && isExclusiveStrong;
    // a single item (e.g. attribute). But this loop iterates over every potential value of that item.
    for (V value : allValues) {
        LOGGER.trace("  consolidating value: {}", value);
        // Check what to do with the value using the usual "triple routine". It means that if a value is
        // in zero set than we need no delta, plus set means add delta and minus set means delete delta.
        // The first set that the value is present determines the result.
        Collection<ItemValueWithOrigin<V, D>> zeroPvwos = collectPvwosFromSet(value, triple.getZeroSet(), valueMatcher);
        Collection<ItemValueWithOrigin<V, D>> plusPvwos = collectPvwosFromSet(value, triple.getPlusSet(), valueMatcher);
        Collection<ItemValueWithOrigin<V, D>> minusPvwos = collectPvwosFromSet(value, triple.getMinusSet(), valueMatcher);
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("PVWOs for value {}:\nzero = {}\nplus = {}\nminus = {}", value, zeroPvwos, plusPvwos, minusPvwos);
        }
        boolean zeroHasStrong = false;
        if (!zeroPvwos.isEmpty()) {
            for (ItemValueWithOrigin<V, D> pvwo : zeroPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    zeroHasStrong = true;
                }
            }
        }
        if (zeroHasStrong && aprioriItemDelta != null && aprioriItemDelta.isValueToDelete(value, true)) {
            throw new PolicyViolationException("Attempt to delete value " + value + " from item " + itemPath + " but that value is mandated by a strong mapping (in " + contextDescription + ")");
        }
        if (!zeroPvwos.isEmpty() && !addUnchangedValues) {
            // Value unchanged, nothing to do
            LOGGER.trace("Value {} unchanged, doing nothing", value);
            continue;
        }
        PrismValueDeltaSetTripleProducer<V, D> exclusiveMapping = null;
        Collection<ItemValueWithOrigin<V, D>> pvwosToAdd = null;
        if (addUnchangedValues) {
            pvwosToAdd = MiscUtil.union(zeroPvwos, plusPvwos);
        } else {
            pvwosToAdd = plusPvwos;
        }
        if (!pvwosToAdd.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwoToAdd : pvwosToAdd) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwoToAdd.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isExclusive()) {
                    if (exclusiveMapping == null) {
                        exclusiveMapping = mapping;
                    } else {
                        String message = "Exclusion conflict in " + contextDescription + ", item " + itemPath + ", conflicting constructions: " + exclusiveMapping + " and " + mapping;
                        LOGGER.error(message);
                        throw new ExpressionEvaluationException(message);
                    }
                }
            }
            if (weakOnly) {
                // Postpone processing of weak values until we process all other values
                LOGGER.trace("Value {} mapping is weak in item {}, postponing processing in {}", value, itemPath, contextDescription);
                continue;
            }
            if (!hasStrong && ignoreNormalMappings) {
                LOGGER.trace("Value {} mapping is normal in item {} and we have exclusiveStrong, skipping processing in {}", value, itemPath, contextDescription);
                continue;
            }
            if (hasStrong && aprioriItemDelta != null && aprioriItemDelta.isValueToDelete(value, true)) {
                throw new PolicyViolationException("Attempt to delete value " + value + " from item " + itemPath + " but that value is mandated by a strong mapping (in " + contextDescription + ")");
            }
            if (!hasStrong && (aprioriItemDelta != null && !aprioriItemDelta.isEmpty())) {
                // There is already a delta, skip this
                LOGGER.trace("Value {} mapping is not strong and the item {} already has a delta that is more concrete, " + "skipping adding in {}", value, itemPath, contextDescription);
                continue;
            }
            if (filterExistingValues && hasValue(itemExisting, value, valueMatcher, comparator)) {
                LOGGER.trace("Value {} NOT added to delta for item {} because the item already has that value in {}", value, itemPath, contextDescription);
                continue;
            }
            LOGGER.trace("Value {} added to delta as ADD for item {} in {}", value, itemPath, contextDescription);
            itemDelta.addValueToAdd((V) value.clone());
            continue;
        }
        // So check for that special case here to avoid removing them.
        if (!minusPvwos.isEmpty() && plusPvwos.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            boolean hasAuthoritative = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwo : minusPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isAuthoritative()) {
                    hasAuthoritative = true;
                }
            }
            if (!hasAuthoritative) {
                LOGGER.trace("Value {} has no authoritative mapping for item {}, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (!hasStrong && (aprioriItemDelta != null && !aprioriItemDelta.isEmpty())) {
                // There is already a delta, skip this
                LOGGER.trace("Value {} mapping is not strong and the item {} already has a delta that is more concrete, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (weakOnly && (itemExisting != null && !itemExisting.isEmpty())) {
                // There is already a value, skip this
                LOGGER.trace("Value {} mapping is weak and the item {} already has a value, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (weakOnly && !applyWeak && (itemExisting == null || itemExisting.isEmpty())) {
                // There is a weak mapping on a property, but we do not have full account available, so skipping deletion of the value is better way
                LOGGER.trace("Value {} mapping is weak and the full account could not be fetched, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (filterExistingValues && !hasValue(itemExisting, value, valueMatcher, comparator)) {
                LOGGER.trace("Value {} NOT add to delta as DELETE because item {} the item does not have that value in {} (matcher: {})", value, itemPath, contextDescription, valueMatcher);
                continue;
            }
            LOGGER.trace("Value {} added to delta as DELETE for item {} in {}", value, itemPath, contextDescription);
            itemDelta.addValueToDelete((V) value.clone());
        }
        if (!zeroPvwos.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            boolean hasAuthoritative = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwo : zeroPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isAuthoritative()) {
                    hasAuthoritative = true;
                }
            }
            if (aprioriItemDelta != null && aprioriItemDelta.isReplace()) {
                // Any strong mappings in the zero set needs to be re-applied as otherwise the replace will destroy it
                if (hasStrong) {
                    LOGGER.trace("Value {} added to delta for item {} in {} because there is strong mapping in the zero set", value, itemPath, contextDescription);
                    itemDelta.addValueToAdd((V) value.clone());
                    continue;
                }
            }
        }
    }
    Item<V, D> itemNew = null;
    if (itemContainer != null) {
        itemNew = itemContainer.findItem(itemPath);
    }
    if (!hasValue(itemNew, itemDelta)) {
        // The application of computed delta results in no value, apply weak mappings
        Collection<? extends ItemValueWithOrigin<V, D>> nonNegativePvwos = triple.getNonNegativeValues();
        Collection<V> valuesToAdd = addWeakValues(nonNegativePvwos, OriginType.ASSIGNMENTS, applyWeak);
        if (valuesToAdd.isEmpty()) {
            valuesToAdd = addWeakValues(nonNegativePvwos, OriginType.OUTBOUND, applyWeak);
        }
        if (valuesToAdd.isEmpty()) {
            valuesToAdd = addWeakValues(nonNegativePvwos, null, applyWeak);
        }
        LOGGER.trace("No value for item {} in {}, weak mapping processing yielded values: {}", itemPath, contextDescription, valuesToAdd);
        itemDelta.addValuesToAdd(valuesToAdd);
    } else {
        LOGGER.trace("Existing values for item {} in {}, weak mapping processing skipped", new Object[] { itemPath, contextDescription });
    }
    if (itemExisting != null) {
        List<V> existingValues = itemExisting.getValues();
        if (existingValues != null) {
            itemDelta.setEstimatedOldValues(PrismValue.cloneCollection(existingValues));
        }
    }
    return itemDelta;
}
Also used : ObjectResolver(com.evolveum.midpoint.schema.util.ObjectResolver) com.evolveum.midpoint.util.exception(com.evolveum.midpoint.util.exception) ExpressionConstants(com.evolveum.midpoint.schema.constants.ExpressionConstants) BooleanUtils(org.apache.commons.lang.BooleanUtils) DOMUtil(com.evolveum.midpoint.util.DOMUtil) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) EvaluatedPolicyRule(com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) com.evolveum.midpoint.prism(com.evolveum.midpoint.prism) PasswordCapabilityType(com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PasswordCapabilityType) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) Utils(com.evolveum.midpoint.model.impl.util.Utils) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) Collection(java.util.Collection) ActivationComputer(com.evolveum.midpoint.common.ActivationComputer) ResourceTypeUtil(com.evolveum.midpoint.schema.util.ResourceTypeUtil) ModelExpressionThreadLocalHolder(com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder) MiscUtil(com.evolveum.midpoint.util.MiscUtil) Task(com.evolveum.midpoint.task.api.Task) EvaluatedPolicyRuleTrigger(com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) ExpressionVariables(com.evolveum.midpoint.repo.common.expression.ExpressionVariables) ExpressionFactory(com.evolveum.midpoint.repo.common.expression.ExpressionFactory) PolyStringType(com.evolveum.prism.xml.ns._public.types_3.PolyStringType) ProvisioningService(com.evolveum.midpoint.provisioning.api.ProvisioningService) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) QName(javax.xml.namespace.QName) NotNull(org.jetbrains.annotations.NotNull) com.evolveum.midpoint.xml.ns._public.common.common_3(com.evolveum.midpoint.xml.ns._public.common.common_3) SchemaConstants(com.evolveum.midpoint.schema.constants.SchemaConstants) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) Trace(com.evolveum.midpoint.util.logging.Trace) DebugUtil(com.evolveum.midpoint.util.DebugUtil) PrismDefaultPolyStringNormalizer(com.evolveum.midpoint.prism.polystring.PrismDefaultPolyStringNormalizer) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) CredentialsCapabilityType(com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) HashSet(java.util.HashSet) SchemaConstantsGenerated(com.evolveum.midpoint.schema.SchemaConstantsGenerated) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) RefinedResourceSchemaImpl(com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl) ObjectTypeUtil(com.evolveum.midpoint.schema.util.ObjectTypeUtil) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) CapabilityUtil(com.evolveum.midpoint.schema.CapabilityUtil) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) ItemDeltaItem(com.evolveum.midpoint.repo.common.expression.ItemDeltaItem) Iterator(java.util.Iterator) Expression(com.evolveum.midpoint.repo.common.expression.Expression) ExpressionEvaluationContext(com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) LoggingUtils(com.evolveum.midpoint.util.logging.LoggingUtils) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) ShadowUtil(com.evolveum.midpoint.schema.util.ShadowUtil) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) Source(com.evolveum.midpoint.repo.common.expression.Source) Comparator(java.util.Comparator) Collections(java.util.Collections) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) ValueMatcher(com.evolveum.midpoint.model.impl.lens.projector.ValueMatcher) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with Mapping

use of com.evolveum.midpoint.model.common.mapping.Mapping in project midpoint by Evolveum.

the class AssignmentEvaluator method evaluateFocusMappings.

private void evaluateFocusMappings(AssignmentPathSegmentImpl segment, EvaluationContext ctx) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
    assertSourceNotNull(segment.source, ctx.evalAssignment);
    // TODO why "assignmentTypeNew" when we consider also old values?
    AssignmentType assignmentTypeNew = LensUtil.getAssignmentType(segment.getAssignmentIdi(), ctx.evaluateOld);
    MappingsType mappingsType = assignmentTypeNew.getFocusMappings();
    LOGGER.trace("Evaluate focus mappings '{}' in {} ({} mappings)", mappingsType.getDescription(), segment.source, mappingsType.getMapping().size());
    AssignmentPathVariables assignmentPathVariables = LensUtil.computeAssignmentPathVariables(ctx.assignmentPath);
    for (MappingType mappingType : mappingsType.getMapping()) {
        Mapping mapping = mappingEvaluator.createFocusMapping(mappingFactory, lensContext, mappingType, segment.source, focusOdo, assignmentPathVariables, systemConfiguration, now, segment.sourceDescription, ctx.task, ctx.result);
        if (mapping == null) {
            continue;
        }
        // TODO: time constratins?
        mappingEvaluator.evaluateMapping(mapping, lensContext, ctx.task, ctx.result);
        ctx.evalAssignment.addFocusMapping(mapping);
    }
}
Also used : Mapping(com.evolveum.midpoint.model.common.mapping.Mapping)

Example 9 with Mapping

use of com.evolveum.midpoint.model.common.mapping.Mapping in project midpoint by Evolveum.

the class ConsolidationProcessor method consolidateValuesToModifyDelta.

private <F extends FocusType> ObjectDelta<ShadowType> consolidateValuesToModifyDelta(LensContext<F> context, LensProjectionContext projCtx, boolean addUnchangedValues, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException {
    // "Squeeze" all the relevant mappings into a data structure that we can process conveniently. We want to have all the
    // (meta)data about relevant for a specific attribute in one data structure, not spread over several account constructions.
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> squeezedAttributes = sqeeze(projCtx, construction -> (Collection) construction.getAttributeMappings());
    projCtx.setSqueezedAttributes(squeezedAttributes);
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> squeezedAssociations = sqeeze(projCtx, construction -> construction.getAssociationMappings());
    projCtx.setSqueezedAssociations(squeezedAssociations);
    // So, we do it here - once and for all.
    if (!squeezedAssociations.isEmpty()) {
        fillInAssociationNames(squeezedAssociations);
    }
    MappingExtractor<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>, F> auxiliaryObjectClassExtractor = construction -> {
        PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> prod = new PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>() {

            @Override
            public QName getMappingQName() {
                return ShadowType.F_AUXILIARY_OBJECT_CLASS;
            }

            @Override
            public PrismValueDeltaSetTriple<PrismPropertyValue<QName>> getOutputTriple() {
                PrismValueDeltaSetTriple<PrismPropertyValue<QName>> triple = new PrismValueDeltaSetTriple<>();
                if (construction.getAuxiliaryObjectClassDefinitions() != null) {
                    for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : construction.getAuxiliaryObjectClassDefinitions()) {
                        triple.addToZeroSet(new PrismPropertyValue<QName>(auxiliaryObjectClassDefinition.getTypeName()));
                    }
                }
                return triple;
            }

            @Override
            public MappingStrengthType getStrength() {
                return MappingStrengthType.STRONG;
            }

            @Override
            public PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> clone() {
                return this;
            }

            @Override
            public boolean isExclusive() {
                return false;
            }

            @Override
            public boolean isAuthoritative() {
                return true;
            }

            @Override
            public boolean isSourceless() {
                return false;
            }
        };
        Collection<PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> col = new ArrayList<>(1);
        col.add(prod);
        return col;
    };
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> squeezedAuxiliaryObjectClasses = sqeeze(projCtx, auxiliaryObjectClassExtractor);
    projCtx.setSqueezedAuxiliaryObjectClasses(squeezedAuxiliaryObjectClasses);
    ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
    ObjectDelta<ShadowType> objectDelta = new ObjectDelta<ShadowType>(ShadowType.class, ChangeType.MODIFY, prismContext);
    objectDelta.setOid(projCtx.getOid());
    // Let's be very very lazy about fetching the account from the resource.
    if (!projCtx.hasFullShadow() && (hasActiveWeakMapping(squeezedAttributes, projCtx) || hasActiveWeakMapping(squeezedAssociations, projCtx) || (hasActiveStrongMapping(squeezedAttributes, projCtx) || hasActiveStrongMapping(squeezedAssociations, projCtx)))) {
        // Full account was not yet loaded. This will cause problems as
        // the weak mapping may be applied even though it should not be
        // applied
        // and also same changes may be discarded because of unavailability
        // of all
        // account's attributes.Therefore load the account now, but with
        // doNotDiscovery options..
        // We also need to get account if there are strong mappings. Strong mappings
        // should always be applied. So reading the account now will indirectly
        // trigger reconciliation which makes sure that the strong mappings are
        // applied.
        // By getting accounts from provisioning, there might be a problem with
        // resource availability. We need to know, if the account was read full
        // or we have only the shadow from the repository. If we have only
        // shadow, the weak mappings may applied even if they should not be. 
        contextLoader.loadFullShadow(context, projCtx, "weak or strong mapping", task, result);
        if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
            return null;
        }
    }
    boolean completeAccount = projCtx.hasFullShadow();
    ObjectDelta<ShadowType> existingDelta = projCtx.getDelta();
    // AUXILIARY OBJECT CLASSES
    ItemPath auxiliaryObjectClassItemPath = new ItemPath(ShadowType.F_AUXILIARY_OBJECT_CLASS);
    PrismPropertyDefinition<QName> auxiliaryObjectClassPropertyDef = projCtx.getObjectDefinition().findPropertyDefinition(auxiliaryObjectClassItemPath);
    PropertyDelta<QName> auxiliaryObjectClassAPrioriDelta = null;
    RefinedResourceSchema refinedSchema = projCtx.getRefinedResourceSchema();
    List<QName> auxOcNames = new ArrayList<>();
    List<RefinedObjectClassDefinition> auxOcDefs = new ArrayList<>();
    ObjectDelta<ShadowType> projDelta = projCtx.getDelta();
    if (projDelta != null) {
        auxiliaryObjectClassAPrioriDelta = projDelta.findPropertyDelta(auxiliaryObjectClassItemPath);
    }
    for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> entry : squeezedAuxiliaryObjectClasses.entrySet()) {
        DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> ivwoTriple = entry.getValue();
        LOGGER.trace("CONSOLIDATE auxiliary object classes ({})", new Object[] { discr });
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Auxiliary object class triple:\n{}", ivwoTriple.debugDump());
        }
        for (ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> ivwo : ivwoTriple.getAllValues()) {
            QName auxObjectClassName = ivwo.getItemValue().getValue();
            if (auxOcNames.contains(auxObjectClassName)) {
                continue;
            }
            auxOcNames.add(auxObjectClassName);
            RefinedObjectClassDefinition auxOcDef = refinedSchema.getRefinedDefinition(auxObjectClassName);
            if (auxOcDef == null) {
                LOGGER.error("Auxiliary object class definition {} for {} not found in the schema, but it should be there, dumping context:\n{}", auxObjectClassName, discr, context.debugDump());
                throw new IllegalStateException("Auxiliary object class definition " + auxObjectClassName + " for " + discr + " not found in the context, but it should be there");
            }
            auxOcDefs.add(auxOcDef);
        }
        ItemDelta<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> itemDelta = LensUtil.consolidateTripleToDelta(auxiliaryObjectClassItemPath, ivwoTriple, auxiliaryObjectClassPropertyDef, auxiliaryObjectClassAPrioriDelta, projCtx.getObjectNew(), null, null, addUnchangedValues, completeAccount, false, discr.toHumanReadableDescription(), false);
        PropertyDelta<QName> propDelta = (PropertyDelta) itemDelta;
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Auxiliary object class delta:\n{}", propDelta.debugDump());
        }
        if (!propDelta.isEmpty()) {
            objectDelta.addModification(propDelta);
        }
    }
    RefinedObjectClassDefinition structuralObjectClassDefinition = projCtx.getStructuralObjectClassDefinition();
    if (structuralObjectClassDefinition == null) {
        LOGGER.error("Structural object class definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
        throw new IllegalStateException("Structural object class definition for " + discr + " not found in the context, but it should be there");
    }
    RefinedObjectClassDefinition rOcDef = new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxOcDefs);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Object class definition for {} consolidation:\n{}", discr, rOcDef.debugDump());
    }
    // with the data in ItemValueWithOrigin triples.
    for (Map.Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> entry : squeezedAttributes.entrySet()) {
        QName attributeName = entry.getKey();
        DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>> triple = entry.getValue();
        PropertyDelta<?> propDelta = consolidateAttribute(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, attributeName, (DeltaSetTriple) triple);
        if (propDelta != null) {
            objectDelta.addModification(propDelta);
        }
    }
    // ASSOCIATIONS
    for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> entry : squeezedAssociations.entrySet()) {
        QName associationName = entry.getKey();
        DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>> triple = entry.getValue();
        ContainerDelta<ShadowAssociationType> containerDelta = consolidateAssociation(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, associationName, triple);
        if (containerDelta != null) {
            objectDelta.addModification(containerDelta);
        }
    }
    return objectDelta;
}
Also used : PrismValue(com.evolveum.midpoint.prism.PrismValue) Construction(com.evolveum.midpoint.model.impl.lens.Construction) ChangeType(com.evolveum.midpoint.prism.delta.ChangeType) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) Autowired(org.springframework.beans.factory.annotation.Autowired) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) com.evolveum.midpoint.common.refinery(com.evolveum.midpoint.common.refinery) LensContext(com.evolveum.midpoint.model.impl.lens.LensContext) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) Map(java.util.Map) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) PrismProperty(com.evolveum.midpoint.prism.PrismProperty) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) InternalsConfig.consistencyChecks(com.evolveum.midpoint.schema.internals.InternalsConfig.consistencyChecks) Collection(java.util.Collection) Task(com.evolveum.midpoint.task.api.Task) MatchingRuleRegistry(com.evolveum.midpoint.prism.match.MatchingRuleRegistry) ObjectUtils(org.apache.commons.lang.ObjectUtils) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) List(java.util.List) FocusType(com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType) Entry(java.util.Map.Entry) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) QName(javax.xml.namespace.QName) MappingStrengthType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) Trace(com.evolveum.midpoint.util.logging.Trace) HashMap(java.util.HashMap) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ArrayList(java.util.ArrayList) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) PrismContext(com.evolveum.midpoint.prism.PrismContext) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) ContainerDelta(com.evolveum.midpoint.prism.delta.ContainerDelta) LensUtil(com.evolveum.midpoint.model.impl.lens.LensUtil) PrismPropertyDefinition(com.evolveum.midpoint.prism.PrismPropertyDefinition) Iterator(java.util.Iterator) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) PrismObject(com.evolveum.midpoint.prism.PrismObject) SynchronizationPolicyDecision(com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) Component(org.springframework.stereotype.Component) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) LayerType(com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType) PrismReference(com.evolveum.midpoint.prism.PrismReference) Comparator(java.util.Comparator) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) ArrayList(java.util.ArrayList) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) MappingStrengthType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) Collection(java.util.Collection) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) Map(java.util.Map) HashMap(java.util.HashMap) PrismPropertyDefinition(com.evolveum.midpoint.prism.PrismPropertyDefinition) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) QName(javax.xml.namespace.QName) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 10 with Mapping

use of com.evolveum.midpoint.model.common.mapping.Mapping in project midpoint by Evolveum.

the class MappingEvaluator method evaluateMappingSetProjection.

public <V extends PrismValue, D extends ItemDefinition, T extends ObjectType, F extends FocusType> void evaluateMappingSetProjection(MappingEvaluatorParams<V, D, T, F> params, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
    String mappingDesc = params.getMappingDesc();
    LensElementContext<T> targetContext = params.getTargetContext();
    PrismObjectDefinition<T> targetObjectDefinition = targetContext.getObjectDefinition();
    ItemPath defaultTargetItemPath = params.getDefaultTargetItemPath();
    Map<ItemPath, MappingOutputStruct<V>> outputTripleMap = new HashMap<>();
    XMLGregorianCalendar nextRecomputeTime = null;
    Collection<MappingType> mappingTypes = params.getMappingTypes();
    Collection<Mapping<V, D>> mappings = new ArrayList<>(mappingTypes.size());
    for (MappingType mappingType : mappingTypes) {
        Mapping.Builder<V, D> mappingBuilder = mappingFactory.createMappingBuilder(mappingType, mappingDesc);
        String mappingName = null;
        if (mappingType.getName() != null) {
            mappingName = mappingType.getName();
        }
        if (!mappingBuilder.isApplicableToChannel(params.getContext().getChannel())) {
            LOGGER.trace("Mapping {} not applicable to channel, skipping {}", mappingName, params.getContext().getChannel());
            continue;
        }
        mappingBuilder.now(params.getNow());
        if (defaultTargetItemPath != null && targetObjectDefinition != null) {
            D defaultTargetItemDef = targetObjectDefinition.findItemDefinition(defaultTargetItemPath);
            mappingBuilder.defaultTargetDefinition(defaultTargetItemDef);
            mappingBuilder.defaultTargetPath(defaultTargetItemPath);
        } else {
            mappingBuilder.defaultTargetDefinition(params.getTargetItemDefinition());
            mappingBuilder.defaultTargetPath(defaultTargetItemPath);
        }
        mappingBuilder.targetContext(targetObjectDefinition);
        if (params.getSourceContext() != null) {
            mappingBuilder.sourceContext(params.getSourceContext());
        }
        // Initialize mapping (using Inversion of Control)
        mappingBuilder = params.getInitializer().initialize(mappingBuilder);
        Mapping<V, D> mapping = mappingBuilder.build();
        Boolean timeConstraintValid = mapping.evaluateTimeConstraintValid(task, result);
        if (params.getEvaluateCurrent() != null) {
            if (params.getEvaluateCurrent() && !timeConstraintValid) {
                LOGGER.trace("Mapping {} is non-current, but evulating current mappings, skipping {}", mappingName, params.getContext().getChannel());
                continue;
            }
            if (!params.getEvaluateCurrent() && timeConstraintValid) {
                LOGGER.trace("Mapping {} is current, but evulating non-current mappings, skipping {}", mappingName, params.getContext().getChannel());
                continue;
            }
        }
        mappings.add(mapping);
    }
    boolean hasFullTargetObject = params.hasFullTargetObject();
    PrismObject<T> aPrioriTargetObject = params.getAPrioriTargetObject();
    LOGGER.trace("Going to process {} mappings for {}", mappings.size(), mappingDesc);
    for (Mapping<V, D> mapping : mappings) {
        if (mapping.getStrength() == MappingStrengthType.WEAK) {
            // Evaluate weak mappings in a second run.
            continue;
        }
        ItemPath mappingOutputPath = mapping.getOutputPath();
        if (params.isFixTarget() && mappingOutputPath != null && defaultTargetItemPath != null && !mappingOutputPath.equivalent(defaultTargetItemPath)) {
            throw new ExpressionEvaluationException("Target cannot be overridden in " + mappingDesc);
        }
        if (params.getAPrioriTargetDelta() != null && mappingOutputPath != null) {
            ItemDelta<?, ?> aPrioriItemDelta = params.getAPrioriTargetDelta().findItemDelta(mappingOutputPath);
            if (mapping.getStrength() != MappingStrengthType.STRONG) {
                if (aPrioriItemDelta != null && !aPrioriItemDelta.isEmpty()) {
                    continue;
                }
            }
        }
        evaluateMapping(mapping, params.getContext(), task, result);
        PrismValueDeltaSetTriple<V> mappingOutputTriple = mapping.getOutputTriple();
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Output triple of mapping {}\n{}", mapping.getContextDescription(), mappingOutputTriple == null ? null : mappingOutputTriple.debugDump(1));
        }
        if (mappingOutputTriple != null) {
            MappingOutputStruct<V> mappingOutputStruct = outputTripleMap.get(mappingOutputPath);
            if (mappingOutputStruct == null) {
                mappingOutputStruct = new MappingOutputStruct<>();
                outputTripleMap.put(mappingOutputPath, mappingOutputStruct);
            }
            if (mapping.getStrength() == MappingStrengthType.STRONG) {
                mappingOutputStruct.setStrongMappingWasUsed(true);
            //                	if (!hasFullTargetObject && params.getTargetLoader() != null) {
            //    					if (!params.getTargetLoader().isLoaded()) {
            //    						aPrioriTargetObject = params.getTargetLoader().load(task, result);
            //    						LOGGER.trace("Loaded object because of strong mapping: {}", aPrioriTargetObject);
            //    						hasFullTargetObject = true;
            //    					}
            //    				}
            }
            PrismValueDeltaSetTriple<V> outputTriple = mappingOutputStruct.getOutputTriple();
            if (outputTriple == null) {
                mappingOutputStruct.setOutputTriple(mappingOutputTriple);
            } else {
                outputTriple.merge(mappingOutputTriple);
            }
        }
    }
    if (params.isEvaluateWeak()) {
        // Second pass, evaluate only weak mappings
        for (Mapping<V, D> mapping : mappings) {
            if (mapping.getStrength() != MappingStrengthType.WEAK) {
                continue;
            }
            ItemPath mappingOutputPath = mapping.getOutputPath();
            if (params.isFixTarget() && mappingOutputPath != null && defaultTargetItemPath != null && !mappingOutputPath.equivalent(defaultTargetItemPath)) {
                throw new ExpressionEvaluationException("Target cannot be overridden in " + mappingDesc);
            }
            MappingOutputStruct<V> mappingOutputStruct = outputTripleMap.get(mappingOutputPath);
            if (mappingOutputStruct == null) {
                mappingOutputStruct = new MappingOutputStruct<>();
                outputTripleMap.put(mappingOutputPath, mappingOutputStruct);
            }
            PrismValueDeltaSetTriple<V> outputTriple = mappingOutputStruct.getOutputTriple();
            if (outputTriple != null) {
                // MID-3847
                continue;
            }
            Item<V, D> aPrioriTargetItem = null;
            if (aPrioriTargetObject != null && mappingOutputPath != null) {
                aPrioriTargetItem = aPrioriTargetObject.findItem(mappingOutputPath);
            }
            if (hasNoValue(aPrioriTargetItem)) {
                mappingOutputStruct.setWeakMappingWasUsed(true);
                evaluateMapping(mapping, params.getContext(), task, result);
                PrismValueDeltaSetTriple<V> mappingOutputTriple = mapping.getOutputTriple();
                if (mappingOutputTriple != null) {
                    // This is all not right. See MID-3847
                    if (!hasFullTargetObject && params.getTargetLoader() != null) {
                        if (!params.getTargetLoader().isLoaded()) {
                            aPrioriTargetObject = params.getTargetLoader().load("weak mapping", task, result);
                            LOGGER.trace("Loaded object because of weak mapping: {}", aPrioriTargetObject);
                            hasFullTargetObject = true;
                        }
                    }
                    if (aPrioriTargetObject != null && mappingOutputPath != null) {
                        aPrioriTargetItem = aPrioriTargetObject.findItem(mappingOutputPath);
                    }
                    if (!hasNoValue(aPrioriTargetItem)) {
                        continue;
                    }
                    if (outputTriple == null) {
                        mappingOutputStruct.setOutputTriple(mappingOutputTriple);
                    } else {
                        outputTriple.merge(mappingOutputTriple);
                    }
                }
            }
        }
    }
    MappingOutputProcessor<V> processor = params.getProcessor();
    for (Entry<ItemPath, MappingOutputStruct<V>> outputTripleMapEntry : outputTripleMap.entrySet()) {
        ItemPath mappingOutputPath = outputTripleMapEntry.getKey();
        MappingOutputStruct<V> mappingOutputStruct = outputTripleMapEntry.getValue();
        PrismValueDeltaSetTriple<V> outputTriple = mappingOutputStruct.getOutputTriple();
        boolean defaultProcessing = true;
        if (processor != null) {
            LOGGER.trace("Executing processor to process mapping evaluation results: {}", processor);
            defaultProcessing = processor.process(mappingOutputPath, mappingOutputStruct);
        }
        if (defaultProcessing) {
            if (outputTriple == null) {
                LOGGER.trace("{} expression resulted in null triple for {}, skipping", mappingDesc, targetContext);
                continue;
            }
            ItemDefinition targetItemDefinition = null;
            if (mappingOutputPath != null) {
                targetItemDefinition = targetObjectDefinition.findItemDefinition(mappingOutputPath);
                if (targetItemDefinition == null) {
                    throw new SchemaException("No definition for item " + mappingOutputPath + " in " + targetObjectDefinition);
                }
            } else {
                targetItemDefinition = params.getTargetItemDefinition();
            }
            ItemDelta<V, D> targetItemDelta = targetItemDefinition.createEmptyDelta(mappingOutputPath);
            Item<V, D> aPrioriTargetItem = null;
            if (aPrioriTargetObject != null) {
                aPrioriTargetItem = aPrioriTargetObject.findItem(mappingOutputPath);
            }
            if (targetContext.isAdd()) {
                Collection<V> nonNegativeValues = outputTriple.getNonNegativeValues();
                if (nonNegativeValues == null || nonNegativeValues.isEmpty()) {
                    LOGGER.trace("{} resulted in null or empty value for {}, skipping", mappingDesc, targetContext);
                    continue;
                }
                targetItemDelta.setValuesToReplace(PrismValue.cloneCollection(nonNegativeValues));
            } else {
                // if we have fresh information (full shadow) AND the mapping used to derive the information was strong,
                // we will consider all values (zero & plus sets) -- otherwise, we take only the "plus" (i.e. changed) set
                // the first case is necessary, because in some situations (e.g. when mapping is changed)
                // the evaluator sees no differences w.r.t. real state, even if there is a difference
                // - and we must have a way to push new information onto the resource
                Collection<V> valuesToReplace;
                if (hasFullTargetObject && mappingOutputStruct.isStrongMappingWasUsed()) {
                    valuesToReplace = outputTriple.getNonNegativeValues();
                } else {
                    valuesToReplace = outputTriple.getPlusSet();
                }
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("{}: hasFullTargetObject={}, isStrongMappingWasUsed={}, valuesToReplace={}", new Object[] { mappingDesc, hasFullTargetObject, mappingOutputStruct.isStrongMappingWasUsed(), valuesToReplace });
                }
                if (valuesToReplace != null && !valuesToReplace.isEmpty()) {
                    if (hasFullTargetObject && targetContext.isFresh() && aPrioriTargetItem != null) {
                        Collection<V> valuesPresent = aPrioriTargetItem.getValues();
                        if (PrismValue.equalsRealValues(valuesPresent, valuesToReplace)) {
                            LOGGER.trace("{} resulted in existing values for {}, skipping creation of a delta", mappingDesc, targetContext);
                            continue;
                        }
                    }
                    targetItemDelta.setValuesToReplace(PrismValue.cloneCollection(valuesToReplace));
                } else if (outputTriple.hasMinusSet()) {
                    LOGGER.trace("{} resulted in null or empty value for {} and there is a minus set, resetting it (replace with empty)", mappingDesc, targetContext);
                    targetItemDelta.setValueToReplace();
                } else {
                    LOGGER.trace("{} resulted in null or empty value for {}, skipping", mappingDesc, targetContext);
                }
            }
            if (targetItemDelta.isEmpty()) {
                continue;
            }
            LOGGER.trace("{} adding new delta for {}: {}", mappingDesc, targetContext, targetItemDelta);
            targetContext.swallowToSecondaryDelta(targetItemDelta);
        }
    }
    for (Mapping<V, D> mapping : mappings) {
        XMLGregorianCalendar mappingNextRecomputeTime = mapping.getNextRecomputeTime();
        if (mappingNextRecomputeTime != null) {
            if (nextRecomputeTime == null || nextRecomputeTime.compare(mappingNextRecomputeTime) == DatatypeConstants.GREATER) {
                nextRecomputeTime = mappingNextRecomputeTime;
            }
        }
    }
    if (nextRecomputeTime != null) {
        boolean alreadyHasTrigger = false;
        if (params.getAPrioriTargetObject() != null) {
            for (TriggerType trigger : params.getAPrioriTargetObject().asObjectable().getTrigger()) {
                if (RecomputeTriggerHandler.HANDLER_URI.equals(trigger.getHandlerUri()) && nextRecomputeTime.equals(trigger.getTimestamp())) {
                    alreadyHasTrigger = true;
                    break;
                }
            }
        }
        if (!alreadyHasTrigger) {
            PrismContainerDefinition<TriggerType> triggerContDef = targetObjectDefinition.findContainerDefinition(ObjectType.F_TRIGGER);
            ContainerDelta<TriggerType> triggerDelta = triggerContDef.createEmptyDelta(new ItemPath(ObjectType.F_TRIGGER));
            PrismContainerValue<TriggerType> triggerCVal = triggerContDef.createValue();
            triggerDelta.addValueToAdd(triggerCVal);
            TriggerType triggerType = triggerCVal.asContainerable();
            triggerType.setTimestamp(nextRecomputeTime);
            triggerType.setHandlerUri(RecomputeTriggerHandler.HANDLER_URI);
            targetContext.swallowToSecondaryDelta(triggerDelta);
        }
    }
}
Also used : ResourceBidirectionalMappingType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBidirectionalMappingType) MappingType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) TriggerType(com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

Mapping (com.evolveum.midpoint.model.common.mapping.Mapping)12 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)7 QName (javax.xml.namespace.QName)5 PrismContainerDefinition (com.evolveum.midpoint.prism.PrismContainerDefinition)4 PrismContainerValue (com.evolveum.midpoint.prism.PrismContainerValue)4 PrismPropertyValue (com.evolveum.midpoint.prism.PrismPropertyValue)4 ItemDeltaItem (com.evolveum.midpoint.repo.common.expression.ItemDeltaItem)4 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)4 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)4 MappingType (com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType)4 RefinedObjectClassDefinition (com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition)3 ItemDefinition (com.evolveum.midpoint.prism.ItemDefinition)3 DeltaSetTriple (com.evolveum.midpoint.prism.delta.DeltaSetTriple)3 PrismValueDeltaSetTriple (com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple)3 ResourceShadowDiscriminator (com.evolveum.midpoint.schema.ResourceShadowDiscriminator)3 Task (com.evolveum.midpoint.task.api.Task)3 ShadowAssociationType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType)3 ArrayList (java.util.ArrayList)3 XMLGregorianCalendar (javax.xml.datatype.XMLGregorianCalendar)3 RefinedAssociationDefinition (com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition)2