Search in sources :

Example 31 with ItemDefinition

use of com.evolveum.midpoint.prism.ItemDefinition in project midpoint by Evolveum.

the class MappingEvaluator method createFocusMapping.

public <V extends PrismValue, D extends ItemDefinition, F extends FocusType, T extends FocusType> Mapping<V, D> createFocusMapping(final MappingFactory mappingFactory, final LensContext<F> context, final MappingType mappingType, ObjectType originObject, ObjectDeltaObject<F> focusOdo, PrismObject<T> defaultTargetObject, AssignmentPathVariables assignmentPathVariables, Integer iteration, String iterationToken, PrismObject<SystemConfigurationType> configuration, XMLGregorianCalendar now, String contextDesc, final Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
    if (!Mapping.isApplicableToChannel(mappingType, context.getChannel())) {
        LOGGER.trace("Mapping {} not applicable to channel {}, skipping.", mappingType, context.getChannel());
        return null;
    }
    StringPolicyResolver stringPolicyResolver = new StringPolicyResolver() {

        private ItemPath outputPath;

        private ItemDefinition outputDefinition;

        @Override
        public void setOutputPath(ItemPath outputPath) {
            this.outputPath = outputPath;
        }

        @Override
        public void setOutputDefinition(ItemDefinition outputDefinition) {
            this.outputDefinition = outputDefinition;
        }

        @Override
        public StringPolicyType resolve() {
            // TODO need to switch to ObjectValuePolicyEvaluator
            if (outputDefinition.getName().equals(PasswordType.F_VALUE)) {
                ValuePolicyType passwordPolicy = credentialsProcessor.determinePasswordPolicy(context.getFocusContext(), task, result);
                if (passwordPolicy == null) {
                    return null;
                }
                return passwordPolicy.getStringPolicy();
            }
            if (mappingType.getExpression() != null) {
                List<JAXBElement<?>> evaluators = mappingType.getExpression().getExpressionEvaluator();
                if (evaluators != null) {
                    for (JAXBElement jaxbEvaluator : evaluators) {
                        Object object = jaxbEvaluator.getValue();
                        if (object instanceof GenerateExpressionEvaluatorType && ((GenerateExpressionEvaluatorType) object).getValuePolicyRef() != null) {
                            ObjectReferenceType ref = ((GenerateExpressionEvaluatorType) object).getValuePolicyRef();
                            try {
                                ValuePolicyType valuePolicyType = mappingFactory.getObjectResolver().resolve(ref, ValuePolicyType.class, null, "resolving value policy for generate attribute " + outputDefinition.getName() + " value", task, new OperationResult("Resolving value policy"));
                                if (valuePolicyType != null) {
                                    return valuePolicyType.getStringPolicy();
                                }
                            } catch (CommonException ex) {
                                throw new SystemException(ex.getMessage(), ex);
                            }
                        }
                    }
                }
            }
            return null;
        }
    };
    ExpressionVariables variables = new ExpressionVariables();
    FOCUS_VARIABLE_NAMES.forEach(name -> variables.addVariableDefinition(name, focusOdo));
    variables.addVariableDefinition(ExpressionConstants.VAR_ITERATION, iteration);
    variables.addVariableDefinition(ExpressionConstants.VAR_ITERATION_TOKEN, iterationToken);
    variables.addVariableDefinition(ExpressionConstants.VAR_CONFIGURATION, configuration);
    Collection<V> targetValues = computeTargetValues(mappingType.getTarget(), defaultTargetObject, variables, mappingFactory.getObjectResolver(), contextDesc, task, result);
    Mapping.Builder<V, D> mappingBuilder = mappingFactory.<V, D>createMappingBuilder(mappingType, contextDesc).sourceContext(focusOdo).targetContext(defaultTargetObject.getDefinition()).variables(variables).originalTargetValues(targetValues).originType(OriginType.USER_POLICY).originObject(originObject).stringPolicyResolver(stringPolicyResolver).rootNode(focusOdo).now(now);
    mappingBuilder = LensUtil.addAssignmentPathVariables(mappingBuilder, assignmentPathVariables);
    Mapping<V, D> mapping = mappingBuilder.build();
    ItemPath itemPath = mapping.getOutputPath();
    if (itemPath == null) {
        // no output element, i.e. this is a "validation mapping"
        return mapping;
    }
    if (defaultTargetObject != null) {
        Item<V, D> existingTargetItem = (Item<V, D>) defaultTargetObject.findItem(itemPath);
        if (existingTargetItem != null && !existingTargetItem.isEmpty() && mapping.getStrength() == MappingStrengthType.WEAK) {
            LOGGER.trace("Mapping {} is weak and target already has a value {}, skipping.", mapping, existingTargetItem);
            return null;
        }
    }
    return mapping;
}
Also used : ExpressionVariables(com.evolveum.midpoint.repo.common.expression.ExpressionVariables) ValuePolicyType(com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) StringPolicyResolver(com.evolveum.midpoint.repo.common.expression.StringPolicyResolver) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) JAXBElement(javax.xml.bind.JAXBElement) Item(com.evolveum.midpoint.prism.Item) ItemDeltaItem(com.evolveum.midpoint.repo.common.expression.ItemDeltaItem) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) SystemException(com.evolveum.midpoint.util.exception.SystemException) ObjectDeltaObject(com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject) PrismObject(com.evolveum.midpoint.prism.PrismObject) GenerateExpressionEvaluatorType(com.evolveum.midpoint.xml.ns._public.common.common_3.GenerateExpressionEvaluatorType) CommonException(com.evolveum.midpoint.util.exception.CommonException) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 32 with ItemDefinition

