Skip to content

Commit

Permalink
Add "real" value metadata into PrismValueImpl
Browse files Browse the repository at this point in the history
Related to MID-6275.
  • Loading branch information
mederly committed Jun 16, 2020
1 parent 88747f7 commit 0797209
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 8 deletions.
Expand Up @@ -12,8 +12,8 @@
import com.evolveum.midpoint.prism.delta.DeltaFactory;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.builder.S_ItemEntry;
import com.evolveum.midpoint.prism.marshaller.JaxbDomHack;
import com.evolveum.midpoint.prism.marshaller.ParsingMigrator;
import com.evolveum.midpoint.prism.metadata.ValueMetadataFactory;
import com.evolveum.midpoint.prism.metadata.ValueMetadataMockUpFactory;
import com.evolveum.midpoint.prism.path.CanonicalItemPath;
import com.evolveum.midpoint.prism.path.ItemPath;
Expand All @@ -35,7 +35,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.Element;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;

import javax.xml.namespace.QName;
Expand Down Expand Up @@ -380,4 +379,10 @@ default ItemPath toPath(ItemPathType path) {
*/
@Experimental
ValueMetadataMockUpFactory getValueMetadataMockUpFactory();

@Experimental
void setValueMetadataFactory(ValueMetadataFactory factory);

@Experimental
ValueMetadataFactory getValueMetadataFactory();
}
Expand Up @@ -49,6 +49,10 @@ public interface PrismValue extends Visitable, PathVisitable, Serializable, Debu
@Experimental
Optional<ValueMetadata> valueMetadata() throws SchemaException;

@Experimental
default void createLiveMetadata() {
}

@NotNull
ItemPath getPath();

Expand Down
Expand Up @@ -5,4 +5,6 @@
@Experimental
public interface ValueMetadata extends PrismContainerValue<Containerable> {

ValueMetadata clone();

}
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2020 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.metadata;

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

import org.jetbrains.annotations.NotNull;

/**
* Provides empty value metadata.
*/
@Experimental
public interface ValueMetadataFactory {

@NotNull
ValueMetadata createEmpty();

}
Expand Up @@ -9,13 +9,15 @@

import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.ValueMetadata;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.SchemaException;

import java.util.Optional;

