Skip to content

Commit

Permalink
DeltaBuilder: support for delete+add order instead of just add+delete
Browse files Browse the repository at this point in the history
Main reason is that delete+add actually matches semantics/behavior.
  • Loading branch information
virgo47 committed Apr 26, 2021
1 parent 4202abe commit 9d0db25
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 26 deletions.
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2010-2015 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.prism.delta.builder;

import java.util.Collection;

import com.evolveum.midpoint.prism.PrismValue;

public interface S_MaybeAdd extends S_ItemEntry {

S_ItemEntry add(Object... realValues);
S_ItemEntry addRealValues(Collection<?> realValues);
S_ItemEntry add(PrismValue... values);
S_ItemEntry add(Collection<? extends PrismValue> values);
}
Expand Up @@ -7,16 +7,21 @@

package com.evolveum.midpoint.prism.delta.builder;

import com.evolveum.midpoint.prism.PrismValue;

import java.util.Collection;

import com.evolveum.midpoint.prism.PrismValue;

/**
* @author mederly
* Using DELETE after ADD in fluent builder goes against the actual semantics that first
* executes DELETE and then ADD - use the correct order to avoid deprecated methods.
*/
public interface S_MaybeDelete extends S_ItemEntry {
@Deprecated
S_ItemEntry delete(Object... realValues);
@Deprecated
S_ItemEntry delete(PrismValue... values);
@Deprecated
S_ItemEntry deleteRealValues(Collection<?> realValues);
@Deprecated
S_ItemEntry delete(Collection<? extends PrismValue> values);
}
Expand Up @@ -7,11 +7,11 @@

package com.evolveum.midpoint.prism.delta.builder;

import java.util.Collection;

import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.delta.PlusMinusZero;

import java.util.Collection;