use of com.evolveum.midpoint.prism.ItemDefinition in project midpoint by Evolveum.

the class ObjectTemplateProcessor method computeItemDeltas.

<F extends FocusType, T extends FocusType> Collection<ItemDelta<?, ?>> computeItemDeltas(Map<ItemPath, DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>>> outputTripleMap, @Nullable Map<ItemPath, ObjectTemplateItemDefinitionType> itemDefinitionsMap, ObjectDelta<T> targetObjectAPrioriDelta, PrismObject<T> targetObject, PrismObjectDefinition<F> focusDefinition, String contextDesc) throws ExpressionEvaluationException, PolicyViolationException, SchemaException {
    Collection<ItemDelta<?, ?>> itemDeltas = new ArrayList<>();
    LOGGER.trace("Computing deltas in {}, focusDelta:\n{}", contextDesc, targetObjectAPrioriDelta);
    boolean addUnchangedValues = false;
    if (targetObjectAPrioriDelta != null && targetObjectAPrioriDelta.isAdd()) {
        addUnchangedValues = true;
    }
    for (Entry<ItemPath, DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>>> entry : outputTripleMap.entrySet()) {
        ItemPath itemPath = entry.getKey();
        DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>> outputTriple = entry.getValue();
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Computed triple for {}:\n{}", itemPath, outputTriple.debugDump());
        }
        final ObjectTemplateItemDefinitionType templateItemDefinition;
        if (itemDefinitionsMap != null) {
            templateItemDefinition = ItemPathUtil.getFromMap(itemDefinitionsMap, itemPath);
        } else {
            templateItemDefinition = null;
        }
        boolean isNonTolerant = templateItemDefinition != null && Boolean.FALSE.equals(templateItemDefinition.isTolerant());
        ItemDelta aprioriItemDelta = getAprioriItemDelta(targetObjectAPrioriDelta, itemPath);
        // if non-tolerant, we want to gather ZERO & PLUS sets
        boolean filterExistingValues = !isNonTolerant;
        ItemDefinition itemDefinition = focusDefinition.findItemDefinition(itemPath);
        ItemDelta itemDelta = LensUtil.consolidateTripleToDelta(itemPath, (DeltaSetTriple) outputTriple, itemDefinition, aprioriItemDelta, targetObject, null, null, addUnchangedValues, filterExistingValues, false, contextDesc, true);
        // Do a quick version of reconciliation. There is not much to reconcile as both the source and the target
        // is focus. But there are few cases to handle, such as strong mappings, and sourceless normal mappings. 
        Collection<? extends ItemValueWithOrigin<?, ?>> zeroSet = outputTriple.getZeroSet();
        Item<PrismValue, ItemDefinition> itemNew = null;
        if (targetObject != null) {
            itemNew = targetObject.findItem(itemPath);
        }
        for (ItemValueWithOrigin<?, ?> zeroSetIvwo : zeroSet) {
            PrismValueDeltaSetTripleProducer<?, ?> mapping = zeroSetIvwo.getMapping();
            if ((mapping.getStrength() == null || mapping.getStrength() == MappingStrengthType.NORMAL)) {
                if (aprioriItemDelta != null && !aprioriItemDelta.isEmpty()) {
                    continue;
                }
                if (!mapping.isSourceless()) {
                    continue;
                }
                LOGGER.trace("Adding zero values from normal mapping {}, a-priori delta: {}, isSourceless: {}", mapping, aprioriItemDelta, mapping.isSourceless());
            } else if (mapping.getStrength() == MappingStrengthType.WEAK) {
                if ((itemNew != null && !itemNew.isEmpty()) || (itemDelta != null && itemDelta.addsAnyValue())) {
                    continue;
                }
                LOGGER.trace("Adding zero values from weak mapping {}, itemNew: {}, itemDelta: {}", mapping, itemNew, itemDelta);
            } else {
                LOGGER.trace("Adding zero values from strong mapping {}", mapping);
            }
            PrismValue valueFromZeroSet = zeroSetIvwo.getItemValue();
            if (itemNew == null || !itemNew.containsRealValue(valueFromZeroSet)) {
                LOGGER.trace("Reconciliation will add value {} for item {}. Existing item: {}", valueFromZeroSet, itemPath, itemNew);
                itemDelta.addValuesToAdd(valueFromZeroSet.clone());
            }
        }
        if (isNonTolerant) {
            if (itemDelta.isDelete()) {
                LOGGER.trace("Non-tolerant item with values to DELETE => removing them");
                // these are useless now - we move everything to REPLACE
                itemDelta.resetValuesToDelete();
            }
            if (itemDelta.isReplace()) {
                LOGGER.trace("Non-tolerant item with resulting REPLACE delta => doing nothing");
            } else {
                for (ItemValueWithOrigin<?, ?> zeroSetIvwo : zeroSet) {
                    itemDelta.addValuesToAdd(zeroSetIvwo.getItemValue().clone());
                }
                itemDelta.addToReplaceDelta();
                LOGGER.trace("Non-tolerant item with resulting ADD delta => converted ADD to REPLACE values: {}", itemDelta.getValuesToReplace());
            }
            // under a special option "createReplaceDelta", but for the time being, let's keep it here
            if (itemDelta instanceof PropertyDelta) {
                PropertyDelta propertyDelta = ((PropertyDelta) itemDelta);
                QName matchingRuleName = templateItemDefinition != null ? templateItemDefinition.getMatchingRule() : null;
                MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleName, null);
                if (propertyDelta.isRedundant(targetObject, matchingRule)) {
                    LOGGER.trace("Computed property delta is redundant => skipping it. Delta = \n{}", propertyDelta.debugDump());
                    continue;
                }
            } else {
                if (itemDelta.isRedundant(targetObject)) {
                    LOGGER.trace("Computed item delta is redundant => skipping it. Delta = \n{}", itemDelta.debugDump());
                    continue;
                }
            }
            PrismUtil.setDeltaOldValue(targetObject, itemDelta);
        }
        itemDelta.simplify();
        itemDelta.validate(contextDesc);
        itemDeltas.add(itemDelta);
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Computed delta:\n{}", itemDelta.debugDump());
        }
    }
    return itemDeltas;
}
Also used : DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) ObjectTemplateItemDefinitionType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateItemDefinitionType) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) PrismValue(com.evolveum.midpoint.prism.PrismValue) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) MatchingRule(com.evolveum.midpoint.prism.match.MatchingRule) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 33 with ItemDefinition