/**
* Provides mock up value metadata for given prism value.
*/
@Experimental
public interface ValueMetadataMockUpFactory {

Optional<ValueMetadata> createValueMetadata(PrismValue value) throws SchemaException;
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.evolveum.midpoint.prism.impl.lex.LexicalProcessor;
import com.evolveum.midpoint.prism.impl.lex.LexicalProcessorRegistry;
import com.evolveum.midpoint.prism.impl.lex.dom.DomLexicalProcessor;
import com.evolveum.midpoint.prism.metadata.ValueMetadataFactory;
import com.evolveum.midpoint.prism.metadata.ValueMetadataMockUpFactory;
import com.evolveum.midpoint.prism.path.*;
import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer;
Expand Down Expand Up @@ -92,6 +93,9 @@ public final class PrismContextImpl implements PrismContext {
@Experimental // temporary
private ValueMetadataMockUpFactory valueMetadataMockUpFactory;

@Experimental
private ValueMetadataFactory valueMetadataFactory;

private ParsingMigrator parsingMigrator;
private PrismMonitor monitor = null;

Expand Down Expand Up @@ -680,4 +684,14 @@ public void setValueMetadataMockUpFactory(ValueMetadataMockUpFactory factory) {
public ValueMetadataMockUpFactory getValueMetadataMockUpFactory() {
return valueMetadataMockUpFactory;
}

@Override
public void setValueMetadataFactory(ValueMetadataFactory valueMetadataFactory) {
this.valueMetadataFactory = valueMetadataFactory;
}

@Override
public ValueMetadataFactory getValueMetadataFactory() {
return valueMetadataFactory;
}
}
Expand Up @@ -13,6 +13,7 @@
import com.evolveum.midpoint.prism.metadata.ValueMetadataMockUpFactory;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.SchemaException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -33,9 +34,13 @@ public abstract class PrismValueImpl extends AbstractFreezable implements PrismV
private OriginType originType;
private Objectable originObject;
private Itemable parent;

private ValueMetadata valueMetadata;

@SuppressWarnings("FieldMayBeFinal") // Cannot be final because it is transient
private transient Map<String,Object> userData = new HashMap<>();

// FIXME: allways null
// FIXME: always null
protected EquivalenceStrategy defaultEquivalenceStrategy;

transient protected PrismContext prismContext;
Expand Down Expand Up @@ -244,6 +249,7 @@ protected void copyValues(CloneStrategy strategy, PrismValueImpl clone) {
if (clone.prismContext == null) {
clone.prismContext = this.prismContext;
}
clone.valueMetadata = valueMetadata != null ? valueMetadata.clone() : null;
}

protected EquivalenceStrategy getEqualsHashCodeStrategy() {
Expand Down Expand Up @@ -380,6 +386,22 @@ public Collection<PrismValue> getAllValues(ItemPath path) {

@Override
public Optional<ValueMetadata> valueMetadata() throws SchemaException {
if (valueMetadata != null) {
return Optional.of(valueMetadata);
} else {
return createMockUpValueMetadata();
}
}

@Override
@Experimental
public void createLiveMetadata() {
valueMetadata = Objects.requireNonNull(prismContext, "no prism context")
.getValueMetadataFactory()
.createEmpty();
}

private Optional<ValueMetadata> createMockUpValueMetadata() throws SchemaException {
PrismContext prismContext = getPrismContext();
if (prismContext != null) {
ValueMetadataMockUpFactory factory = prismContext.getValueMetadataMockUpFactory();
Expand All @@ -389,4 +411,12 @@ public Optional<ValueMetadata> valueMetadata() throws SchemaException {
}
return Optional.empty();
}

@Override
protected void performFreeze() {
if (valueMetadata != null) {
valueMetadata.freeze();
}
super.performFreeze();
}
}
Expand Up @@ -511,8 +511,8 @@ public void assertDefinitions(boolean tolerateRaw, String sourceDescription) thr
delegate.assertDefinitions(tolerateRaw, sourceDescription);
}

public PrismContainerValue<Containerable> clone() {
return delegate.clone();
public ValueMetadata clone() {
return holding(delegate.clone());
}

public PrismContainerValue<Containerable> createImmutableClone() {
Expand Down
Expand Up @@ -17,6 +17,7 @@
import com.evolveum.midpoint.schema.internals.InternalMonitor;
import com.evolveum.midpoint.schema.internals.InternalsConfig;

import com.evolveum.midpoint.schema.metadata.MidpointValueMetadataFactory;
import com.evolveum.midpoint.schema.metadata.MidpointValueMetadataMockUpFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.model.model_3.ObjectFactory;
Expand Down Expand Up @@ -66,6 +67,7 @@ public PrismContext createPrismContext() throws SchemaException, FileNotFoundExc
}
context.setParsingMigrator(new MidpointParsingMigrator());
context.setValueMetadataMockUpFactory(new MidpointValueMetadataMockUpFactory(context));
context.setValueMetadataFactory(new MidpointValueMetadataFactory(context));
return context;
}

Expand Down
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2020 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.schema.metadata;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.ValueMetadata;
import com.evolveum.midpoint.prism.impl.metadata.ValueMetadataAdapter;
import com.evolveum.midpoint.prism.metadata.ValueMetadataFactory;
import com.evolveum.midpoint.util.annotation.Experimental;

import com.evolveum.midpoint.xml.ns._public.common.common_3.ValueMetadataType;

import org.jetbrains.annotations.NotNull;

@Experimental
public class MidpointValueMetadataFactory implements ValueMetadataFactory {

@NotNull private final PrismContext prismContext;

public MidpointValueMetadataFactory(@NotNull PrismContext prismContext) {
this.prismContext = prismContext;
}

@Override
@NotNull
public ValueMetadata createEmpty() {
return ValueMetadataAdapter.holding(
new ValueMetadataType(prismContext)
.asPrismContainerValue());
}
}
Expand Up @@ -11,21 +11,25 @@
import java.io.File;
import java.util.Optional;

import com.evolveum.midpoint.prism.*;

import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.util.exception.SchemaException;

import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.Test;

import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.ValueMetadata;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.TestResource;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import javax.xml.datatype.XMLGregorianCalendar;

/**
* Tests the value metadata handling. Currently the only "handling" is creation of metadata mock-up.
*/
Expand All @@ -44,6 +48,34 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
addObject(USER_ALICE, initTask, initResult);
}

@Test
public void test010TestLiveMetadata() throws SchemaException {
given();
UserType mark = new UserType(prismContext)
.name("mark");
PrismPropertyValue<PolyString> nameValue = mark.asPrismObject()
.findProperty(UserType.F_NAME)
.getValue(PolyString.class);
nameValue.createLiveMetadata();

when();
Optional<ValueMetadata> metadata = nameValue.valueMetadata();
assertThat(metadata).isPresent();

XMLGregorianCalendar now = XmlTypeConverter.createXMLGregorianCalendar();

ValueMetadataType realMetadataValue = (ValueMetadataType) metadata.get().asContainerable();
realMetadataValue.setProvisioning(new ProvisioningMetadataType(prismContext));
realMetadataValue.getProvisioning().setLastProvisioningTimestamp(now);

then();
Optional<ValueMetadata> metadataAfter = nameValue.valueMetadata();
assertThat(metadataAfter).isPresent();

ValueMetadataType realMetadataValueAfter = (ValueMetadataType) metadataAfter.get().asContainerable();
assertThat(realMetadataValueAfter.getProvisioning().getLastProvisioningTimestamp()).isEqualTo(now);
}

@Test
public void test100CheckValueMetadata() throws Exception {
given();
Expand Down

0 comments on commit 0797209

Please sign in to comment.