Skip to content

Commit

Permalink
Merge branch 'feature/prism-api'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jan 3, 2019
2 parents 3bb3e85 + 7d91e8c commit da933aa
Show file tree
Hide file tree
Showing 37 changed files with 609 additions and 278 deletions.
Expand Up @@ -305,7 +305,7 @@ public I getUpdatedItem(PrismContext prismContext) throws SchemaException {
valueWrapper.normalize(prismContext);
if (ValueStatus.DELETED.equals(valueWrapper.getStatus())) {
updatedItem.remove(valueWrapper.getValue());
} else if (!updatedItem.containsEquivalentValue(valueWrapper.getValue(), null)) {
} else if (!updatedItem.containsEquivalentValue(valueWrapper.getValue())) {
PrismValue cloned = ObjectWrapper.clone(valueWrapper.getValue());
if (cloned != null) {
updatedItem.add(cloned);
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition;
import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;
import com.evolveum.midpoint.prism.match.MatchingRule;
import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
import com.evolveum.midpoint.prism.query.ObjectFilter;
Expand Down Expand Up @@ -108,7 +109,7 @@ private boolean matches(ResourceAttribute<?> identifier, ResourceAttribute<?> at
RefinedAttributeDefinition rAttrDef = rOcDef.findAttributeDefinition(identifier.getElementName());
QName matchingRuleQName = rAttrDef.getMatchingRuleQName();
if (matchingRuleQName == null || matchingRuleRegistry == null) {
return identifier.equalsRealValue(attributeToMatch);
return identifier.equals(attributeToMatch, EquivalenceStrategy.REAL_VALUE);
}
MatchingRule<Object> matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleQName, rAttrDef.getTypeName());
return matchingRule.match(identifier.getRealValue(), attributeToMatch.getRealValue());
Expand Down
170 changes: 124 additions & 46 deletions infra/prism-api/src/main/java/com/evolveum/midpoint/prism/Item.java
Expand Up @@ -221,6 +221,13 @@ public interface Item<V extends PrismValue, D extends ItemDefinition> extends It
* - Referencable in PrismReferenceValue
* - Containerable in PrismContainerValue
* - Objectable in PrismObjectValue
*
* Note that the real value can contain operational items.
*
* It can also contain container IDs (although they are not considered to be part of the real value).
*
* It does not contain information about item element name nor other metadata like origin, definition, etc.
* (Although e.g. Containerable can be converted back into PrismContainerValue that can be used to retrieve this information.)
*/
@Nullable
Object getRealValue();
Expand All @@ -241,12 +248,17 @@ public interface Item<V extends PrismValue, D extends ItemDefinition> extends It

/**
* Adds a given value, unless an equivalent one is already there (if checkUniqueness is true).
*
* @return true if this item changed as a result of the call (i.e. if the value was really added)
*
* Note that even if checkUniqueness is false we check the cardinality of the item according to its definition,
* i.e. we do not allow single-valued item to contain more than one value.
*/
boolean add(@NotNull V newValue, boolean checkUniqueness) throws SchemaException;

/**
* Adds a given value, unless an equivalent one is already there. It is the same as calling add with checkUniqueness=true.
*
* @return true if this item changed as a result of the call (i.e. if the value was really added)
*/
boolean add(@NotNull V newValue) throws SchemaException;
Expand All @@ -261,30 +273,45 @@ public interface Item<V extends PrismValue, D extends ItemDefinition> extends It

/**
* Adds given values, with the same semantics as repeated add(..) calls.
*
* @return true if this item changed as a result of the call (i.e. if at least one value was really added)
*/
boolean addAll(Collection<V> newValues) throws SchemaException;

/**
* Adds given values, with the same semantics as repeated add(..) calls.
* For equality testing uses give strategy.
*
* @return true if this item changed as a result of the call (i.e. if at least one value was really added)
*/
boolean addAll(Collection<V> newValues, EquivalenceStrategy strategy) throws SchemaException;

/**
* Removes given value from the item.
*
* "Given value" currently means any value that is considered equivalent via REAL_VALUE equivalence strategy
* or a value that is considered "the same" via "representsSameValue(.., lax=false)" method.
*
* TODO This is to be refined; most probably including a comparator or comparison strategy designation.
*
* @return true if this item changed as a result of the call (i.e. if at least one value was really removed)
*
* Note that there can be more than one values removed.
*/
boolean remove(V newValue);
boolean remove(V value);

/**
* Removes all given values from the item.
* Removes values equivalent to given value from the item; under specified equivalence strategy
* OR when values represent the same value via "representsSameValue(.., lax=false)" method.
*
* @return true if this item changed as a result of the call (i.e. if at least one value was really removed)
*/
boolean removeAll(Collection<V> newValues);
boolean remove(V value, @NotNull EquivalenceStrategy strategy);

/**
* Removes all given values from the item. It is basically a shortcut for repeated remove(value) call.
*
* @return true if this item changed as a result of the call (i.e. if at least one value was really removed)
*/
boolean removeAll(Collection<V> values);

/**
* Removes all values from the item.
Expand All @@ -294,32 +321,113 @@ public interface Item<V extends PrismValue, D extends ItemDefinition> extends It
/**
* Replaces all values of the item by given values.
*/
void replaceAll(Collection<V> newValues) throws SchemaException;
void replaceAll(Collection<V> newValues, EquivalenceStrategy strategy) throws SchemaException;

/**
* Replaces all values of the item by given value.
*/
void replace(V newValue);
void replace(V newValue) throws SchemaException;

//endregion

//region Comparing values
//region Finding and comparing values

/**
* Compares this item to the specified object under NOT_LITERAL strategy (if no other is pre-set).
*/
@Override
boolean equals(Object obj);

/**
* Compares this item to the specified object under given strategy.
*/
boolean equals(Object obj, @NotNull EquivalenceStrategy equivalenceStrategy);

/**
* Compares this item to the specified object under given strategy.
*/
boolean equals(Object obj, @NotNull ParameterizedEquivalenceStrategy equivalenceStrategy);

/**
* Computes hash code to be used under NOT_LITERAL equivalence strategy.
*/
@Override
int hashCode();

/**
* Computes hash code to be used under given equivalence strategy.
*/
int hashCode(@NotNull EquivalenceStrategy equivalenceStrategy);

/**
* Computes hash code to be used under given equivalence strategy.
*/
int hashCode(@NotNull ParameterizedEquivalenceStrategy equivalenceStrategy);

/**
* @return true if the item contains a given value (by default using NOT_LITERAL strategy)
*
* Note that the "sameness" (ID-only value matching) is NOT considered here.
*/
boolean contains(V value);

@Deprecated
boolean containsEquivalentValue(V value, Comparator<V> comparator);
/**
* @return true if the item contains a given value under specified equivalence strategy
*
* Note that the "sameness" (ID-only value matching) is NOT considered here.
*/
boolean contains(V value, @NotNull EquivalenceStrategy strategy);

boolean contains(V value, EquivalenceStrategy strategy);
/**
* @return true if the item contains a given value using comparator (if not null) or
* under specified equivalence strategy (if comparator is null).
*
* Note that the "sameness" (ID-only value matching) is NOT considered here.
*/
boolean contains(V value, @Nullable EquivalenceStrategy strategy, @Nullable Comparator<V> comparator);

boolean contains(V value, @NotNull EquivalenceStrategy strategy, Comparator<V> comparator);
/**
* @return true if the item contains an equivalent value (the same as {@link #containsEquivalentValue(PrismValue, Comparator)}
* with comparator being null)
*/
boolean containsEquivalentValue(V value);

boolean containsRealValue(V value);
/**
* @return true if the item contains an equivalent value
*
* Item value is considered to be equivalent to the given value if:
* 1) given value is ID-only container value and item value has the same ID, or
* 2) comparator is not null and it gives "equals" (0) result when comparing these values, or
* 3) comparator is null and values match under IGNORE_METADATA_CONSIDER_DIFFERENT_IDS strategy
*/
boolean containsEquivalentValue(V value, @Nullable Comparator<V> comparator);

/**
* @return a value of this item that is equivalent to the given one under given equivalence strategy
* (or null if no such value exists)
*/
V findValue(V value, @NotNull EquivalenceStrategy strategy);

/**
* @return true if the values of this item match the "matchValues" collection, under given comparator.
*
* If comparator is null the default equals(..) comparison is used.
*/
boolean valuesEqual(Collection<V> matchValues, @Nullable Comparator<V> comparator);

/**
* Computes a difference (delta) with the specified item using IGNORE_METADATA_CONSIDER_DIFFERENT_IDS equivalence strategy.
*/
ItemDelta<V,D> diff(Item<V,D> other);

/**
* 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.
*/
ItemDelta<V,D> diff(Item<V,D> other, @NotNull ParameterizedEquivalenceStrategy strategy);

boolean valuesExactMatch(Collection<V> matchValues, Comparator<V> comparator);
//endregion

PrismValue findValue(PrismValue value, EquivalenceStrategy strategy);

Collection<V> getClonedValues();

Expand All @@ -337,11 +445,6 @@ public interface Item<V extends PrismValue, D extends ItemDefinition> extends It

<IV extends PrismValue,ID extends ItemDefinition> PartiallyResolvedItem<IV,ID> findPartial(ItemPath path);

// We want this method to be consistent with property diff
ItemDelta<V,D> diff(Item<V,D> other);

// We want this method to be consistent with property diff
ItemDelta<V,D> diff(Item<V,D> other, ParameterizedEquivalenceStrategy strategy);

/**
* Creates specific subclass of ItemDelta appropriate for type of item that this definition
Expand Down Expand Up @@ -416,7 +519,7 @@ static <T extends Item> Collection<T> resetParentCollection(Collection<T> items)

void assertDefinitions(String sourceDescription) throws SchemaException;

void assertDefinitions(boolean tolarateRawValues, String sourceDescription) throws SchemaException;
void assertDefinitions(boolean tolerateRawValues, String sourceDescription) throws SchemaException;

/**
* Returns true is all the values are raw.
Expand All @@ -436,31 +539,6 @@ static boolean hasNoValues(Item<?, ?> item) {
return item == null || item.getValues().isEmpty();
}

/**
* Note: hashcode and equals compare the objects in the "java way". That means the objects must be
* almost precisely equal to match (e.g. including source demarcation in values and other "annotations").
* For a method that compares the "meaningful" parts of the objects see equivalent().
*/
@Override
int hashCode();

int hashCode(@NotNull EquivalenceStrategy equivalenceStrategy);

int hashCode(@NotNull ParameterizedEquivalenceStrategy equivalenceStrategy);

/**
* Note: hashcode and equals compare the objects in the "java way". That means the objects must be
* almost precisely equal to match (e.g. including source demarcation in values and other "annotations").
* For a method that compares the "meaningful" parts of the objects see equivalent().
*/
@Override
boolean equals(Object obj);

boolean equals(Object obj, @NotNull EquivalenceStrategy equivalenceStrategy);

boolean equals(Object obj, @NotNull ParameterizedEquivalenceStrategy equivalenceStrategy);

boolean equalsRealValue(Object obj);

/**
* Returns true if this item is metadata item that should be ignored
Expand Down
Expand Up @@ -246,13 +246,6 @@ void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions,

PrismContainerDefinition<C> deepCloneDefinition(boolean ultraDeep, Consumer<ItemDefinition> postCloneAction);

@Deprecated
boolean containsEquivalentValue(PrismContainerValue<C> value);

@Deprecated
@Override
boolean containsEquivalentValue(PrismContainerValue<C> value, Comparator<PrismContainerValue<C>> comparator);

@Override
void accept(Visitor visitor, ItemPath path, boolean recursive);

Expand Down
Expand Up @@ -258,9 +258,6 @@ <IV extends PrismValue,ID extends ItemDefinition,I extends Item<IV,ID>> I findOr

boolean hasCompleteDefinition();

@Override
boolean representsSameValue(PrismValue other, boolean lax);

boolean isRaw();

boolean addRawElement(Object element) throws SchemaException;
Expand Down
Expand Up @@ -148,9 +148,6 @@ public interface PrismReferenceValue extends PrismValue, ShortDumpable {
@Override
int hashCode();

@Override
boolean representsSameValue(PrismValue other, boolean lax);

@Override
String toString();

Expand Down
Expand Up @@ -56,4 +56,9 @@ private static <T> PrismPropertyValue<T> createRaw(XNode rawElement, PrismContex
return prismContext.itemFactory().createPropertyValue(rawElement);
}

public static boolean differentIds(PrismValue v1, PrismValue v2) {
Long id1 = v1 instanceof PrismContainerValue ? ((PrismContainerValue) v1).getId() : null;
Long id2 = v2 instanceof PrismContainerValue ? ((PrismContainerValue) v2).getId() : null;
return id1 != null && id2 != null && id1.longValue() != id2.longValue();
}
}
Expand Up @@ -17,6 +17,7 @@

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;
import com.evolveum.midpoint.prism.equivalence.ParameterizedEquivalenceStrategy;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.DebugDumpable;
Expand Down Expand Up @@ -256,13 +257,15 @@ public interface ItemDelta<V extends PrismValue,D extends ItemDefinition> extend
void simplify();

void applyTo(PrismContainerValue containerValue) throws SchemaException;
void applyTo(PrismContainerValue containerValue, ParameterizedEquivalenceStrategy strategy) throws SchemaException;

void applyTo(Item item) throws SchemaException;
void applyTo(Item item, ParameterizedEquivalenceStrategy strategy) throws SchemaException;

/**
* Applies delta to item were path of the delta and path of the item matches (skips path checks).
*/
void applyToMatchingPath(Item item) throws SchemaException;
void applyToMatchingPath(Item item, ParameterizedEquivalenceStrategy strategy) throws SchemaException;

ItemDelta<?,?> getSubDelta(ItemPath path);

Expand Down
Expand Up @@ -17,6 +17,7 @@
package com.evolveum.midpoint.prism.delta;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.equivalence.ParameterizedEquivalenceStrategy;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand Down Expand Up @@ -155,7 +156,7 @@ public static void applyTo(Collection<? extends ItemDelta> deltas, PrismContaine
public static void applyToMatchingPath(Collection<? extends ItemDelta> deltas, PrismContainer propertyContainer)
throws SchemaException {
for (ItemDelta delta : deltas) {
delta.applyToMatchingPath(propertyContainer);
delta.applyToMatchingPath(propertyContainer, ParameterizedEquivalenceStrategy.DEFAULT_FOR_DELTA_APPLICATION);
}
}

Expand Down
Expand Up @@ -17,6 +17,7 @@

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;
import com.evolveum.midpoint.prism.equivalence.ParameterizedEquivalenceStrategy;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand Down Expand Up @@ -198,6 +199,8 @@ <IV extends PrismValue,ID extends ItemDefinition> Collection<PartiallyResolvedDe
*/
void applyTo(PrismObject<O> targetObject) throws SchemaException;

void applyTo(PrismObject<O> targetObject, ParameterizedEquivalenceStrategy strategy) throws SchemaException;

/**
* Applies this object delta to specified object, returns updated object.
* It leaves the original object unchanged.
Expand Down
Expand Up @@ -39,8 +39,10 @@ public interface EquivalenceStrategy {
ParameterizedEquivalenceStrategy LITERAL = ParameterizedEquivalenceStrategy.LITERAL;
ParameterizedEquivalenceStrategy NOT_LITERAL = ParameterizedEquivalenceStrategy.NOT_LITERAL;
ParameterizedEquivalenceStrategy IGNORE_METADATA = ParameterizedEquivalenceStrategy.IGNORE_METADATA;
ParameterizedEquivalenceStrategy IGNORE_METADATA_CONSIDER_DIFFERENT_IDS = ParameterizedEquivalenceStrategy.IGNORE_METADATA_CONSIDER_DIFFERENT_IDS;
ParameterizedEquivalenceStrategy LITERAL_IGNORE_METADATA = ParameterizedEquivalenceStrategy.LITERAL_IGNORE_METADATA;
ParameterizedEquivalenceStrategy REAL_VALUE = ParameterizedEquivalenceStrategy.REAL_VALUE;
ParameterizedEquivalenceStrategy REAL_VALUE_CONSIDER_DIFFERENT_IDS = ParameterizedEquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS;

boolean equals(Item<?,?> first, Item<?,?> second);
boolean equals(PrismValue first, PrismValue second);
Expand Down

0 comments on commit da933aa

Please sign in to comment.