use of com.evolveum.midpoint.prism.ItemDefinition in project midpoint by Evolveum.

the class TestModelExpressions method executeScriptExpressionString.

private String executeScriptExpressionString(final String TEST_NAME, ExpressionVariables variables) throws SchemaException, IOException, JAXBException, ExpressionEvaluationException, ObjectNotFoundException {
    // GIVEN
    OperationResult result = new OperationResult(TestModelExpressions.class.getName() + "." + TEST_NAME);
    ScriptExpressionEvaluatorType scriptType = parseScriptType("expression-" + TEST_NAME + ".xml");
    ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl(PROPERTY_NAME, DOMUtil.XSD_STRING, PrismTestUtil.getPrismContext());
    ScriptExpression scriptExpression = scriptExpressionFactory.createScriptExpression(scriptType, outputDefinition, TEST_NAME);
    if (variables == null) {
        variables = new ExpressionVariables();
    }
    // WHEN
    TestUtil.displayWhen(TEST_NAME);
    List<PrismPropertyValue<String>> scriptOutputs = evaluate(scriptExpression, variables, false, TEST_NAME, null, result);
    // THEN
    TestUtil.displayThen(TEST_NAME);
    display("Script output", scriptOutputs);
    result.computeStatus();
    TestUtil.assertSuccess(result);
    if (scriptOutputs.size() == 0) {
        return null;
    }
    assertEquals("Unexpected number of script outputs", 1, scriptOutputs.size());
    return scriptOutputs.get(0).getValue();
}
Also used : ExpressionVariables(com.evolveum.midpoint.repo.common.expression.ExpressionVariables) PrismPropertyDefinitionImpl(com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ScriptExpressionEvaluatorType(com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType) ScriptExpression(com.evolveum.midpoint.model.common.expression.script.ScriptExpression) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue)

