Skip to content

Commit

Permalink
Fix associations in GUI
Browse files Browse the repository at this point in the history
Now they can be displayed and also managed (add/delete value).
  • Loading branch information
mederly committed Apr 23, 2024
1 parent 4971504 commit 17b242a
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import java.util.Collections;
import java.util.List;

import com.evolveum.midpoint.gui.api.prism.wrapper.*;
import com.evolveum.midpoint.gui.impl.prism.panel.PrismContainerPanel;
import com.evolveum.midpoint.schema.processor.*;
import com.evolveum.midpoint.gui.api.factory.wrapper.WrapperContext;

import com.evolveum.midpoint.gui.api.prism.wrapper.ItemWrapper;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.web.component.prism.ValueStatus;

Expand All @@ -23,15 +24,11 @@
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.prism.ItemStatus;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerWrapper;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismReferenceWrapper;
import com.evolveum.midpoint.gui.impl.prism.wrapper.ShadowAssociationWrapperImpl;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
Expand All @@ -53,14 +50,19 @@ public class ShadowAssociationWrapperFactoryImpl extends PrismContainerWrapperFa

@Override
public boolean match(ItemDefinition<?> def) {
return QNameUtil.match(def.getTypeName(), ShadowAssociationValueType.COMPLEX_TYPE);
return def instanceof ShadowAssociationDefinition;
}

@Override
public int getOrder() {
return 10;
}

@Override
public void registerWrapperPanel(PrismContainerWrapper<ShadowAssociationValueType> wrapper) {
getRegistry().registerWrapperPanel(ShadowAssociationValueType.COMPLEX_TYPE, PrismContainerPanel.class);
}

