Skip to content

Commit

Permalink
Add limited metadata mapping functionality
Browse files Browse the repository at this point in the history
1. Created AbstractMappingImpl (= MappingImpl + MetadataMappingImpl)
2. The same for AbstractMappingBuilder
3. Adapted the rest of code to this change
4. Hacked IvwoConsolidator and other components to preserve
value metadata

Related to MID-6275.
  • Loading branch information
mederly committed Jun 18, 2020
1 parent 1a4ec87 commit 2ba3bfe
Show file tree
Hide file tree
Showing 37 changed files with 2,415 additions and 1,786 deletions.
Expand Up @@ -440,6 +440,9 @@ default boolean add(@NotNull V newValue) throws SchemaException {
*/
boolean contains(V value, @Nullable EquivalenceStrategy strategy, @Nullable Comparator<V> comparator);

@Experimental
V findValue (V value, @Nullable EquivalenceStrategy strategy, @Nullable Comparator<V> comparator);

/**
* @return true if the item contains an equivalent value (the same as {@link #containsEquivalentValue(PrismValue, Comparator)}
* with comparator being null)
Expand Down
Expand Up @@ -186,4 +186,7 @@ static PrismObject<?> asPrismObject(Objectable o) {
static <T extends Objectable> T asObjectable(PrismObject<T> object) {
return object != null ? object.asObjectable() : null;
}

default void fixMockUpValueMetadata() {
}
}
Expand Up @@ -54,12 +54,27 @@ public interface PrismValue extends Visitable, PathVisitable, Serializable, Debu
* Client code would be simpler. HIGHLY EXPERIMENTAL.
*/
@Experimental
@NotNull
ValueMetadata getValueMetadata() throws SchemaException;

/**
* Sets metadata for this value.
*/
@Experimental
void setValueMetadata(ValueMetadata valueMetadata);

@Experimental
default void createLiveMetadata() {
}

/**
* Converts mock-up metadata (if present) into materialized form.
* TEMPORARY. Remove after mocking up is gone.
*/
@Experimental
default void fixMockUpValueMetadata() {
}

@NotNull
ItemPath getPath();

Expand Down
Expand Up @@ -535,4 +535,22 @@ private void validate(ItemDelta<V, D> delta) {
throw new IllegalArgumentException("Attempt to set delta without definition");
}
}

// TEMPORARY
public void fixMockUpValueMetadata() {
fixMockUpValueMetadata(itemOld);
fixMockUpValueMetadata(itemNew);
fixMockUpValueMetadata(delta);
}

// TEMPORARY
private void fixMockUpValueMetadata(Visitable<?> visitable) {
if (visitable != null) {
visitable.accept(v -> {
if (v instanceof PrismValue) {
((PrismValue) v).fixMockUpValueMetadata();
}
});
}
}
}
Expand Up @@ -426,6 +426,25 @@ public boolean contains(V value, EquivalenceStrategy strategy, Comparator<V> com
}
}

@Override
@Experimental
public V findValue(V value, EquivalenceStrategy strategy, Comparator<V> comparator) {
if (comparator == null) {
if (strategy == null) {
return findValue(value, defaultEquivalenceStrategy);
} else {
return findValue(value, strategy);
}
} else {
for (V myValue : getValues()) {
if (comparator.compare(myValue, value) == 0) {
return myValue;
}
}
return null;
}
}

public boolean valuesEqual(Collection<V> matchValues, Comparator<V> comparator) {
return MiscUtil.unorderedCollectionCompare(values, matchValues, comparator);
}
Expand Down
Expand Up @@ -467,4 +467,13 @@ public static <T extends Objectable> List<T> asObjectableList(@NotNull List<Pris
.map(o -> o.asObjectable())
.collect(Collectors.toList());
}

// TEMPORARY
public void fixMockUpValueMetadata() {
accept(v -> {
if (v instanceof PrismValue) {
((PrismValue) v).fixMockUpValueMetadata();
}
});
}
}
Expand Up @@ -395,6 +395,7 @@ public Optional<ValueMetadata> valueMetadata() throws SchemaException {
}

