Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Kateryna Honchar committed May 9, 2022
2 parents bef3a0c + 0e1f2a0 commit 98dd034
Show file tree
Hide file tree
Showing 26 changed files with 924 additions and 271 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2010-2022 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.merger;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.PathKeyedMap;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.SchemaException;

import org.jetbrains.annotations.NotNull;

import java.util.Map;

/**
* Implements the actual merging of two objects ({@link Containerable}) of the same type.
*
* @param <C> type of objects to be merged
*/
public abstract class BaseMergeOperation<C extends Containerable> {

@NotNull private final C target;
@NotNull private final C source;
@NotNull private final ItemMerger rootMerger;

protected BaseMergeOperation(@NotNull C target, @NotNull C source, @NotNull ItemMerger rootMerger) {
this.target = target;
this.source = source;
this.rootMerger = rootMerger;
}

public void execute() throws ConfigurationException, SchemaException {
rootMerger.merge(target.asPrismContainerValue(), source.asPrismContainerValue());
}

protected static boolean hasValue(PrismContainerValue<?> pcv, @NotNull ItemName itemName) {
Item<?, ?> item = pcv.findItem(itemName);
return item != null && item.hasAnyValue();
}

protected static PathKeyedMap<ItemMerger> createPathMap(Map<ItemPath, ItemMerger> sourceMap) {
PathKeyedMap<ItemMerger> newMap = new PathKeyedMap<>();
newMap.putAll(sourceMap);
return newMap;
}

protected static PathKeyedMap<ItemMerger> emptyPathMap() {
return new PathKeyedMap<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.provisioning.impl.resources.merger;
package com.evolveum.midpoint.schema.merger;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;
Expand All @@ -24,7 +24,7 @@
import javax.xml.namespace.QName;
import java.util.*;

import static com.evolveum.midpoint.provisioning.impl.resources.merger.GenericItemMerger.Kind.CONTAINER;
import static com.evolveum.midpoint.schema.merger.GenericItemMerger.Kind.CONTAINER;
import static com.evolveum.midpoint.util.MiscUtil.argCheck;
import static com.evolveum.midpoint.util.MiscUtil.stateCheck;

Expand All @@ -40,7 +40,7 @@
* 2. For multi-valued items with a natural key defined, the values having the same key are considered matching.
* 3. For multi-valued items without a natural key, no values are matching.
*/
class GenericItemMerger implements ItemMerger {
public class GenericItemMerger implements ItemMerger {

private static final Trace LOGGER = TraceManager.getTrace(GenericItemMerger.class);

Expand All @@ -50,14 +50,14 @@ class GenericItemMerger implements ItemMerger {
/** Mergers to be used for child items. */
@NotNull private final PathKeyedMap<ItemMerger> childrenMergers;

GenericItemMerger(
public GenericItemMerger(
@Nullable NaturalKey naturalKey,
@NotNull PathKeyedMap<ItemMerger> childrenMergers) {
this.naturalKey = naturalKey;
this.childrenMergers = childrenMergers;
}

GenericItemMerger(@NotNull PathKeyedMap<ItemMerger> childrenMergers) {
public GenericItemMerger(@NotNull PathKeyedMap<ItemMerger> childrenMergers) {
this(null, childrenMergers);
}

Expand Down Expand Up @@ -115,26 +115,27 @@ public void merge(
Item<?, ?> sourceItem = source.findItem(itemName);
if (sourceItem == null || sourceItem.hasNoValues()) {
LOGGER.trace("Nothing found at source; keeping target unchanged");
return;
}
Item<?, ?> targetItem = target.findItem(itemName);
if (targetItem == null || targetItem.hasNoValues()) {
LOGGER.trace("Nothing found at target; copying source value(s) to the target");
//noinspection unchecked
target.add(
sourceItem.clone());
return;
}
boolean isTargetItemSingleValued = isSingleValued(targetItem);
boolean isSourceItemSingleValued = isSingleValued(sourceItem);
stateCheck(isSourceItemSingleValued == isTargetItemSingleValued,
"Mismatch between the cardinality of source and target items: single=%s (source) vs single=%s (target)",
isSourceItemSingleValued, isTargetItemSingleValued);
if (isSourceItemSingleValued) {
mergeSingleValuedItem(targetItem, sourceItem);
} else {
mergeMultiValuedItem(targetItem, sourceItem);
Item<?, ?> targetItem = target.findItem(itemName);
if (targetItem == null || targetItem.hasNoValues()) {
LOGGER.trace("Nothing found at target; copying source value(s) to the target");
//noinspection unchecked
target.add(
sourceItem.clone());
} else {
boolean isTargetItemSingleValued = isSingleValued(targetItem);
boolean isSourceItemSingleValued = isSingleValued(sourceItem);
stateCheck(isSourceItemSingleValued == isTargetItemSingleValued,
"Mismatch between the cardinality of source and target items: single=%s (source) vs single=%s (target)",
isSourceItemSingleValued, isTargetItemSingleValued);
if (isSourceItemSingleValued) {
mergeSingleValuedItem(targetItem, sourceItem);
} else {
mergeMultiValuedItem(targetItem, sourceItem);
}
}
}
LOGGER.trace("Finished merging item {}", itemName);
}

private void mergeSingleValuedItem(Item<?, ?> targetItem, Item<?, ?> sourceItem)
Expand Down Expand Up @@ -226,14 +227,14 @@ private boolean isSingleValued(@NotNull Item<?, ?> item) {
}
}

static class NaturalKey {
public static class NaturalKey {
@NotNull private final Collection<QName> constituents;

private NaturalKey(@NotNull Collection<QName> constituents) {
this.constituents = constituents;
}

static NaturalKey of(QName... constituents) {
public static NaturalKey of(QName... constituents) {
return new NaturalKey(List.of(constituents));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.provisioning.impl.resources.merger;
package com.evolveum.midpoint.schema.merger;

import org.jetbrains.annotations.NotNull;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.provisioning.impl.resources.merger;
package com.evolveum.midpoint.schema.merger;

import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.provisioning.impl.resources.merger;
package com.evolveum.midpoint.schema.merger;

import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.path.ItemName;

import com.evolveum.midpoint.schema.merger.resource.ResourceMergeOperation;
import com.evolveum.midpoint.util.exception.ConfigurationException;

import com.evolveum.midpoint.util.exception.SchemaException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2010-2022 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.merger.objdef;

import static com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType.F_ABSTRACT;

import java.util.Map;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.schema.merger.BaseMergeOperation;
import com.evolveum.midpoint.schema.merger.GenericItemMerger;
import com.evolveum.midpoint.schema.merger.IgnoreSourceItemMerger;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDefinitionType;

/**
* Merges {@link ResourceObjectTypeDefinitionType} objects.
*/
public class ResourceObjectTypeDefinitionMergeOperation extends BaseMergeOperation<ResourceObjectTypeDefinitionType> {

public ResourceObjectTypeDefinitionMergeOperation(
@NotNull ResourceObjectTypeDefinitionType target,
@NotNull ResourceObjectTypeDefinitionType source) {

super(target,
source,
new GenericItemMerger(
createPathMap(
Map.of(
F_ABSTRACT, IgnoreSourceItemMerger.INSTANCE // otherwise everything would be abstract
// TODO attribute/associations (natural keys)!
))));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (C) 2010-2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

/**
* Supports merging of (usually) configuration beans.
*
* For example, resource inheritance and object type inheritance is implemented here.
*
* Other uses will be considered in the future.
*/
package com.evolveum.midpoint.schema.merger;

0 comments on commit 98dd034

Please sign in to comment.