@Override
protected PrismContainerWrapper<ShadowAssociationValueType> createWrapperInternal(PrismContainerValueWrapper<?> parent, PrismContainer<ShadowAssociationValueType> childContainer,
ItemStatus status, WrapperContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ public boolean canRepresent(QName typeName) {
return QNameUtil.match(typeName, getTypeName());
}

// TODO do we really want to return e.g. inetOrgPerson as the type name for `attributes` and `associations` container?!
@Override
public @NotNull QName getTypeName() {
return objectDefinition.getTypeName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ public QName getMatchingRuleQName() {
.getMatchingRuleSafe(getMatchingRuleQName(), getTypeName());
}

@Override
public @NotNull QName getTypeName() {
return nativeDefinition.getTypeName();
}

@Override
public @NotNull Class<T> getTypeClass() {
// TODO cache this somehow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import java.util.Objects;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismContainerDefinition.PrismContainerDefinitionMutator;
import com.evolveum.midpoint.prism.annotation.ItemDiagramSpecification;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.AssociationsCapabilityType;
import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -50,7 +52,8 @@
*/
public class ShadowAssociationDefinitionImpl
extends ShadowItemDefinitionImpl<ShadowAssociation, ShadowAssociationValueType, NativeShadowAssociationDefinition, ResourceObjectAssociationType>
implements ShadowAssociationDefinition {
implements ShadowAssociationDefinition,
PrismContainerDefinitionMutator<ShadowAssociationValueType> {

@Serial private static final long serialVersionUID = 1L;

Expand Down Expand Up @@ -89,7 +92,7 @@ private ShadowAssociationDefinitionImpl(
super(layer, nativeDefinition, customizationBean, limitationsMap, accessOverride);
this.associationClassDefinition = associationClassDefinition;
this.associationTypeDefinition = associationTypeDefinition;
this.complexTypeDefinition = getComplexTypeDefinition();
this.complexTypeDefinition = createComplexTypeDefinition();
this.maxOccurs = maxOccurs;
}

Expand Down Expand Up @@ -189,6 +192,11 @@ private static SystemException alreadyChecked(ConfigurationException e) {
return SystemException.unexpected(e, "(object was already checked)");
}

@Override
public @NotNull QName getTypeName() {
return ShadowAssociationValueType.COMPLEX_TYPE;
}

private @NotNull ComplexTypeDefinition createComplexTypeDefinition() {
var genericDefinition = stateNonNull(
PrismContext.get().getSchemaRegistry().findComplexTypeDefinitionByType(ShadowAssociationValueType.COMPLEX_TYPE),
Expand Down Expand Up @@ -239,6 +247,10 @@ public int getMaxOccurs() {
}
}

@Override
public void setMinOccurs(int value) {
}

public void setMaxOccurs(int value) {
checkMutable();
maxOccurs = value;
Expand Down Expand Up @@ -343,10 +355,9 @@ public boolean canRepresent(@NotNull QName type) {
}

@Override
public @NotNull PrismContainerDefinition.PrismContainerDefinitionMutator<ShadowAssociationValueType> mutator() {
throw new UnsupportedOperationException(); // FIXME ... what about GUI?
// checkMutableOnExposing();
// return this;
public @NotNull PrismContainerDefinitionMutator<ShadowAssociationValueType> mutator() {
checkMutableOnExposing();
return this;
}

@Override
Expand Down Expand Up @@ -499,4 +510,179 @@ public int hashCode() {
public ItemCorrelatorDefinitionType getCorrelatorDefinition() {
return null; // Association cannot be used as a correlator - for now
}

// FIXME remove this eventually (after GUI stops setting maxOccurs on this definition)

@Override
public void setCompileTimeClass(Class<ShadowAssociationValueType> compileTimeClass) {
}

@Override
public PrismPropertyDefinition<?> createPropertyDefinition(QName name, QName propType, int minOccurs, int maxOccurs) {
throw new UnsupportedOperationException();
}

@Override
public PrismPropertyDefinition<?> createPropertyDefinition(QName name, QName propType) {
throw new UnsupportedOperationException();
}

@Override
public PrismPropertyDefinition<?> createPropertyDefinition(String localName, QName propType) {
throw new UnsupportedOperationException();
}

@Override
public PrismContainerDefinition<?> createContainerDefinition(QName name, QName typeName, int minOccurs, int maxOccurs) {
throw new UnsupportedOperationException();
}

@Override
public PrismContainerDefinition<?> createContainerDefinition(@NotNull QName name, @NotNull ComplexTypeDefinition ctd, int minOccurs, int maxOccurs) {
throw new UnsupportedOperationException();
}

@Override
public void setComplexTypeDefinition(ComplexTypeDefinition complexTypeDefinition) {
}

@Override
public void setProcessing(ItemProcessing processing) {
}

@Override
public void setValueEnumerationRef(PrismReferenceValue valueEnumerationRef) {
}

@Override
public void setOperational(boolean operational) {
}

@Override
public void setAlwaysUseForEquals(boolean alwaysUseForEquals) {
}

@Override
public void setDynamic(boolean value) {
}

@Override
public void setReadOnly() {
}

@Override
public void setDeprecatedSince(String value) {
}

@Override
public void addSchemaMigration(SchemaMigration value) {
}

@Override
public void setSchemaMigrations(List<SchemaMigration> value) {
}

@Override
public void setDeprecated(boolean deprecated) {
}

@Override
public void setRemoved(boolean removed) {
}

@Override
public void setRemovedSince(String removedSince) {
}

@Override
public void setExperimental(boolean experimental) {
}

@Override
public void setPlannedRemoval(String value) {
}

@Override
public void setElaborate(boolean value) {
}

@Override
public void setHeterogeneousListItem(boolean value) {
}

@Override
public void setSubstitutionHead(QName value) {
}

@Override
public void setIndexed(Boolean indexed) {
}

@Override
public void setIndexOnly(boolean value) {
}

@Override
public void setInherited(boolean value) {
}

@Override
public void setSearchable(boolean value) {
}

@Override
public void setOptionalCleanup(boolean optionalCleanup) {
}

@Override
public void setRuntimeSchema(boolean value) {
}

@Override
public void setMergerIdentifier(String value) {
}

@Override
public void setNaturalKeyConstituents(List<QName> naturalKeyConstituents) {
}

@Override
public void setCanRead(boolean val) {
}

@Override
public void setCanModify(boolean val) {
}

@Override
public void setCanAdd(boolean val) {
}

@Override
public void setDisplayHint(DisplayHint displayHint) {
}

@Override
public void setEmphasized(boolean emphasized) {
}

@Override
public void setDisplayName(String displayName) {
}

@Override
public void setDisplayOrder(Integer displayOrder) {
}

@Override
public void setHelp(String help) {
}

@Override
public void setDocumentation(String documentation) {
}

@Override
public void setDiagrams(List<ItemDiagramSpecification> value) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.schema.util.ShadowUtil;
Expand Down Expand Up @@ -137,14 +138,28 @@ private void applyToAssociationDelta(ItemDelta<?, ?> itemDelta)
// just to be sure
return;
}
if (!(itemDelta.getDefinition() instanceof ShadowAssociationDefinition)) {
if (requiresDefinitionApplication(itemDelta)) {
//noinspection unchecked,rawtypes
((ItemDelta) itemDelta).applyDefinition(
definition.findAssociationDefinitionRequired(
itemDelta.getElementName()));
}
}

private static boolean requiresDefinitionApplication(ItemDelta<?, ?> itemDelta) {
if (!(itemDelta.getDefinition() instanceof ShadowAssociationDefinition)) {
return true;
}
// TODO implement in a nicer way
AtomicBoolean containsRaw = new AtomicBoolean(false);
itemDelta.foreach(val -> {
if (!(val instanceof ShadowAssociationValue)) {
containsRaw.set(true);
}
});
return containsRaw.get();
}

/**
* Just applies the definition to a bean.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,6 @@ public int hashCode() {
return currentLayer;
}

@Override
public @NotNull QName getTypeName() {
return nativeDefinition.getTypeName();
}

public boolean isRuntimeSchema() {
return true;
}
Expand Down

0 comments on commit 17b242a

Please sign in to comment.