Example 34 with ItemDefinition

use of com.evolveum.midpoint.prism.ItemDefinition in project midpoint by Evolveum.

the class ObjectMerger method mergeItem.

private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O> objectLeft, PrismObject<O> objectRight, String mergeConfigurationName, ItemMergeConfigurationType itemMergeConfig, ItemPath itemPath, Task task, OperationResult result) throws SchemaException, ConfigurationException, ExpressionEvaluationException, ObjectNotFoundException {
    I itemLeft = (I) objectLeft.findItem(itemPath);
    I itemRight = (I) objectRight.findItem(itemPath);
    if (itemLeft == null && itemRight == null) {
        return null;
    }
    ItemDefinition itemDefinition = null;
    if (itemLeft != null) {
        itemDefinition = itemLeft.getDefinition();
    } else {
        itemDefinition = itemRight.getDefinition();
    }
    if (itemDefinition.isOperational()) {
        // we do not want to modify them explicitly.
        return null;
    }
    Expression<PrismValue, ItemDefinition> valueExpression = null;
    if (itemMergeConfig.getValueExpression() != null) {
        ExpressionType expressionType = itemMergeConfig.getValueExpression();
        valueExpression = expressionFactory.makeExpression(expressionType, itemDefinition, "value expression for item " + itemPath + " in merge configuration " + mergeConfigurationName, task, result);
    }
    ItemDelta itemDelta = itemDefinition.createEmptyDelta(itemPath);
    MergeStategyType leftStrategy = itemMergeConfig.getLeft();
    MergeStategyType rightStrategy = itemMergeConfig.getRight();
    if (leftStrategy == null || leftStrategy == MergeStategyType.IGNORE) {
        if (rightStrategy == null || rightStrategy == MergeStategyType.IGNORE) {
            // IGNORE both
            if (itemLeft == null) {
                return null;
            } else {
                itemDelta.setValueToReplace();
                return itemDelta;
            }
        } else {
            // IGNORE left, TAKE/EXPRESSION right
            if (itemRight == null) {
                itemDelta.setValueToReplace();
            } else {
                Collection<PrismValue> valuesToTake = getValuesToTake(objectLeft, objectRight, SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result);
                itemDelta.setValuesToReplace(valuesToTake);
            }
            return itemDelta;
        }
    } else {
        if (rightStrategy == null || rightStrategy == MergeStategyType.IGNORE) {
            if (leftStrategy == MergeStategyType.TAKE) {
                // TAKE left, IGNORE right
                return null;
            } else {
                // EXPRESSION left, IGNORE right
                Collection<PrismValue> valuesToLeave = getValuesToTake(objectLeft, objectRight, SIDE_LEFT, itemLeft, leftStrategy, valueExpression, task, result);
                List<PrismValue> currentLeftValues = itemLeft.getValues();
                Collection<PrismValue> leftValuesToRemove = diffValues(currentLeftValues, valuesToLeave);
                if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) {
                    itemDelta.addValuesToDelete(leftValuesToRemove);
                    return itemDelta;
                } else {
                    return null;
                }
            }
        } else {
            // TAKE/EXPRESSION left, TAKE/EXPRESSION right
            if (itemLeft == null) {
                Collection<PrismValue> valuesToTake = getValuesToTake(objectLeft, objectRight, SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result);
                itemDelta.addValuesToAdd(valuesToTake);
                return itemDelta;
            } else {
                // We want to add only those values that are not yet there.
                // E.g. adding assignments that are there can cause unnecessary churn
                Collection<PrismValue> leftValuesToLeave = getValuesToTake(objectLeft, objectRight, SIDE_LEFT, itemLeft, leftStrategy, valueExpression, task, result);
                Collection<PrismValue> rightValuesToTake = getValuesToTake(objectLeft, objectRight, SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result);
                for (PrismValue rightValueToTake : rightValuesToTake) {
                    if (!PrismValue.collectionContainsEquivalentValue(leftValuesToLeave, rightValueToTake)) {
                        itemDelta.addValueToAdd(rightValueToTake);
                    }
                }
                List<PrismValue> currentLeftValues = itemLeft.getValues();
                Collection<PrismValue> leftValuesToRemove = diffValues(currentLeftValues, leftValuesToLeave);
                if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) {
                    itemDelta.addValuesToDelete(leftValuesToRemove);
                }
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Merging item {} T/T case:\n  leftValuesToLeave: {}\n  rightValuesToTake: {}\n  leftValuesToRemove: {}\n itemDelta:\n{}", new Object[] { itemPath, leftValuesToLeave, rightValuesToTake, leftValuesToRemove, itemDelta.debugDump(2) });
                }
                return itemDelta;
            }
        }
    }
}
Also used : ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) MergeStategyType(com.evolveum.midpoint.xml.ns._public.common.common_3.MergeStategyType) ExpressionType(com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType) PrismValue(com.evolveum.midpoint.prism.PrismValue)

