From 5423dbd4c50ec4e762e61a802ceb81c33a8f0e4e Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Thu, 27 May 2021 18:19:11 +0200 Subject: [PATCH] Use ItemDefinitionTransformer in SchemaTransformator Implemented minimal subset of "MutableDefinition" contracts to satisfy GUI and other tests. --- .../impl/controller/SchemaTransformer.java | 33 +- .../transform/DefinitionsToTransformable.java | 48 +++ ...PartiallyMutableComplexTypeDefinition.java | 295 ++++++++++++++++++ .../PartiallyMutableItemDefinition.java | 282 +++++++++++++++++ .../TransformableComplexTypeDefinition.java | 105 ++++++- .../TransformableContainerDefinition.java | 97 +++++- .../TransformableItemDefinition.java | 240 ++++++++++---- .../TransformableObjectDefinition.java | 33 +- .../TransformablePropertyDefinition.java | 110 ++++++- .../TransformableReferenceDefinition.java | 26 +- 10 files changed, 1134 insertions(+), 135 deletions(-) create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/DefinitionsToTransformable.java create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableComplexTypeDefinition.java create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableItemDefinition.java diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java index d01041dc035..7e1fe375953 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SchemaTransformer.java @@ -15,11 +15,12 @@ import com.evolveum.midpoint.model.impl.lens.LensElementContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; -import com.evolveum.midpoint.model.impl.schema.transform.TransformableContainerDefinition; +import com.evolveum.midpoint.model.impl.schema.transform.DefinitionsToTransformable; import com.evolveum.midpoint.model.impl.schema.transform.TransformableItemDefinition; import com.evolveum.midpoint.model.impl.schema.transform.TransformableObjectDefinition; import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.PrismItemAccessDefinition.Mutable; +import com.evolveum.midpoint.prism.ItemDefinitionTransformer.TransformableItem; +import com.evolveum.midpoint.prism.ItemDefinitionTransformer.TransformableValue; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -47,6 +48,8 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import com.google.common.base.Preconditions; + import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -199,7 +202,8 @@ void applySchemasAndSecurity(PrismObject object, GetOp ObjectSecurityConstraints securityConstraints = compileSecurityConstraints(object, task, result); - PrismObjectDefinition objectDefinition = TransformableObjectDefinition.of(object); + transform(object, new DefinitionsToTransformable()); + PrismObjectDefinition objectDefinition = object.getDefinition(); if (phase == null) { if (!GetOperationOptions.isExecutionPhase(rootOptions)) { @@ -247,6 +251,11 @@ void applySchemasAndSecurity(PrismObject object, GetOp LOGGER.trace("applySchemasAndSecurity finishing"); // to allow folding in log viewer } + private void transform(Item object, ItemDefinitionTransformer transformation) { + Preconditions.checkArgument(object instanceof TransformableItem, "Value must be %s", TransformableValue.class.getSimpleName()); + ((TransformableItem) object).transformDefinition(null, transformation); + } + void applySchemasAndSecurity(LensContext context, AuthorizationPhaseType phase, Task task, OperationResult parentResult) throws SecurityViolationException, SchemaException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException { LOGGER.trace("applySchemasAndSecurity({}) starting", context); @@ -393,13 +402,10 @@ private void applySecurityConstraints(PrismContainerValue pcv, ObjectSecurity if (pcv.hasNoItems()) { return; } - // FIX PCV type for subtypes - TransformableContainerDefinition.ensureMutableType(pcv); List itemsToRemove = new ArrayList<>(); for (Item item : pcv.getItems()) { ItemPath itemPath = item.getPath(); - @SuppressWarnings({ "unchecked", "rawtypes" }) - ItemDefinition itemDef = ensureMutableDefinition((Item) item); + ItemDefinition itemDef = item.getDefinition(); if (itemDef != null && itemDef.isElaborate()) { LOGGER.trace("applySecurityConstraints(item): {}: skip (elaborate)", itemPath); continue; @@ -411,6 +417,7 @@ private void applySecurityConstraints(PrismContainerValue pcv, ObjectSecurity LOGGER.trace("applySecurityConstraints(item): {}: decisions R={}, A={}, M={}", itemPath, itemReadDecision, itemAddDecision, itemModifyDecision); if (applyToDefinitions && itemDef != null) { + itemDef = ensureMutableDefinition((Item) item); if (itemReadDecision != AuthorizationDecisionType.ALLOW) { mutable(itemDef).setCanRead(false); } @@ -457,6 +464,10 @@ private > D ensureMutableDefinition(Item item) if (TransformableItemDefinition.isMutableAccess(original)) { return original; } + if (true) { + throw new IllegalStateException("Transformer did not applied transformable properly"); + } + D replace = TransformableItemDefinition.publicFrom(original); try { item.applyDefinition(replace, true); @@ -466,8 +477,8 @@ private > D ensureMutableDefinition(Item item) return replace; } - private Mutable mutable(ItemDefinition itemDef) { - return TransformableItemDefinition.access(itemDef); + private MutableItemDefinition mutable(ItemDefinition itemDef) { + return itemDef.toMutable(); } private void applySecurityConstraints(ObjectDelta objectDelta, ObjectSecurityConstraints securityConstraints, AuthorizationPhaseType phase, @@ -849,6 +860,10 @@ private UserInterfaceElementVisibilityType reduceItems(PrismContainerDefinition< return containerVisibility; } + if (containerDefinition.getItemName().getLocalPart().equals("extension")) { + containerDefinition.getItemName(); + } + Collection itemsToDelete; if (containerVisibility == HIDDEN) { // Delete everything diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/DefinitionsToTransformable.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/DefinitionsToTransformable.java new file mode 100644 index 00000000000..f95185b5580 --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/DefinitionsToTransformable.java @@ -0,0 +1,48 @@ +package com.evolveum.midpoint.model.impl.schema.transform; + +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.ItemDefinitionTransformer; +import com.evolveum.midpoint.prism.TypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; + +public class DefinitionsToTransformable implements ItemDefinitionTransformer { + + @Override + public T applyValue(ComplexTypeDefinition parentDef, ItemDefinition itemDef, + T valueDef) { + if (valueDef instanceof ComplexTypeDefinition) { + if (itemDef instanceof TransformableContainerDefinition) { + TransformableComplexTypeDefinition maybe = ((TransformableContainerDefinition) itemDef).getComplexTypeDefinition(); + if (valueDef.getTypeName().equals(maybe.getTypeName())) { + return (T) maybe; + } + } + return (T) TransformableComplexTypeDefinition.from((ComplexTypeDefinition) valueDef); + } + return valueDef; + } + + + @Override + public > I transformItem(ComplexTypeDefinition parentDef, I currentDef) { + if (currentDef == null || currentDef instanceof TransformableItemDefinition) { + return currentDef; + } + // Parent is transformable + if (parentDef instanceof TransformableComplexTypeDefinition) { + if (currentDef instanceof ResourceAttributeDefinition) { + return (I) TransformablePropertyDefinition.of((ResourceAttributeDefinition) currentDef); + } + if (currentDef instanceof ResourceAttributeContainerDefinition) { + return (I) TransformableContainerDefinition.of((ResourceAttributeContainerDefinition) currentDef); + } + ItemDefinition defFromParent = parentDef.findLocalItemDefinition(currentDef.getItemName()); + if (defFromParent != null) { + return (I) defFromParent; + } + } + return TransformableItemDefinition.publicFrom(currentDef); + } +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableComplexTypeDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableComplexTypeDefinition.java new file mode 100644 index 00000000000..6453c0e203b --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableComplexTypeDefinition.java @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2010-2021 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.model.impl.schema.transform; + +import java.util.List; +import javax.xml.namespace.QName; + +import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.ItemProcessing; +import com.evolveum.midpoint.prism.MutableComplexTypeDefinition; +import com.evolveum.midpoint.prism.MutablePrismPropertyDefinition; +import com.evolveum.midpoint.prism.SchemaMigration; +import com.evolveum.midpoint.schema.processor.MutableObjectClassComplexTypeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinitionImpl; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.google.common.annotations.VisibleForTesting; + +interface PartiallyMutableComplexTypeDefinition extends MutableComplexTypeDefinition { + + @Override + default void setInstantiationOrder(Integer order) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setProcessing(ItemProcessing processing) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setDeprecated(boolean deprecated) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setExperimental(boolean experimental) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setEmphasized(boolean emphasized) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setDisplayName(String displayName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setDisplayOrder(Integer displayOrder) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setHelp(String help) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setRuntimeSchema(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setTypeName(QName typeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setDocumentation(String value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void addSchemaMigration(SchemaMigration schemaMigration) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void add(ItemDefinition definition) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void delete(QName itemName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default MutablePrismPropertyDefinition createPropertyDefinition(QName name, QName typeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default MutablePrismPropertyDefinition createPropertyDefinition(String name, QName typeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default @NotNull ComplexTypeDefinition clone() { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setExtensionForType(QName type) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setAbstract(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setSuperType(QName superType) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setObjectMarker(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setContainerMarker(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setReferenceMarker(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setDefaultNamespace(String namespace) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setIgnoredNamespaces(@NotNull List ignoredNamespaces) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setXsdAnyMarker(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setListMarker(boolean value) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void setCompileTimeClass(Class compileTimeClass) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void replaceDefinition(QName itemName, ItemDefinition newDefinition) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + + } + + @Override + default void addSubstitution(ItemDefinition itemDef, ItemDefinition maybeSubst) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + + public interface ObjectClassDefinition extends PartiallyMutableComplexTypeDefinition, MutableObjectClassComplexTypeDefinition { + + @Override + default void add(ItemDefinition definition) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void addPrimaryIdentifier(ResourceAttributeDefinition identifier) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void addSecondaryIdentifier(ResourceAttributeDefinition identifier) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setDescriptionAttribute(ResourceAttributeDefinition descriptionAttribute) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setNamingAttribute(ResourceAttributeDefinition namingAttribute) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setNamingAttribute(QName namingAttribute) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setNativeObjectClass(String nativeObjectClass) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setAuxiliary(boolean auxiliary) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setKind(ShadowKindType kind) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setDefaultInAKind(boolean defaultAccountType) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setIntent(String intent) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setDisplayNameAttribute(ResourceAttributeDefinition displayName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + default void setDisplayNameAttribute(QName displayName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + @VisibleForTesting + default ResourceAttributeDefinitionImpl createAttributeDefinition(QName name, QName typeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + @VisibleForTesting + default ResourceAttributeDefinitionImpl createAttributeDefinition(String localName, QName typeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + @VisibleForTesting + default ResourceAttributeDefinition createAttributeDefinition(String localName, String localTypeName) { + throw new IllegalStateException("ComplexTypeDefinition is not modifiable"); + } + + @Override + @NotNull MutableObjectClassComplexTypeDefinition clone(); + } + + +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableItemDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableItemDefinition.java new file mode 100644 index 00000000000..5265a4f45b3 --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/PartiallyMutableItemDefinition.java @@ -0,0 +1,282 @@ +package com.evolveum.midpoint.model.impl.schema.transform; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ComplexTypeDefinition; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.ItemProcessing; +import com.evolveum.midpoint.prism.MutableItemDefinition; +import com.evolveum.midpoint.prism.MutablePrismContainerDefinition; +import com.evolveum.midpoint.prism.MutablePrismPropertyDefinition; +import com.evolveum.midpoint.prism.MutablePrismReferenceDefinition; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.SchemaMigration; +import com.evolveum.midpoint.schema.processor.MutableResourceAttributeDefinition; + +public interface PartiallyMutableItemDefinition> extends MutableItemDefinition { + + @Override + default void setProcessing(ItemProcessing processing) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDeprecated(boolean deprecated) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setExperimental(boolean experimental) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setEmphasized(boolean emphasized) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDisplayName(String displayName) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDisplayOrder(Integer displayOrder) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setHelp(String help) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setRuntimeSchema(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setTypeName(QName typeName) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDocumentation(String value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void addSchemaMigration(SchemaMigration schemaMigration) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setMinOccurs(int value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setMaxOccurs(int value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setCanRead(boolean val) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setCanModify(boolean val) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setCanAdd(boolean val) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setValueEnumerationRef(PrismReferenceValue valueEnumerationRef) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setOperational(boolean operational) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDynamic(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setItemName(QName name) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setReadOnly() { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setDeprecatedSince(String value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setPlannedRemoval(String value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setElaborate(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setHeterogeneousListItem(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setSubstitutionHead(QName value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setIndexOnly(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + public interface Container extends PartiallyMutableItemDefinition>, MutablePrismContainerDefinition { + + @Override + default void setCompileTimeClass(Class compileTimeClass) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default MutablePrismPropertyDefinition createPropertyDefinition(QName name, QName propType, int minOccurs, int maxOccurs) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default MutablePrismPropertyDefinition createPropertyDefinition(QName name, QName propType) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default MutablePrismPropertyDefinition createPropertyDefinition(String localName, QName propType) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default MutablePrismContainerDefinition createContainerDefinition(QName name, QName typeName, int minOccurs, int maxOccurs) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default MutablePrismContainerDefinition createContainerDefinition(QName name, ComplexTypeDefinition ctd, int minOccurs, int maxOccurs) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setInherited(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + + } + + @Override + default void setComplexTypeDefinition(ComplexTypeDefinition complexTypeDefinition) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + } + + public interface Reference extends MutablePrismReferenceDefinition, PartiallyMutableItemDefinition { + + @Override + default void setTargetTypeName(QName typeName) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + + @Override + default void setComposite(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + } + + public interface Property extends MutablePrismPropertyDefinition, PartiallyMutableItemDefinition> { + + @Override + default void setIndexed(Boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + + @Override + default void setMatchingRuleQName(QName matchingRuleQName) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + + @Override + default void setInherited(boolean value) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + } + + public interface Attribute extends MutableResourceAttributeDefinition, Property { + + @Override + default void setReturnedByDefault(Boolean returnedByDefault) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + + @Override + default void setNativeAttributeName(String nativeAttributeName) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + + @Override + default void setFrameworkAttributeName(String frameworkAttributeName) { + throw new IllegalStateException("Item Definition is not modifiable"); + } + } +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableComplexTypeDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableComplexTypeDefinition.java index 8d02d469ce1..bd06969d47b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableComplexTypeDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableComplexTypeDefinition.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.function.Consumer; @@ -28,12 +29,14 @@ import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.deleg.ObjectClassTypeDefinitionDelegator; -public class TransformableComplexTypeDefinition implements ComplexTypeDefinitionDelegator { +public class TransformableComplexTypeDefinition implements ComplexTypeDefinitionDelegator, PartiallyMutableComplexTypeDefinition { private static final long serialVersionUID = 1L; + private static final TransformableItemDefinition REMOVED = new Removed(); private final Map> overrides = new HashMap<>(); - private transient ComplexTypeDefinition delegate; + private final ComplexTypeDefinition delegate; + private transient List> definitionsCache; public TransformableComplexTypeDefinition(ComplexTypeDefinition delegate) { this.delegate = delegate; @@ -66,6 +69,9 @@ private > ID overriden(ID originalItem) { return null; } ItemDefinition overriden = overrides.computeIfAbsent(originalItem.getItemName(), k -> TransformableItemDefinition.from(originalItem)); + if (overriden instanceof Removed) { + return null; + } TransformableItemDefinition.apply(overriden, originalItem); return (ID) overriden; } @@ -105,11 +111,23 @@ public ID findNamedItemDefinition(@NotNull QName fir @Override public @NotNull List> getDefinitions() { - List> ret = new ArrayList<>(); - for (ItemDefinition originalItem : ComplexTypeDefinitionDelegator.super.getDefinitions()) { - ret.add(overriden(originalItem)); + + if (definitionsCache == null) { + List> ret = new ArrayList<>(); + for (ItemDefinition originalItem : ComplexTypeDefinitionDelegator.super.getDefinitions()) { + ItemDefinition wrapped = overriden(originalItem); + if (wrapped != null) { + ret.add(wrapped); + } + } + definitionsCache = ret; } - return ret; + return definitionsCache; + } + + @Override + public boolean isEmpty() { + return getDefinitions().isEmpty(); } @Override @@ -154,12 +172,32 @@ public void freeze() { @Override public @NotNull ComplexTypeDefinition deepClone(Map ctdMap, Map onThisPath, Consumer postCloneAction) { - throw new UnsupportedOperationException(); + if (ctdMap != null) { + ComplexTypeDefinition clone = ctdMap.get(this.getTypeName()); + if (clone != null) { + return clone; // already cloned + } + } + ComplexTypeDefinition cloneInParent = onThisPath.get(this.getTypeName()); + if (cloneInParent != null) { + return cloneInParent; + } + var copy = copy(); + if (ctdMap != null) { + ctdMap.put(this.getTypeName(), copy); + } + onThisPath.put(this.getTypeName(), copy); + for (Entry> entry : overrides.entrySet()) { + ItemDefinition item = entry.getValue().deepClone(ctdMap, onThisPath, postCloneAction); + copy.overrides.put(entry.getKey(), item); + } + onThisPath.remove(this.getTypeName()); + return copy; } @Override public MutableComplexTypeDefinition toMutable() { - throw new UnsupportedOperationException(); + return this; } /** @@ -169,10 +207,21 @@ public MutableComplexTypeDefinition toMutable() { * @param name * @param definition */ - public void replaceDefinition(QName name, ItemDefinition definition) { + @SuppressWarnings("rawtypes") + @Override + public void replaceDefinition(QName name, ItemDefinition definition) { overrides.put(name, definition); } + @Override + public void delete(QName itemName) { + ItemDefinition existing = findLocalItemDefinition(itemName); + if (existing != null) { + definitionsCache = null; + overrides.put(existing.getItemName(), REMOVED); + } + } + public TransformableComplexTypeDefinition copy() { TransformableComplexTypeDefinition copy = new TransformableComplexTypeDefinition(delegate()); copy.overrides.putAll(overrides); @@ -180,7 +229,8 @@ public TransformableComplexTypeDefinition copy() { } - public static class ObjectClass extends TransformableComplexTypeDefinition implements ObjectClassTypeDefinitionDelegator { + public static class ObjectClass extends TransformableComplexTypeDefinition + implements ObjectClassTypeDefinitionDelegator, PartiallyMutableComplexTypeDefinition.ObjectClassDefinition { private static final long serialVersionUID = 1L; @@ -194,8 +244,8 @@ public ObjectClassComplexTypeDefinition delegate() { } @Override - public ObjectClassComplexTypeDefinition clone() { - throw new UnsupportedOperationException(); + public MutableObjectClassComplexTypeDefinition clone() { + return copy(); } @Override @@ -205,16 +255,41 @@ public ObjectClass copy() { @Override public MutableObjectClassComplexTypeDefinition toMutable() { - throw new UnsupportedOperationException(); + return this; } - @SuppressWarnings("rawtypes") @Override public @NotNull ObjectClassComplexTypeDefinition deepClone(Map ctdMap, Map onThisPath, Consumer postCloneAction) { - throw new UnsupportedOperationException(); + return (ObjectClassComplexTypeDefinition) super.deepClone(ctdMap, onThisPath, postCloneAction); } } + @SuppressWarnings("rawtypes") + private static class Removed extends TransformableItemDefinition { + + private static final long serialVersionUID = 1L; + + protected Removed() { + super(null); + } + + @Override + protected ItemDefinition publicView() { + return null; + } + + + @Override + public String toString() { + return "REMOVED"; + } + + @Override + protected TransformableItemDefinition copy() { + return this; + } + } + } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableContainerDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableContainerDefinition.java index 38a2d452ec2..f1b1d4843ee 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableContainerDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableContainerDefinition.java @@ -8,7 +8,11 @@ package com.evolveum.midpoint.model.impl.schema.transform; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + import javax.xml.namespace.QName; import org.jetbrains.annotations.NotNull; @@ -21,13 +25,13 @@ 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.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.deleg.ContainerDefinitionDelegator; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.processor.deleg.AttributeContainerDefinitionDelegator; @@ -35,10 +39,9 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType; import com.google.common.base.Preconditions; -public class TransformableContainerDefinition extends TransformableItemDefinition, PrismContainerDefinition> implements ContainerDefinitionDelegator { - - - +public class TransformableContainerDefinition + extends TransformableItemDefinition, PrismContainerDefinition> + implements ContainerDefinitionDelegator, PartiallyMutableItemDefinition.Container { private static final long serialVersionUID = 1L; @@ -56,6 +59,7 @@ public TransformableContainerDefinition(PrismContainerDefinition delegate, Co + @SuppressWarnings({ "rawtypes", "unchecked" }) public static TransformableContainerDefinition of(PrismContainerDefinition originalItem) { if (originalItem instanceof TransformableContainerDefinition) { return (TransformableContainerDefinition) originalItem; @@ -72,6 +76,7 @@ public static TransformableContainerDefinition of(P return complexTypeDefinition.getTypeName(); } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public Class getTypeClass() { return complexTypeDefinition.getTypeClass(); @@ -122,15 +127,8 @@ public ID findLocalItemDefinition(@NotNull QName nam public ID findNamedItemDefinition(@NotNull QName firstName, @NotNull ItemPath rest, @NotNull Class clazz) { if (complexTypeDefinition != null) { - ID maybe = complexTypeDefinition.findNamedItemDefinition(firstName, rest, clazz); - if (maybe != null) { - return maybe; - } + return complexTypeDefinition.findNamedItemDefinition(firstName, rest, clazz); } - if (complexTypeDefinition != null && complexTypeDefinition.isXsdAnyMarker()) { - throw new UnsupportedOperationException("Not implemented yet"); - } - return null; } @@ -175,6 +173,13 @@ public Class getCompileTimeClass() { public TransformableComplexTypeDefinition getComplexTypeDefinition() { return complexTypeDefinition; } + @Override + public boolean isEmpty() { + if (complexTypeDefinition == null) { + return true; + } + return complexTypeDefinition.isEmpty(); + } @Override public String getDefaultNamespace() { @@ -217,14 +222,33 @@ public ContainerDelta createEmptyDelta(ItemPath path) { @Override public @NotNull PrismContainerDefinition clone() { - throw new UnsupportedOperationException("Clone not supported"); + return new TransformableContainerDefinition<>(this, complexTypeDefinition); + } + + @Override + public ItemDefinition> deepClone(boolean ultraDeep, Consumer postCloneAction) { + return deepClone(new HashMap<>(), new HashMap<>(), postCloneAction); + } + + @Override + public ItemDefinition> deepClone(Map ctdMap, + Map onThisPath, Consumer postCloneAction) { + ComplexTypeDefinition ctd = getComplexTypeDefinition(); + if (ctd != null) { + ctd = ctd.deepClone(ctdMap, onThisPath, postCloneAction); + } + return copy(ctd); + } + + protected TransformableContainerDefinition copy(ComplexTypeDefinition def) { + return new TransformableContainerDefinition<>(this, def); } @Override public PrismContainerDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { TransformableComplexTypeDefinition typeDefCopy = complexTypeDefinition.copy(); typeDefCopy.replaceDefinition(itemName, newDefinition); - return new TransformableContainerDefinition<>(this, typeDefCopy); + return copy(typeDefCopy); } @Override @@ -235,7 +259,7 @@ public void replaceDefinition(QName itemName, ItemDefinition newDefinition) { @Override public MutablePrismContainerDefinition toMutable() { - return null; + return this; } @Override @@ -249,6 +273,16 @@ public void freeze() { // FIXME: Intentional NOOP } + @Override + public PrismContainer instantiate() throws SchemaException { + return instantiate(getItemName()); + } + + @NotNull + @Override + public PrismContainer instantiate(QName elementName) throws SchemaException { + return this.getPrismContext().itemFactory().createContainer(elementName, this); + } @Override protected PrismContainerDefinition publicView() { @@ -278,12 +312,17 @@ public static class AttributeContainer extends TransformableContainerDefinition< /** * */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; protected AttributeContainer(ResourceAttributeContainerDefinition delegate) { super(delegate); } + public AttributeContainer(AttributeContainer copy, + TransformableComplexTypeDefinition typeDef) { + super(copy, typeDef); + } + @Override public ResourceAttributeContainerDefinition delegate() { return (ResourceAttributeContainerDefinition) super.delegate(); @@ -300,10 +339,34 @@ public TransformableComplexTypeDefinition.ObjectClass getComplexTypeDefinition() return (TransformableComplexTypeDefinition.ObjectClass) super.getComplexTypeDefinition(); } + @Override + public PrismContainerDefinition cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) { + TransformableComplexTypeDefinition typeDefCopy = complexTypeDefinition.copy(); + typeDefCopy.replaceDefinition(itemName, newDefinition); + return new AttributeContainer(this, typeDefCopy); + } + @Override public @NotNull ResourceAttributeContainerDefinition clone() { throw new UnsupportedOperationException(); } + @Override + public ResourceAttributeContainer instantiate() { + return instantiate(getItemName()); + } + + @Override + public @NotNull ResourceAttributeContainer instantiate(QName elementName) { + ResourceAttributeContainer deleg = delegate().instantiate(elementName); + deleg.setDefinition(this); + return deleg; + } + + } + + @Override + protected TransformableContainerDefinition copy() { + return new TransformableContainerDefinition<>(this); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableItemDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableItemDefinition.java index 5f3400f99da..4848b4d34bc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableItemDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableItemDefinition.java @@ -1,8 +1,16 @@ package com.evolveum.midpoint.model.impl.schema.transform; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.ComplexTypeDefinition; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.ItemProcessing; +import com.evolveum.midpoint.prism.MutableItemDefinition; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismItemAccessDefinition; @@ -21,12 +29,31 @@ * and European Union Public License. See LICENSE file for details. */ -public abstract class TransformableItemDefinition,D extends ItemDefinition> implements ItemDefinitionDelegator, PrismItemAccessDefinition.Mutable { +public abstract class TransformableItemDefinition,D extends ItemDefinition> + implements ItemDefinitionDelegator, PrismItemAccessDefinition.Mutable, PartiallyMutableItemDefinition { private static final long serialVersionUID = 1L; private D delegate; + + private boolean allowAdd = true; + private boolean allowRead = true; + private boolean allowModify = true; + + private String displayName; + + private String help; + private Integer displayOrder; + private Boolean emphasized; + private Boolean deprecated; + private Boolean experimental; + + private Integer minOccurs; + private Integer maxOccurs; + private ItemProcessing processing; + private PrismReferenceValue valueEnumerationRef; + protected TransformableItemDefinition(D delegate) { if (delegate instanceof TransformableItemDefinition) { // CopyOf constructor @@ -36,27 +63,63 @@ protected TransformableItemDefinition(D delegate) { this.allowAdd = copyOf.allowAdd; this.allowRead = copyOf.allowRead; this.allowModify = copyOf.allowModify; - this.template = copyOf.template; this.minOccurs = copyOf.minOccurs; this.maxOccurs = copyOf.maxOccurs; this.processing = copyOf.processing; + + this.help = copyOf.help; + this.displayOrder = copyOf.displayOrder; + this.emphasized = copyOf.emphasized; + this.deprecated = copyOf.deprecated; + this.experimental = copyOf.experimental; + this.valueEnumerationRef = copyOf.valueEnumerationRef; this.delegate = copyOf.delegate(); } else { this.delegate = delegate; } + } - private boolean allowAdd = true; - private boolean allowRead = true; - private boolean allowModify = true; - private ObjectTemplateItemDefinitionType template; - private Integer minOccurs; - private Integer maxOccurs; - private ItemProcessing processing; - private PrismReferenceValue valueEnumerationRef; + @SuppressWarnings("unchecked") + public static > TransformableItemDefinition from(ID originalItem) { + if (originalItem == null) { + return null; + } + if (originalItem instanceof TransformableItemDefinition) { + return ((TransformableItemDefinition) originalItem); + } + if (originalItem instanceof PrismPropertyDefinition) { + return (TransformableItemDefinition) TransformablePropertyDefinition.of((PrismPropertyDefinition) originalItem); + } + if (originalItem instanceof PrismReferenceDefinition) { + return (TransformableItemDefinition) TransformableReferenceDefinition.of((PrismReferenceDefinition) originalItem); + } + if (originalItem instanceof PrismObjectDefinition) { + return (TransformableItemDefinition) TransformableObjectDefinition.of((PrismObjectDefinition) originalItem); + } + if (originalItem instanceof PrismContainerDefinition) { + return (TransformableItemDefinition) TransformableContainerDefinition.of((PrismContainerDefinition) originalItem); + } + throw new IllegalArgumentException("Unsupported item definition type " + originalItem.getClass()); + } + + + public static > ID publicFrom(ID definition) { + TransformableItemDefinition accessDef = from(definition); + if (accessDef != null) { + return accessDef.publicView(); + } + return null; + } + + + public static boolean isMutableAccess(ItemDefinition definition) { + return definition instanceof TransformableItemDefinition; + } + @Override public D delegate() { @@ -79,36 +142,39 @@ public boolean canRead() { } @Override - public void setCanAdd(boolean val) { - allowAdd = val; + public int getMinOccurs() { + return preferLocal(minOccurs, delegate().getMinOccurs()); } + @Override - public void setCanModify(boolean val) { - allowModify = val; + public int getMaxOccurs() { + return preferLocal(maxOccurs, delegate.getMaxOccurs()); } + @Override - public void setCanRead(boolean val) { - allowRead = val; + public ItemProcessing getProcessing() { + return preferLocal(processing, delegate.getProcessing()); } @Override - public int getMinOccurs() { - return preferLocal(minOccurs, delegate().getMinOccurs()); + public void setCanAdd(boolean val) { + allowAdd = val; } @Override - public int getMaxOccurs() { - return preferLocal(maxOccurs, delegate.getMaxOccurs()); + public void setCanModify(boolean val) { + allowModify = val; } @Override - public ItemProcessing getProcessing() { - return preferLocal(processing, delegate.getProcessing()); + public void setCanRead(boolean val) { + allowRead = val; } + @SuppressWarnings("unchecked") protected > ID apply(ID originalItem) { if (delegate == null) { @@ -117,37 +183,6 @@ protected > ID apply(ID originalItem) { return (ID) publicView(); } - @SuppressWarnings("unchecked") - public static > TransformableItemDefinition from(ID originalItem) { - if (originalItem == null) { - return null; - } - if (originalItem instanceof TransformableItemDefinition) { - return ((TransformableItemDefinition) originalItem); - } - if (originalItem instanceof PrismPropertyDefinition) { - return (TransformableItemDefinition) TransformablePropertyDefinition.of((PrismPropertyDefinition) originalItem); - } - if (originalItem instanceof PrismReferenceDefinition) { - return (TransformableItemDefinition) TransformableReferenceDefinition.of((PrismReferenceDefinition) originalItem); - } - if (originalItem instanceof PrismObjectDefinition) { - return (TransformableItemDefinition) TransformableObjectDefinition.of((PrismObjectDefinition) originalItem); - } - if (originalItem instanceof PrismContainerDefinition) { - return (TransformableItemDefinition) TransformableContainerDefinition.of((PrismContainerDefinition) originalItem); - } - throw new IllegalArgumentException("Unsupported item definition type " + originalItem.getClass()); - } - - public static > ID publicFrom(ID definition) { - TransformableItemDefinition accessDef = from(definition); - if (accessDef != null) { - return accessDef.publicView(); - } - return null; - } - protected abstract D publicView(); @Override @@ -172,70 +207,123 @@ public void revive(PrismContext prismContext) { delegate.revive(prismContext); } - public static boolean isMutableAccess(ItemDefinition definition) { - return definition instanceof TransformableItemDefinition; - } - public static TransformableItemDefinition access(ItemDefinition itemDef) { Preconditions.checkArgument(itemDef instanceof TransformableItemDefinition, "Definition must be %s", TransformableItemDefinition.class.getName()); return (TransformableItemDefinition) itemDef; } - public void applyTemplate(ObjectTemplateItemDefinitionType templateItemDefType) { - this.template = templateItemDefType; + public void applyTemplate(ObjectTemplateItemDefinitionType apply) { + if (apply.getDisplayName() != null) { + this.setDisplayName(apply.getDisplayName()); + } + if (apply.getHelp() != null) { + this.setHelp(apply.getHelp()); + } + if (apply.getDisplayOrder() != null) { + this.setDisplayOrder(apply.getDisplayOrder()); + } + if (apply.isEmphasized() != null) { + this.setEmphasized(apply.isEmphasized()); + } + if (apply.isDeprecated() != null) { + this.setDeprecated(apply.isDeprecated()); + } + if (apply.isExperimental() != null) { + this.setExperimental(apply.isExperimental()); + } } @Override public String getDisplayName() { - return preferLocal(template.getDisplayName(), delegate().getDisplayName()); + return preferLocal(this.displayName, delegate().getDisplayName()); } @Override public String getHelp() { - return preferLocal(template.getHelp(), delegate().getHelp()); + return preferLocal(this.help, delegate().getHelp()); } @Override public Integer getDisplayOrder() { - return preferLocal(template.getDisplayOrder(), delegate().getDisplayOrder()); + return preferLocal(this.displayOrder, delegate().getDisplayOrder()); } @Override public boolean isEmphasized() { - return preferLocal(template.isEmphasized(), delegate().isEmphasized()); + return preferLocal(this.emphasized, delegate().isEmphasized()); } @Override public boolean isDeprecated() { - return preferLocal(template.isDeprecated(), delegate().isDeprecated()); + return preferLocal(this.deprecated, delegate().isDeprecated()); } @Override public boolean isExperimental() { - return preferLocal(template.isExperimental(), delegate().isExperimental()); + return preferLocal(this.experimental, delegate().isExperimental()); } private T preferLocal(T fromTemplate, T fromDelegate) { return fromTemplate != null ? fromTemplate : fromDelegate; } - public void setMinOccurs(Integer value) { + @Override + public void setMinOccurs(int value) { this.minOccurs = value; } - public void setMaxOccurs(Integer value) { + @Override + public void setMaxOccurs(int value) { this.maxOccurs = value; } + @Override public void setValueEnumerationRef(PrismReferenceValue valueEnumerationRVal) { this.valueEnumerationRef = valueEnumerationRVal; } + @Override + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + + @Override + public void setHelp(String help) { + this.help = help; + } + + + @Override + public void setDisplayOrder(Integer displayOrder) { + this.displayOrder = displayOrder; + } + + + @Override + public void setEmphasized(boolean emphasized) { + this.emphasized = emphasized; + } + + + @Override + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + + @Override + public void setExperimental(boolean experimental) { + this.experimental = experimental; + } + + @Override public PrismReferenceValue getValueEnumerationRef() { return preferLocal(valueEnumerationRef, delegate().getValueEnumerationRef()); } + @Override public void setProcessing(ItemProcessing itemProcessing) { this.processing = itemProcessing; } @@ -246,6 +334,24 @@ static void apply(ItemDefinition overriden, ItemDefinition originalItem) { } } + @Override + public MutableItemDefinition toMutable() { + return this; + } + + @Override + public ItemDefinition deepClone(boolean ultraDeep, Consumer postCloneAction) { + return deepClone(new HashMap<>(), new HashMap<>(), postCloneAction); + } + + @Override + public ItemDefinition deepClone(Map ctdMap, + Map onThisPath, Consumer postCloneAction) { + return copy(); + } + + protected abstract TransformableItemDefinition copy(); + @Override public String toString() { return "Transformable:" + delegate.toString(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableObjectDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableObjectDefinition.java index 746d2d90a14..8e24ee751c7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableObjectDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableObjectDefinition.java @@ -22,7 +22,8 @@ import com.evolveum.midpoint.prism.deleg.ObjectDefinitionDelegator; import com.evolveum.midpoint.util.exception.SchemaException; -public class TransformableObjectDefinition extends TransformableContainerDefinition implements ObjectDefinitionDelegator { +public class TransformableObjectDefinition extends TransformableContainerDefinition + implements ObjectDefinitionDelegator, MutablePrismObjectDefinition { public TransformableObjectDefinition(PrismObjectDefinition delegate) { super(delegate); @@ -48,7 +49,7 @@ protected PrismObjectDefinition publicView() { @Override public MutablePrismObjectDefinition toMutable() { - throw new UnsupportedOperationException(); + return this; } @Override @@ -65,21 +66,23 @@ public PrismObjectDefinition cloneWithReplacedDefinition(QName itemName, Item @Override public PrismObjectDefinition deepClone(boolean ultraDeep, Consumer postCloneAction) { - throw new UnsupportedOperationException(); + return (PrismObjectDefinition) super.deepClone(ultraDeep, postCloneAction); + } + + @Override + protected TransformableContainerDefinition copy(ComplexTypeDefinition def) { + return new TransformableObjectDefinition<>(this, def); } - public static PrismObjectDefinition of(PrismObject object) { - PrismObjectDefinition origDef = object.getDefinition(); - if (origDef instanceof TransformableObjectDefinition) { - return origDef; - } - TransformableObjectDefinition newDef = TransformableObjectDefinition.of(origDef); - try { - object.applyDefinition(newDef, true); - } catch (SchemaException e) { - throw new IllegalStateException("Can not replace definition for transformable one", e); - } - return newDef; + @Override + public PrismObject instantiate() throws SchemaException { + return instantiate(getItemName()); + } + + @Override + public @NotNull PrismObject instantiate(QName name) throws SchemaException { + // TODO Auto-generated method stub + return getPrismContext().itemFactory().createObject(name, this); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformablePropertyDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformablePropertyDefinition.java index 927ffe862b8..c9b7cfa97eb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformablePropertyDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformablePropertyDefinition.java @@ -7,8 +7,16 @@ package com.evolveum.midpoint.model.impl.schema.transform; +import java.util.Map; +import java.util.function.Consumer; + +import javax.xml.namespace.QName; + import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; +import com.evolveum.midpoint.common.refinery.deleg.RefinedAttributeDefinitionDelegator; +import com.evolveum.midpoint.prism.ComplexTypeDefinition; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.MutablePrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismContext; @@ -19,7 +27,8 @@ import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.processor.deleg.AttributeDefinitionDelegator; -public class TransformablePropertyDefinition extends TransformableItemDefinition, PrismPropertyDefinition> implements PropertyDefinitionDelegator { +public class TransformablePropertyDefinition extends TransformableItemDefinition, PrismPropertyDefinition> + implements PropertyDefinitionDelegator, PartiallyMutableItemDefinition.Property { private static final long serialVersionUID = 1L; @@ -32,11 +41,13 @@ public static PrismPropertyDefinition of(PrismPropertyDefinition origi if (originalItem instanceof TransformablePropertyDefinition) { return originalItem; } + if (originalItem instanceof RefinedAttributeDefinition) { + return new RefinedAttribute<>(originalItem); + } if (originalItem instanceof ResourceAttributeDefinition) { return new ResourceAttribute<>(originalItem); } - return new TransformablePropertyDefinition<>(originalItem); } @@ -60,9 +71,24 @@ public void freeze() { throw new UnsupportedOperationException(); } + @Override + protected TransformablePropertyDefinition copy() { + return new TransformablePropertyDefinition<>(this); + } + @Override public MutablePrismPropertyDefinition toMutable() { - throw new UnsupportedOperationException(); + return this; + } + + @Override + public @NotNull PrismProperty instantiate() { + return instantiate(getItemName()); + } + + @Override + public @NotNull PrismProperty instantiate(QName name) { + return getPrismContext().itemFactory().createProperty(name, this); } @SuppressWarnings("unchecked") @@ -71,12 +97,14 @@ protected > ID apply(ID originalItem) { return (ID) publicView(); } + + @Override protected PrismPropertyDefinition publicView() { return this; } - public static class ResourceAttribute extends TransformablePropertyDefinition implements AttributeDefinitionDelegator { + public static class ResourceAttribute extends TransformablePropertyDefinition implements AttributeDefinitionDelegator, PartiallyMutableItemDefinition.Attribute { private static final long serialVersionUID = 1L; public ResourceAttribute(PrismPropertyDefinition delegate) { @@ -90,13 +118,85 @@ public ResourceAttributeDefinition delegate() { @Override public @NotNull ResourceAttributeDefinition clone() { - throw new UnsupportedOperationException(); + return copy(); + } + + @Override + protected ResourceAttribute copy() { + return new ResourceAttribute<>(this); } @Override public MutableResourceAttributeDefinition toMutable() { + return this; + } + + @Override + public @NotNull com.evolveum.midpoint.schema.processor.ResourceAttribute instantiate() { + return instantiate(getItemName()); + } + + @Override + public @NotNull com.evolveum.midpoint.schema.processor.ResourceAttribute instantiate(QName name) { + var deleg = delegate().instantiate(name); + deleg.setDefinition(this); + return deleg; + } + } + + public static class RefinedAttribute extends ResourceAttribute implements RefinedAttributeDefinitionDelegator { + + public RefinedAttribute(PrismPropertyDefinition delegate) { + super(delegate); + } + + @Override + public RefinedAttributeDefinition delegate() { + return (RefinedAttributeDefinition) super.delegate(); + } + + @Override + public @NotNull RefinedAttributeDefinition clone() { + return copy(); + } + + @Override + protected RefinedAttribute copy() { + return new RefinedAttribute<>(this); + } + + @Override + public RefinedAttributeDefinition deepClone(Map ctdMap, + Map onThisPath, Consumer postCloneAction) { throw new UnsupportedOperationException(); } + + @Override + public boolean canAdd() { + return delegate().canAdd(); + } + + @Override + public boolean canModify() { + return delegate().canModify(); + } + + @Override + public boolean canRead() { + return delegate().canRead(); + } + + @Override + public @NotNull com.evolveum.midpoint.schema.processor.ResourceAttribute instantiate() { + return instantiate(getItemName()); + } + + @Override + public @NotNull com.evolveum.midpoint.schema.processor.ResourceAttribute instantiate(QName name) { + var deleg = delegate().instantiate(name); + deleg.setDefinition(this); + return deleg; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableReferenceDefinition.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableReferenceDefinition.java index 5925f16d243..15f31f5c68e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableReferenceDefinition.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/schema/transform/TransformableReferenceDefinition.java @@ -7,15 +7,17 @@ package com.evolveum.midpoint.model.impl.schema.transform; +import javax.xml.namespace.QName; + import org.jetbrains.annotations.NotNull; -import com.evolveum.midpoint.prism.MutableItemDefinition; -import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.MutablePrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.deleg.ReferenceDefinitionDelegator; -public class TransformableReferenceDefinition extends TransformableItemDefinition implements ReferenceDefinitionDelegator { +public class TransformableReferenceDefinition extends TransformableItemDefinition + implements ReferenceDefinitionDelegator, PartiallyMutableItemDefinition.Reference { private static final long serialVersionUID = 1L; @@ -33,17 +35,27 @@ protected PrismReferenceDefinition publicView() { } @Override - public void revive(PrismContext prismContext) { + public MutablePrismReferenceDefinition toMutable() { + return this; + } + @Override + public @NotNull PrismReference instantiate() { + return instantiate(getItemName()); } @Override - public MutableItemDefinition toMutable() { - throw new UnsupportedOperationException(); + public @NotNull PrismReference instantiate(QName name) { + return getPrismContext().itemFactory().createReference(name, this); } @Override public @NotNull PrismReferenceDefinition clone() { - throw new UnsupportedOperationException(); + return copy(); + } + + @Override + protected TransformableReferenceDefinition copy() { + return new TransformableReferenceDefinition(this); } }