Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Mar 23, 2020
2 parents 1548bae + d237c48 commit 0a3430f
Show file tree
Hide file tree
Showing 31 changed files with 1,063 additions and 513 deletions.
Expand Up @@ -47,6 +47,11 @@ protected void onInitialize() {
}

private void initLayout() {
//TODO migth fix MID-6125, not sure about this one, it's really hard to replicate
// but prismContext is transient so it might be lost during the serilaization/deserialization
if (getModelObject() != null) {
AbstractItemWrapperColumnPanel.this.getModelObject().revive(getPageBase().getPrismContext());
}
ListView<VW> listView = new ListView<VW>(ID_VALUES, new PropertyModel<>(getModel(), "values")) {

private static final long serialVersionUID = 1L;
Expand Down

Large diffs are not rendered by default.

Expand Up @@ -27,6 +27,7 @@
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.google.common.annotations.VisibleForTesting;

Expand Down Expand Up @@ -270,6 +271,18 @@ default V getAnyValue(@NotNull ValueSelector<V> selector) {
@NotNull
Collection<?> getRealValues();

@Experimental
@NotNull
default Collection<Object> getRealValuesOrRawTypes(PrismContext prismContext) {
List<Object> rv = new ArrayList<>();
for (V value : getValues()) {
if (value != null) {
rv.add(value.getRealValueOrRawType(prismContext));
}
}
return rv;
}

/**
* Returns true if the item contains 0 or 1 values and (by definition) is not multivalued.
*/
Expand Down Expand Up @@ -458,12 +471,18 @@ default boolean add(@NotNull V newValue) throws SchemaException {

/**
* Computes a difference (delta) with the specified item using IGNORE_METADATA_CONSIDER_DIFFERENT_IDS equivalence strategy.
*
* Compares item values only -- does NOT dive into lower levels.
*/
ItemDelta<V,D> diff(Item<V,D> other);
default ItemDelta<V,D> diff(Item<V,D> other) {
return diff(other, ParameterizedEquivalenceStrategy.DEFAULT_FOR_DIFF);
}

/**
* Computes a difference (delta) with the specified item using given equivalence strategy.
* Note this method cannot accept general EquivalenceStrategy here; it needs the parameterized strategy.
*
* Compares item values only -- does NOT dive into lower levels.
*/
ItemDelta<V,D> diff(Item<V,D> other, @NotNull ParameterizedEquivalenceStrategy strategy);

Expand Down
Expand Up @@ -94,18 +94,11 @@ public String toString() {
'}';
}

public static ItemType fromItem(Item<?, ?> item) {
public static ItemType fromItem(Item item, PrismContext prismContext) {
if (item != null) {
ItemType rv = new ItemType();
rv.setName(item.getElementName());
if (item instanceof PrismContainer && (item.getDefinition() == null || ((PrismContainerDefinition) item.getDefinition()).getCompileTimeClass() == null)) {
// a special case -- item.getRealValues() does not work here (TODO generalize this)
for (PrismContainerValue<?> value : ((PrismContainer<?>) item).getValues()) {
rv.value.add(new RawType(value, null, item.getPrismContext()));
}
} else {
rv.value.addAll(item.getRealValues());
}
rv.value.addAll(item.getRealValuesOrRawTypes(prismContext));
return rv;
} else {
return null;
Expand Down
Expand Up @@ -26,6 +26,8 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.util.annotation.Experimental;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -488,6 +490,15 @@ public boolean add(@NotNull V newValue, boolean checkUniqueness, EquivalenceStra
return values.add(newValue);
}

/**
* Adds a given value with no checks, no definition application, and so on.
* For internal use only.
*/
@Experimental
public boolean addForced(@NotNull V newValue) {
return values.add(newValue);
}

public boolean removeAll(Collection<V> newValues) {
checkMutable();
boolean changed = false;
Expand Down Expand Up @@ -581,23 +592,13 @@ public void merge(Item<V,D> otherItem) throws SchemaException {
}
}

public ItemDelta<V,D> diff(Item<V,D> other) {
return diff(other, ParameterizedEquivalenceStrategy.DEFAULT_FOR_DIFF);
}

public ItemDelta<V,D> diff(Item<V,D> other, @NotNull ParameterizedEquivalenceStrategy strategy) {
List<? extends ItemDelta> itemDeltas = new ArrayList<>();
diffInternal(other, itemDeltas, strategy);
if (itemDeltas.isEmpty()) {
return null;
}
if (itemDeltas.size() > 1) {
throw new UnsupportedOperationException("Item multi-delta diff is not supported yet");
}
return itemDeltas.get(0);
List<ItemDelta<V, D>> itemDeltas = new ArrayList<>();
diffInternal(other, itemDeltas, true, strategy);
return MiscUtil.extractSingleton(itemDeltas);
}

void diffInternal(Item<V, D> other, Collection<? extends ItemDelta> deltas,
void diffInternal(Item<V, D> other, Collection<? extends ItemDelta> deltas, boolean rootValuesOnly,
ParameterizedEquivalenceStrategy strategy) {
ItemDelta delta = createDelta();
if (other == null) {
Expand All @@ -621,7 +622,7 @@ void diffInternal(Item<V, D> other, Collection<? extends ItemDelta> deltas,
boolean found = false;
while (iterator.hasNext()) {
PrismValueImpl otherValue = (PrismValueImpl) iterator.next();
if (thisValue.representsSameValue(otherValue, true)) {
if (!rootValuesOnly && thisValue.representsSameValue(otherValue, true)) {
found = true;
// Matching IDs, look inside to figure out internal deltas
((PrismValueImpl) thisValue).diffMatchingRepresentation(otherValue, deltas, strategy);
Expand Down
Expand Up @@ -689,7 +689,7 @@ public List<? extends ItemDelta> diffModifications(PrismContainer<C> other) {

public List<? extends ItemDelta> diffModifications(PrismContainer<C> other, ParameterizedEquivalenceStrategy strategy) {
List<? extends ItemDelta> itemDeltas = new ArrayList<>();
diffInternal(other, itemDeltas, strategy);
diffInternal(other, itemDeltas, false, strategy);
return itemDeltas;
}

Expand Down
Expand Up @@ -1058,7 +1058,7 @@ private void diffItems(PrismContainerValue<C> thisValue, PrismContainerValue<C>
}
}
// The "delete" delta will also result from the following diff
((ItemImpl) thisItem).diffInternal(otherItem, deltas, strategy);
((ItemImpl) thisItem).diffInternal(otherItem, deltas, false, strategy);
}

other.getItems();
Expand Down
Expand Up @@ -280,7 +280,7 @@ public ObjectDelta<O> diff(PrismObject<O> other, ParameterizedEquivalenceStrateg
objectDelta.setOid(getOid());

Collection<? extends ItemDelta> itemDeltas = new ArrayList<>();
diffInternal(other, itemDeltas, strategy);
diffInternal(other, itemDeltas, false, strategy);
objectDelta.addModifications(itemDeltas);

return objectDelta;
Expand Down
Expand Up @@ -287,11 +287,6 @@ public final boolean valuesEqual(Collection<V> matchValues,
return delegate().valuesEqual(matchValues, comparator);
}

public final ItemDelta<V, D> diff(
Item<V, D> other) {
return delegate().diff(other);
}

public final ItemDelta<V, D> diff(
Item<V, D> other,
@NotNull ParameterizedEquivalenceStrategy strategy) {
Expand Down
Expand Up @@ -251,7 +251,11 @@ private <T> T unmarshalFromMapOrHeteroList(@NotNull XNodeImpl mapOrList, @NotNul

if (Containerable.class.isAssignableFrom(beanClass)) {
// This could have come from inside; note we MUST NOT parse this as PrismValue, because for objects we would lose oid/version
return prismContext.parserFor(mapOrList.toRootXNode()).type(beanClass).parseRealValue();
return prismContext
.parserFor(mapOrList.toRootXNode())
.context(pc)
.type(beanClass)
.parseRealValue();
} else if (SearchFilterType.class.isAssignableFrom(beanClass)) {
if (mapOrList instanceof MapXNodeImpl) {
T bean = (T) unmarshalSearchFilterType((MapXNodeImpl) mapOrList, (Class<? extends SearchFilterType>) beanClass, pc);
Expand Down Expand Up @@ -1011,7 +1015,10 @@ private Object unmarshalSinglePropValue(XNodeImpl xsubnode, String fieldName, Cl
RawType raw = new RawType(xsubnode, prismContext);
// FIXME UGLY HACK: parse value if possible
if (xsubnode.getTypeQName() != null) {
PrismValue value = prismContext.parserFor(xsubnode.toRootXNode()).parseItemValue(); // TODO what about objects? oid/version will be lost here
PrismValue value = prismContext
.parserFor(xsubnode.toRootXNode())
.context(pc)
.parseItemValue(); // TODO what about objects? oid/version will be lost here
if (value != null && !value.isRaw()) {
raw = new RawType(value, xsubnode.getTypeQName(), prismContext);
}
Expand Down
Expand Up @@ -438,7 +438,18 @@ private <T> PrismProperty<T> parseProperty(@NotNull XNodeImpl node, @NotNull QNa
} else if (node instanceof MapXNodeImpl || node instanceof PrimitiveXNodeImpl || node.isHeterogeneousList()) {
PrismPropertyValue<T> pval = parsePropertyValue(node, itemDefinition, pc);
if (pval != null) {
property.add(pval);
try {
property.add(pval);
} catch (SchemaException e) {
if (pc.isCompat()) {
// Most probably the "apply definition" call while adding the value failed. This occurs for raw
// values with (somewhat) incorrect definitions being added. Overall, this is more a hack than serious
// solution, because we sometimes want to add static-schema-less property values. TODO investigate this.
((PrismPropertyImpl<T>) property).addForced(pval);
} else {
throw e;
}
}
}
} else if (node instanceof SchemaXNodeImpl) {
SchemaDefinitionType schemaDefType = beanUnmarshaller.unmarshalSchemaDefinitionType((SchemaXNodeImpl) node);
Expand Down
Expand Up @@ -8,6 +8,7 @@
package com.evolveum.midpoint.schema.util;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.PrettyPrinter;
Expand Down Expand Up @@ -58,10 +59,15 @@ public static NamedValueType toNamedValueType(Object object, QName name, PrismCo
private static void setAnyValueTypeContent(Object object, AnyValueType anyValue, PrismContext prismContext) {
if (object instanceof PrismValue) {
PrismValue prismValue = (PrismValue) object;
if (prismValue.hasRealClass()) {
setAnyValueReal(prismValue.getRealValue(), anyValue, prismContext);
boolean emptyEmbeddedValue = prismValue instanceof PrismPropertyValue && ((PrismPropertyValue) prismValue).getValue() == null;
if (emptyEmbeddedValue) {
// very strange case - let's simply skip it; there's nothing to store to AnyValueType here
} else {
setAnyValueDynamic(prismValue, anyValue, prismContext);
if (prismValue.hasRealClass()) {
setAnyValueReal(prismValue.getRealValue(), anyValue, prismContext);
} else {
setAnyValueDynamic(prismValue, anyValue, prismContext);
}
}
} else {
setAnyValueReal(object, anyValue, prismContext);
Expand Down Expand Up @@ -94,7 +100,7 @@ public static boolean isAtLeastNormal(TracingLevelType level) {
return isAtLeast(level, TracingLevelType.NORMAL);
}

public static boolean isAtLeast(TracingLevelType level, @NotNull TracingLevelType threshold) {
private static boolean isAtLeast(TracingLevelType level, @NotNull TracingLevelType threshold) {
return level != null && level.ordinal() >= threshold.ordinal();
}
}
Expand Up @@ -6,16 +6,17 @@
*/
package com.evolveum.midpoint.schema;

import static org.testng.AssertJUnit.*;

import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext;
import static org.testng.AssertJUnit.*;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismContainer;

import org.testng.AssertJUnit;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -601,7 +602,7 @@ public void testResourceNsFixUndeclaredPrefixes() throws SchemaException, IOExce
resourceFixed.checkConsistence();

// WHEN
String xmlBroken = getPrismContext().serializeObjectToString(resourceBroken, PrismContext.LANG_XML);
String xmlBroken = getPrismContext().xmlSerializer().serialize(resourceBroken);
ObjectDelta<ResourceType> resourceDelta = resourceBroken.diff(resourceFixed, EquivalenceStrategy.LITERAL_IGNORE_METADATA);

// THEN
Expand All @@ -623,7 +624,7 @@ public void testResourceNsFixUndeclaredPrefixes() throws SchemaException, IOExce
PrismObject<ResourceType> resourceUpdated = resourceBroken.clone();
resourceDelta.applyTo(resourceUpdated);

String xmlUpdated = getPrismContext().serializeObjectToString(resourceUpdated, PrismContext.LANG_XML);
String xmlUpdated = getPrismContext().xmlSerializer().serialize(resourceUpdated);
System.out.println("UPDATED RESOURCE:");
System.out.println(xmlUpdated);
assertFalse("__UNDECLARED__ flag in updated resource", xmlUpdated.contains("__UNDECLARED__"));
Expand Down Expand Up @@ -661,6 +662,7 @@ private void assertModificationPolyStringValue(RawType value, PolyStringType...
for (PolyStringType expectedValue : expectedValues) {
if (expectedValue.getOrig().equals(valueAsPoly.getOrig()) && expectedValue.getNorm().equals(valueAsPoly.getNorm())) {
found = true;
break;
}
}
assertTrue(found);
Expand Down Expand Up @@ -695,13 +697,13 @@ public void testCampaign() throws SchemaException, IOException {

@Test(enabled = false)
public void testReplaceModelOperationContext() throws Exception {
PrismObject prismObject = PrismTestUtil.parseObject(new File(TEST_DIR, "task-modelOperationContext-before.xml"));
PrismObject<TaskType> prismObject = PrismTestUtil.parseObject(new File(TEST_DIR, "task-modelOperationContext-before.xml"));

ObjectDelta delta = getPrismContext().deltaFactory().object().createEmptyModifyDelta(TaskType.class, prismObject.getOid()
);
ObjectDelta<TaskType> delta = getPrismContext().deltaFactory().object().createEmptyModifyDelta(TaskType.class, prismObject.getOid());
//noinspection unchecked
delta.addModificationReplaceContainer(TaskType.F_MODEL_OPERATION_CONTEXT);

PrismObject changed = prismObject.clone();
PrismObject<TaskType> changed = prismObject.clone();
ItemDeltaCollectionsUtil.applyTo(delta.getModifications(), changed);
Collection<? extends ItemDelta> processedModifications = prismObject.diffModifications(changed, EquivalenceStrategy.LITERAL_IGNORE_METADATA);

Expand Down Expand Up @@ -778,4 +780,63 @@ public void testSystemConfigurationDiffPlusNarrow() throws Exception {
deltaNarrowed.applyTo(workingCopy);
PrismAsserts.assertEquals("before + delta (narrowed) is different from after", after, workingCopy);
}
@Test
public void testDiffContainerValues() {
UserType user1 = new UserType(getPrismContext())
.beginAssignment()
.id(1L)
.targetRef("oid-a", RoleType.COMPLEX_TYPE)
.<UserType>end()
.beginAssignment()
.id(2L)
.targetRef("oid-b", RoleType.COMPLEX_TYPE)
.end();
UserType user2 = new UserType(getPrismContext())
.beginAssignment()
.id(3L)
.targetRef("oid-a", RoleType.COMPLEX_TYPE)
.<UserType>end()
.beginAssignment()
.targetRef("oid-c", RoleType.COMPLEX_TYPE)
.end();
PrismContainer<AssignmentType> assignment1 = user1.asPrismObject().findContainer(UserType.F_ASSIGNMENT);
PrismContainer<AssignmentType> assignment2 = user2.asPrismObject().findContainer(UserType.F_ASSIGNMENT);
ContainerDelta<AssignmentType> diff = assignment1.diff(assignment2);

PrismTestUtil.display("assignment1", assignment1);
PrismTestUtil.display("assignment2", assignment2);
PrismTestUtil.display("diff", diff);

assertEquals("Wrong values to add", assignment2.getValues(), diff.getValuesToAdd());
assertEquals("Wrong values to delete", assignment1.getValues(), diff.getValuesToDelete());
//noinspection SimplifiedTestNGAssertion
assertEquals("Wrong values to replace", null, diff.getValuesToReplace());
}

@Test
public void testDiffSingleContainerValues() {
UserType user1 = new UserType(getPrismContext())
.beginActivation()
.validFrom("2020-03-20T15:11:40.936+01:00")
.validTo("2020-03-21T15:11:40.936+01:00")
.end();
UserType user2 = new UserType(getPrismContext())
.beginActivation()
.validFrom("2020-02-20T15:11:40.936+01:00")
.validTo("2020-02-21T15:11:40.936+01:00")
.end();
PrismContainer<ActivationType> activation1 = user1.asPrismObject().findContainer(UserType.F_ACTIVATION);
PrismContainer<ActivationType> activation2 = user2.asPrismObject().findContainer(UserType.F_ACTIVATION);

ItemDelta<?, ?> diff = activation1.diff(activation2);

PrismTestUtil.display("activation1", activation1);
PrismTestUtil.display("activation2", activation2);
PrismTestUtil.display("diff", diff);

assertEquals("Wrong values to add", activation2.getValues(), diff.getValuesToAdd());
assertEquals("Wrong values to delete", activation1.getValues(), diff.getValuesToDelete());
//noinspection SimplifiedTestNGAssertion
assertEquals("Wrong values to replace", null, diff.getValuesToReplace());
}
}
Expand Up @@ -572,7 +572,7 @@ private String dumpValueCombination(Collection<? extends PrismValue> pvalues, Li
for (PrismValue pval: pvalues) {
SourceTriple<?,?> sourceTriple = sourceTriplesIterator.next();
sb.append(sourceTriple.getName().getLocalPart()).append('=');
sb.append(pval==null?null:(Object)pval.getRealValue());
sb.append(pval==null?null:(Object)pval.getRealValueOrRawType(prismContext));
if (sourceTriplesIterator.hasNext()) {
sb.append(", ");
}
Expand Down

0 comments on commit 0a3430f

Please sign in to comment.