Example 35 with ItemDefinition

use of com.evolveum.midpoint.prism.ItemDefinition in project midpoint by Evolveum.

the class CredentialPolicyEvaluator method hasValueDelta.

private <F extends FocusType> boolean hasValueDelta(ObjectDelta<UserType> focusDelta, ItemPath credentialsPath) {
    if (focusDelta == null) {
        return false;
    }
    for (PartiallyResolvedDelta<PrismValue, ItemDefinition> partialDelta : focusDelta.findPartial(credentialsPath)) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Residual delta:\n{}", partialDelta.debugDump());
        }
        ItemPath residualPath = partialDelta.getResidualPath();
        if (residualPath == null || residualPath.isEmpty()) {
            continue;
        }
        LOGGER.trace("PATH: {}", residualPath);
        QName name = ItemPath.getFirstName(residualPath);
        LOGGER.trace("NAME: {}", name);
        if (isValueElement(name)) {
            return true;
        }
    }
    return false;
}
Also used : QName(javax.xml.namespace.QName) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) PrismValue(com.evolveum.midpoint.prism.PrismValue) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

ItemDefinition (com.evolveum.midpoint.prism.ItemDefinition)35 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)13 PrismPropertyDefinition (com.evolveum.midpoint.prism.PrismPropertyDefinition)6 PrismPropertyValue (com.evolveum.midpoint.prism.PrismPropertyValue)6 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)6 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)6 QName (javax.xml.namespace.QName)6 ItemDelta (com.evolveum.midpoint.prism.delta.ItemDelta)5 StringPolicyResolver (com.evolveum.midpoint.repo.common.expression.StringPolicyResolver)5 ArrayList (java.util.ArrayList)5 PrismContainerDefinition (com.evolveum.midpoint.prism.PrismContainerDefinition)4 PrismValue (com.evolveum.midpoint.prism.PrismValue)4 MappingType (com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType)4 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)4 RefinedObjectClassDefinition (com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition)3 PrismObjectDefinition (com.evolveum.midpoint.prism.PrismObjectDefinition)3 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)3 PropertyDelta (com.evolveum.midpoint.prism.delta.PropertyDelta)3 ObjectDeltaObject (com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject)3 Task (com.evolveum.midpoint.task.api.Task)3