in services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java [1221:1283]
private boolean mergeSystemProperties(Map<String, Object> targetProperties, Map<String, Object> sourceProperties) {
boolean changed = false;
for (Map.Entry<String, Object> sourceProperty : sourceProperties.entrySet()) {
if (sourceProperty.getValue() != null) {
if (!targetProperties.containsKey(sourceProperty.getKey())) {
targetProperties.put(sourceProperty.getKey(), sourceProperty.getValue());
changed = true;
} else {
Object targetProperty = targetProperties.get(sourceProperty.getKey());
if (targetProperty instanceof Map && sourceProperty.getValue() instanceof Map) {
// merge Maps like "goals", "campaigns"
@SuppressWarnings("unchecked")
Map<String, Object> mapSourceProp = (Map<String, Object>) sourceProperty.getValue();
@SuppressWarnings("unchecked")
Map<String, Object> mapTargetProp = (Map<String, Object>) targetProperty;
for (Map.Entry<String, ?> mapSourceEntry : mapSourceProp.entrySet()) {
if (!mapTargetProp.containsKey(mapSourceEntry.getKey())) {
mapTargetProp.put(mapSourceEntry.getKey(), mapSourceEntry.getValue());
changed = true;
}
}
} else if (targetProperty instanceof Collection && sourceProperty.getValue() instanceof Collection) {
// merge Collections like "lists"
if (ControlGroupPersonalizationStrategy.PERSONALIZATION_STRATEGY_STATUS.equals(sourceProperty.getKey())) {
// Special handling for personalization strategy statuses
// TODO UNOMI-719: move this in a dedicated extension point to handle this kind of merge strategy in a more generic way
List<Map<String, Object>> sourceStatuses = (List<Map<String, Object>>) sourceProperty.getValue();
List<Map<String, Object>> targetStatuses = (List<Map<String, Object>>) targetProperty;
for (Map<String, Object> sourceStatus : sourceStatuses) {
if (targetStatuses
.stream()
.noneMatch(targetStatus -> targetStatus.get(ControlGroupPersonalizationStrategy.PERSONALIZATION_STRATEGY_STATUS_ID)
.equals(sourceStatus.get(ControlGroupPersonalizationStrategy.PERSONALIZATION_STRATEGY_STATUS_ID)))) {
// there is no existing status for the status ID, we can safely add it to master
targetStatuses.add(sourceStatus);
changed = true;
}
}
} else {
Collection sourceCollection = (Collection) sourceProperty.getValue();
Collection targetCollection = (Collection) targetProperty;
for (Object sourceItem : sourceCollection) {
if (!targetCollection.contains(sourceItem)) {
try {
targetCollection.add(sourceItem);
changed = true;
} catch (Exception e) {
// may be Collection type issue
}
}
}
}
}
}
}
}
return changed;
}