@Override
@NotNull
public ValueMetadata getValueMetadata() throws SchemaException {
if (valueMetadata != null) {
return valueMetadata;
Expand All @@ -410,6 +411,11 @@ public ValueMetadata getValueMetadata() throws SchemaException {
}
}

@Override
public void setValueMetadata(ValueMetadata valueMetadata) {
this.valueMetadata = valueMetadata;
}

@Override
@Experimental
public void createLiveMetadata() {
Expand All @@ -429,6 +435,18 @@ private Optional<ValueMetadata> createMockUpValueMetadata() throws SchemaExcepti
return Optional.empty();
}

// TEMPORARY
@Override
public void fixMockUpValueMetadata() {
if (valueMetadata == null) {
try {
createMockUpValueMetadata().ifPresent(metadata -> valueMetadata = metadata.clone());
} catch (SchemaException e) {
throw new IllegalStateException(e);
}
}
}

@Override
protected void performFreeze() {
if (valueMetadata != null) {
Expand Down
Expand Up @@ -10,29 +10,13 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

import javax.xml.namespace.QName;

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

import com.evolveum.midpoint.prism.CloneStrategy;
import com.evolveum.midpoint.prism.ConsistencyCheckScope;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.Itemable;
import com.evolveum.midpoint.prism.PartiallyResolvedItem;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismReference;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.Visitor;
import com.evolveum.midpoint.prism.delta.ContainerDelta;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;
import com.evolveum.midpoint.prism.equivalence.ParameterizedEquivalenceStrategy;
Expand Down Expand Up @@ -269,6 +253,13 @@ public final boolean contains(V value, EquivalenceStrategy strategy,
return delegate().contains(value, strategy, comparator);
}

@Override
public V findValue(V value,
@Nullable EquivalenceStrategy strategy,
@Nullable Comparator<V> comparator) {
return delegate().findValue(value, strategy, comparator);
}

public final boolean containsEquivalentValue(V value) {
return delegate().containsEquivalentValue(value);
}
Expand Down
Expand Up @@ -15,6 +15,8 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.impl.PrismContainerValueImpl;

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

Expand Down Expand Up @@ -145,15 +147,23 @@ public void setParent(Itemable parent) {
delegate.setParent(parent);
}

// TODO is this correct?
public Optional<ValueMetadata> valueMetadata() {
return Optional.of(this);
// TODO reconsider
return Optional.empty();
}

// TODO is this correct?
@Override
@NotNull
public ValueMetadata getValueMetadata() {
return this;
// TODO reconsider
return holding(new PrismContainerValueImpl<>());
}

@Override
public void setValueMetadata(ValueMetadata valueMetadata) {
// Metadata should not have its own metadata. (At least for now.)
// TODO reconsider
throw new UnsupportedOperationException("Couldn't set metadata on value metadata");
}

public @NotNull ItemPath getPath() {
Expand Down
Expand Up @@ -7,6 +7,7 @@

package com.evolveum.midpoint.schema.metadata;

import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.ValueMetadata;
import com.evolveum.midpoint.prism.impl.metadata.ValueMetadataAdapter;
Expand All @@ -29,8 +30,12 @@ public MidpointValueMetadataFactory(@NotNull PrismContext prismContext) {
@Override
@NotNull
public ValueMetadata createEmpty() {
return ValueMetadataAdapter.holding(
return createFrom(
new ValueMetadataType(prismContext)
.asPrismContainerValue());
}

public static ValueMetadata createFrom(PrismContainerValue<?> pcv) {
return ValueMetadataAdapter.holding(pcv);
}
}
Expand Up @@ -220,7 +220,7 @@ private String getMappingInfo(OperationResultType result) {
MappingEvaluationTraceType trace = getTrace(result, MappingEvaluationTraceType.class);
String context = getContext(result, "context");
if (trace != null) {
MappingType mapping = trace.getMapping();
AbstractMappingType mapping = trace.getMapping();
if (mapping != null) {
if (mapping.getName() != null) {
return mapping.getName();
Expand Down
Expand Up @@ -38,7 +38,7 @@ public void visualize(StringBuilder sb, OpNode node, int indent) {
boolean oneLine = generic == GenericTraceVisualizationType.ONE_LINE;
MappingEvaluationTraceType trace = node.getTrace(MappingEvaluationTraceType.class);
MappingKindType kind = trace != null ? trace.getMappingKind() : null;
MappingType mapping = trace != null ? trace.getMapping() : null;
AbstractMappingType mapping = trace != null ? trace.getMapping() : null;
String name = mapping != null ? mapping.getName() : null;

String nullPrefix = indent(sb, node, indent);
Expand Down Expand Up @@ -145,31 +145,31 @@ private String shortOutputDump(DeltaSetTripleType output, GenericTraceVisualizat
return formatSingleLine(output, generic);
}

private boolean isAuthoritative(MappingType mapping) {
private boolean isAuthoritative(AbstractMappingType mapping) {
if (mapping != null) {
return defaultIfNull(mapping.isAuthoritative(), true);
} else {
return true;
}
}

private boolean isExclusive(MappingType mapping) {
private boolean isExclusive(AbstractMappingType mapping) {
if (mapping != null) {
return defaultIfNull(mapping.isExclusive(), false);
} else {
return false;
}
}

private MappingStrengthType getStrength(MappingType mapping) {
private MappingStrengthType getStrength(AbstractMappingType mapping) {
if (mapping != null) {
return defaultIfNull(mapping.getStrength(), MappingStrengthType.NORMAL);
} else {
return MappingStrengthType.NORMAL;
}
}

private String getTarget(MappingType mapping, MappingEvaluationTraceType trace) {
private String getTarget(AbstractMappingType mapping, MappingEvaluationTraceType trace) {
if (mapping != null && mapping.getTarget() != null) {
return String.valueOf(mapping.getTarget().getPath());
} else if (trace.getImplicitTargetPath() != null) {
Expand All @@ -179,7 +179,7 @@ private String getTarget(MappingType mapping, MappingEvaluationTraceType trace)
}
}

private List<String> getSources(MappingType mapping, MappingEvaluationTraceType trace) {
private List<String> getSources(AbstractMappingType mapping, MappingEvaluationTraceType trace) {
if (mapping == null || mapping.getSource().isEmpty()) {
if (trace.getImplicitSourcePath() != null) {
return singletonList(String.valueOf(trace.getImplicitSourcePath()));
Expand All @@ -193,7 +193,7 @@ private List<String> getSources(MappingType mapping, MappingEvaluationTraceType
}
}

private String shortExpressionDebugDump(MappingType mapping, GenericTraceVisualizationType level) {
private String shortExpressionDebugDump(AbstractMappingType mapping, GenericTraceVisualizationType level) {
List<JAXBElement<?>> evaluators;
if (mapping != null && mapping.getExpression() != null) {
evaluators = mapping.getExpression().getExpressionEvaluator();
Expand Down
Expand Up @@ -88,6 +88,7 @@
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>
<xsd:element name="valueMetadata" type="tns:ValueMetadataType" />

<xsd:complexType name="StorageMetadataType">
<xsd:annotation>
Expand Down
Expand Up @@ -1418,7 +1418,7 @@
<xsd:extension base="tns:TraceType">
<xsd:sequence>
<xsd:element name="mappingKind" type="tns:MappingKindType" minOccurs="0"/>
<xsd:element name="mapping" type="tns:MappingType" minOccurs="0"/>
<xsd:element name="mapping" type="tns:AbstractMappingType" minOccurs="0"/>
<xsd:element name="containingObjectRef" type="tns:ObjectReferenceType" minOccurs="0"/>
<xsd:element name="timeFrom" type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="timeTo" type="xsd:dateTime" minOccurs="0"/>
Expand Down
Expand Up @@ -13,6 +13,8 @@
import java.util.Iterator;
import java.util.List;

import com.evolveum.midpoint.prism.ValueMetadata;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.ItemDefinition;
Expand Down Expand Up @@ -321,9 +323,29 @@ private boolean evaluateCondition(ExpressionVariables staticVariables)
@NotNull
private List<V> evaluateTransformation(ExpressionVariables staticVariables) throws ExpressionEvaluationException,
ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
return combinatorialEvaluation.evaluator.transformSingleValue(staticVariables, outputSet,
List<V> transformationOutput = combinatorialEvaluation.evaluator.transformSingleValue(staticVariables, outputSet,
inputVariableState == InputVariableState.NEW, context,
context.getContextDescription(), context.getTask(), result);
computeAndApplyOutputValueMetadata(transformationOutput);
return transformationOutput;
}

private void computeAndApplyOutputValueMetadata(List<V> output) throws CommunicationException, ObjectNotFoundException,
SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ValueMetadataComputer valueMetadataComputer = context.getValueMetadataComputer();
if (valueMetadataComputer != null) {
ValueMetadata outputValueMetadata = valueMetadataComputer.compute(valuesTuple, result);
if (outputValueMetadata != null) {
for (int i = 0; i < output.size(); i++) {
V oVal = output.get(i);
if (i < output.size()-1) {
oVal.setValueMetadata(outputValueMetadata.clone());
} else {
oVal.setValueMetadata(outputValueMetadata);
}
}
}
}
}

private void setTraceComment(String comment) {
Expand Down

0 comments on commit 2ba3bfe

Please sign in to comment.