use of com.evolveum.midpoint.prism.delta.DeltaSetTriple in project midpoint by Evolveum.
the class TestPolicyRules method test110AssignRolePirateToJack.
@Test
public void test110AssignRolePirateToJack() throws Exception {
final String TEST_NAME = "test110AssignRolePirateToJack";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TestPolicyRules.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
addModificationToContextAssignRole(context, USER_JACK_OID, ROLE_PIRATE_OID);
display("Input context", context);
assertFocusModificationSanity(context);
rememberShadowFetchOperationCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
projector.project(context, "test", task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertAssignAccountToJack(context);
DeltaSetTriple<EvaluatedAssignmentImpl<UserType>> evaluatedAssignmentTriple = (DeltaSetTriple) context.getEvaluatedAssignmentTriple();
// display("Output evaluatedAssignmentTriple", evaluatedAssignmentTriple);
dumpPolicyRules(context);
assertEvaluatedRules(context, 4);
EvaluatedExclusionTrigger trigger = (EvaluatedExclusionTrigger) assertTriggeredRule(context, null, PolicyConstraintKindType.EXCLUSION, 1, true);
assertNotNull("No conflicting assignment in trigger", trigger.getConflictingAssignment());
assertEquals("Wrong conflicting assignment in trigger", ROLE_PIRATE_OID, trigger.getConflictingAssignment().getTarget().getOid());
}
use of com.evolveum.midpoint.prism.delta.DeltaSetTriple in project midpoint by Evolveum.
the class TestPolicyRules method test210AssignRoleEmployeeToJack.
/**
* Employee conflicts with Contractor.
*/
@Test
public void test210AssignRoleEmployeeToJack() throws Exception {
final String TEST_NAME = "test210AssignRoleEmployeeToJack";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TestPolicyRules.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
addModificationToContextAssignRole(context, USER_JACK_OID, ROLE_CORP_EMPLOYEE_OID);
display("Input context", context);
assertFocusModificationSanity(context);
rememberShadowFetchOperationCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
projector.project(context, "test", task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
DeltaSetTriple<EvaluatedAssignmentImpl<UserType>> evaluatedAssignmentTriple = (DeltaSetTriple) context.getEvaluatedAssignmentTriple();
//display("Output evaluatedAssignmentTriple", evaluatedAssignmentTriple);
dumpPolicyRules(context);
// Judge: criminal-exclusion, unassignment, all-assignment-operations
// Employee: approve-any-corp-role, notify-exclusion-violations, employee-excludes-contractor
// Contractor: approve-any-corp-role, notify-exclusion-violations, contractor-excludes-employee
assertEvaluatedRules(context, 10);
EvaluatedExclusionTrigger trigger = (EvaluatedExclusionTrigger) assertTriggeredRule(context, ROLE_CORP_EMPLOYEE_OID, PolicyConstraintKindType.EXCLUSION, 1, false);
assertNotNull("No conflicting assignment in trigger", trigger.getConflictingAssignment());
assertEquals("Wrong conflicting assignment in trigger", ROLE_CORP_CONTRACTOR_OID, trigger.getConflictingAssignment().getTarget().getOid());
}
use of com.evolveum.midpoint.prism.delta.DeltaSetTriple in project midpoint by Evolveum.
the class TestPolicyRules method test112AssignRolePirateWithExceptionToJack.
/**
* Assignment with an exception from the exclusion rule.
*/
@Test
public void test112AssignRolePirateWithExceptionToJack() throws Exception {
final String TEST_NAME = "test112AssignRolePirateWithExceptionToJack";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(TestPolicyRules.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
addModificationToContextAssignRole(context, USER_JACK_OID, ROLE_PIRATE_OID, assignment -> {
PolicyExceptionType policyException = new PolicyExceptionType();
policyException.setRuleName(ROLE_JUDGE_POLICY_RULE_EXCLUSION_NAME);
assignment.getPolicyException().add(policyException);
});
display("Input context", context);
assertFocusModificationSanity(context);
rememberShadowFetchOperationCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
projector.project(context, "test", task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertAssignAccountToJack(context);
DeltaSetTriple<EvaluatedAssignmentImpl<UserType>> evaluatedAssignmentTriple = (DeltaSetTriple) context.getEvaluatedAssignmentTriple();
// display("Output evaluatedAssignmentTriple", evaluatedAssignmentTriple);
dumpPolicyRules(context);
List<EvaluatedPolicyRule> evaluatedRules = assertEvaluatedRules(context, 4);
assertTriggeredRules(context, 0, null);
EvaluatedPolicyRule evaluatedPolicyRule = evaluatedRules.get(0);
Collection<PolicyExceptionType> exceptions = evaluatedPolicyRule.getPolicyExceptions();
assertEquals("Wrong number of exceptions", 1, exceptions.size());
PolicyExceptionType policyException = exceptions.iterator().next();
assertEquals("Wrong rule name in poliy excpetion", ROLE_JUDGE_POLICY_RULE_EXCLUSION_NAME, policyException.getRuleName());
}
use of com.evolveum.midpoint.prism.delta.DeltaSetTriple 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;
}
use of com.evolveum.midpoint.prism.delta.DeltaSetTriple 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;
}
Aggregations