Skip to content

Commit

Permalink
Fix variable initialization in object merger
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jun 10, 2020
1 parent a0e3a7f commit 7ad7453
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 200 deletions.
Expand Up @@ -15,6 +15,7 @@
import com.evolveum.midpoint.prism.delta.*;
import com.evolveum.midpoint.prism.path.ItemPath;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -146,11 +147,13 @@ private <O extends ObjectType> void executeDelta(ObjectDelta<O> objectDelta, Mod
}
}

public <O extends ObjectType> MergeDeltas<O> computeMergeDeltas(Class<O> type, String leftOid, String rightOid,
<O extends ObjectType> MergeDeltas<O> computeMergeDeltas(Class<O> type, String leftOid, String rightOid,
final String mergeConfigurationName, final Task task, final OperationResult result)
throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException, SecurityViolationException {

//noinspection unchecked
final PrismObject<O> objectLeft = (PrismObject<O>) objectResolver.getObjectSimple(type, leftOid, null, task, result).asPrismObject();
//noinspection unchecked
final PrismObject<O> objectRight = (PrismObject<O>) objectResolver.getObjectSimple(type, rightOid, null, task, result).asPrismObject();

PrismObject<SystemConfigurationType> systemConfiguration = systemObjectCache.getSystemConfiguration(result);
Expand Down Expand Up @@ -242,7 +245,6 @@ public void visit(Visitable visitable) {
}
}


ItemDelta itemDelta;
try {
itemDelta = mergeItem(objectLeft, objectRight, mergeConfigurationName, defaultItemMergeConfig, itemPath,
Expand All @@ -257,7 +259,9 @@ public void visit(Visitable visitable) {
}
};

//noinspection unchecked
objectLeft.accept(visitor);
//noinspection unchecked
objectRight.accept(visitor);


Expand Down Expand Up @@ -425,8 +429,6 @@ private void takeProjections(MergeStrategyType strategy, List<ShadowType> merged
LOGGER.trace("Discriminator does NOT match {}", candidateProjection);
}
}


}

private boolean projectionMatches(ShadowType candidateProjection,
Expand All @@ -439,11 +441,10 @@ private boolean projectionMatches(ShadowType candidateProjection,
ProjectionMergeSituationType situationPattern = projectionMergeConfig.getSituation();
if (situationPattern != null) {
ProjectionMergeSituationType projectionSituation = determineSituation(candidateProjection, projectionsLeft, projectionsRight);
if (situationPattern != projectionSituation) {
return false;
}
return situationPattern == projectionSituation;
} else {
return true;
}
return true;
}

private void takeUnmatchedProjections(MergeStrategyType strategy, List<ShadowType> mergedProjections,
Expand Down Expand Up @@ -509,12 +510,14 @@ private ShadowType getProjection(ObjectReferenceType linkRef, Task task, Operati
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, CommunicationException, SecurityViolationException {
//noinspection unchecked
I itemLeft = (I) objectLeft.findItem(itemPath);
//noinspection unchecked
I itemRight = (I) objectRight.findItem(itemPath);
if (itemLeft == null && itemRight == null) {
return null;
}
ItemDefinition itemDefinition = null;
ItemDefinition itemDefinition;
if (itemLeft != null) {
itemDefinition = itemLeft.getDefinition();
} else {
Expand All @@ -526,12 +529,14 @@ private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O
return null;
}

Expression<PrismValue, ItemDefinition> valueExpression = null;
Expression<PrismValue, ItemDefinition> valueExpression;
if (itemMergeConfig.getValueExpression() != null) {
ExpressionType expressionType = itemMergeConfig.getValueExpression();
valueExpression = expressionFactory.makeExpression(expressionType, itemDefinition, MiscSchemaUtil.getExpressionProfile(),
"value expression for item " + itemPath + " in merge configuration " + mergeConfigurationName,
task, result);
} else {
valueExpression = null;
}

ItemDelta itemDelta = itemDefinition.createEmptyDelta(itemPath);
Expand All @@ -553,6 +558,7 @@ private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O
} else {
Collection<PrismValue> valuesToTake = getValuesToTake(objectLeft, objectRight,
SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result);
//noinspection unchecked
itemDelta.setValuesToReplace(valuesToTake);
}
return itemDelta;
Expand All @@ -566,9 +572,11 @@ private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O
// EXPRESSION left, IGNORE right
Collection<PrismValue> valuesToLeave = getValuesToTake(objectLeft, objectRight,
SIDE_LEFT, itemLeft, leftStrategy, valueExpression, task, result);
//noinspection unchecked
List<PrismValue> currentLeftValues = itemLeft.getValues();
Collection<PrismValue> leftValuesToRemove = diffValues(currentLeftValues, valuesToLeave);
if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) {
//noinspection unchecked
itemDelta.addValuesToDelete(leftValuesToRemove);
return itemDelta;
} else {
Expand All @@ -580,6 +588,7 @@ private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O
if (itemLeft == null) {
Collection<PrismValue> valuesToTake = getValuesToTake(objectLeft, objectRight,
SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result);
//noinspection unchecked
itemDelta.addValuesToAdd(valuesToTake);
return itemDelta;

Expand All @@ -593,29 +602,30 @@ private <O extends ObjectType, I extends Item> ItemDelta mergeItem(PrismObject<O

for (PrismValue rightValueToTake: rightValuesToTake) {
if (!PrismValueCollectionsUtil.collectionContainsEquivalentValue(leftValuesToLeave, rightValueToTake)) {
//noinspection unchecked
itemDelta.addValueToAdd(rightValueToTake);
}
}

//noinspection unchecked
List<PrismValue> currentLeftValues = itemLeft.getValues();
Collection<PrismValue> leftValuesToRemove = diffValues(currentLeftValues, leftValuesToLeave);

if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) {
//noinspection unchecked
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)});
}

LOGGER.trace("Merging item {} T/T case:\n leftValuesToLeave: {}\n rightValuesToTake: {}\n leftValuesToRemove: {}\n itemDelta:\n{}",
itemPath, leftValuesToLeave, rightValuesToTake, leftValuesToRemove, itemDelta.debugDumpLazily(2));

return itemDelta;
}
}
}
}