/**
* Note: When dealing with PolyStrings, the real values should be of PolyString, not of PolyStringType type.
*/
Expand All @@ -27,10 +27,10 @@ public interface S_ValuesEntry {
S_MaybeDelete add(PrismValue... values);
S_MaybeDelete add(Collection<? extends PrismValue> values);

S_ItemEntry delete(Object... realValues);
S_ItemEntry deleteRealValues(Collection<?> realValues);
S_ItemEntry delete(PrismValue... values);
S_ItemEntry delete(Collection<? extends PrismValue> values);
S_MaybeAdd delete(Object... realValues);
S_MaybeAdd deleteRealValues(Collection<?> realValues);
S_MaybeAdd delete(PrismValue... values);
S_MaybeAdd delete(Collection<? extends PrismValue> values);

S_ItemEntry replace(Object... realValues);
S_ItemEntry replaceRealValues(Collection<?> realValues);
Expand Down
Expand Up @@ -15,6 +15,7 @@
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.*;
import com.evolveum.midpoint.prism.delta.builder.S_ItemEntry;
import com.evolveum.midpoint.prism.delta.builder.S_MaybeAdd;
import com.evolveum.midpoint.prism.delta.builder.S_MaybeDelete;
import com.evolveum.midpoint.prism.delta.builder.S_ValuesEntry;
import com.evolveum.midpoint.prism.impl.PrismPropertyValueImpl;
Expand All @@ -30,12 +31,15 @@
* <p>
* ObjectDelta ::= (ItemDelta)* ( 'OBJECT-DELTA(oid)' | 'ITEM-DELTA' | 'ITEM-DELTAS' )
* <p>
* ItemDelta ::= 'ITEM(...)' ( ( 'ADD-VALUES(...)' 'DELETE-VALUES(...)'? ) | 'DELETE-VALUES(...)' | 'REPLACE-VALUES(...)' )
* ItemDelta ::= 'ITEM(...)' ( ( 'ADD-VALUES(...)' 'DELETE-VALUES(...)'? ) |
* ( 'DELETE-VALUES(...)' 'ADD-VALUES(...)'? ) | 'REPLACE-VALUES(...)' )
* <p>
* EXPERIMENTAL IMPLEMENTATION.
* When combining DELETE and ADD prefer using DELETE first to match the actual behavior.
* It is not possible to
*/
@Experimental
public class DeltaBuilder<T extends Containerable> implements S_ItemEntry, S_MaybeDelete, S_ValuesEntry {
public class DeltaBuilder<T extends Containerable>
implements S_ItemEntry, S_MaybeDelete, S_MaybeAdd, S_ValuesEntry {

private final Class<T> objectClass;
private final ComplexTypeDefinition containerCTD;
Expand Down Expand Up @@ -257,12 +261,12 @@ public S_ValuesEntry old(Collection<? extends PrismValue> values) {
}

@Override
public S_ItemEntry delete(Object... realValues) {
public S_MaybeAdd delete(Object... realValues) {
return deleteRealValues(Arrays.asList(realValues));
}

@Override
public S_ItemEntry deleteRealValues(Collection<?> realValues) {
public S_MaybeAdd deleteRealValues(Collection<?> realValues) {
for (Object v : realValues) {
if (v != null) {
currentDelta.addValueToDelete(toPrismValue(currentDelta, v));
Expand All @@ -278,7 +282,7 @@ public S_ItemEntry deleteRealValues(Collection<?> realValues) {
// }

@Override
public S_ItemEntry delete(PrismValue... values) {
public S_MaybeAdd delete(PrismValue... values) {
for (PrismValue v : values) {
if (v != null) {
currentDelta.addValueToDelete(v);
Expand All @@ -288,7 +292,7 @@ public S_ItemEntry delete(PrismValue... values) {
}

@Override
public S_ItemEntry delete(Collection<? extends PrismValue> values) {
public S_MaybeAdd delete(Collection<? extends PrismValue> values) {
for (PrismValue v : values) {
if (v != null) {
currentDelta.addValueToDelete(v);
Expand Down
Expand Up @@ -983,24 +983,23 @@ public void test163ReplacingProjectionRefs()
UUID refTargetOid4 = UUID.randomUUID();
delta = prismContext.deltaFor(UserType.class)
.item(UserType.F_LINK_REF)
// add must go first here, even though it overrules conflicting delete later
.delete(new ObjectReferenceType() // type is ignored/ignorable
.oid(refTargetOid1.toString()).relation(refRelation1),
new ObjectReferenceType()
.oid(refTargetOid2.toString()).relation(refRelation2),
new ObjectReferenceType() // nonexistent anyway
.oid(refTargetOid3.toString()).relation(refRelation2),
new ObjectReferenceType() // like add bellow, will be "narrowed" out
.oid(refTargetOid3.toString()).relation(refRelation1))
.add(new ObjectReferenceType().oid(refTargetOid3.toString())
.type(ShadowType.COMPLEX_TYPE).relation(refRelation1),
// delete of this lower will be "narrowed" out, this WILL be added
// delete above will be "narrowed" out, this WILL be added
new ObjectReferenceType().oid(refTargetOid3.toString())
.type(ShadowType.COMPLEX_TYPE).relation(refRelation2),
new ObjectReferenceType().oid(refTargetOid4.toString())
.type(ShadowType.COMPLEX_TYPE).relation(refRelation1),
new ObjectReferenceType().oid(refTargetOid4.toString())
.type(ShadowType.COMPLEX_TYPE).relation(refRelation2))
.delete(new ObjectReferenceType() // type is ignored/ignorable
.oid(refTargetOid1.toString()).relation(refRelation1),
new ObjectReferenceType()
.oid(refTargetOid2.toString()).relation(refRelation2),
new ObjectReferenceType() // nonexistent anyway
.oid(refTargetOid3.toString()).relation(refRelation2),
new ObjectReferenceType() // from add above, will be "narrowed" out
.oid(refTargetOid3.toString()).relation(refRelation1))
.asObjectDelta(user1Oid);

when("modifyObject is called");
Expand Down

0 comments on commit 9d0db25

Please sign in to comment.