Skip to content

Commit

Permalink
Implement associations reading in UCF
Browse files Browse the repository at this point in the history
Association definitions are now correctly parsed from ConnId schema
to midPoint schema (although not serialized to XSD and read back from
it, yet). The RawShadowAssociationDefinition was created, and
ShadowAssociationDefinition adapted. However, association classes are
still not present in ConnId nor in midPoint - it looks like we will need
them in near future.

Association values are read from ConnId objects and converted to (newly
created) ShadowAssociationValue helper objects.

Work in progress. But the reading at UCF level seems to work.
  • Loading branch information
mederly committed Mar 10, 2024
1 parent 886e246 commit e2a8f1f
Show file tree
Hide file tree
Showing 47 changed files with 1,882 additions and 924 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,9 @@ public boolean hasRefinements() {
public @NotNull LayerType getCurrentLayer() {
return getRefinedAttributeDefinition().getCurrentLayer();
}

@Override
public void shortDump(StringBuilder sb) {
getRefinedAttributeDefinition().shortDump(sb);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,11 @@ public static String debugDump(int indent, LayerType layer, AbstractResourceObje
sb.append(rAttrDef.debugDump(indent + 1, layer));
}
sb.append("\n");
for (ShadowAssociationDefinition assocDef : _this.getAssociationDefinitions()) {
sb.append("\n");
sb.append(assocDef.debugDump(indent + 1));
}
sb.append("\n");
DebugUtil.debugDumpWithLabel(sb, "Expanded definition bean", _this.getDefinitionBean(), indent + 1);
_this.addDebugDumpTrailer(sb, indent);
return sb.toString();
Expand Down Expand Up @@ -806,7 +811,7 @@ public void validate() throws SchemaException {
return definitionBean;
}

void addAssociationDefinition(@NotNull ShadowAssociationDefinition associationDef) {
public void addAssociationDefinition(@NotNull ShadowAssociationDefinition associationDef) {
checkMutable();
associationDefinitions.add(associationDef);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ default <T> ResourceAttributeDefinition<T> findAttributeDefinitionRequired(
throws SchemaException {
return MiscUtil.requireNonNull(
findAttributeDefinition(name),
() -> new SchemaException("no definition of attribute " + name + " in " + this + contextSupplier.get()));
() -> new SchemaException("No definition of attribute " + name + " in " + this + contextSupplier.get()));
}

/**
Expand All @@ -98,7 +98,7 @@ default ResourceAttributeDefinition<?> findAttributeDefinitionStrictlyRequired(
@NotNull QName name, @NotNull Supplier<String> contextSupplier) {
return MiscUtil.requireNonNull(
findAttributeDefinition(name),
() -> new IllegalStateException("no definition of attribute " + name + " in " + this + contextSupplier.get()));
() -> new IllegalStateException("No definition of attribute " + name + " in " + this + contextSupplier.get()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
* TODO consider removing
*/
public interface MutableRawResourceAttributeDefinition<T>
extends MutablePrismPropertyDefinition<T> {

void setReturnedByDefault(Boolean returnedByDefault);
extends ResourceItemUcfDefinition.Mutable,
ResourceItemPrismDefinition.Mutable,
MutablePrismPropertyDefinition<T> {

void setNativeAttributeName(String nativeAttributeName);

void setFrameworkAttributeName(String frameworkAttributeName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public interface MutableResourceObjectClassDefinition extends ResourceObjectClas

void add(ItemDefinition<?> definition);

void addAssociationDefinition(ShadowAssociationDefinition definition);

void addPrimaryIdentifierName(QName name);

void addSecondaryIdentifierName(QName name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.evolveum.midpoint.prism.DeepCloneOperation;
import com.evolveum.midpoint.prism.ItemProcessing;
import com.evolveum.midpoint.prism.MutablePrismPropertyDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.normalization.Normalizer;
import com.evolveum.midpoint.util.DebugUtil;
Expand All @@ -35,7 +36,12 @@
*/
public class RawResourceAttributeDefinition<T>
extends PrismPropertyDefinitionImpl<T>
implements MutableRawResourceAttributeDefinition<T>, ResourceAttributeDefinition<T> {
implements
MutableRawResourceAttributeDefinition<T>,
ResourceItemUcfDefinition.Delegable,
ResourceItemUcfDefinition.Mutable.Delegable,
MutablePrismPropertyDefinition<T>,
ResourceAttributeDefinition<T> {

@Serial private static final long serialVersionUID = -1756347754109326906L;

Expand All @@ -50,9 +56,7 @@ public class RawResourceAttributeDefinition<T>
*/
private static final LayerType DEFAULT_LAYER = LayerType.MODEL;

private String nativeAttributeName;
private String frameworkAttributeName;
private Boolean returnedByDefault;
@NotNull private final ResourceItemUcfDefinitionData ucfData = new ResourceItemUcfDefinitionData();

RawResourceAttributeDefinition(QName elementName, QName typeName) {
this(elementName, typeName, DEFAULT_LAYER);
Expand All @@ -63,6 +67,11 @@ private RawResourceAttributeDefinition(QName elementName, QName typeName, @NotNu
this.currentLayer = currentLayer;
}

@Override
public ResourceItemUcfDefinitionData ucfData() {
return ucfData;
}

@NotNull
@Override
public ResourceAttribute<T> instantiate() {
Expand All @@ -75,41 +84,11 @@ public ResourceAttribute<T> instantiate(QName name) {
return new ResourceAttributeImpl<>(name, this);
}

public Boolean getReturnedByDefault() {
return returnedByDefault;
}

@Override
public void setReturnedByDefault(Boolean returnedByDefault) {
checkMutable();
this.returnedByDefault = returnedByDefault;
}

public String getNativeAttributeName() {
return nativeAttributeName;
}

@Override
public void setNativeAttributeName(String nativeAttributeName) {
checkMutable();
this.nativeAttributeName = nativeAttributeName;
}

public String getFrameworkAttributeName() {
return frameworkAttributeName;
}

@Override
public boolean hasRefinements() {
return false;
}

@Override
public void setFrameworkAttributeName(String frameworkAttributeName) {
checkMutable();
this.frameworkAttributeName = frameworkAttributeName;
}

//region Dummy methods

@Override
Expand Down Expand Up @@ -183,9 +162,9 @@ public Boolean getReadReplaceMode() {
return this;
} else {
RawResourceAttributeDefinition<T> newDef = new RawResourceAttributeDefinition<>(getItemName(), getTypeName(), layer);
newDef.setNativeAttributeName(nativeAttributeName);
newDef.setFrameworkAttributeName(frameworkAttributeName);
newDef.setReturnedByDefault(returnedByDefault);
newDef.setNativeAttributeName(getNativeAttributeName());
newDef.setFrameworkAttributeName(getFrameworkAttributeName());
newDef.setReturnedByDefault(getReturnedByDefault());
newDef.freeze(); // TODO ok?
return newDef;
}
Expand Down Expand Up @@ -287,7 +266,7 @@ public boolean isDisplayNameAttribute() {

public String getDisplayName() {
// Not sure why, but this is the way it always was.
return MiscUtil.getFirstNonNull(displayName, nativeAttributeName);
return MiscUtil.getFirstNonNull(displayName, getNativeAttributeName());
}

@Override
Expand Down Expand Up @@ -330,9 +309,9 @@ private static <T> RawResourceAttributeDefinition<T> copyFrom(RawResourceAttribu

private void copyDefinitionDataFrom(ResourceAttributeDefinition<T> source) {
super.copyDefinitionDataFrom(source);
nativeAttributeName = source.getNativeAttributeName();
frameworkAttributeName = source.getFrameworkAttributeName();
returnedByDefault = source.getReturnedByDefault();
setNativeAttributeName(source.getNativeAttributeName());
setFrameworkAttributeName(source.getFrameworkAttributeName());
setReturnedByDefault(source.getReturnedByDefault());
}

@Override
Expand All @@ -341,27 +320,28 @@ public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
RawResourceAttributeDefinition<?> that = (RawResourceAttributeDefinition<?>) o;
return Objects.equals(nativeAttributeName, that.nativeAttributeName)
&& Objects.equals(frameworkAttributeName, that.frameworkAttributeName)
&& Objects.equals(returnedByDefault, that.returnedByDefault);
return Objects.equals(ucfData, that.ucfData);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), nativeAttributeName, frameworkAttributeName, returnedByDefault);
return Objects.hash(super.hashCode(), ucfData);
}

@Override
protected void extendToString(StringBuilder sb) {
super.extendToString(sb);
if (getNativeAttributeName()!=null) {
String nativeAttributeName = getNativeAttributeName();
if (nativeAttributeName != null) {
sb.append(" native=");
sb.append(getNativeAttributeName());
sb.append(nativeAttributeName);
}
if (getFrameworkAttributeName()!=null) {
String frameworkAttributeName = getFrameworkAttributeName();
if (frameworkAttributeName !=null) {
sb.append(" framework=");
sb.append(getFrameworkAttributeName());
sb.append(frameworkAttributeName);
}
var returnedByDefault = getReturnedByDefault();
if (returnedByDefault != null) {
sb.append(" returnedByDefault=");
sb.append(returnedByDefault);
Expand All @@ -388,4 +368,9 @@ public String debugDump(int indent, LayerType layer) {
DebugUtil.debugDumpWithLabelToString(sb, "attribute " + getItemName().getLocalPart(), this, indent);
return sb.toString();
}

@Override
public void shortDump(StringBuilder sb) {
sb.append(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2010-2015 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.processor;

import java.io.Serial;
import javax.xml.namespace.QName;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.AbstractFreezable;
import com.evolveum.midpoint.prism.impl.ItemDefinitionImpl;

/**
* "Raw" definition of a shadow association, i.e. the one obtained from the connector.
*
* To be used _solely_ within {@link ShadowAssociationDefinition}.
*
* Unlike {@link RawResourceAttributeDefinition}, we do not extend {@link ItemDefinitionImpl} here.
* This is because there are a lot of its features we don't need here. This decision may be reconsidered.
*/
public class RawShadowAssociationDefinition
extends AbstractFreezable
implements ResourceItemUcfDefinition.Delegable, ResourceItemUcfDefinition.Mutable.Delegable,
ResourceItemPrismDefinition, ResourceItemPrismDefinition.Mutable.Delegable {

@Serial private static final long serialVersionUID = 1259898180994611076L;

/** MidPoint name. */
@NotNull private final QName itemName;

@NotNull private final ResourceItemUcfDefinitionData ucfData = new ResourceItemUcfDefinitionData();

@NotNull private final ResourceItemPrismDefinitionData prismData = new ResourceItemPrismDefinitionData();

public RawShadowAssociationDefinition(@NotNull QName itemName) {
this.itemName = itemName;
}

@Override
public ResourceItemUcfDefinitionData ucfData() {
return ucfData;
}

@Override
public ResourceItemPrismDefinitionData prismData() {
return prismData;
}

public @NotNull QName getItemName() {
return itemName;
}

@Override
public void shortDump(StringBuilder sb) {
sb.append(this);
}

@Override
public String toString() {
return "rawSAD: " + itemName.getLocalPart() + prismData + ucfData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
import static com.evolveum.midpoint.schema.util.ResourceObjectTypeDefinitionTypeUtil.SuperReference;
import static com.evolveum.midpoint.util.DebugUtil.lazy;
import static com.evolveum.midpoint.util.MiscUtil.configCheck;
import static com.evolveum.midpoint.util.MiscUtil.stateCheck;

import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.util.QNameUtil;

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

Expand All @@ -34,6 +36,7 @@
import com.evolveum.midpoint.schema.merger.objdef.ResourceObjectTypeDefinitionMergeOperation;
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
Expand Down Expand Up @@ -127,6 +130,7 @@ class RefinedResourceSchemaParser {
// Associations refer to object types, attributes, and delineation, so they must come after them.
parseAssociationTypesDefinitions();
parseLegacyAssociations();
parseNativeAssociations();

completeSchema.freeze();

Expand Down Expand Up @@ -286,6 +290,14 @@ private void parseLegacyAssociations() throws ConfigurationException {
}
}

/** TEMPORARY CODE!!! TO BE REMOVED. */
private void parseNativeAssociations() {
for (ResourceObjectDefinition objectDef : completeSchema.getResourceObjectDefinitions()) {
new ResourceObjectDefinitionParser(objectDef)
.parseNativeAssociations();
}
}

/** These are associations from the {@link SchemaHandlingType#getAssociationType()} section. */
private void parseAssociationTypesDefinitions() throws ConfigurationException {
for (var assocTypeDefCI : schemaHandling.getAssociationTypes()) {
Expand Down Expand Up @@ -489,6 +501,18 @@ private void setupIdentifiers() {
}
}

/** TEMPORARY CODE!!! TO BE REMOVED. */
void parseNativeAssociations() {
var rawObjectClassDef = definition.getRawObjectClassDefinition();
for (var origAssocDef : rawObjectClassDef.getAssociationDefinitions()) {
stateCheck(origAssocDef.isRaw(), "Non-raw definition %s in %s", origAssocDef, rawObjectClassDef);
// TODO connect with the refinements
definition.addAssociationDefinition(
ShadowAssociationDefinition.fromRaw(
origAssocDef.getRawDefinitionRequired(), null));
}
}

/**
* Parses protected objects, delineation, and so on.
*/
Expand Down Expand Up @@ -642,8 +666,9 @@ void parse() throws ConfigurationException {

// Attaching to subject types
for (ResourceObjectTypeDefinition subjectTypeDef : subjectTypeDefinitions) {
// TODO connect to the raw definition, if one is present
var associationDef = ShadowAssociationDefinition.parseAssociationType(
typeDefinition, simulationDefinition, associationTypeDefinitionCI);
simulationDefinition.getLocalSubjectItemName(), typeDefinition, null, associationTypeDefinitionCI);
configCheck(!subjectTypeDef.containsAssociationDefinition(associationDef.getItemName()),
"Association %s already exists in %s in %s",
associationDef.getItemName(), subjectTypeDef, associationTypeDefinitionCI);
Expand Down Expand Up @@ -717,6 +742,7 @@ private class LegacyAssociationParser {
var associationTypeDefinition = ShadowAssociationTypeDefinition.parseLegacy(
associationDefCI, simulationDefinition, subjectTypeDefinition, objectTypeDefinitions);

// TODO check if raw definition is not present
return ShadowAssociationDefinition.parseLegacy(associationTypeDefinition, associationDefCI);
}

Expand Down

0 comments on commit e2a8f1f

Please sign in to comment.