@NotNull
private Collection<PrismValue> diffValues(List<PrismValue> currentValues, Collection<PrismValue> valuesToLeave) {
if (valuesToLeave == null || valuesToLeave.isEmpty()) {
return PrismValueCollectionsUtil.cloneCollection(currentValues);
Expand All @@ -636,11 +646,13 @@ private <O extends ObjectType, I extends Item> Collection<PrismValue> getValuesT
return new ArrayList<>(0);
}
if (strategy == MergeStrategyType.TAKE) {
//noinspection unchecked
return cleanContainerIds(origItem.getClonedValues());
} else if (strategy == MergeStrategyType.EXPRESSION) {
if (valueExpression == null) {
throw new ConfigurationException("Expression strategy specified but no expression present");
}
//noinspection unchecked
List<PrismValue> origValues = origItem.getValues();
Collection<PrismValue> valuesToTake = new ArrayList<>(origValues.size());
for (PrismValue origValue: origValues) {
Expand Down Expand Up @@ -668,13 +680,15 @@ private Collection<PrismValue> cleanContainerIds(Collection<PrismValue> pvals) {
return pvals;
}


private <O extends ObjectType> Collection<PrismValue> evaluateValueExpression(PrismObject<O> objectLeft, PrismObject<O> objectRight, String side, PrismValue origValue, Expression<PrismValue, ItemDefinition> valueExpression,
Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
private <O extends ObjectType> Collection<PrismValue> evaluateValueExpression(PrismObject<O> objectLeft,
PrismObject<O> objectRight, String side, PrismValue origValue,
Expression<PrismValue, ItemDefinition> valueExpression, Task task, OperationResult result)
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException,
ConfigurationException, SecurityViolationException {
ExpressionVariables variables = new ExpressionVariables();
variables.put(ExpressionConstants.VAR_SIDE, side, String.class);
variables.put(ExpressionConstants.VAR_OBJECT_LEFT, side, String.class);
variables.put(ExpressionConstants.VAR_OBJECT_RIGHT, side, String.class);
variables.put(ExpressionConstants.VAR_OBJECT_LEFT, objectLeft, String.class);
variables.put(ExpressionConstants.VAR_OBJECT_RIGHT, objectRight, String.class);
variables.put(ExpressionConstants.VAR_INPUT, origValue, origValue.getParent().getDefinition());
variables.put(ExpressionConstants.VAR_VALUE, origValue, origValue.getParent().getDefinition());
ExpressionEvaluationContext exprContext = new ExpressionEvaluationContext(null, variables, "for value "+origValue, task);
Expand All @@ -697,5 +711,4 @@ private MergeConfigurationType selectConfiguration(
}
throw new ConfigurationException("Merge configuration with name '"+mergeConfigurationName+"' was not found");
}

}

0 comments on commit 7ad7453

Please sign in to comment.